Люди добрый и умные, помогите начинающему скриптеру. Голову сломал. Выставляю заявку на продажу фьючерса и контролирую ее по битовым флагам на исполнение. Типа так: if bit.band(trade.flags,1) == 0 and bit.band(trade.flags,2) == 0 then ZayavkaIspolnena_F_Buy = true end После получения (строго после) условия ZayavkaIspolnena_F_Buy = true проверяю позицию по getFuturesHolding и часто получается так, что позиции теряются (не показывает getFuturesHolding), хотя заявка исполнена. Ставил задержку между ZayavkaIspolnena_F_Buy и getFuturesHolding sleep (1000) - уже лучше, но на 5 раз проскочило опять, в этот раз была заявка на 20 позиций реализована частями (15+3+1+1), а на getFuturesHolding выдало наличие =18 (а по факту в портфеле появились все 20 фьючерсов), т.е. последние 2 сделки не успели по системе перейти в позиции до сработки getFuturesHolding. Топорно увеличивать еще паузу между ZayavkaIspolnena_F_Buy и getFuturesHolding - но до какого интервала? да и не правильно это, концепт моего бота подламывает. Уверен, что опытные товарищи эту проблему легко решают в коде, подскажите, как точно получить значение реализованной заявки.
p.s. по-простому расчетно брать из кол-ва в заявке мне не вариант, т.к. скрипт подразумевает частичное исполнение заявки и снятие ее, потом расчет, и перевыставление на остаток, т.е. мне надо контролировать позицию к заявке по наличию в портфеле
Дмитрий, А зачем Вы вообще связываетесь с getFuturesHolding? Вы знаете, что заявка исполнена (или исполнена частично, или не исполнена вообще). Портфель тоже нередко глючит (это если у брокера его смотреть). Так контролируйте всё, что угодно по собственным данным скрипта, ведите портфель сами, периодически сверяясь с брокером.
Евгений написал: где то в коде скорее всего ошибка
там код проще простого, я везде месседжей и "ловушек" понаставил, код идет без ошибок и хронологически по месседжам видно, что заявка исполнена, а позиций нет
Владимир написал: Дмитрий, А зачем Вы вообще связываетесь с getFuturesHolding? Вы знаете, что заявка исполнена (или исполнена частично, или не исполнена вообще). Портфель тоже нередко глючит (это если у брокера его смотреть). Так контролируйте всё, что угодно по собственным данным скрипта, ведите портфель сами, периодически сверяясь с брокером.
Вот оно как прогрессивный люд то делает... Понял, попробую так, расчетно держать портфель, по итогам операции или по таймингу делать сверку с портфелем в терминале. Спасибо.
Дмитрий, Не знаю, как прогрессивный люд, а я делаю только так. Только ещё нюанс: функция сверки с портфелем тоже глючит, и в данный момент она у меня отключена.
Владимир написал: Дмитрий, Не знаю, как прогрессивный люд, а я делаю только так. Только ещё нюанс: функция сверки с портфелем тоже глючит, и в данный момент она у меня отключена.
Понятно. А если говорить про расчетным метод контроля, не могли бы еще подсказать, почему OnTrade - функция обратного вызова по сделке - вызывается по каждой сделке ровно 3 раза, а не один? специально ставил счетчик по номеру заявки и сравнивал с таблицей сделок - кол-во по счетчику в OnTrade набегает всегда ровно в 3 раза больше кол-ва сделок. Наверное, что-то кроме самой сделки еще колбэк ловит?
Дмитрий, Я когда-то тоже спрашивал "почему OnTrade вызывается по каждой сделке ровно 3 раза, а не один". И даже пару раз регистрировал пожелание, чтобы убрать этот маразм (как и многие другие пользователи в течение многих лет). Теперь, по слухам, она вызывается уже не 3, а 4 раза. На днях тут обсуждалось и высказывалось сожаление, что не 5.
О, я в тренде вопросов ))) Главное заключается в том, что многократный вызов колбэка утраивает все расчетные значения, которые я запрашиваю для будущего расчета средней стоимости сделки по заявке, поэтому по факту средняя стоимость сделки из одной большой заявки выходит правильно.
Владимир написал: Дмитрий , Не знаю, как прогрессивный люд, а я делаю только так. Только ещё нюанс: функция сверки с портфелем тоже глючит, и в данный момент она у меня отключена.
Понятно. А если говорить про расчетным метод контроля, не могли бы еще подсказать, почему OnTrade - функция обратного вызова по сделке - вызывается по каждой сделке ровно 3 раза, а не один? специально ставил счетчик по номеру заявки и сравнивал с таблицей сделок - кол-во по счетчику в OnTrade набегает всегда ровно в 3 раза больше кол-ва сделок. Наверное, что-то кроме самой сделки еще колбэк ловит?
Не знаю, насколько сложная у вас задумка, но позволю себе поделиться мыслями. 1. OnTrade идет нафиг, как и большая часть калбеков. 2. Вы выставили заявку по конкретному инструменту. Контролируйте ее исполнение по флагам, но тут есть нюансы. 3. Если даже заявка по флагам исполнена - не факт, что она не отклонена биржей или брокером. В таком случае в таблице заявок она не появится, хоть запроверяйтесь. Поэтому либо сверяете число открытых позиций через getFuturesHolding до и после исполнения заявки, либо ловите OnTransReply и проверяете коды ошибок. Но слепо полагаться только на order.flags нельзя. 4. Цену исполнения заявки можно получить из таблицы trades. Связь между заявкой и сделкой лично мне больше нравится прослеживать через trans_id - идентификатор транзакции будет одинаковый у заявки и заключенной по ней сделки. Если вы входите в рынок по стоп-заявке, то trans_id будет одинаковый у всех - у стоп-заявки, у выставленной по ней лимитки и у сделки. Идентификаторы присваивайте инкрементно с какого-нибудь большого значения, например с 1000000. 5. Обращения к таблицам QUIK - сравнительно медленные операции, но если ваш робот не выставляет по 10000 заявок в час - то это неважно.
P.S. ZayavkaIspolnena_F_Buy = true - простите, но это жесть. Учите английский.
Glukator, Я тут уже объяснял (кажется, Николаю), почему я использую именно OnTrade и почему это единственный коллбек, который я использую. При этом мне совершенно плевать на все флаги: пришло прерывание - значит сделка совершена. Мне также плевать, отклонена ли она биржей или брокером или просто мою заявку никто не захотел исполнить: сделки не было. Число открытых позиций мой скрипт и так прекрасно знает лучше всякого getFuturesHolding, и потому ему плевать и на него, и на OnTransReply. Цену исполнения заявки можно получить после идентификации заявки, а это гарантируется только через trans_id, вместо которого мне Квик время от времени любезно преподносит 0. И дело не только в том, что "обращения к таблицам QUIK - сравнительно медленные операции", но и в том, что там информация тоже не всегда достоверна.
P.S. Мой робот не выставляет по 10000 заявок в час, но 7200 теоретически может - ограничение стоит не более двух заявок в секунду.
Спасибо за ответ. Ваш подход мне понятен, и я с ним в большинстве согласен. В моем случае уход от любых асинхронных вызовов обусловлен дрянной связью (YOTA), которая имеет привычку отваливаться в любую секунду и восстанавливаться, когда ей вздумается. Отправив заявку, можно OnTrade и не дождаться. А через 10-15 минут, когда QUIK соизволит восстановить подключение после серии ошибок "вы уже работаете в системе", все равно придется разбираться с числом позиций, чтобы понять, что же за это время изменилось. В таких условиях работать на коротких таймфреймах невозможно, и надо в первую очередь обходить различные глюки связи.
Нули в trans_id мне пока не прилетали, возьму на заметку.
Glukator написал: Спасибо за ответ. Ваш подход мне понятен, и я с ним в большинстве согласен. В моем случае уход от любых асинхронных вызовов обусловлен дрянной связью (YOTA), которая имеет привычку отваливаться в любую секунду и восстанавливаться, когда ей вздумается. Отправив заявку, можно OnTrade и не дождаться. А через 10-15 минут, когда QUIK соизволит восстановить подключение после серии ошибок "вы уже работаете в системе", все равно придется разбираться с числом позиций, чтобы понять, что же за это время изменилось. В таких условиях работать на коротких таймфреймах невозможно, и надо в первую очередь обходить различные глюки связи.
Нули в trans_id мне пока не прилетали, возьму на заметку.
В вашем случае надо либо интернет настроить , либо установить квик на виртуальный сервер. Цена вопроса рублей 300 в месяц.
На самом деле, если Вы знаете до торгов какими конкретно инструментами будете торговать и Ваш робот работает по свечам на таймах не менее минуты, то колбеки вообще не нужны. ---------------------- При таких условиях , робота проще написать как индикатор, т е скрипты Вам тоже нафиг. ------------------------------------ В итоге у Вас получится универсальный робот, который без переделки можно запускать для любого конкретного инструмента. ----------------- Рекомендую всем, особенно буратинам и чайникам.
Glukator, Да, в Вашем случае пользоваться OnTrade почти невозможно - здесь есть ещё один нюанс: после обрыва и восстановления связи прилетает колода старых прерываний, которые уже обработаны. На днях у меня оборвалась связь, скрипт продолжал работать, и после восстановления прилетело штук 50 OnTrade, если не все 100. Благо, у скрипта заведён стек активных заявок, и он всю эту хрень отфильтровал, а если нет, то портфель придётся восстанавливать часа два.
А глюков предостаточно и без проблем со связью. Нули в trans_id прилетают примерно каждую сотую сделку, но чаще всего в одном из трёх (или сколько там - 4?) коллбеков на одно событие хоть в одном из них айдишка нормальная и позволяет провести идентификацию сделки. Но не так уж и редко все прерывания приходят с нулём, и при достаточно большом количестве сделок (как у меня) это начинает раздражать. В общем, написал процедуру нечёткого поиска, которая большинство сделок с "нулями" тоже правильно идентифицирует.
Есть и другие глюки, совершенно уникальные. У меня иногда (очень редко, далеко не каждый день) вылетал скрипт с диагностикой что-то типа "attempt to index a number value". Стал разбираться - оказалось, что когда я вызываю некую функцию с аргументами вроде SomeFunc(1,2) туда приходит "не совсем то": у меня имена полей во всех таблицах целочисленные (типа "индексы") - их я и передаю. Но народные Lua-умельцы тип integer вообще отменили, заменив его на дурацкий тип number (руки бы пообрывал!), а эта антиллехтуальная сволочь со своей долбаной "динамической типизацией" (и ноги тоже!), получив эти аргументы, начинает соображать, что же это такое ей прислали. Нет, в подавляющем большинстве случаев она всё-таки соображает верно, но примерно раз на 10000 вызовов она полагает, что ей прислали не 1, а 1.002345 и пытается по этой белиберде индексироваться. Пришлось вставить на входе самой часто используемой функции j=tonumber(string.format("%1.0f",j)) - пока работает. Но куда дальше занесёт неуемная фантазия разработчиков, просто боюсь себе представить.
nikolz, Лапуль, нормальные люди создают роботов для ГРУППЫ инструментов, и отдают ему на откуп динамическую балансировку портфеля - ему ЛУЧШЕ знать какими конкретно инструментами от будет торговать "в данное время суток".
Что бы Вы понимали в коллбеках, лапуль! Мой робот работает по свечам на таймах от 10 секунд до 4 часов, и коллбеки ему очень даже нужны при торговле НА ЛЮБОМ таймфрейме. И я уже не раз говорил, что никогда не понимал на кой вообще нужны индикаторы и что слушать "рекомендации" от тех, у кого на лбу выбито крупными буквами "ЧАЙНИК" довольно утомительно.
Владимир, Вы хотя бы иногда читали документацию на Lua 5.3 б прежде, чем написать эту чушь: -------------------- " Но народные Lua-умельцы тип integer вообще отменили, заменив его на дурацкий тип number" ------------- На форуме бывают дети, они же вам верят.
для тех кому лень читать (из документации Lua5.3):
/* @@ LUA_INT_TYPE defines the type for Lua integers. @@ LUA_FLOAT_TYPE defines the type for Lua floats. ** Lua should work fine with any mix of these options (if supported ** by your C compiler). The usual configurations are 64-bit integers ** and 'double' (the default), 32-bit integers and 'float' (for ** restricted platforms), and 'long'/'double' (for C compilers not ** compliant with C99, which may not have support for 'long long'). */
nikolz, Лапуль, я не только читал, но и много раз писал об этом, начиная с самого первого своего сообщения на этом форуме:
25.09.2020 09:50:33: Я не нашёл тип данных integer ВООБЩЕ! И как же мне работать с битовыми масками? Как на Lua реализуется конструкция вида: if (iData & 0x80) { blah-blah-blah }?
28.09.2020 09:20:15: Нет, похоже, здесь мы друг друга не поняли. Как я могу анализировать указанный бит, если тип данных не integer, а real? Там же, насколько я помню, мантисса с характеристикой, а не двоичное представление числа!
29.09.2020 10:31:16: Убрать тип integer из языка, на мой взгляд, есть самая большая дурость.
29.09.2020 18:25:00: В документации на lua указан только тип number, а он принимает значения с плавающей точкой. Иными словами это тип real (float, double) в других языках программирования, но никак не integer. А что толку мне от флагов терминала? Мне нужен целочисленный тип ДЛЯ СВОИХ данных!
13.03.2021 11:47:57: Преобразование типов (tonumber, tostring) - претензий нет. Но за динамическую типизацию, замену операций булевой алгебры на убожество типа bit.band руки-ноги бы повыдёргивал разработчиком! А уж за убийство типа integer... ТАКОГО маразма я ещё не встречал ни в одном языке - Lua первый!
13.10.2020 18:51:52: В 64-разрядный integer спокойно влезают даже 20-значные числа - более 18 квинтиллионов!
19.05.2021 16:10:49: Один goto чего стоит! В Си это обычный JMP (в отличие от ассемблера, без возможности межпрограммного перехода), а здесь это кастрированное убожество, нафиг никому не нужное. Про сборщик мусора я ваще молчу. И вершина идиотизма: тип integer вообще уничтожен!
19.06.2021 19:08:23: Я прекрасно понимаю, что абсолютным приоритетом является обеспечение надёжной торговли через терминал QUIK - всё остальное вторично (включая весь Lua с потрохами или наиболее одиозные его моменты вроде динамической типизации или кражи типа integer).
25.03.2021 12:28:31: Язык отвратителен, и только за убийство типа integer и замену его на вонючий "тип number" создателей нельзя подпускать к компу ближе, чем на километр.
03.03.2021 10:13:06: Какие уж тут, к чёрту, "быстродействие и наглядность"? Вместо одной ассемблерной команды - вызов функции, вместо угробленного типа INTEGER и красавцев-операторов типа &, | или >>= убожество с указанием номера бита.
03.03.2021 11:56:56: Да я уже тыщу раз говорил: я НЕ МОГУ записать в переменную значение какого-либо типа - это как уж моча в голову интерпретатору ударит. И это ПЕРВЫЙ попавшийся мне язык за мои 40 лет программирования, в котором уничтожен тип integer! Даже в JS, у которого тоже этот идиотский "тип var") он имеется!
03.03.2021 17:44:47: There are eight basic types in Lua: nil, boolean, number, string, function, userdata, thread, and table. lua_Number. The type of floats in Lua. By default this type is double, but that can be changed to a single float or a long double.
03.03.2021 20:45:39: Повторяю: в языке НЕТ ни типа integer, ни типа float. Если бы они были, не было бы никакой проблемы с 19-значными кодами. И целочисленный тип вовсе не обязательно signed.
04.08.2021 10:49:50: Для меня вот совершенно очевидно, что тип integer обязан быть в языке - это первый язык, который я встретил за долгие годы программирования, в котором его нет!
20.02.2022 15:27:55: И вообще, разделение по потокам - это одна из главных глупостей Lua (после этой долбаной "динамической типизации" и убийства типа integer).
А документацию читайте - на заборе тоже много чего написано. Как раз для Вашего уровня квалификации как программиста.