если каждые 10 мск пересчитывать число строк в таблице, то по какой та причине бывает так что строки пропускаются. Мне пришлось писать скрипт который проверяет количество строк. И если их меньше прошлого максимума то пропускать до следующей итерации. А вообще дыр много если пишешь что та не моно.
По заданию в зависимости от базового актива, парсились фьючерсы. По первым двум сиволам. В таблице этих фиючерсов может быть 4, в зависимости от периода фьючерса. У меня их как правило два ближний и дальний, Так вот, бывает так что одна из строк не считывалась. Это критическая ошибка при написании подобного на LUA. Залепил очередную дырку.
напишите простой скрипт, возьмите любых четыре фьюча. И в цикле пересчитывайте при каждой итерации в Main количество строк, sleep 10 Всё поймете, это трешь! У вас местами будут не считываться одна из строк. Да, это арбитраж. Где не нужно вписывать ничего, лишь базовый актив! Всё остальное делается в теле скрипта. Конечно я всё давел до идеала, и залепил ещё несколько подобных дыр. Но это не торговый софт, это сплошные дыры! Дело в том, если не видеться что та, то бот уравнивает позу принося убытки. Скидывая и набирая позицию вновь. Даже не пойму как это возможно, пропустить строку которая есть в таблице. Но в моменте её типа нет!
И это не зависит от sleep 10 или 1000 это лишь увеличит шанс найти ошибку. При 1000 она будет крайне редка, но будет! И вы долго будете искать кто дурак. А дело не в вас! Просто софт, не для работы с деньгами. Дыры Дыры Дыры
function main()
local t = {
["A"] = 1,
["B"] = 1,
["C"] = 1,
["D"] = 1,
}
local _c
local _t = os.time()
local c_err = 0
while true do
local c = 0
for k,v in pairs(t) do
c = c + 1
end
if not _c then
_c = c
message("c = "..tostring(c),1)
else
if _c ~= c then
c_err = c_err + 1
message( "_c ~= c "..tostring(_c).." ~= "..tostring(c), 3 )
end
end
sleep(10)
local time = os.time()
if time - _t > 10 then
message("Количество неправильных количеств: "..tostring(c_err).." (_c = "..tostring(_c)..")",1)
_t = time
end
end
end
Boris Litvinov написал: если каждые 10 мск пересчитывать число строк в таблице, то по какой та причине бывает так что строки пропускаются. Мне пришлось писать скрипт который проверяет количество строк. И если их меньше прошлого максимума то пропускать до следующей итерации. А вообще дыр много если пишешь что та не моно.
По заданию в зависимости от базового актива, парсились фьючерсы. По первым двум сиволам. В таблице этих фиючерсов может быть 4, в зависимости от периода фьючерса. У меня их как правило два ближний и дальний, Так вот, бывает так что одна из строк не считывалась. Это критическая ошибка при написании подобного на LUA. Залепил очередную дырку.
Добрый день.
Пришлите скрипт на котором воспроизводится проблема и сообщите версию рабочего места QUIK.
Проблема, имхо, в том, что в таблице FUTURES_CLIENT_HOLDING присутствуют "технические лимиты" по фьючам, у которых Торговый счет - это строка из цифр, которые не должны отображаться обычным пользователям, и количество которых изменяется после загрузки лимитов по фьючам в Квик.
К примеру, у меня количество FUTURES_CLIENT_HOLDING выросло после старта торгов с 264 до 275, при этом сразу долгое время прыгало с 264 на 265 и обратно.
Скрытый текст
Код
local Misc = require("Misc")
local function writeTtoFile(fn)
local f = io.open(fn,"w+")
for i=0,getNumberOf("FUTURES_CLIENT_HOLDING")-1 do
local t = getItem("FUTURES_CLIENT_HOLDING",i)
f:write(Misc.asString(t),"\n")
end
f:close()
end
local function run()
local _c
local _t = os.time()
local c_err = 0
while true do
local c = getNumberOf("FUTURES_CLIENT_HOLDING")
if _c ~= c then
message("c = "..tostring(c),1)
if _c then c_err = c_err + 1 end
_c = c
--message( "_c ~= c "..tostring(_c).." ~= "..tostring(c), 3 )
local fn = getScriptPath().."\\FUTURES_CLIENT_HOLDING\\FUTURES_CLIENT_HOLDING_"..os.date("%Y%m%d_%H%M%S")..".lua"
writeTtoFile(fn)
end
sleep(10)
local time = os.time()
if time - _t > 10 then
message("Количество неправильных количеств: "..tostring(c_err).." (_c = "..tostring(_c)..")",1)
_t = time
end
end
end
function main()
local ok,res = pcall(run)
if not ok then
message( tostring(res),3 )
message( tostring(debug.traceback()),3 )
end
end
Думал что всё закрыл, и сегодня запустил на реальном счете бот! Повторю раньше он был моно! Теперь он мониторит весь спектр в зависимости от базового актива. На тестах что только не делал, обрывы сети, перезагрузка квика, набор позы выходы. всё было синхронно как часы.
С утра уже запустил на реале! в Main Sleep100 Результат на скрине. Гребаный КВИК! Друзья на S# будет так же. Специально на Lua писал для стабильности, но её нет даже на LUA В двух словах, смысл скрпта смотреть в таблицу фьючей и повторять зеркально. Но в моменте что та происходит, типа 0 позиций по фьючу. Всё на скрине!
не нужно ругать квик, он просто не для этого. как и S# - глючная надстройка над надстройкой. очевидно вы не правильно подбираете инструменты. выкиньте в помойку суррогаты и разнесите графику и датафид с исполнением. это типа очевидно и стандартно для грамотных мтс. это будет дороже, но смартком или транзакт АПИ больше подойдут для таких дел, мне кажетцта :)
Так как этот редкий глюк обнаружить крайне сложно, решил поставить счетчик на подтверждение что эта грёбаная таблица не лжет! И только после подтверждения двух итераций что поза сменилась давать добро на исполнения второй ноги! Всем удачи.
Boris Litvinov написал: Думал что всё закрыл, и сегодня запустил на реальном счете бот! Повторю раньше он был моно! Теперь он мониторит весь спектр в зависимости от базового актива. На тестах что только не делал, обрывы сети, перезагрузка квика, набор позы выходы. всё было синхронно как часы.
С утра уже запустил на реале! в Main Sleep100 Результат на скрине. Гребаный КВИК! Друзья на S# будет так же. Специально на Lua писал для стабильности, но её нет даже на LUA В двух словах, смысл скрпта смотреть в таблицу фьючей и повторять зеркально. Но в моменте что та происходит, типа 0 позиций по фьючу. Всё на скрине!
Добрый день.
Опишите последовательность воспроизведения проблемы и выложите ваш скрипт.
4 день треша. С утра запустил переделанный скипт. Повторюсь, скрипт смотрит и парсит таблицу фьючей, при этом зеркально совершая сделки базового актива. В общем был установлен счетчик, который считает итерацию. При этом не дает совершить уровнять позу на текущей. А лишь на следующей. Каждfя итерация sleep 100 Ну думалось что эта гребеная талица дает это глюк лишь в одной итерации. Вот результат на демо счете. Повторю что это происходит рас в день, а может вообще не произойти, как повезет! Дальше лечить буду Sleep 1100 будет залипать перед следующей итерацией на исполнение транзакции. Будем поглядеть, Sleep 100 в Main и сбои итерации не помогли!
Если лечение пойдет на пользу, оставлять постоянно такой тормоз не 1100 не буду! Только если 0 позиций, в этом случае будет работать фильтр. А так как выход в 0 крайне редкий. Проблема не критична! Критично то, что это вообще так работает с торговым софтом! Мне кажется этот 0 транслируется просто! И дело не совсем в квике, а в трансляции позы фьюча, но могу ошибаться!
Дело в том, что скрипт вам мой не поможет, эта же беда происходит на S#. Сложно сказать что происходит, но контроль позиции через эту таблицу крайне сложен. Понимаю что такого рода задачи мало кому нужны, пишут моно боты. Решил сделать на LUA после перенести на C++ DLL Повторюсь, при написании не программирую идею, а латаю дыры в софте, которых иметь не должен подобный продукт! Проскакивает ноль позиций, через все фильтры, значит ноль транслируют! Специально пускают в моменте! Обрывы, перезапуски Квика, входы выходы, всё работает без сбоев. Но наступает в моменте 0. Откуда он берется ХЗ И да, общаюсь с товарищем, говорит у него подобная тема на транзаке работает как часы через S#. Но стоит зайти тем же софтом через Квик, та же петрушка!
3.6.1 getFuturesHolding Функция предназначена для получения информации по фьючерсным позициям. TABLE getFuturesHolding(STRING firmid, STRING trdaccid, STRING sec_code, NUMBER type) Функция возвращает таблицу Lua с параметрами Таблицы позиций по фьючерсам. В случае ошибки функция возвращает «nil».
3.6.1 getFuturesHolding Функция предназначена для получения информации по фьючерсным позициям. TABLE getFuturesHolding(STRING firmid, STRING trdaccid, STRING sec_code, NUMBER type) Функция возвращает таблицу Lua с параметрами Таблицы позиций по фьючерсам. В случае ошибки функция возвращает «nil».
В общем пока что в глубоком тесте всё,. getFuturesHolding отложил, слишком много вводных. Повторю способ лечения. 1. После парсинга стоит счетчик, и если в таблице было найдено два SR то при пропуске строки в цикле, покажет 1 а не 2, фильтр не пропустит до следующей итерации. 2. транзакция осуществляется только на следующей итерации если позиция по фьючу 0. Плюс между итерациями срабатывает sleep 2000. Но это только при нуле по фьючам. Если позиция не 0, то ни каких задержек не стоит.
Так же подчистил скрипт и теперь могу утверждать что это баг критический для подобного софта. И будет работать аналогично на S#, ALAB и т.д. По этому вопрос с разработчиков приводов снят. А вот Разработчикам Quik следует написать самим это задание, и поставить на тест! Убедившись что у них там полный привет! Не реально усложнен контроль позиции. Живет своей жизнью так сказать таблица фьючей!
Вы не поверите, но понять что же Вы нашли я не смог. ----------------------- Давайте сначала отделим мух от котлет -------------------- 1) что такое 10 мск (мск - это что?) московское время международный стандарт или что-то другое? -------------------------- 2) Вы очевидно знаете, что для луа официально есть только C (CИ ) а не С++ и тем более не С#. Поэтому для начала либо рассказывайте какие обертки вы применяете и как вы их проверили на глюки. ------------------------------- 3) Вы очевидно знаете, что данные приходят блоками При этом могут приходить и пропущенные строки. Тот факт что у вас на тесте работает а в реале глючит намекает на такую возможность ------------------------------------- 4) Вы знаете, что в интернете все приходит асинхронно и потом склеивается пакет ------------------------------- 5) Вы знаете, что на компе используется алгоритм Нейгла и он может вам создавать плавающие задержки ------------------------------- 6) Вы знаете, что квик вообще работает на теме минимум 10 мс (миллисекунд) Этот тайм обычно используется как минимальный квант для задач. ------------------------------ Если Вы этого не знаете, то примите к сведению И расскажите медленно что Вы и как тестируете и почему решили что это баги КВИКА а не вашей программы.
Николай Камынин, вы начните искать для начала! Проблема описана выше, на любом языке, работать будет одинаково! НА ЛЮБОМ! Для себя решил уже задачу! И описал способ решения. Повторюсь контроль позиций в этой таблице затруднителен, и решается через грабли. После теста буду писать С++ DLL. С учетом этого бага.
Николай Камынин, И на счет демо вы не правильно поняли. Это я подумал что протестил. А на само деле, что бы поймать баг пяти минут мало. Как на реале, так и на демо, баг проявляется
есть догадки! дело в том, что во многих инвест конторах в квике лимиты по деньгам и бумагам (грубо говоря, все позиции клиента) загружаются вручную или автоматически из файла. Т.е. грубо говоря, квик не знает сколько у вас денег и бумаг, пока кто-то ему не "скажет" через загрузку лимитов. Такой пункт в меню квика каждый может увидеть у себя в квике. Но эта опция на клиентских квиках не работает. Так вот скорее всего в конторе Бориса загрузка лимитов может происходить более 1 раза в день. К примеру, ответственный сотрудник утром загружает лимиты из сохраненного вчера файла лимитов. Далее бэк-офис в течение дня (если не успел до начала торгов) расчитывает новые лимиты и готовит новый файл с лимитами, который снова загружаются в квик. Квик автоматически перечитывает все быстро пересчитывает. Но у Бориса его автоматика успевает получить пустые таблицы. Отсюда "баги"
Что та похожее и происходит. То что в моменте, а этого для бота более чем достаточно, транслируют пустую таблицу. При этом идет торговая сессия это очевидно! То что это происходит на серверах КВИК а не других платформах, так же доказано! Повторюсь, если это кому то будет нужно, и для тех кто пишет подобные ТС. Этот костыль придется прикручивать не зависимо от языков и приводов. Иначе ваши позиции будут скидываться, и перенабираться вновь! Проблема второй день теста, решина! Но то что speep 2000 давит при нулевой позе фьюча и по другому решить не смог это печаль! Но не не печальнее пере набора позы! Всем спасибо!
Boris Litvinov, возможно, Вы не учитываете некоторые нюансы Таблицы позиций по клиентским счетам (фьючерсы) -- futures_client_holding. Когда в ней возникают строки по инструменту, когда исчезают?
Чтобы строка с нужным фьючерсом появилась в этой таблице (если ее не было), я выдаю вспомогательную заявку по дальней цене (строка появилась) и снимаю заявку. Далее могу работать с этой строкой. Но если я закрываю позицию, то строка держится в таблице не бесконечно, а день-два, как карты лягут.
Борис Гудылин написал: Boris Litvinov , возможно, Вы не учитываете некоторые нюансы Таблицы позиций по клиентским счетам (фьючерсы) -- futures_client_holding. Когда в ней возникают строки по инструменту, когда исчезают?
Чтобы строка с нужным фьючерсом появилась в этой таблице (если ее не было), я выдаю вспомогательную заявку по дальней цене (строка появилась) и снимаю заявку. Далее могу работать с этой строкой. Но если я закрываю позицию, то строка держится в таблице не бесконечно, а день-два , как карты лягут.
Примерьтесь.
Этот пост не об этом! Читайте ветку, что бы понять суть проблемы.
Что та похожее и происходит. То что в моменте, а этого для бота более чем достаточно, транслируют пустую таблицу. При этом идет торговая сессия это очевидно! То что это происходит на серверах КВИК а не других платформах, так же доказано! Повторюсь, если это кому то будет нужно, и для тех кто пишет подобные ТС. Этот костыль придется прикручивать не зависимо от языков и приводов. Иначе ваши позиции будут скидываться, и перенабираться вновь! Проблема второй день теста, решина! Но то что speep 2000 давит при нулевой позе фьюча и по другому решить не смог это печаль! Но не не печальнее пере набора позы! Всем спасибо!
давно это было, но я не использую sleep в потоках в том числе и в main QLUA. попробуйте использовать ожидание событий в потоке а не sleep. подробнее, как это сделать см книгу Джеффри Рихтер( для тех, кто не знает)
Николай Камынин написал: давно это было, но я не использую sleep в потоках в том числе и в main QLUA. попробуйте использовать ожидание событий в потоке а не sleep. подробнее, как это сделать см книгу Джеффри Рихтер( для тех, кто не знает)