Если данный признак (поле) не описан в документации, значит получить его нельзя. Если же речь идет о параметре таблицы текущих торгов, можно воспользоваться экспортом по DDE с включенной опцией "Формальные заголовки", чтобы посмотреть наименование параметра.
Если данный признак (поле) не описан в документации, значит получить его нельзя. Если же речь идет о параметре таблицы текущих торгов, можно воспользоваться экспортом по DDE с включенной опцией "Формальные заголовки", чтобы посмотреть наименование параметра.
Да, речь про параметр таблицы текущих торгов. Задача не посмотреть его, а получить доступ в макросе, как к одному из статичных параметров инструмента. Он скорее ведь не относится к текущим торгам. Рассмотрите тогда возможность расширить таблицу securities этим и, возможно, еще какими-либо статичными параметрами инструментов. Кторые выводятся сейчас в интерфейс ТТТ.
Андрей написал: Да, речь про параметр таблицы текущих торгов.
В данном случае, повторимся, можно посмотреть название данного параметра воспользовавшись экспортом по DDE, а затем, при помощи данного названия, получить значение параметра при помощи функции getParamEx().
Андрей написал: Да, речь про параметр таблицы текущих торгов.
В данном случае, повторимся, можно посмотреть название данного параметра воспользовавшись экспортом по DDE, а затем, при помощи данного названия, получить значение параметра при помощи функции getParamEx().
А если Excel нет? Как вывести в csv файл, например? Или еще что-либо открыто доступное. В документации тема не раскрыта, все на примере Excel.
В первую очередь, необходимо понимать, что параметры таблицы текущих торгов транслируются биржей (не только их значение, но и сам набор). К сожалению, описать их все не представляется возможным.
В текущей реализации, экспорт таблицы текущих торгов возможен только средствами DDE (не обязательно в Excel) и ODBC. Можем зарегистрировать пожелание на возможность экспорта в текстовый файл. Регистрируем?
Прежде прошу привести пример существующего способа экспорта по DDE в самый простой общедоступный получатель данных, помимо Excel. Попробовал в OpenOffice кстати, не работает. Либо что нужно указать в настройках вывода.
Кажется, гораздо проще было бы добавить в руководство описание полей и поддерживать его актуальность. Что вполне естественно. Впрочем, такие пожелания были неоднократно.
Roman Azarov, Ну и что, если "параметры таблицы текущих торгов транслируются биржей (не только их значение, но и сам набор)"? ТТТ в Квике - это ТТТ В КВИКЕ! Можно сделать свои имена параметров, можно даже с синонимами - это же как два пальца об асфальт! Что значит "не представляется возможным"? И при чём тут вообще экспорт, DDE, ODBC или там CSV? Нужен доступ к данным, то бишь МЕТОД! Не описания структур данных (которые, к тому же, могут измениться в любой момент), а методы для их получения. Точно такая же хрень во всей этой катавасии со свечами - алгоритмически вопрос выеденного яйца не стоит, а обсуждение идёт годами. Методы нужны, методы!
Здравствуйте. Андрей, Для экспорта данных по из терминала QUIK по DDE минимальное необходимо указать корректное название DDE-сервера приложения, в которое будете выполнять экспорт. Уточнить корректное название DDE-сервера, необходимость указания существующей рабочей книги, а также необходимые настройки на стороне принимающего приложения - необходимо уточнять непосредственно у разработчиков этого самого приложения. В Вашем случае - можете уточнить необходимые настройки у разработчиков OpenOffice.
Nikolay, Разные ТС транслируют огромное количество разных параметров. На сколько нам известно, большинство из них предоставляют собственные спецификации, из которых можно узнать какие параметры транслируются, как они называются и какой смысл в них вкладываются. Эти же ТС поддерживают актуальность своих документов. Если Вам необходимо узнать актуальные параметры, транслируемые ТС, или понять смысл параметра, который есть в Таблице текущих торгов, но не представлен в документации - рекомендуем обратиться к специалистам соответствующей торговой системы.
Владимир, Описывать все доступные параметры всех доступных ТС и их ключи для обращения из LUA, а также поддерживать эту информацию в актуальном состоянии не представляется возможным потому что это крайней большой объём неоправданной работы. Уже сейчас - если Вам нужно описание параметра, который не представлен в документации QUIK - Вы можете обратиться к биржевым спецификациям, актуальность которых поддерживают специалисты биржи. Если Вам необходимо получить в LUA-скрипт параметр ТТТ, ключ которого не описан в документации - Вы можете узнать его, выполнив экспорт ТТТ по DDE с формальными заголовками.
Можем зарегистрировать Ваше пожелание на добавление какой-либо дополнительной функции QLUA, но для этого убедительная просьба сформулировать Ваше пожелание содержательно, без излишней лирики, а также принимая во внимание следующий регламент работы с клиентскими пожеланиями.
Andrey Bezrukov, Так Вы предлагаете, чтобы сами юзеры мордовали запросами своих брокеров или, прости, Господи, биржи? Господа, мы работаем в Квике! В самой популярной торговой системе (по крайней мере, в России)! Кому, как не вам интегрировать "необходимые настройки от разных ТС", унифицировать их "огромное количество разных параметров"?. Брокеры сами предлагают использовать именно ваш софт - вот буквально сегодня один из них предложил мне обновить очередное "шило на мыло". Я, как всегда, покорно обновил. И чего?
И какой у вас, простите, "крайне большой объём неоправданной работы"? Чем вы, собственно, там занимаетесь? Четверть, если не треть кода моего скрипта написана исключительно для компенсации глюков вашего софта, и код этот пестрит комментариями типа "это костыль от дебилизма с goto" или "прорисовка таблицы визуализации выведена из main в самостоятельную функцию для возможности исправления ошибки программного обеспечения QUIK (исчезновение текста в ячейках таблицы)". К кому прикажете обращаться? К Биллу Гейтсу?
А я перестал давать вам "пожелания на добавление какой-либо дополнительной функции" - вы же на них просто не реагируете ВААПЩЕ НИКАК! А давал я их когда-то именно "содержательно, без излишней лирики" - например, 13.03.2021 11:47:57: И самое главное - почему обеспечение уникальности идентификаторов транзакций ложится на юзера? Ведь для Квика это просто порядковый номер строки в его таблице - даже искать ничего не надо! Так не проще ли сделать ID=sendTransaction, а в случае неудачи возвращать 0? И волки целы, и овцы сыты.
Или чуть позже, 27.04.2021 20:35:04, уже "с лирикой": Ну зачем рядовому юзеру знать, например, о существовании sendTransaction? Не говоря уже о том, что обеспечивать уникальность их айдишек он должен сам - во радость! А набивать значениями таблицы с фиксированными именами полей - это как?
А насчёт указанного Вами "регламента работы с клиентскими пожеланиями" - так там чёрным по белому: Компания с большим вниманием относится к пожеланиям пользователей, стараясь реагировать на них максимально оперативно, понимая востребованность тех или иных доработок.
И даже: Работоспособность системы является наиболее приоритетной задачей для всех - разработчиков, тестеров и технической поддержки.
Ну и как там с "работоспособностью"? Лично я просто БОЮСЬ новых версий - функциональности они наверняка не добавят (да она уже почти и не нужна), а новых глюков - сколько угодно! У меня вот никак руки не доходят убрать в main подачу заявки из обработчика прерываний (кнопки "купить" и "продать" в моём меню): 99 раз она работает нормально, а на сотый подвешивает Квик! Как вообще может ИНТЕРПРЕТИРУЕМЫЙ код подвесить систему, да так, что её можно убить только из диспетчера задач - это выше моего понимания! А потеря управления по OnStop? А сколько раз вам писали пожелание, чтобы на одно событие приходило ОДНО, БЛИН, прерывание, а не целая колода? А дамп состояния моего портфеля я теперь сбрасываю на диск каждые 5 минут - это просто мне заняться больше нечем?Так что НЕ ХОЧЕТСЯ давать вам "ясно сформулированные предложения, тем более с озвученной аргументацией", даже если они "всячески приветствуются" (перед тем, как бросить в корзину).
Владимир, Мы Вам описали общую ситуацию, вдаваться в детали рабочего процесса мы не намерены.
Если Вы подозреваете некорректную работу интерпретатора QLUA - сообщите нам об этом, сопроводив Ваше сообщение информацией, полезной для анализа, например, необходимый и достаточный фрагмент кода, подробное описание, файлы *.dmp, Ваши логи или иную информацию, которую не текущем этапе Вы считаете полезной для диагностики ошибки. Можете предоставить эти данные нам по почте, по адресу quiksupport@arqatech.com, например.
Если речь идёт о задачах, которые Вы можете уже сейчас решить штатными средствами, но они Вам кажутся неудобными, и Вы бы хотели изменений, которые бы позволили сделать Ваш рабочий процесс более эффективным / простым / надёжным и т.п. - сформулируйте Ваше пожелание на соответствующую доработку с учётом регламента, приведённого выше.
Под "работоспособностью системы" подразумевается не только качество интеграции терминала с внешними решениями. Это, безусловно, тоже важный функционал, но не самый критичный. Большее внимание, как Вы наверняка понимаете, уделяется прежде всего фактическому доступу к торговым системам бирж через систему QUIK, в т.ч. и через терминал QUIK. Очевидно, что каким-бы удобным ни был клиентский функционал, какой-бы технологичной ни была интеграция терминала QUIK с Вашим решением – их смысл полностью теряется, в случае потери доступа к торгам через QUIK. Мы стараемся этого не допустить, это приоритетная задача.
С учётом ограниченного трудового ресурса и критичностью стоящих перед нами задач, к сожалению, вопреки Вашим ожиданиям, не представляется возможным сделать «всё и сразу, «хорошо и правильно»». Мы вынуждены расставлять соответствующие приоритеты, выделяя из них в первую очередь безусловно приоритетные задачи, критичные для всей системы в целом. Это же касается очевидных недоработок и ошибок в работе ПО, в т.ч. клиентский части.
Далее, по мере возможности – выполняется анализ и реализация зафиксированных клиентских пожеланий, от рассмотрения которых мы не отказываемся, если нет объективных и очевидных причин, по которым их рассмотрения и/или реализация не имеет смысла – это, например, случай с дублированием биржевых специфик в документацию к клиентскому терминалу.
Рассчитываем на Ваше понимание. Заранее большое спасибо.
Andrey Bezrukov, Я же говорю: я УСТАЛ "сообщать вам об этом, сопроводив сообщение информацией, полезной для анализа" - всё это уходит, как в песок. Я всё могу понять, кроме глухого молчания.
Да, в моих пожеланиях речь нередко идёт о задачах, которые я могу уже сейчас решить штатными средствами, но они мне кажутся неудобными. При этом я прекрасно понимаю, что абсолютным приоритетом является обеспечение надёжной торговли через терминал QUIK - всё остальное вторично (включая весь Lua с потрохами или наиболее одиозные его моменты вроде динамической типизации или кражи типа integer). Я тоже старался "расставлять соответствующие приоритеты, выделяя из них в первую очередь безусловно приоритетные задачи" - так, как я это вижу. Ладно, пробегусь ещё разок по своим сообщениям... мамочки, да их 777 - более полуметра! Итак, высказанные уже давно пожелания:
1. Почти мгновенно после того, как я появился здесь и попробовал написать свой первый скрипт, я столкнулся с ситуацией потери управления по OnStop. Антон тогда подробно расписал мне, что происходит и почему, и с тех пор у меня в самом этом обработчике сидит запись результатов, закрытие лога, убийство таблиц и прочее, но ведь это же ненормально! Согласитесь, весьма неприятно потерять результаты всего дня только потому, что мы имели неосторожность "не вовремя" обратиться к функциям основного потока вроде SetCell. Пожелание: после остановки бесконечного цикла передавать управление следующему за циклом оператору в main - так, как это и происходит, если флаг isRun сбрасывается не в OnStop, а в любом другом месте.
2. Я не понимаю (и не хочу понимать!) почему "для того, чтобы строки отображались, необходимо, чтобы вызов CreateWindow() производился ДО процедуры добавления строк в таблицу". Здесь участники дискуссии, на мой взгляд, очень убедительно показывали, что такого быть не должно. Пожелание: хотя бы внесите в описание языка эту "особенность"! Ведь многие (особенно новички) даже не подозревают о таких "нюансах" и тратят многие часы на отладку того, что в принципе не может быть отлажено.
3. Я считаю, что более одного коллбека на одно событие есть грубейшая ошибка в программном обеспечении, которая, к сожалению, не исправляется годами. Пожелание: исправить.
4. Некоторые функции допускают необязательные аргументы (например, основание системы счисления в tonumber), а другие - нет. Так, SetColor (iTable, iRow, iCol, BCol, TCol) НЕ работает, а если подставить туда два дополнительных аргумента , SelBCol, SelTCol, равные QTABLE_NO_INDEX (-1) - начинает работать! Поскольку мне совершенно не были нужны выделенные ячейки, до необходимости переделать вызов в SetColor (iTable, iRow, iCol, BCol, TCol, SelBCol, SelTCol, -1, -1) без подсказки от службы техподдержки я бы просто не додумался НИКОГДА! Пожелание: разрешить не вводить необязательные аргументы функций везде, где это возможно (подставляя при необходимости значения по умолчанию).
5. При удалении строк с помощью DeleteRow и/или вставке (InsertRow) могут проявляться разные неприятные эффекты (данные пропадают или записываются не в те строки). Похоже, здесь путаются понятия ключа и индекса (кстати, этот эффект проявляется в таблице заявок в Квике даже при ручной торговле: после обрыва связи часть строк могут оказаться пустыми, и помогает только перезапуск Квика). Пожелание: исправить.
6. В циклах имеется break, а вот continue почему-то нет (эмулирую его при помощи goto). Пожелание: исправить.
7. Время от времени пропадает текст в таблицах (последний раз это проявилось вчера на версии, обновлённой позавчера). Приходится выносить создание таблицы в отдельную функцию, а в обработчик событий вешать (на Enter) DestroyTable+CreateWindow+SetWindowPos. Пожелание: исправить.
8. Почему обеспечение уникальности идентификаторов транзакций ложится на юзера? Пожелание: переделать вызов как ID=sendTransaction(), а в случае неудачи возвращать 0. А лучше дать вместо неё более простой интерфейс sendOrder (или даже Buy и Sell), и уж, конечно, не заполнять таблицы, а передавать необходимые данные аргументами.
9. Часто обсуждаемой проблемой являются свечи, доступ к которым в существующей реализации весьма затруднён. Пожелание: дать утилиту типа GetLastCandles (class, sec, interval, numberof). По умолчанию одна последняя свеча. Возможно, даже с коллбеком. Или хранить (хотя бы в той же ТТТ) последние свечи по всем таймфреймам.
0. А если уж "с учётом ограниченного трудового ресурса и критичностью стоящих перед вами задач". Пожелание: запретить к чертям всем юзерам любые обмены с сервером в обход Квика - не наше это собачье дело! Тогда вся математика резко упрощается, и огромный пласт потенциальных ошибок просто исчезает как класс. В конце концов, человек, торгующий в Квике вручную (через стаканы) именно так и поступает. Так с какой радости скрипт должен вести себя иначе?
Ну, а за динамическую типизацию и за тип integer... далее нецензурно.
Andrey Bezrukov, Ну вот, всё по старой схеме, один в один! Хоть бы отклонили что-нибудь, хоть бы какая реакция была! Так что ответьте САМИ: стоит ли давать вам "ясно сформулированные предложения с озвученной аргументацией" или нет. А я с местной техподдержкой разговаривать больше не хочу.
Благодарим за подробное описание. По пунктам: 1. Чтобы исключить возможное недопонимание ситуации в целом и сути запрашиваемой доработки, просьба привести ссылку на тему, в которой данный эффект обсуждался, если это возможно.
2. Ваше сообщение получено, проблема изучается. Постараемся в ближайшее время дать ответ.
3. Если подразумеваются вызов callback-функций по получению данных по заявке/сделке/стоп-заявке/обезличенной сделке/позиции (обобщим для простоты – некой «записи-quik»), по которой уже однажды вызывалась соответствующая callback-функция, то здесь нет ошибки, которую надо было бы исправлять. Для этих событий – вызов происходит не только при первичном получении записи-quik, но и при получении обновления по этой записи. Так, например, при выставлении заявки – OnOrder будет вызван при получении заявки (в результат её успешной регистрации в ТС), так и при её снятии/исполнении. Каких-либо изменений логики в этом плане не будет. Если имеется что-либо иное – просьба конкретизировать – о каких именно событиях идёт речь?
4. Это пожелание сформулировано очень общим образом и в такой формулировке мы пожелания не рассматриваем (см. регламент). Просьба подготовить и предоставить список интересующих Вас функций с указанием их параметров, которые, по-Вашему, мнению должны быть необязательными. Мы рассмотрим возможность модификации формата вызова указанных функций.
5. Описанный в данном пункте эффект воспроизвести не удаётся. Наиболее вероятно, путаница привносится логикой Вашего кода. Предлагаем этот момент проверить Вам самостоятельно. Если же Вы настаиваете на некорректной работе функций DeleteRow и InsertRow – просьба привести минимальный необходимый и достаточный пример (или фрагмент) скрипта, достаточный для воспроизведения эффекта. Можете прислать скрипт на почтовый адрес quiksupport@arqatech.com со ссылкой на данную ветку форума.
6. break – это statement языка LUA, и отсутствие continue – это, если так можно выразиться, упущение самого языка LUA, а не QLUA. Предлагаем с этим пожеланием обратиться непосредственно к разработчикам LUA. До тех пор, пока в LUA не будет реализован continue – предлагаем использовать goto, т.к. для LUA это вполне популярная практика.
7. Просьба для анализа эффекта привести минимальный необходимый и достаточный пример (или фрагмент) скрипта, достаточный для воспроизведения эффекта. Можете прислать скрипт на почтовый адрес quiksupport@arqatech.com со ссылкой на данную ветку форума.
8,9. Ваши пожелания зарегистрированы. Мы постараемся рассмотреть их и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелании в будущих версиях ПО.
Andrey Bezrukov, УХ ТЫ! Даже не читая - я охренел. Меняю своё мнение о сотрудниках техподдержки на прямо противоположное, приношу свои извинения за домыслы нехорошие о вас. Почитаем...
3. Да, подразумеваются именно вызов callback-функций (одна из причин, почему я стал пользоваться только OnTrade, как минимально необходимой для торговли). Они тоже приходят пачками по три штуки, совершенно одинаковых. Приходится запоминать её ID и отбрасывать дубли. Если учесть, что заявки могут быть в несколько лотов, а также "левые" (сделанные юзером в обход скрипта), приходится изворачиваться глистом на сковородке. У меня это сейчас выглядит так:
Код
s=0; -- ID найденной сделки или 0
for j=1,a[i][12][0][0] do -- цикл по сделкам (поиск уже обработанной)
if tostring(a[i][12][j][0])==tostring(n.order_num) then
if tostring(a[i][12][j][1])==tostring(n.trade_num) then goto Q;end;
k=a[i][12][j][2]; -- остаток лотов по этой заявке
end; -- конец условия "найдена сделка этой заявки"
if tostring(a[i][12][j][0])==tostring(n.trans_id) and a[i][12][j][1]==0 then
s=j;goto qq;end;end; -- первая сделка по заявке
if k==0 then -- сделка по "левой" заявке (в обход скрипта)
...
Мало того, они приходят вразнобой! Вот я матерился по этому поводу 09.12.2020 15:09:04: Как оказалось, я страдал чрезмерным оптимизмом: мало того, что прерывания OnOrder и OnTrade приходят пачками (что, конечно, есть форменное свинство и должно быть исправлено), так они ещё приходят и вразнобой! По крайней мере, когда одна заявка реализуется через нескольких сделок: сначала приходит OnTrade с ID заявки и ID сделки, затем с ID заявки и ID ВТОРОЙ сделки, а затем с ID заявки и снова, падла. с ID ПЕРВОЙ сделки! В результате мой алгоритм думает, что сделок совершено больше, чем в действительности.
4. Почему же "очень общим образом"? Совершенно конкретно: SetColor (iTable, iRow, iCol, BCol, TCol, SelBCol, SelTCol, -1, -1) красит ячейку, а без двух последних аргументов - нет. При этом даже не ругается, а "просто не работает". А кому они нужны, эти SelBCol и SelTCol? Разве что для каких-то экзотических применений. А какие ещё аргументы должны быть необязательными - не знаю. Напоролся - сказал.
5. Нет, я ни на чём не настаиваю - это проявлялось давно, и я почти сразу стал в случае необходимости изменения набора строк перебивать заново всю таблицу - глюки тут же пропали.
Код
Clear(T); -- обнуляем таблицу
for i=0,N-1 do -- цикл по тикерам (вставка строк и анализ)
if a[i][0][9]~=-1 then -- тикер должен быть
a[i][0][9]=InsertRow(T,-1);end;end;
6. Ясно, Неприятность эту мы переживём!(с)
7. Насколько я помню, Старатель подробнейшим образом разбирал это дело. А я даже не разбирался - просто повесил в обработчике: if (n==QTABLE_CHAR and l==13) then DestroyTable(T);D();J();end; После чего пропавший текст восстанавливается. В общем, помогло. И, поскольку я скрипт пишу для себя, разбираться с подобными вещами не буду - других дел выше крыши.
Владимир, 1. Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО. 3. Обновления записей-quik приходят в соответствии с тем, как их рассылает сервер. Соответственно и callback-функции реагируют на каждую полученную запись. Если они приходят наборами – реакция происходит для каждой записи из набора.
Далее, одинаковыми они могут Вам казаться на основании тех параметров, доступ к которым возможен при помощи QLUA. Но кроме этих параметров есть также и служебные, технические параметры недоступные Вам для обработки. В этом случае – разница в записях кроется именно в отличии этих параметров, callback-функции честно реагируют на эти обновления.
Архитектурно, в плане рассылки данных – крайне маловероятно будут какие-то изменения в обозримой перспективе, как отметили ранее. Тем не менее, Ваше негодование по данному поводу вполне понятно. Можем предложить зарегистрировать пожелание на модификацию имеющихся callback-ов / добавление их аналогов, которые бы вызывались только в том случае, если в полученном обновлении записи-quik изменились те параметры, которые доступны из QLUA-функции. Регистрируем?
4. Ваша формулировка пожелания (цитата ниже) – характеризуется как крайне общая.
Цитата
Владимир написал: Пожелание: разрешить не вводить необязательные аргументы функций везде, где это возможно (подставляя при необходимости значения по умолчанию).
С учётом Вашего последнего комментария – зарегистрировали Ваше пожелание на модификацию формата вызова функции SetColor. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО. Если у Вас появятся дополнительные соображения в данном ключе – сообщите о них, пожалуйста.
По пунктам 5, 6 – Ваши комментарии приняли к сведению. В таком случае, ввиду отсутствия «рабочих примеров», на которых можно было бы воспроизвести ошибку или понять характерные условия её воспроизведения, а также с учётом того, что поставленная задача всё же решается несмотря на эти эффекты – предлагаем в рамках данной беседы эти темы исключить из рассмотрения.
Если же возникнет необходимость вернуться к этой теме – просьба подготовить запрошенные примеры скриптов, с которыми можно было бы выполнить дальнейшую диагностику.
Владимир написал: Вот ссылка на тему, начиная с моего сообщения и вниз, до ответов Антона:
Замечу, что никогда не форсил тему исправления данного поведения. Заменить там WaitForSingleObject на цикл с MsgWaitForMultipleObjects можно, но какие при этом неожиданные глюки полезут, угадать сложно, надо будет тестить долго и упорно и есть шансы, что что-нибудь упустят и оно в продакшене вылезет. В то же время из скрипта, зная об этой особенности, можно проблему обойти, пусть и не очень красиво.
Andrey Bezrukov, Хорошо, всё считаю согласованным, кроме пункта 3. Юзеру-то какое дело, что там "есть также и служебные, технические параметры недоступные для обработки"? Ладно, у меня за плечами 40 лет программирования, причём, в основном, системщиком - я уже давно научился "доставать левой ногой правое ухо" и проблему с многократными вызовами на одно событие фактически решил. А новичкам что делать, которые в подавляющем большинстве либо получайники либо полные? Конечно, регистрируем!
Anton, Я тоже боюсь любых модификаций, но я по натуре перфекционист: НУЖНО хотя бы пытаться!
Владимир, По пункту 3: Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Andrey Bezrukov написал: Так, например, при выставлении заявки – OnOrder будет вызван при получении заявки (в результат её успешной регистрации в ТС), так и при её снятии/исполнении.
Добавлю еще по этому поводу. Иногда, редко, OnOrder по созданию заявки приходит еще один самый первый раз, даже раньше OnTransReply, причем с trans_id=0. Речь про заявки из макроса, которым я назначаю trans_id. Как говорилось ранее, да, OnOrder дублируется несколько раз после OnTransReply. С изменениями в поле uid кажется. Но вот такое, что он приходит еще раз раньше OnTransReply.. не ожидано было. Не ошибка ли?
Так он становится неотличим от заявки, которую вводишь руками. Поэтому давайте все же зарегестрируем пожелание, чтобы onOrder не рассылался раньше, чем на сервере обработается в полной мере транзакция, назначится trans_id. И все пришедшие ОnOrder будут с верными trans_id (как и order_num). А уж какие-то прочие поля можно досылать потом.
Дело в том, что ответы на транзакции и заявки транслируются биржей через сервер QUIK в терминал разными независимыми потоками. Следствием этого является то, что на том или ином участке может возникнуть взаимная задержка между получением получением ответа от биржи на транзакцию и получением самой заявки как таковой, их обработки сервером (в т.ч. простановки trans_id, UID на заявке) и отправкой в терминал.
Как следствие, это приводит к не вполне прогнозируемому порядку срабатывания OnTranseply и OnOrder.
Такая асинхронность, хоть и вызывает некоторые неудобства к обработке функций обратного вызова - позволяет обеспечивать высокую производительность системы QUIK в целом. Поэтому, какой-либо значимой переработки в этом месте, как и обозначали ранее - регистрации пожеланий к какой-либо значимой доработке не предлагаем.
Кроме того, поскольку параметры trans_id и uid на заявке доступны из скрипта - уже сейчас можно реализовать необходимую логику, которая будет выполнять или пропускать соответствующий блок скрипта в зависимости от того, равен ли trans_id нулю или нет при очередном срабатывании OnOrder.
Кроме того, поскольку параметры trans_id и uid на заявке доступны из скрипта - уже сейчас можно реализовать необходимую логику, которая будет выполнять или пропускать соответствующий блок скрипта в зависимости от того, равен ли trans_id нулю или нет при очередном срабатывании OnOrder.
Повторюсь, для осмысленной обработки прихода OnOrder с trans_id=0 нужно отличать его от подобного при ручном вводе заявки. Тогда обеспечьте такую возможность по какому-то иному признаку. Чтобы точно понимать, что этот приход - не от ручной заявки, а от некоей транзакции в процессе заполнения trans_id.
если такого признака пока нет, можно назначить некий бит флага под это дело, например. Который =1, если trans_id имеет финальное значение. Вобщем варианты есть, чтобы не тормозить независымые потоки.
Это должно быть общим принципом. Приходят колбеки в процессе дозаполнения полей - ок. Но тогда обеспечьте надежный способ отличать, заполнено поле уже или нет. Незаполненное поле не должно иметь значение, валидное для заполненного.
Андрей написал: Повторюсь, для осмысленной обработки прихода OnOrder с trans_id=0 нужно отличать его от подобного при ручном вводе заявки.
Можете самостоятельно указать признак в комментарии, см параметр CLIENT_CODE
Цитата
20-ти символьное составное поле, может содержать код клиента и текстовый комментарий (поручение) с тем же разделителем, что и при вводе заявки вручную. Необязательный параметр
Андрей написал: Повторюсь, для осмысленной обработки прихода OnOrder с trans_id=0 нужно отличать его от подобного при ручном вводе заявки.
Можете самостоятельно указать признак в комментарии, см параметр CLIENT_CODE
Цитата
20-ти символьное составное поле, может содержать код клиента и текстовый комментарий (поручение) с тем же разделителем, что и при вводе заявки вручную. Необязательный параметр
А вы уверены, что он будет проставлен в этом первом пришедшем OnOrder, в котором даже trans_id не проставлен? Не думаю.. т.к. транзакция еще не обработана. И в любом случае это bad design, о чем я выше пишу, когда не заполненное поле имеет значение, валидное для заполненного. И исправить это не сложно без потерь производительности, нужно сделать.
Андрей написал: А вы уверены, что он будет проставлен в этом первом пришедшем OnOrder, в котором даже trans_id не проставлен? Не думаю.. т.к. транзакция еще не обработана.
CLIENT_CODE - это биржевой параметр. Вы отправляете транзакцию на биржу и в OnOrder приезжает тело заявки с биржи, включая CLIENT_CODE.
Цитата
Андрей написал: И в любом случае это bad design, о чем я выше пишу, когда не заполненное поле имеет значение, валидное для заполненного. И исправить это не сложно без потерь производительности, нужно сделать.
Мы не можем что-то добавить в биржевой протокол, только биржа это может. Добавить свои собственные параметры, да можем, и UID и trans_id мы как раз и добавили. Добавить к ним еще один? Зачем он ведь будет работать точно так же. И с ним будут точно такие же проблемы.
Sergey Gorokhov написал: Мы не можем что-то добавить в биржевой протокол, только биржа это может. Добавить свои собственные параметры, да можем, и UID и trans_id мы как раз и добавили. Добавить к ним еще один? Зачем он ведь будет работать точно так же. И с ним будут точно такие же проблемы.
Приведите пожалуйста полный список полей транзакции, которые входят и в ордера и в биржевой протокол и, значит, заполнены в каждом пришедшем OnOrder. А свои дополнения можно сделать как пишу выше, чтобы не было неразберихи. Либо =nil (отсутствуют в пришедшем ордере), либо -1, пока вы не вставите истинное значение.
Андрей написал: Приведите пожалуйста полный список полей транзакции, которые входят и в ордера и в биржевой протокол и, значит, заполнены в каждом пришедшем OnOrder.
Андрей написал: А свои дополнения можно сделать как пишу выше, чтобы не было неразберихи. Либо =nil (отсутствуют в пришедшем ордере), либо -1, пока вы не вставите истинное значение.
Еще раз, trans_id это наш параметр, его в принципе никогда нет в ордере. Наш сервер его проставляет, а не биржа.
Андрей написал: А свои дополнения можно сделать как пишу выше, чтобы не было неразберихи. Либо =nil (отсутствуют в пришедшем ордере), либо -1, пока вы не вставите истинное значение.
Еще раз, trans_id это наш параметр, его в принципе никогда нет в ордере. Наш сервер его проставляет, а не биржа.
Он всегда есть в OnOrder, ореде с т.з. елиента. Вы хотите сказать, что вы не можете своими внутренними признаками определить, ручной ордер или нет? Чтобы для ручных возвращать trans_id не так же, как для незаполненных. Ну исторически уже привыкли к 0 для ручных, а для незаполненных тогда просто не возвращать поле (=nil). Из ваших слов про биржу не следует, что вы не можете так формировать свои поля в OnOrder.
И насчет CLIENT_CODE в транзакции. Я его заполняю своим номером. Как его получить в OnOrder? Там нет такого поля, есть похожее по описанию brokerref, но оно не содержит моих данных, а именно /код клиента.
Андрей написал: Он всегда есть в OnOrder, ореде с т.з. елиента. Вы хотите сказать, что вы не можете своими внутренними признаками определить, ручной ордер или нет? Чтобы для ручных возвращать trans_id не так же, как для незаполненных. Ну исторически уже привыкли к 0 для ручных, а для незаполненных тогда просто не возвращать поле (=nil). Из ваших слов про биржу не следует, что вы не можете так формировать свои поля в OnOrder.
Эти "внутренние признаки" есть только на транзакции. Сервер получает транзакцию и запоминает "внутренние признаки" Далее транзакция отправляется на биржу и там регистрируется заявка. Обратно на сервер отправляется две сущности, ответ на транзакцию (текст типа "ваша заявка зарегистрирована...") и тело заявки (то что в таблице ORDERS биржевого интерфейса). Далее серверу нужно найти исходную транзакцию и связать ее с заявкой, происходит это через ответ на транзакцию. В ответе на транзакцию есть номер заявки, в теле заявки тоже есть номер заявки. Таким образом, зная это, сервер может найти исходную транзакцию и взять из нее "внутренние признаки" которые потом установить на теле заявки. Все усложняет то что тело заявки и ответ на транзакцию едут разными потоками, которые никак между собой не синхронизируются. Если ответ на транзакцию приехал раньше тела заявки то проблем нет, сервер заранее определяет "внутренние признаки" и когда заявка приедет, отправит ее клиенту вместе с признаками. Но т.к. потоки не синхронизируются бывают случаи когда тело заявки приезжает ДО ответа на транзакцию. Т.е. сервер получает тело заявки и не может найти исходную транзакцию, тогда тело заявки сразу передается клиенту, а потом, когда поступает ответ на транзакцию, сервер делает еще одну отправку тела заявки, но с уже проставленными "внутренними признаками" Исходя из этого, отвечаем на вопрос, мы не можем своими внутренними признаками определить, ручной ордер или нет до тех пор, пока не получен ответ на транзакцию.
Цитата
Андрей написал: И насчет CLIENT_CODE в транзакции. Я его заполняю своим номером. Как его получить в OnOrder? Там нет такого поля, есть похожее по описанию brokerref, но оно не содержит моих данных, а именно /код клиента.
Да brokerref, там должен быть комментарий. Проверьте еще раз.
Андрей написал: Какой правильный формат CLIENT_CODE , если 123456/345 не работает? 345 - это доп данные
В зависимости от настроек на стороне брокера, код клиента и комментарий могут разделяться либо "/" либо "//". Посмотрите как оно выглядит у Вас в таблице заявок
Андрей написал: обеспечьте надежный способ отличать, заполнено поле уже или нет. Незаполненное поле не должно иметь значение, валидное для заполненного.
Цитата
Андрей написал: для незаполненных тогда просто не возвращать поле (=nil).
Андрей написал: Какой правильный формат CLIENT_CODE , если 123456/345 не работает? 345 - это доп данные
В зависимости от настроек на стороне брокера, код клиента и комментарий могут разделяться либо "/" либо "//". Посмотрите как оно выглядит у Вас в таблице заявок
Еще наткнулся на странное сообщение "Нужно следить за UID экземпляра QUIK, чтобы фильтровать "чужие" заявки.". Это еще актуально? Действительно ли могут прийти колбеки заявок других клиентов? Я то предполагал это поле либо 0, либо правильным..
Андрей написал: Действительно ли могут прийти колбеки заявок других клиентов?
Конечно нет, это исключено. Только брокер может видеть заявки других клиентов.
Представьте себе два терминала, где в каждом из них настроен доступ к нескольким счетам клиента/клиентов, и этот набор счетов одинаковый для обоих терминалов. Если в одном из терминалов отправляется заявка, то другой терминал увидит коллбэки, связанные с ней.
Андрей написал: Действительно ли могут прийти колбеки заявок других клиентов?
Конечно нет, это исключено. Только брокер может видеть заявки других клиентов.
Спасибо. Еще отвлеченный вопрос. Допустим у меня открыт стакан. Я выделяю в нем строку и хочу нажатием клавиш запустить программную обработку информации (инструмент, выделенная цена). В идеале запуском макроса, хотя запуск макросов по событиям у вас не реализован. Но как можно реализовать в следящем макросе?
Может вы тоже подскажете, как это делается обобщенно через win32 ф-ции библиотеки w32 конкретно для стакана? Название активного окна (стакан) и выделенная в стакане строка. И как в макросе ожидать нажатие клавиш.
Может вы тоже подскажете, как это делается обобщенно через win32 ф-ции библиотеки w32 конкретно для стакана? Название активного окна (стакан) и выделенная в стакане строка. И как в макросе ожидать нажатие клавиш.
нужно написать свой скрипт, который рисует вам стакан (так же как это делает сам терминал), ловить действия пользователя в нем стандартными средствами и запускать нужные вам обработчики.
Может вы тоже подскажете, как это делается обобщенно через win32 ф-ции библиотеки w32 конкретно для стакана? Название активного окна (стакан) и выделенная в стакане строка. И как в макросе ожидать нажатие клавиш.
нужно написать свой скрипт, который рисует вам стакан (так же как это делает сам терминал), ловить действия пользователя в нем стандартными средствами и запускать нужные вам обработчики.
Но так горазда больше оверхеда по ведению онлайн еще одного стакана, хотя ф-цию нужно запускать на разовой основе. Неужели прочитать окно стакана нельзя?