Сейчас проверил, и требуются разъяснения. Скрипт выставил заявку. Система приняла, в онордере флаг 29, лотов 5 произошло частичное исполнение, трейд. в онордере флаг опять 29, остаток 4 (продался один контракт)
Я расчитывал, что флаг изменится и строил логику поиска нужной записи по номеру заявки и изменившемуся флагу на частичное исполнение. Вижу что по факту флаг что при выставлении, что после частичного исполнения не изменился. Проясните, в чем я не прав и как работать с флагом?
Добрый день, Сергей! Зарегистрируйте, пожалуйста, пожелание. Если его нет еще. Получается, что вкладки можно создавать, и фильтры есть, а по инструментам отформатировать таблицы прямого функционала не достаточно.
Добрый день! Не нашел ни в документации ни на форуме. Скажите, какой символ в пользовательском фильтре таблицы означает "любой символ"? Например мне нужно, чтобы в таблице отображались только опционы сбера. Они имеют формат: SR(страйк)BH5 например Хочу чтобы в таблице отображались только сберовские с любым страйком. Что то типа SR******BH5. (Все колы сбера)
Что интересно, с dir можно и на русском, а ping на русском не получается.
Viktor MMM , с вас - парсер результатов вывода. А то мне лень самому делать.
Отлично! Спасибо большое! Не догадался бы так сделать. То, что не пишет на русском, я не расстраиваюсь. Подойдет и английский. Читал на просторах, что луа под кириллицу плохо заточен, так что дальше в этом направлении и копать не буду. Результат читабельный, можно смело кидать в лог, вытаскивать нужные данные, проверять - в сервере дело или в инете.
Что за парсер вас интересует? В смысле, вытащить отдельно % потерь или еще чего? Скажите, сделаю.
Да это понятно, что в данном случае можно и так обойтись. Но я хочу сделать по-человечески. Сообщения могут отличаться. И гадать что там не хочу. Уже почти нашел решение, упускаю перекодировку, перевожу на английский - устроит вполне. Дело осталось за запуском двух команд в одной сессии командной строки. Если подскажете как это сделать, буду признателен.
Пошел другим путем. Если в командной строке перед пингом ввести chcp 861, то сообщения пойдут на англицком. Если потом chcp 866, вернется кодировка русская. Вопрос, как в указанном выше скрипте добавить исполнение chcp 861? Чтоб не новая "сессия" командной строки начиналась, а в составе той, что с пингом?
Скрипт библиотеки нашел, скопировал, но не работает. Разобраться сам не могу. Кто-нибудь еще знает способы перекодировки? Был бы признателен за, может, более явную наводку.
Михаил, спасибо за наводку, но у меня не работает пример. Ругается на bit32. Судя по всему надо подключать какие то библиотеки, в луа 5.3 она уже включена, но как его доустановить - понять не могу да и будет ли это работать в квике - не знаю. У меня стоит 5.1, ставил вроде без танцев с бубном. Скажите, эту библиотеку можно отдельно подключить? как это сделать, если она уже в составе сборки? Для меня работа с библиотеками - темный лес, ничего не понимаю(( Может, есть другой способ решения моей задачи?
Вот сама функция, взята из примера, на который навел Сергей Горохов
Код
function backticks_table(cmd)
local tab = {}
local pipe = assert(io.popen(cmd),
"backticks_table(" .. cmd .. ") failed.")
local line = pipe:read("*line")
while line do
table.insert(tab, line)
line = pipe:read("*line")
end
return tab
end
for k, v in ipairs(backticks_table("ping google.com"), k) do
print(v)
end
Что значит сохранить? Я не вполне понимаю. Скрипт пингует айпишник. Получает строку с вышеуказанным содержимым. Я хочу с этой строки взять нужные данные (полбеды, решаемо) но и хочу её в нормальной кодировке, в которой луа и выдает строки в файл и в дебугвью, выдать в лог. А получаются - кроказябры. Посреди нормально читаемого лога вот эта хрень. Отсюда и вопрос, как перекодировать строку и выдать её в читаемом виде?
Что это за кодировка, я не силен, но, наверное, Windows)) В самой командной строке шрифт русский, все нормально. Но скрипт с луа на выходе кириллицу не дает. Как перекодировать и получить кириллицу?
к вопросу 2. Если сводить к минимуму ТВС, настраивать графики на минимальное отображение кол-ва свечей, еще что-то подстроить, списки, понятное дело, повлияет все это на качество обмена данных между раб местом и сервером? Или все это припарки?
Сергей, день добрый. Про зависание - понятно, но его не было, логи шли по скриптам, а ответа все не было. Потом он пришел секунд через 30 и из-за моей реализации скрипт поплыл.
Про брокера понятно, так что конкретизирую вопросы:
1. Ситуация - ждем ответ, его все нет. Что вы, как разработчики, посоветуете делать? Если просто дальше ждать, то может вообще моя транзакция не дошла? Если еще одну отправить - две могут в результате исполнится. Какой алгоритм действий вы можете предложить в ситуации долгого ответа?
2. Кроме бесконечного цикла в скрипте, сами по себе настройки квика могут повлиять на скорость и качество обмена инф с сервером? Нагруженость, так сказать, квика повлияет на это?
Еще вопрос. На скорость получения ответа что-то влияет? Например объем данных, получаемых в раб место, заполненность ТВС, которая к концу сессии выше и тд.
День добрый! Столкнулся с проблемой. Очередной.. Даю команду на снятие заявки. Жду сначала ответа от трансрепли, потом от онордера. Макс ожидание 10 сек. Прошла одна пауза (в раб. сессию), потом вторая десятисекундка - тишина. Скрипт решил что не прошло, и продолжил работу, благополучно навертев мне всякой ерунды.
Вопрос. Если я отправил заявку и не пришел ответ, что делать? Ждать до бесконечности? Ведь может же получиться, что и при соединении и при сессии, при всем нормальном, ответа долго не будет, а потом он придет и команда исполнится? И может ли так получиться, что команда просто уйдет в никуда и потеряется. Без всяких ответов? Если такого быть не может, то да, надо ждать, ведь отменить то, что я уже отправил и на что ответа не получил я не могу. Или могу?
Да, Николай, здравствуйте. Я понял уже что появление события рубит мой поток или как его назвать.. Хотел сделать скрипт изящнее, с использованием возможностей клуа, но, из-за того что я не программист, пришлось приводить архитектуру к обычному синхронному языку. События дополняют таблицы и все. А скрипт по этим таблицам в нужное время работает. Понимаю, что получился велосипед на платформе машины, но только так смог добиться устойчивой работы.
Ясно. Выходит, что отслеживать "лишние" надо всегда. По алгоритму я правильно написал. Ждать, рубить и заново. Предвидеть и все четко сделать не получится по определению.
А что со статусами было? 0 и 1 выскакивали? не отслеживали? Или сразу через 10 сек статус 3 и в путь.
Получается такая логика. Скрипт в начале, собственно так и есть у меня, проверяет выставленные "прошлые заявки" от этого скрипта. Если есть - рубит их все, а потом начинает работу. Если пошла задержка, и время вышло - в начало скрипта. И так будет до тех пор, пока для начала не примутся заявки на рубку))
Вот лично я бы на брокера грешил. Это может быть "слабым звеном". А начнете разбирательства, ниточки уйдут. А при смене было б идеально открыть счет на другое имя. На жену/ребенка..
Теоретически, конечно, но если вы свой алгоритм 100% знаете и 100% знаете что делает злоумышленник в ответ на это, можете другим ботом на другом брокере его начать косить) Но брокера надо менять, ответ от биржи, думаю, быстро не получите, а действовать надо уже вчера. Можно не менять даже а просто открыть с меньшим если страта позволит у другого и там запустить. На первом либо приостановиться либо снизить объемы.
День добрый! Согласно документации по клуа, событие в OnTransReply должно появляться всегда в ответ на транзакцию пользователя. Формат следующий (из документации по квику):
«0» - транзакция отправлена серверу,
«1» - транзакция получена на сервер QUIK от клиента,
«2» - ошибка при передаче транзакции в торговую систему, поскольку отсутствует подключение шлюза Московской Биржи, повторно транзакция не отправляется,
«3» - транзакция выполнена,
«4» - транзакция не выполнена торговой системой, код ошибки торговой системы будет указан в поле «DESCRIPTION»,
«5» - транзакция не прошла проверку сервера QUIK по каким-либо критериям. Например, проверку на наличие прав у пользователя на отправку транзакции данного типа,
«6» - транзакция не прошла проверку лимитов сервера QUIK,
«10» - транзакция не поддерживается торговой системой. К примеру, попытка отправить «ACTION = MOVE_ORDERS» на Московской Бирже,
«11» - транзакция не прошла проверку правильности электронной подписи. К примеру, если ключи, зарегистрированные на сервере, не соответствуют подписи отправленной транзакции.
«12» - не удалось дождаться ответа на транзакцию, т.к. истек таймаут ожидания. Может возникнуть при подаче транзакций из QPILE.
«13» - транзакция отвергнута, т.к. ее выполнение могло привести к кросс-сделке (т.е. сделке с тем же самым клиентским счетом).
Вопросы: 1. Всегда ли должен прийти ответ на транзакцию при наличии связи с сервером? Другими словами, значит ли отсутствие ответа в течение какого-то времени (какого?) что связи с сервером нет? 2. Верна ли логика, что если статус не 3, то значит она отвергнута? 3. Наличие статусов 0 и 1 говорит о том, что заявка подвисла и не обработана, но получена и, теоретически, может быть принята. Значит ли это, что надо просто подождать, получив эти статусы? Сколько ждать? 4. И, как результат, сообщите алгоритм, по которому можно 100% выяснить, что заявка прошла или не прошла.
s_mike@rambler.ru, да, спасибо, про загрузку колбэков помню. Сейчас еще помучаю корутины с циклом, нашел еще пример и, скорее всего, сделаю как Вы говорите.
PS на простых примерах у меня корутины эти работают, но как появляются колбэки так все сыпется. Что-то я не учитываю.
Да, эту ссылку Вы уже мне давали, или еще где от Вас я её видел и просматривал. В моем вопросе, к сожалению, не сдвигает меня с мертвой точки. Но тут, я понимаю, дело во многом во мне. Наверняка. Все-равно спасибо.
sam063rus, да, я его переделал. Вынес создание за цикл, резюмировал в итоге только тогда когда статус - dead. Вот сейчас это выглядит так: (то, что относится к корутине)
Код
function OnOrder(trans_order)
PrintDbgStr("В онордере прошло событие flag ="..tostring(flag))
PrintDbgStr("статус в онордере " .. tostring(coroutine.status(co)))
--if coroutine.status(co) == "running" then coroutine.resume(co) end
if flag and trans_order["sec_code"] == SECCODE and trans_order["brokerref"] == COMMENT_ALL and trans_order["class_code"] == CLASSCODE then
table.sinsert(ORDER_TABLE,1,trans_order)
PrintDbgStr("Прошли по условию в онордер")
flag = false
--if coroutine.status(co) == "normal" or coroutine.status(co) == "suspended" then coroutine.resume(co) end
coroutine.resume(co)
end
end
закомментированы разные варианты, я пробую то так то эдак.. Flag, что бы при двойном подтверждении два раза не срабатывал резюм.
Код
function bots()
PrintDbgStr("В BOTS скрипте даем команду на продажу")
PrintDbgStr(tostring(coroutine.status(co)))
--_SellOpt(TRID_TRADE,2000,QTY,MODE,COMMENT_ALL)
flag = true
_SellOpt(TRID_TRADE,2000,QTY,MODE,COMMENT_ALL)
PrintDbgStr("BOTS залип после продажи")
coroutine.yield()
PrintDbgStr("BOTS отлип после продажи")
--sleep (5000)
PrintDbgStr("приступаем к удалению")
PrintDbgStr(tostring(coroutine.status(co)))
--sleep(1000)
num2 = _GetActiveOrdersNum()[1]
PrintDbgStr("Выставлена заявка №".. tostring(num2))
flag = true
_KillOrder(num2,TRID_KILL)
PrintDbgStr("BOTS залип после удаления")
coroutine.yield()
PrintDbgStr("BOTS отлип после удаления")
--coroutine.resume(co)
end
is_run=true
flag = true
PrintDbgStr(COMMENT_ALL..": Инициализация прошла")
co = coroutine.create(bots)
function main( ... )
first = true
PrintDbgStr(tostring(coroutine.status(co)))
while is_run do
PrintDbgStr("В основном скрипте пошел прогон")
PrintDbgStr(tostring(coroutine.status(co)))
if first then coroutine.resume(co)
first = false
end
if coroutine.status(co) == "dead" then
co = coroutine.create(bots)
end
PrintDbgStr(tostring(coroutine.status(co)))
sleep(200)
end
end
и лог в итоге:
Скрытый текст
00000001 0.00000000 [9384] SR6500BF5//SCRYPT: Инициализация прошла 00000002 0.00055721 [9384] suspended 00000003 0.00062351 [9384] В основном скрипте пошел прогон 00000004 0.00070361 [9384] suspended 00000005 0.00077565 [9384] В BOTS скрипте даем команду на продажу 00000006 0.00083352 [9384] running 00000007 0.00097225 [9384] SR6500BF5//SCRYPT: Проверка цены на существенный выход. Цена в установленных пределах _VerifyPriceToTheor(price,direction) 00000008 0.00130182 [9384] SR6500BF5//SCRYPT: Отправляю команду в терминал на Продажу _SellOpt(trid,price,qty,mode,comment) 00000009 0.00482790 [9384] BOTS залип после продажи 00000010 0.00490033 [9384] suspended 00000011 0.20509318 [9384] В основном скрипте пошел прогон 00000012 0.20515488 [9384] suspended 00000013 0.20520814 [9384] suspended 00000014 0.36994475 [9384] В онордере прошло событие flag =true 00000015 0.37005705 [9384] статус в онордере suspended 00000016 0.37009996 [9384] Прошли по условию в онордер 00000017 0.37016127 [9384] BOTS отлип после продажи 00000018 0.37022066 [9384] приступаем к удалению 00000019 0.37028122 [9384] running 00000020 0.37132820 [9384] В онордере прошло событие flag =false 00000021 0.37138492 [9384] статус в онордере dead 00000022 0.40539524 [9384] В основном скрипте пошел прогон 00000023 0.40549716 [9384] dead 00000024 0.40567231 [9384] suspended 00000025 0.60553598 [9384] В основном скрипте пошел прогон 00000026 0.60559422 [9384] suspended 00000027 0.60565478 [9384] suspended 00000028 0.80577093 [9384] В основном скрипте пошел прогон 00000029 0.80582190 [9384] suspended 00000030 0.80587631 [9384] suspended 00000031 1.00597680 [9384] В основном скрипте пошел прогон 00000032 1.00604546 [9384] suspended 00000033 1.00611746 [9384] suspended 00000034 1.21077490 [9384] В основном скрипте пошел прогон 00000035 1.24667192 [9384] suspended 00000036 1.26349628 [9384] suspended . . . . 00000085 4.54232550 [9384] SR6500BF5//SCRYPT: Скрипт остановлен пользователем
вот это место:
00000017 0.37016127 [9384] BOTS отлип после продажи 00000018 0.37022066 [9384] приступаем к удалению 00000019 0.37028122 [9384] running 00000020 0.37132820 [9384] В онордере прошло событие flag =false 00000021 0.37138492 [9384] статус в онордере dead
с чего вдруг когда отлипает BOTS, скрипт проходит дальше,статус руннинг, и как заходит в num2 = _GetActiveOrdersNum()[1], появляется событие в онордере, flag пустить не должен на резюм, а статус уже DEAD. Что может два раза резюмировать или даже три!!! чтобы корутина померла так досрочно..
Наверное, я это и делаю. Я хочу, чтобы скрипт не работал дальше пока не придет подтверждение. Это и есть синхронная работа. Но просто завешивать его циклом (а вместе с ним, наверное, и другие скрипты) я не хочу. Вот и пытаюсь тоже самое сделать через корутины и их приостановки/возобновление. Но вот ведут они себя не понятно. Я не программист, потому мне и непонятно) То была активна то вдруг умерла.. Еще пару дней или завтра побьюсь о них и брошу. Я бы не стал особо за них цепляться, если бы Михаил не посоветовал. К его мнению прислушиваюсь. Но, конечно, может он и не понял задачу и посоветовал то, что работать не будет, тем более что потом отписался, что может и не потребуются они. Но они же, блин, как раз вроде то и делают!Ну вот, как то так)
Мне приходится её ожидать, чтобы не было двойных/тройных заявок. Скрипт входит по несколько раз пока не пришла информация. Конечно, можно рубить флагами, флаги сбрасывать по событиям. Потом еще наслаиваются фокусы с двойными подтверждениями.. потому и пришел к этой задаче. Реализовать - не получается пока. Умирает корутина и все.. Почему -не знаю, даже тему отдельную создал
Есть функция, вызывается как корутина. В ней две остановки - после выставления ордера и после снятия ордера. в трансрепли (или в ордеррепли - не важно) стоит разрешение работать дальше. Первая остановка проходит нормально, заявка выставляется. Пока корутина не начала работать её статус - suspended начала - running когда выполняем первый останов статус - suspended транзрепли его отлепляет и статус становится опять running тут все понятно, все логично так и быть должно
но, когда в функции начинает исполнятся другая функция (это единственное наблюдение) статус моей корутины - dead. А я еще не дошел до второй остановки даже. Не с чего ей останавливаться по завершению. Я ведь правильно понимаю, что dead - значит завершена? или я не прав?
Да, ошибка перестала выскакивать, спасибо. Но все это время пытаюсь заставить скрипт работать как мне надо - не получается. Многое уже поменял. Михаил, скажите, пожалуйста, реально ли воплотить на корутинах такую логику:
майн запускает корутину. в ней функция выставления ордера на продажу. после выставления прерываю её через coroutine.yield() Хочу чтобы функция дальше не работала, а ждала resume от OnOrder Пришло подтверждение - работаем дальше.
Как я это делаю - работает не понятно как. Статус корутины то normal, то running, то вдруг dead, хотя до конца функция в корутине не доработала.. Может я и все правильно делаю, может эти корутины в квике как-то работают особенно, что моей логике не поддаются? Их вообще используют? А то может бьюсь головой о стену..
Michael Bulychev, добрый день! По разным источникам стараюсь разобраться с корутинами, раз уж без них никак. Пожалуйста, подскажите, что не так делаю?
Задача следующая. Выставляю ордер на продажу. Хочу, чтобы после отправки заявки, функция приостановилась и возобновила работу после получения и обработки ответа от OnOrder.
Часть кода без входных переменных и инициализации, убрал лишнее
Код
function _SellOpt(trid,price,qty,mode,comment)
-----------
local command =---------
PrintDbgStr(COMMENT_ALL..": Отправляю команду в терминал на Продажу _SellOpt(trid,price,qty,mode,comment)")
local _commToQuik = sendTransaction(command)
return 0
end
function OnOrder(trans_order)
PrintDbgStr("В онордере прошло событие ")
if trans_order["sec_code"] == SECCODE and trans_order["brokerref"] == COMMENT_ALL and trans_order["class_code"] == CLASSCODE then table.sinsert(ORDER_TABLE,1,trans_order)
is_run = false
coroutine.resume(co)
end
end
function bots()
PrintDbgStr("В BOTS скрипте даем команду на продажу")
_SellOpt(TRID_TRADE,2000,QTY,MODE,COMMENT_ALL)
PrintDbgStr("BOTS залип")
coroutine.yield()
PrintDbgStr("BOTS отлип")
end
function main( ... )
while is_run do
PrintDbgStr("В основном скрипте пошел прогон")
co = coroutine.create(bots())
sleep(2000)
end
end
После исполнения скрипт, выставив заявку останавливается с ошибкой в окне доступных скриптов:
Код
attempt to yield across metamethod/C-call boundary
Лог:
Код
00000001 12:23:37 [7844] SR6500BF5//SCRYPT: Инициализация прошла
00000002 12:23:37 [7844] В основном скрипте пошел прогон
00000003 12:23:37 [7844] В BOTS скрипте даем команду на продажу
00000004 12:23:37 [7844] SR6500BF5//SCRYPT: Проверка цены на существенный выход. Цена в установленных пределах _VerifyPriceToTheor(price,direction)
00000005 12:23:37 [7844] SR6500BF5//SCRYPT: Отправляю команду в терминал на Продажу _SellOpt(trid,price,qty,mode,comment)
00000006 12:23:37 [7844] BOTS залип
Мою логику, исполнения, думаю, понять не трудно. Но очевидно, что делаю не верно.
День добрый. Хочу, чтобы текущая функция, приостановилась, пока не разрешу идти дальше. Не флагом рубить всю функцию, и колбэком каким-нибудь его скидывать, а прямо посреди работы функции. Это возможно сделать? Есть такой функционал? Что то типа заморозки, а когда можно - отморозить. Но, конечно , не завесить весь терминал и другие скрипты. И сразу еще вопрос. Выход из функции возможен только через return 0 ? Есть что-то вроде break и continue?
Хочу, чтобы в лог шли не только с моего скрипта данные, но и параллельно все, что показывает квик. Мало ли, что он покажет. Без них бывает сложно определить, что именно тогда произошло. Можно, конечно, но события тогда надо предвидеть. По сообщениям было бы проще.