Это работает А это не работает. что в 5.3 что в 5.4
> t=setmetatable({},{ __bshl = function(x,y) print(x,y) end}) > print (t<<2) stdin:1: attempt to perform bitwise operation on a table value (global 't') stack traceback: stdin:1: in main chunk [C]: in ? > print (t>>2) stdin:1: attempt to perform bitwise operation on a table value (global 't') stack traceback: stdin:1: in main chunk [C]: in ?
Есть библиотека для 5.3. Работает на ура. И в квике и в standalone
Пересобрал ее на 5.4. Работают все три десятка ее функций (и в квике и в standalone) без каких либо проблем, кроме одной. Она работает в standalone, но напрочь отказывется работать в квике.
Выкинул из нее все лишнее, оставил минимум для теста
вызов из луа: message("result=" .. tostring(xx.test("message('hello world!!',3)")))
И если в standalone мы получаем два сообщения OK, hello world и nil в качестве возврата, то в квике мы сразу получаем loadbuffer error и дальше, конечно мусор.
Может, кто то пальцем сможет указать направление в пустыне?
Скрипт на луа, выставляющий 2 метки на один график
res = AddLabel("ri", { --IMAGE_PATH = "E:\\GoogleDisk\\ROBOT\\__TEST\\2-0.bmp", IMAGE_PATH = "E:\\GoogleDisk\\ROBOT\\__TEST\\2-0a.bmp", TEXT = "", DATE = 20220105, TIME = 150000, YVALUE = 151550, ALIGNMENT = "LEFT" }) res1 = AddLabel("ri", { IMAGE_PATH = "E:\\GoogleDisk\\ROBOT\\__TEST\\2-0.bmp", --IMAGE_PATH = "E:\\GoogleDisk\\ROBOT\\__TEST\\2-0a.bmp", TEXT = "", DATE = 20220105, TIME = 150000, YVALUE = 151650, ALIGNMENT = "LEFT" }) message(tostring(res).. " " .. tostring(res1))
Как видим, отличие лишь в бмп файле (yvalue изменены, чтобы видеть метки не друг на друге)
в результате выставляется всегда только вторая метка, при первая не выставляется. Терминал при исполнении этого скрипта выдает сообщение в окно сообщений: Произошла ошибка при загрузке файла чивотатам\2-0.bmp
скрипт выдает message вида 23465.0 nil
Из чего можно сделать вывод, что файл 2-0.bmp битый, а файл 2-0a.bmp нормальный.
ok. Но раньше то все было нормально!
Запускали мы сейчас скрипт на версии 9. Запустим его на версии 8.
Как отличить пустую свечу графика, получаемого по getcandlebyindex от правых фантомных свечей в случае, если график сдвинут вправо от источника его данных?
Settings={} Settings.Name = "minimal" getInfoParam("VERSION") function Init() return 1 end function OnCalculate(index) return 1 end
[3676] QLUA E:\Quik-Junior\LuaIndicators\1.lua:3: attempt to call a nil value (global 'getInfoParam') Куда дели функцию getInfoParam, жители крайнего Севера?
В 8.13 боевой выставляет картинку на диаграмму, а в 9.1 демо - нет. Оба терминала на одной машине, запущены одновременно, идентификаторы идентичны, проверено, скопировано через буфер обмена.
Как такое может быть? Отчего это может зависеть? Индусов в программисты наняли?
При активной работе с метками терминал через некоторое время начинает тупить и в результате вываливается с диагностикой о нехватке видеопамяти.
Свободной видеопамяти еще много гигабайт. Скрипт просто переставляет метки посредством SetLabel. Написать тест из 10 строчек кода вы должны суметь сами.
Почему вываливается если видеопамяти полно? Почему расходуется видеопамять при использовании SetLabel?
Я уже много раз вам указывал на эту ошибку (и не только я). Много раз она "будет исправлена в очередной версии ПО"
function main() message(tostring( AddLabel("gazp", {HINT="zzzzz",TEXT="",TRANSPARENCY=0,DATE=20210730,IMAGE_PATH="нет такого файла",TIME=40500,YVALUE=284.51,ALIGNMENT="RIGHT"} ))) end
Эта функция возвращает успех, номер метки. А не должна. Ошибка тянется с 2013 года, но компания Арка не чешется абсолютно.
Отдельный привет Алексею Иванникову. У вас полно ошибок, которые вы не исправляете годами или не в состоянии исправить.. Открывайте ваши регистрации или куда вы все это пишете, ищите. Можете поискать по форуму.
Каждая уважающая себя среда должна иметь кроме прочего, исполняемую в ней игрушку. Я таких для терминала quik не встречал.
Одно время была очень популярна игра 2048б мне заказывали ее написать для какого-то сайта. Вот ее вариант для quik, нарисовал под пиво:
Код
local stopped
game = {
cell = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
best = 0,
-- key = nil,
-- t = nil,
colors = { [0] = QTABLE_DEFAULT_COLOR,
[2] = RGB(248,248,255),
[4] = RGB(255,239,213),
[8] = RGB(255,222,173),
[8] = RGB(255,218,185),
[16] = RGB(205,92,92),
[32] = RGB(255,69,0),
[64] = RGB(238,238,0),
[128] = RGB(238,118,33),
[256] = RGB(255,160,122),
[512] = RGB(255,0,0),
[1028]= RGB(238,18,137),
[2048]= RGB(139,0,0)
},
create_table =
function(self)
self.t = AllocTable()
for i = 1,4 do
AddColumn(self.t, i, "", true, QTABLE_INT_TYPE, 10)
end
CreateWindow(self.t)
SetWindowPos(self.t,100,100,300,130)
for i = 1,4 do
InsertRow(self.t,i)
end
SetTableNotificationCallback(self.t,
function(_t, msg, _p, key)
if msg == QTABLE_VKEY then
self.key = key
elseif msg == QTABLE_CLOSE then
stopped = true
end
end)
SetWindowCaption(self.t, "2048 game by www.bot4sale.ru")
end,
draw =
function(self)
local cell = self.cell
for row=1,4 do
for column=1,4 do
local value = cell[(row-1)*4 + column]
SetCell(self.t,row,column,value==0 and "" or tostring(value))
SetColor(self.t,row,column,game.colors[value],0,game.colors[value],0)
end
end
end,
incr =
function(self)
local t,open = self.cell,{}
for i=1,16 do
if t[i]==0 then
open[#open+1]=i
end
end
t[open[math.random(#open)]] = math.random()<0.1 and 4 or 2
end,
pack =
function(self,ofr,oto,ost,ifr,ito,ist)
local t = self.cell
for outer=ofr,oto,ost do
local skip = 0
for inner=ifr,ito,ist do
local i = outer+inner
if t[i]==0 then
skip=skip+1
else
if skip>0 then
t[i-skip*ist],t[i],self.diff = t[i],0,true
end
end
end
end
end,
comb =
function(self,ofr,oto,ost,ifr,ito,ist)
local t = self.cell
for outer=ofr,oto,ost do
for inner=ifr,ito-ist,ist do
local i,j = outer+inner,outer+inner+ist
if t[i]>0 and t[i]==t[j] then
t[i],t[j],self.diff,self.best = t[i]*2,0,true,math.max(self.best,t[i]*2)
end
end
end
end,
move =
function(self,dir)
local loopdata = { {0,12,4,1,4,1},
{0,12,4,4,1,-1},
{1,4,1,0,12,4},
{1,4,1,12,0,-4}
}
local ofr,oto,ost,ifr,ito,ist = table.unpack(loopdata[dir])
self:pack(ofr,oto,ost,ifr,ito,ist)
self:comb(ofr,oto,ost,ifr,ito,ist)
self:pack(ofr,oto,ost,ifr,ito,ist)
end,
full =
function(self)
local t = self.cell
for r=0,12,4 do
for c=1,4 do
local i,v = r+c,t[r+c]
if (v==0) or (c>1 and t[i-1]==v) or (c<4 and t[i+1]==v) or (r>0 and t[i-4]==v) or (r<12 and t[i+4]==v) then
return false
end
end
end
return true
end,
play =
function(self)
math.randomseed(os.time())
self:incr()
self:incr()
while not stopped do
self:draw()
if self.best == 2048 then
message("Поздравляю!\n\nwww.bot4sale.ru")
break
end
if self:full() then
message("Game Over!")
break
end
self.diff = false
if self.key==0x25 then -- Left
self:move(1)
elseif self.key==0x27 then -- Right
self:move(2)
elseif self.key==0x26 then -- Up
self:move(3)
elseif self.key==0x28 then -- Down
self:move(4)
end
self.key = nil
if self.diff then
self:incr()
end
sleep(100)
end
end,
rules =
function()
message("Правила игры:\n\nВ каждом раунде появляется плитка номинала «2» или «4». Нажатием стрелки игрок может скинуть все плитки игрового поля в одну из 4 сторон. Если при сбрасывании две плитки одного номинала «налетают» одна на другую, то они превращаются в одну, номинал которой равен сумме соединившихся плиток. После каждого хода на свободной секции поля появляется новая плитка номиналом «2» или «4». Если при нажатии кнопки местоположение плиток или их номинал не изменится, то ход не совершается. Если в одной строчке или в одном столбце находится более двух плиток одного номинала, то при сбрасывании они начинают соединяться с той стороны, в которую были направлены.\nЛевый столбец с номерами строк участия в игре не принимает.\n\ns_mike@rambler.ru")
end
}
local game = game
--------------------------------------------------
function main()
game:create_table()
game:rules()
game:play()
end
В сообщении на экране www.bot4sale.ru будет оформлена как ссылка, тут все в порядке. Но при нажатии на эту ссылку открывается проводник, а не браузер. Думаю, что и с другими типами (call-to и прочими будет то же самое)
По умолчанию приложением для открытия URL назначен Хром.
возможна ли ситуация с получением данных графика, когда свеча уже имеется (учтена в getnumcandles), но ее значение не заполнено и по getCandlesByIndex возвращаются ohlcv 0?
возникает при очень частом опросе графика, последующий запрос выдает то же количество свечей, но ohlcv уже реальные
добавляя в терминал язык луа, вы наверняка подразумевали , что на нем будут писаться разные роботы и прочая торгующая ерунда.
в таком случае у вас должно быть понимание, как необходимо при помощи языка луа принимать решение о возможности начала работы алгоритма после старта скрипта.
проблема состоит в проверке, что данные, получаемые роботом из терминала, отражают текущее или почти текущее состояние торгов и можно приступать к анализу условий и самой торговле.
варианты:
1. Терминал давно запущен до запуска робота 2. Терминал и робот запущены одновременно , необходимые данные в терминале доступны 3. Терминал и робот запущены одновременно , необходимые данные в терминале пока недоступны 4. Смена сессии , нужные шлюзы доступны/недоступны, когда нибудь подключатся 5. У косого брокера на букву Ф опять понос и посреди дня он медленно и печально начал перезагружать всю историю с 1812 года 6. Инструмент неликвидный, много пропущенных свечей, в том числе последних
и так далее..
в общих словах вопрос.
как робот может понять, что данные, ему даёт терминал, являются более-менее актуальными, а не прошлогодними и можно торговать? Пожалуйста, приведите какую нибудь осмысленную последовательность проверок.
я понимаю, что терминал сам не знает, последняя свеча ему пришла или непоследняя. Но луа в терминал вы же не по пьяни встраивали, а после "регистрации пожелания, постараемся его рассмотреть и сообщить" и далее по тексту.
вы же пробовали сами что то писать на луа, верно?)
После получения сигнала смены сессии я отписываюсь от всех инструментов и подписываюсь заново. Как понимаю, это необходимо при возможном изменении истории инструмента при смене сессии.
Подписка на инструмент сразу после смены сессии ошибок не возвращает, но и "мёд не носит" - свечи не приходят, колбек не дергается.
В последней версии терминала 8 5 2 11 наблюдаю падения приложения при переносе мышкой (drag&drop) пользовательских индикаторов между диаграммами. При переносе встроенных индикаторов проблемы нет.
Что-то я сильно устал, пробуя пересобрать из исходников sqlite3.dll из пакета lua sql для работы с 8 квиком. Может, кто покажет указующим перстом, где это счастье можно взять в готовом виде?
В индикаторе необходимо сохранять определённые данные между запусками терминала
соответственно:
1. как отличить ручное удаление индикатора (или закрытие окна/диаграммы) от закрытия терминала? 2. как идентифицировать данный экземпляр индикатора, чтобы сохранить данные для него?
ну и попутно.
Третий параметр setvalue() может быть nil. Всегда и всюду в lua правые параметры nil при вызове функций можно опускать, но не в случае этой функции. Я уже раз пятый наезжаю на эту граблю... Может, стоит привести в норму?
Существует ли способ однозначно определить тип актива Фьючерсы/акции/опционы без использования таблицы текущих торгов? ТТТ может быть не открыта и получить оттуда нужные поля далеко не всегда возможно.
По коду класса тоже ненадежно, классов много разных на разных площадках
По наличию в полном наименовании слова "Фьючерсы" или "Опционы" как то видится ненадежным.
1. Как я понимаю, за прошедшие несколько лет (5? 8? 10?) ошибка терминала, проявляющаяся в НЕРИСОВАНИИ на диаграмме маленьких меток, так и не решена? Тестовый пример, иллюстрирующий проблему, я приводил на форуме очень давно и "будет исправлена в очередной версии"
2. Другая проблема. Индикатор рисует метки на диаграмме. В момент запуска терминала с установленным индикатором все прекрасно, за исключением одного - метки не выводятся. Логирование результатов AddLabel свидетельствует об успешности операций, функция возвращает номера меток в инкрементальном порядке. Но на экране их нет. Перезапуск индикатора - и все рисуется прекрасно. При обычном добавлении индикатора при уже запущенном терминале тоже все хорошо.
Было бы очень неплохо иметь возможность получать в скрипте lua колбек при нажатии пользователем метки на графике по аналогии с SetTableNotificationCallback
Сегодня установил новую версию терминала и оооо-паньки...Новый индикатор.
Цитата
Добавлен новый индикатор «Глубина рынка», отражающий объемы заявок в виде гистограммы. Подробное описание см. в п. 4.2.15 Раздела 4 «Работа с графиками» Руководства пользователя QUIK.
Что-то он мне напоминает... Даже помню что. Написано в 2015 году было.
Практически один-в-один. Все режимы те же самые, тот же способ отображения из будущего по шкале времени, та же возможность отображать накопительные объемы.
Плагиат расцениваю как комплимент )
Всем, кто пытается писать какие-то вкусности для творений арка - на заметку - даже спасибы от этой компании не дождетесь, не то что бутылку пива.
Снова возвращаюсь к вопросу. о котором разработчики позабыли, как видится.
Вот эта функция крутится в цикле опроса:
Код
-- Собирает из ТОС новые обезличенные сделки
rescan =
function()
if database.need_rescan == false then
return
end
database.need_rescan = false
local num_trades = getNumberOf("all_trades") - 1
local items = SearchItems("all_trades",
database.tos + 1,
num_trades,
database.search_function,
"class_code,sec_code,datetime.day,datetime.month,datetime.year"
) or {}
database.tos = num_trades
log.write("Получено ",`#'items," сделок")
for _,n in ipairs(items) do -- Всегда по возрастанию
database.process_trade(getItem("all_trades",n))
end
database.save()
end,
---------------------------------------------------------------
-- Обработка одной сделки
process_trade =
function(trade)
-- Костыль для фильтрации кривых обезличенных сделок, которые шлёт терминал
if not trade or trade.datetime.year == 1601 then
log.error("BS: Ошибка терминала. Недопустимая таблица обезличенной сделки ",trade)
return
end
Подписка на тиковые данные происходит по двум колбекам.
Код
oncleanup.subscribe(function()
repository.init()
end
)
onconnected.subscribe(function(flag)
if flag then
repository.init()
end
end
)
repository.init в частности исполняет следующее
Код
local security = getSecurityInfo(_class,_code)
if not security then
log.write("Инструмент ",instrument_dir," не обнаружен")
screen.add(_class,_code,INSTRUMENT_NOT_FOUND)
return
end
local ds,err = CreateDataSource(_class,_code,INTERVAL_TICK)
if not ds then
log.write("Невозможно получить обезличенные сделки по инструменту ",instrument_dir)
screen.add(_class,_code,INSTRUMENT_NOT_FOUND)
return
end
table.insert(database.ds,ds)
log.write("Подписка на инструмент ",instrument_dir," успешна")
Указанный эффект всегда происходит при первом включений терминала в пределах дня. Последующие включения такой эффект не несут.
Если я что-то делаю неправильно, было бы полезно понять. что именно. Иначе получается, что это грубая ошибка терминала.
Есть индикатор, одновременно запущенный на несколшьких разных инструментах (или одинаковых), с разными или одинаковыми настройкками, на произвольных таймфреймах и т.п.
Необходимо:
Найти способ для каждой запущенной копии индикатора сгенерировать свой ключ (строка, число) для установления связи между этой конкретной копией индикатора и внешним ПО. Основная проблема - получение внешним ПО информации о закрытии индикатора (тем или иным способом), закрытии терминала и корректная работа при перезапуске индикатора (например в режиме связанных окон).
Допустимы любые быстрые способы - средства терминала, winapi и так далее. У меня не хватает фантазии пока.
Не могу понять, что происходит с метками в момент обновления окна в режиме связанных окон.
насколько я могу предположить, что после обновления окна идентификатор остается тем же и функция Setlabelparams должна метку найти и переставить. если запрос setlabelparams происходит в момент обновления окна, там может произойти что-то неясное и, как я думаю, происходит. Но что?
Каков должен быть алгоритм работы по перестановке метки из скрипта посредством setlabelparams? чтобы он работал в режиме связанных окон?
Напоминаю также о ошибке, заключающейся в отсутствии вызова ondestroy индикатора в том же режиме связанных окон. Это серьезная проблема - невозможно исполнить финализацию (закрыть процессы, удалить файлы, отвязаться от апишных дел и прочего)
Что обусловлено отсутствие колбеков от Createdate source при условии, что последний вернул код успеха? Эффект проявляется при запуске терминала с работающим скриптом.
Эффект никогда не проявляется при запуске скрипта при уже работающем терминале.
Кусочек текста скрипта,занимающегося обработкой таблицы обезличенных сделок:
Код
-- Собирает из ТОС новые обезличенные сделки
rescan =
function()
if not database.need_tos_rescan then
return
end
local num_trades = getNumberOf("all_trades") - 1
local items = SearchItems("all_trades",
database.tos + 1,
num_trades,
database.search_function,
"class_code,sec_code,datetime.day,datetime.month,datetime.year"
) or {}
database.tos = num_trades
for _,n in ipairs(items) do
database.process_trade(getItem("all_trades",n))
end
database.save()
end,
---------------------------------------------------------------
-- Обработка одной сделки
process_trade =
function(trade)
log.write(trade)
local trade_datetime = datetime(trade.datetime)
что мы тут имеем?
rescan() получает новые сделки из ТОС и для каждой вызывает обработчик process_trade первое действие в process_trade есть вывод в лог самой сделки следующее действие - превращение времени сделки в некий объект.
Время от времени (закономерность неясна) последнее действие приводит к развалу скрипта по причине недопустимых данных в datetime сделки.
Все строчки абсолютно нормальные, а последняя выведенная очень интересна. Все поля нулевые, в том числе и datetime. Соответственно, обработка datetime приводит к краху:
Код
E:\quik\LuaIndicators\BS.lua:1085: Assert failed: /GoogleDisk/ROBOT/_LUA/datetime.lua : 106
Невозможно рассчитать Unix time: {week_day=1,hour=0,ms=0,mcs=0,year=1601,month=1,day=1,sec=0,min=0,isdst=false}
stack traceback:
E:\quik\LuaIndicators\BS.lua:1085: in function <E:\quik\LuaIndicators\BS.lua:1074>
(tail call): ?
E:\quik\LuaIndicators\BS.lua:1446: in function 'floor'
E:\quik\LuaIndicators\BS.lua:2563: in function 'process_trade'
E:\quik\LuaIndicators\BS.lua:2545: in function 'rescan'
E:\quik\LuaIndicators\BS.lua:2828: in function 'iterate'
E:\quik\LuaIndicators\BS.lua:1839: in function <E:\quik\LuaIndicators\BS.lua:1802>
Ситуация регулярно появляется как на моем компьютере, так и на множестве других компьютеров, что установлен этот скрипт.