Владимир написал: Nikolay, Не совсем так: торгую как раз ТОЛЬКО я - это я "купил 5 штук по цене X, потом еще 3 по цене Y, потом продал 2 по цене Z". Я их купил, это моя собственность, и только я могу знать, какие именно из них я продаю (хочу ли я это знать - это другой вопрос). Но ни брокер, ни кто-либо ещё этого знать в принципе не могут, и потому вынуждены считать по FIFO.
Так поэтому в Квике так и транслируется. Не нравится - считай сам.
Возникает встречный вопрос - Вы пробовали посмотреть что хранится в указанных таблицах?
Что же касается стоимости, то вот купили Вы 5 штук по цене X, потом еще 3 по цене Y, потом продали 2 по цене Z. Какая стоимость приобретения? Т.к. торгуете не только Вы, то приняты соглашения о методике расчета.
Alex написал: Пытался запустить Ваш скрипт, выдает. ошибку. attempt to index a nil value (local 'pipe')
Правильно. Lua умеет писать (читать) в существующий "именованый файл". Поэтому на другой стороне его надо создать. Т.е. нужен сервер (служба), обслуживающий каналы. Вот его и надо на стороне питона делать
local pipe = io.open("\\\\.\\PIPE\\"..pipe_name, "w+b")
if not pipe then
return
end
pipe:write('BlaBla') -- записываем команду в канал
--Читаем
local rd = ''
local ct = os.time()
-- Для примера: Т.к. время ожидания ответа может быть не мгновенным, то ожидаем 2 секунды, читая из канала ответ.
while os.time() - ct < 2 and rd == '' do
rd = pipe:read('*a')
end
tele_pipe:close() -- закрываем канал
А python - это же такая "помойка". Неужели нет готовой библиотеки сервера named pipes? Поиск выдает тонны вариантов.
срабатывания условий тэйка сервером выставляется новая заявка с новым номером order_num который нужно как-то отфильтровать и получить
При срабатывании стоп ордера происходит отправка транзакции сервером брокера. В случае успеха отправки (может не пройти), в стоп ордере, точнее в таблице stop_orders для записи вашего ордера, будет заполнено поле linked_order. Это и есть тот номер лимитного ордера, который отправлен по факту активации стоп ордера. По нему и ищите, фильтруйте. Правда, как и всегда при клиент-серверном взаимодействии, событие смены статуса стоп ордера и событие заполнения linked_order, и появление его в таблице orders, не мгновенные. И необходимо организовать методы ожидания.
Описанная в данном инциденте проблема была устранена в версии 7.23.0 терминала QUIK. Данная версия была разослана всем брокерам системы QUIK в рамках стандартной процедуры обновления версии 23.11.2018. По поводу получения обновления рекомендуем вам обратиться к своему брокеру.
Приносим извинения за причиненные неудобства.
Подниму..
Вроде работало, не следил. Но теперь в 9-ой версии не работает.
Если при первичной инициализации индикатора было x линий (добавление на график). А уже при повторной (после изменения настроек) линий больше x, то отрисовка линий происходит некорректно.
Так она и так выводится если код индикатора открыт. Впрочем, можно обернуть текст функции OnCalculate (или исполняемой функции) в pcall. И выводить в лог или сообщения текст ошибки. Только стоит сделать кеш ошибок, чтобы не выводить одну и ту же на каждом баре, а то терминал "умирает" на длинных графиках, выводя в три прохода все эти сообщения.
nikolz написал: поправлю на запись о регистрации или снятии (исполнении) заявки уходит не более 10 мкс --------------- на формирование и отсылки транзакции на снятие заявки уходит до 300 мкс ---------------------------- на формирование и отсылку транзакции на новую заявку уходит 400 мкс
Это при летной погоде. Надеяться на такие времена всегда - плохая затея. Мой наблюдаемый рекорд от отправки транзакции до появления ордера - 10 минут.
nikolz написал: не все так просто. Например, уже есть активные заявки до включения скрипта. либо произошел разрыв соединения и восстановление через несколько минут и часть активных заявок сработали. Ну и т д
Конечно не просто. Собственно это и было написано, что необходимо свои заявки опрашивать. Также скрипт должен хранить свое состояние, чтобы при перезапуске, восстановлении соединения и т.д., проверить себя, что изменилось. Может быть так, что терминал упал вчера, а восстановился только сегодня. Поэтому все такие ситуации необходимо предусматривать. И закладывать архитектуру на колбеках - не самое надежное решение.
Вы, конечно, можете постоянно не сканировать активные заявки по таблице. При первичной постановке ордера необходимо один раз найти ордер в таблице ордеров и запомнить индекс таблицы. Тогда последующие обращения уже будут простые, без поиска. Если же речь про то, чтобы вообще не искать ордера, то для лимитных ордеров - это не лучшая затея, т.к. в клиринг их снимут и необходимо предпринять какие-то действия. Да, можете по колбеку получить новое состояние ордера и отреагировать, но это если этот колбек не был пропущен.
Konstantin написал: Убрал onAllTrade результат тот же. Может ещё что убрать...
Советую последовательно анализировать.
Для начала уберите обработку очереди и просто в каждом колбеке выводите сообщение, что пришел такой колбек. Функция main будет cодержать только sleep(10), например.
Код
function main ()
while is_run do
--if # MAIN_QUEUE > 0 then
-- ProcessingCallbakc(MAIN_QUEUE[ 1 ])
-- table.sremove (MAIN_QUEUE, 1 )
-- message ( "Размер очереди " .. tostring( # MAIN_QUEUE))
--end
sleep ( 10 )
end
end
Потом уже последовательно возвращать в колбеках заполнение очереди. По одному, не во всех сразу. Тогда, анализируя поведение скрипта, найдете причину.
И, главное, измените в функции ProcessingCallbakc sleep(3000) на sleep(10). А лучше вообще убрать. Я не представляю что необходимо выполнять три секунды на каждый колбек.
Сдвинуть помогут. Вопрос был про сам сдвиг. Давить в конец, удалить в начале. Как я понимаю задача держать в массиве заданное число элементов. Правда эту задачу можно решить кольцевым массивом, рассчитывая очередное место индекса массива через остаток от деления, например.
И очень странная работа с временем. Если необходимо получить разницу времени, то у Вас есть unix-time, простое арифметическое действие даст разницу в секундах. Также время есть и в параметре alltrade - время прошедшей сделки. И да, в этом колбеке выполнять что-то сложное - очень плохо.
Т.к. в примере присутствует OnAllTrade и у Вас организована подписка на поток сделок, скажем, по многим инструментам, то он будет постоянно блокировать поток для внесения новых данных. Лучше удалить этот колбек. Либо добавляйте print debug сообщения, для оценки происходящего.
nikolz написал: сервер брокера никак не контролирует то, что транслирует с биржи. его задача работать со заявками клиентов, проверять достаточность средств и формат заявок и отправлять их на сервер биржи. время сервера иногда гуляет относительно времени биржи.
Это я как раз понимаю. Вопрос ведь в том, что если время серверной части может быть так рассинхронизированным, то не приведет ли это к последствиям. Мы же не знаем как организована работа со временем в серверной части.
То что время серверной части не связано с временем биржи - это понятно. А вот если есть сильная рассинхронизация, то это повод что-то сделать.
Вопрос был не про синхронизацию. По факту вопрос был: контролирует ли серверная часть, поток данных от биржи. Данная проблема решилась, когда брокер разорвал соединение (по крайнее мере терминал разорвал соединение самостоятельно) и после восстановления соединения время было синхронно.
И проблема явно была не в задержках, иначе бы данные приходили с задержкой. Они же приходили корректно.
Прямо сейчас наблюдаю такую картину. Время сервера отстает на минуту от текущего времени (оно синхронизировано и корректно). При этом время последней сделки на минуту впереди времени сервера и близко к правильному текущему времени, т.е. тоже опережает время сервера.
Я могу понять, что это проблема брокера (Сбербанк), но с какой стати время сделки в будущем относительно времени сервера брокера и времени пакета? Т.е. я понимаю, что время сделки просто транслирует биржа, но серверная часть должна же не просто транслировать, но и как-то контролировать, что она транслирует.
Если не прошла транзакция, оправленная командой самого терминала, то это уже не проблема клиента, если говорите, что данные обновлялись и торговая сессия шла. Я бы брокеру Алфьа не стал так уж доверять.
В данном случае, я тоже не очень понимаю смысл этого анализа, т.к. за время цикла задержки потока стакан изменится много раз. И это если анализировать всего один, не то что тысячи. Можно догадываться, какая задача решается, но часто пытаются через стакан посчитать сумму заявок. Хотя это берется из ТТТ одной строкой. При этом, анализируя стакан, также стоит учитывать, что через Квик доступна только малая часть глубины стакана - в лучшем случае 50 строк, а чаще всего 20.
Но обсуждали чисто техническую реализацию, поэтому все это лирика.
Ну так Вы выполняете Unsubscribe_Level_II_Quotes один раз. Если она вернула false, то можете ее вызывать в цикле еще раз (но не бесконечно), пока она не вернет истину. Это Вам выше и написали.
Решается она в виде очереди обработки, раз скорость не так важна. Оставим в стороне вопрос самого этого анализа.
Создаете очередь задач. Очередь - массив. Задача - объект, содержащий методы подписки, анализа отписки. Далее в цикле начинаете обрабатывать, например по 10 за раз. Если в какой-то момент не происходит подписка, то просто переключаетесь на следующую еще не выполненную задачу. И так пока очередь не опустеет. Можете обрабатывать простым циклом, можете корутинами - как угодно.
В книге автора языка есть хороший пример по скачиванию файла из интернета кусками. Это, по сути, та же задача.
Получить можно и без рисования. Но как показывает практика, часто данные не транслируются вовсе или с перебоями. Возможно зависит от брокера, у одного работает, у другого нет.
Но вот как мне из ds получить значения параметров для акций, к примеру "LAST" ?
Предположу, что Вы хотите получить данные из Таблицы текущих торгов, т.к. не описываете какую задачу решаете. Если так, то это не стоит делать через CreateDataSource. Проще и быстрее это сделать через функцию getParamEx http://luaq.ru/getParamEx.html
А CreateDataSource используйте если необходимо "упаковать" данные в свечи, бары.
Для срочного рынка и для фондового рынка используются разные счета. Если Вы указываете класс фондовой секции TQBR, то и ACCOUNT укажите для нее.Он вряд ли будет начинаться с SPBFUT, т.к. это явно срочный рынок.
Нет, математики их не заменят. Но когда программист не знает элементарную математику, это гораздо хуже, если он не знает Git. Тем более, что сейчас Git, Docker, Cuber. А через несколько лет скажут что так не модно. Одно то, что сейчас почему-то все решили, что приложение - это браузер и больше ничего не надо, уже вызывает отторжение.
Это не "сюр", а требование к качеству кода, который должен проходит ревью. Так что есть минимальные требования к современным программистам для работы в команде.
Сюр. Потому как есть алгоритмист, который пишет код, выполняющий то, что могу понять несколько людей на планете. Кто проверять то будет?
Если же речь, про "показать котиков", то да. Надо проверять. Но как показывает практика, проверяют не то. Цепляются за форматирование и нарушение "святого" SOLID, а безопасность остается дырявой. Почему, а потому что, опять же, специалистов мало.
Справедливости ради, знание современных систем хранения версий - это ни в коем времени не характеризует кого-то как программиста. Я когда начинал, мы учились на бумаге. В первую очередь просто алгоритмы. Потом код на бумаге. И ничего, абстрактное мышление хорошо развивает. То что сейчас без знаний Git не считают кого-то полноценным программистом, то это сюр, т.к. это знание ничего не дает.
local t0 = os.clock ()
local t1,t2,t3,t4,t5,t6,t7 = t0,t0,t0,t0,t0,t0,t0 -- таймеры
-- функции исполняемого кода
function f1 (x1) print (x1 .. ", f1"); end
function f2 (x1,x2) print (x1 .. ", f2"); end
function f3 (x1,x2,x3) print (x1 .. ", f3"); end
function f4 (x1,x2,x3,x4) print (x1 .. ", f4"); end
function f5 (x1,x2,x3,x4,x5) print (x1 .. ", f5"); end
function f6 (x1,x2,x3,x4,x5,x6) print (x1 .. ", f6"); end
function f7 (x1,x2,x3,x4,x5,x6,x7) print (x1 .. ", f7"); end
while true do --бесконечный цикл
local x = os.clock ()
if x - t1 > 1 then f1(x) t1 = x end
if x - t2 > 2 then f2(x,x2) t2 = x end
if x - t3 > 3 then f3(x,x2,x3) t3 = x end
if x - t4 > 4 then f4(x,x2,x3,x4) t4 = x end
if x - t5 > 5 then f5(x,x2,x3,x4,x5) t5 = x end
if x - t6 > 6 then f6(x,x2,x3,x4,x5,x6) t6 = x end
if x - t7 > 7 then f7(x,x2,x3,x4,x4,x6,x7) t7 = x end
end
?????
И это удобно, красиво и т.д.
Мне нужен таймер в одной функции, в другой, в третьей и т.д.
Шаблон создания таймера должен быть одинаковый типа
Много примеров, но все они мало применимы. Какие циклы. Тайме, чаще всего, организуется по месту, а не где-то в main, в одной точке. Далее, чтобы это было удобно, могли бы хоть функцию обратного вызова организовать, чтобы по завершению она была бы вызвана. Иначе зачем он нужен, чтобы напечатать привет...
А исходя из этого - таймер это объект - шаблон, класс, замыкакние. Который создается там где он нужен и вызывается его проверка. По истечению вызовется функция в контексте определения, что даст захваченную область видимости этой функции и не надо возится с параметрами.
Мне НЕ НУЖНЫ обращения к данным сервера - мне нужны данные моего брокера, касающиеся моего портфеля
Так они и находятся на сервере брокера и транслируются в терминал. Если Вы не верите записям в терминале и хотите их проверить, то тогда и нужен прямой доступ к записям на сервере. Что, конечно, никогда не будет реализовано. И ни в коем случае недопустимо даже рассматривать такое.
Цитата
и почти 146% гарантии, что беготня по таблице сделок с этим НЕ справится
А по таблице сделок не надо бегать, тогда и проблемы не будет. Колбек же, в свою очередь, в ряде случаев требует решения синхронизации данных. Впрочем, решение на колбеках тоже рабочее. И часто используется. Здесь вопрос предпочтений для конкретного алгоритмического решения.
Система меню, конечно, позволяет изменять настройки, но есть настройки, которые не изменяются при активном алгоритме. Например ТФ баров. Да, Вы опять скажете, что это никому не надо, мне тоже не надо, но кому-то надо. И не мне указывать что и как делать. Поэтому в такой момент скрипт не совершает торговые операции, но при этом ведет контроль позиции и сделок. Поэтому снимать ордера - это не вариант. Судя по всему, у Вас все ордера "рыночные", но вернемся к другим пользователям и окажется, что видов ордеров может быть много. И есть те, кому это надо. И по наблюдениям, рыночные ордера - это не самое распространенное явление.
Что касается обсуждаемой "проблемы", то просмотр прямых таблиц дает гарантию, что если там есть запись, то она не будет пропущена. Если же Вы про гарантии, что запись есть у брокера, но нет в терминале, то это находится в области ошибок работы клиент-серверной архитектуры, рассогласование данных. И это Вы никак не проконтролируете, т.к. у Вас нет методов прямого обращения к данным сервера. Но даже исключение проблемы работы колбеков уже повышает стабильность решений.
Как часто смотреть - постоянно. Если это сделано корректно, то это не вызывает существенных накладных расходов. И смотреть во все необходимые таблицы. Необходимы сделки - таблица сделок. Необходимы ордера - таблица ордеров. Необходимы данные лимитов по бумагам - таблица depo_limits, куда, собственно, метод getDepoEx и смотрит. Вы же смотрите в таблицу текущих торгов, и, наверно, постоянно.
Да много причин. Упал Квик, при перезапуске придут все пропущенные колбеки, но не факт, что скрипт еще будет в рабочем состоянии в этом момент. Пользователь остановил скрипт для изменения настроек. Пользователь запустил скрипт не в начале торговой сессии. Если скрипт для себя, то можно говорить себе - у меня так не будет никогда. Но когда это решение для других, то я не могу знать как оно будет использовано. Поэтому и должно работать в таких ситуациях.
А если скрипт временно не работает, то это не значит, что заявки снимаются (а значит могут быть исполнены). Или Вы предлагаете при каждой остановке скрипта снимать все?
Что же касается учета сделок, то я использую свои колбеки, организованные на выявлении новых записей в таблице сделок. Т.е. я прямо смотрю в таблицы терминала. Да. Можно говорить, что такое решение странное, не красивое и т.д. Но колбек не дает гарантий и на этом разговор заканчивается.
Как я сказал, проблема не в том, что он пришел поздно (хотя даже этого достаточно, чтобы уже задуматься), а в том, что он может быть пропущен (не работал скрипт). И тогда алгоритм скрипта что, пропустил сделку? Это слишком опасно. И не надо говорить, что такого не будет. Иногда достаточно одного раза. Поэтому в такой важно части необходимо самое надежное решение как базовое. И это не колбек терминала.
Если бы в Квике была гарантированная доставка сообщений, как в RabbitMQ, то да. Но раз нет гарантий, то я не очень понимаю, как можно выбирать это для такого рода решений.
Если Вы используете колбеки, то да. Но если скрипт не работал в момент совершения сделки (пропустили колбек), то это не должно приводить к проблемам в работе скрипта.
Владимир написал: Это вовсе не "само собой разумеется" - это подразумевает наличие механизма восстановления после сбоев, который как раз у всех (включая меня, Бориса и Вас) пркактически отсутствует.
Что значит отсутствует. Я Ваш код не видел, а свой вижу. И у меня, ленивого, нет никакого желания сидеть за монитором и контролировать. Зачем тогда автоматизация торговли, если все равно сидишь за терминалом. Много других полезных занятий есть. Поэтому скрипт должен все помнить, считать, проверять, корректировать. А если что-то не так, то пришлет оповещение на почту.
Зачем рассказывать про то как скрипты работают месяцами - это само собой разумеется, а как иначе.
Про баланс, опять, вопрос очень размытый. Баланс брокера - это единая, общая картина. А скрипту же чаще всего необходимо видеть только свое. В этом случае этот баланс что даст? Вот сделки необходимо считать, да. Надо контролировать лимиты денежных средств, перед подачей транзакции. Иногда, чтобы развернуть позицию необходимо сначала закрыть прошлую, а потом уже открывать новую. Такие технические моменты необходимы.
Баланс брокера контролируется в тех алгоритмах, которые учитывают сторонние операции. Т.е. реагируют на внешние изменения. И в них это действительно важно. Но баланс должен быть подкреплен сделками. И, наверно, это и есть проверка. Потому что если получили баланс 0, а сделок нет, то лучше не принимать решения. Или наоборот - сделки есть, а баланс старый. И получаешь ошибку транзакции - в шорт нельзя.
Т.к. мы работаем с деньгами, то, как и при проектировании авиалайнера, лучше использовать самый надежный способ как основной. Понятие у брокера - очень размытое. Один брокер, например в клиринг снимает все лимиты и баланс, а другой нет. Это относится к срочной секции, но в данном случае показывает, что разные брокеры ведут себя по-разному.Поэтому сверять можно, но нельзя это делать вне торговой сессии. Плюс, нельзя исключать и ошибки, задержки передачи данных на стороне сервера брокера. Чаще всего через некоторое время все выравнивается. По крайней мере я не знаю случаев когда брокер "украл" позицию.
Если же скрипт ведет свою позицию, то сверять уже не имеет смысла, т.к. скрипт ничего не знает про других участников, как то - другие скрипты, руки человека. Например, конечно, можно все скрипты заставить обмениваться информацией, но если сделку совершит человек или брокер закроет все позиции, то уже непонятно как сводить баланс.
Поэтому если скрипт смотрит баланс, то он смотрит на него и контролирует сумму по всем сделкам, чтобы принимать решения только когда все сделки пройдут. Т.к. часто бывает так, что баланс позиции изменился, а сделок еще нет. Или наоборот. Т.к. каждая новая сделка - это контроль лимитов, то необходимо ждать когда пройдут все операции связанные с любой сделкой. Но это не сверка баланса, а просто получение нового баланса, подтвержденного сделками.
есть таблица depo_limits Вы можете простым перебором получить данные, можете отфильтровать SearchItems и уже их перебрать. И скажу, что это будет надежнее.