Alexander (Все сообщения пользователя)

Выбрать дату в календареВыбрать дату в календаре

Страницы: Пред. 1 2 3 4 5
Как работает OnCalculate(), Интерактивно указываю интервал расчета при помощи меток. Пересчитывается только текущая свеча
 
Здравствуйте. Простейший индикатор на минутном графике работает когда его добавляешь на график. После перезагрузки без конца квик то подключится, то отключится, постоянно выводит информационное окно с разными сообщениями, получается всё время циклится - висит. Индикаторов таких несколько на разных графиках. Чтобы после перезагрузки вообще загрузиться приходится переименовать папку LuaIndicators, тогда удаётся зайти в квик и работать. Чтобы запустить графики, надо опять переименовать папку обратно в LuaIndicators, удалить на каждом графике индикатор и загрузить индикатор заного. Для тестирования ошибки оствил один график и один свой индикатор, так же попробовал в режиме ЗАМЫКАНИЙ. Кстати совсем не понятно, что это за режим такой и зачем он нужен, чем он отличается от обычного режима - очень хотелось бы получить на это ответ. Ну так вобщем сделал из индикатора совсем наипростейший, фактически оставив там только return nil и всё, тестил далее в режиме ЗАМЫКАНИЙ, так как никаой разницы с простым режимом не увидел. В теле OnCalculate поставил вывод через  PrintDbgStr("Index = " .. tostring(index)). И что получилось. Судя по выводам отладки видно, что все свечи вызываются последовательно начиная с 1 и до какой-то свечи, потом опять с 1 и до какой-то свечи, потом опять, короче раза 3 или даже 4 прогоняются свечи с 1 до последней. На этом всё. Болеее функция  OnCalculate вообще НЕ ВЫЗЫВАЕТСЯ!!! График при этом работает, свечи на нём идут, а OnCalculate не вызывается ВООБЩЕ. Почему такое? Почему при добавлении графика работает и OnCalculate вызывается и не один раз даже на свечу минутную, а при перезагрузке вызываются какие-то старые не нужные мне свечи последовательно и причём не один раз, а при приходе новых свечей OnCalculate перестаёт вызываться. И что за ЗАМЫКАНИЯ такие, как их использовать и в чём их смысл?
Обновление пользовательской таблицы/окна
 
Цитата
Anzhelika Belokur написал:
Alexander, добрый день.

Для разбора описанных Вами проблем, нам нужны примеры скриптов, один с  4-мя параметрами, когда таблица будет обновляться, второй без этого параметра. Просьба прислать запрошенную информацию нам на  quiksupport@arqatech.com  со ссылкой на данную ветку форума.
Все тонкости проблемы описаны выше и достаточно подробно. Нет никакого смысла отправлять примеры скриптов. Всё расписано до мелочей просто. Зачем примеры скриптов с SetCell с 4-мя параметрами и с тремя? С 4-мя это когда 4 параметра, 3 - это когда 3. Что тут не ясно то? Отсутствует последний параметр когда 3 параметра. Если будете реально разбирать проблему, то разработчики пусть читают эту тему, последние сообщения все. Они знают свою программу и lua. Если они прочитают что написао в теме, то всё им и так будет ясно. Вобщем если кто реально будет вникать в проблему из разработчиков, то прочитав тему и все мои сообщения, он всё поймёт.
Обновление пользовательской таблицы/окна
 
Цитата
Alexander написал:
Цитата
Anzhelika Belokur написал:
Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Ещё добавляю информации. Как я и писал ранее удалось таки заставить обновляться таблицу используя функцию Highlight, но косяки остаются при уходе подсвечиваемой строки за пределы таблицы при прокрутке и надо опять подсвечтвать строку в поле видимости таблицы или тыкать в заголовок мышкой. А дополнение такое - если в таблице вывод идёт строковой переменной через SetCell и SetCell без последнего 4-го числового параметра, то Highlight не помогает и жутко тормозит, прокрутка таблицы идёт с лагом в секунды, а может и минуты. Поэтому, чтобы Highlight работала и заставляла принудительно обновлять таблицу, вызовы SetCell делаю с передачей ей 4-го параметра равного числовому значению, я использую 1, хотя можно и любое другое число, хоть ноль, лишь бы было число. Хотя по умолчанию это число при выводе строки не нужно. Вот такие вот особенности. Может поможет Вам разобраться в проблеме.
И ещё, если все вызовы SetCell будут с 4-м параметром числом и хотя бы один из них SetCell будет без этого параметра, то таблица обновляться не будет и будет подвисать, как только все SetCell-ы будут со всеми 4-мя параметрами, так начинает обновляться и не тормозит, но косяки с выходом подсвечиваемой строки за пределы видимости таблицы так и не пропадают.
Обновление пользовательской таблицы/окна
 
Цитата
Anzhelika Belokur написал:
Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Ещё добавляю информации. Как я и писал ранее удалось таки заставить обновляться таблицу используя функцию Highlight, но косяки остаются при уходе подсвечиваемой строки за пределы таблицы при прокрутке и надо опять подсвечтвать строку в поле видимости таблицы или тыкать в заголовок мышкой. А дополнение такое - если в таблице вывод идёт строковой переменной через SetCell и SetCell без последнего 4-го числового параметра, то Highlight не помогает и жутко тормозит, прокрутка таблицы идёт с лагом в секунды, а может и минуты. Поэтому, чтобы Highlight работала и заставляла принудительно обновлять таблицу, вызовы SetCell делаю с передачей ей 4-го параметра равного числовому значению, я использую 1, хотя можно и любое другое число, хоть ноль, лишь бы было число. Хотя по умолчанию это число при выводе строки не нужно. Вот такие вот особенности. Может поможет Вам разобраться в проблеме.
Обновление пользовательской таблицы/окна
 
Разработчики, ответьте же хоть что-нибудь! Так же добавляю новую информацию для размышления. Попробовал отправлять сообщения WM_PAINT в цикле с задержкой 100 мс непосредственно окну таблицы из другой программы(написал на C++). Дескриптор окна необновляемой таблицы можно увидеть через Spy++. Сначала просто его использовал. Потом сделал автоматический поиск дескриптора в программе через FindWindow и FindWindowEx начиная с родительского окна QUIK. Так вот отправка WM_PAINT непосредственно процедуре обработки сообщений окна таблицы никакого результата не даёт, хотя SendMessage проходит без ошибок. Так же если отсылать в цикле UpdateWindow - тоже результата нет. UpdateWindow так же срабатывает без ошибок. Косяк на стороне квика. Выходит, что окно получает WM_PAINT, но перерисовывает его с необновлённого буфера. SetCell-ы видимо обновляют один буфер, но есть ещё другой буфер из которого WM_PAINT рисует окно, так вот из первого буфера во второй информация не попадает, а она туда должна попадать с периодичностью хотя бы 100 мс, тогда и WM_PAINT будет обновлять окно. Разработчики готовы вникнуть в суть проблемы или нет?
Обновление пользовательской таблицы/окна
 
Цитата
Alexander написал:
, точно. Попробовал использовать Highlight и действительно помогло! Спасибо. Но разрабам не помешает всё-таки сделать функцию UpdateWindow.
Помогло то помогло, да вот только не совсем. Если подсвечивать строку, которая ушла из поля видимости, например скроллингом, то таблица опять перестаёт обновляться. Я сделал так, чтобы подсвечивалась любая строка на которую ткнуть мышкой. Получается, что чтобы заствить таблицу обновляться - сначала тыкаю в любую строку в таблице, она подсвечивается и таблица обновляется. Если таблица большая и делаешь скроллинг(прокрутку) содержимого таблицы, то как только подсвечиваемая строка уходит за пределы таблицы, т.е. исчезает из поля видимости, то тут же таблица обновляться перестаёт. И нужно опять тыкать на любую видимую строку в таблице. Это не практично. Лучшее решение как я и писал выше - нужна функция UpdateWindow, но поддержка категорически молчит по этому поводу.
Обновление пользовательской таблицы/окна
 
Цитата
Nikolay написал:
Я писал выше - вместе с обновлением текста ячейки вызываю Highlight - помогает.
Да, точно. Попробовал использовать Highlight и действительно помогло! Спасибо. Но разрабам не помешает всё-таки сделать функцию UpdateWindow.
Обновление пользовательской таблицы/окна
 
Цитата
Alexander написал:
Пробовал:
1) получать заголовок окна через GetWindowCaption и заново его же выставлять через SetWindowCaption - не помогает.
2) получать координаты окна через GetWindowRect и заново выставлять окно по тем же самым координатам через SetWindowPos - не помогает. При этом окно становится поверх всех окон, только наведёшь другое окно на него, как моё окно становится поверх наведённого, причём данные в окне как не обновлялись, так и не обновляются. Чтобы обновились - по прежнему нужно либо ткнуть в окно мышкой, либо навести её на заголовок окна.
3) пробовал тоже самое что и п.1, только ещё плюс менять координаты на 1 пиксель, затем возвращать обратно - тут вообще смех просто получается - окно дёргается туда-сюда, а результат точно такой же как в п.1
Решения на данный момент нет. Программирование на Lua теряет всякий смысл при выводе данных в таблицу. Данные обновляются только в буфере программы, а окно не перерисовывается. Что делать? Писать отдельную программу на C? Искать окно в недрах Windows? Получать его хэндл и отправлять принудительно окну сообщение WM_PAINT на перерисовку? Это извращение какое-то.
Пункт 3 не помог потому, что окно сдвигал на 1 пиксель туда-сюда, при этом не меняя размер самого окна, а только изменяя координаты его верхнего левого угла. А вот если координаты левого верхнего оставить прежними, а менять координаты правого нижнего на 1 пиксель туда-сюда(фактически меняя размер всего окна получается), то окно начинает таки обновляться как положено. Но работать так невозможно, потому что окно во-первых дёргается, а во-вторых всегда поверх всех окон, только перекроешь его другим окном, как оно опять сверху.
Обновление пользовательской таблицы/окна
 
Пробовал:
1) получать заголовок окна через GetWindowCaption и заново его же выставлять через SetWindowCaption - не помогает.
2) получать координаты окна через GetWindowRect и заново выставлять окно по тем же самым координатам через SetWindowPos - не помогает. При этом окно становится поверх всех окон, только наведёшь другое окно на него, как моё окно становится поверх наведённого, причём данные в окне как не обновлялись, так и не обновляются. Чтобы обновились - по прежнему нужно либо ткнуть в окно мышкой, либо навести её на заголовок окна.
3) пробовал тоже самое что и п.1, только ещё плюс менять координаты на 1 пиксель, затем возвращать обратно - тут вообще смех просто получается - окно дёргается туда-сюда, а результат точно такой же как в п.1
Решения на данный момент нет. Программирование на Lua теряет всякий смысл при выводе данных в таблицу. Данные обновляются только в буфере программы, а окно не перерисовывается. Что делать? Писать отдельную программу на C? Искать окно в недрах Windows? Получать его хэндл и отправлять принудительно окну сообщение WM_PAINT на перерисовку? Это извращение какое-то.
Обновление пользовательской таблицы/окна
 
Поддержка, ответьте пожалуйста на вопрос выше. Что конкретно сделать, чтобы обновлялось окно? Или сделаете функцию UpdateWindow?
Глубина стакана на акциях., Способы увеличения глубины стакана акций
 
Цитата
serggio написал:
Вам ровно пять сообщений назад поддержка  ответила .
Я видел, что ответила поддержка. Заметьте, что после этого так же nikolz задал свой вопрос и поддержка не ответила. Вообще поддержка ответила, что такой стакан "огрызок" по сути - транслирует биржа. Т.е. биржа у себя имеет полный стакан котировок на акции, а брокеру она транслирует "огрызок" этого стакана. Вам не кажется это странным? Как поддержка вообще взялась тут ответить за брокера? Квик оперирует данными брокера, но не биржи. Поэтому думаю вопрос этот пока открыт и напишу брокеру - пусть он ответит какой полный стакан на бирже и какой стакан ему транслирует биржа и почему. Толи сам брокер делает у себя такие настройки, что биржа ему даёт не полный стакан, толи брокер получает таки полный стакан с биржи, но по каким то своим понятиям транслирует нам в квик не полный стакан.
Глубина стакана на акциях., Способы увеличения глубины стакана акций
 
Цитата
nikolz написал:
Вопрос к разработчиками.
Как я понимаю, глубина стакана - это размер очереди заявок на сервере биржи.
--------------------
Регулируется ли на сервере КВИК брокера размер транслируемой очереди т е глубина стакана.
Еесли да , то какая максимальная,
если нет , то какая максимальная на сервере биржи.
Спасибо
Скорее всего биржа всё-таки даёт брокеру полный стакан, а вот брокер уже режет его по своему усмотрению. Но пусть ответит поддержка. И почему например на акции только 20 глубина максимум, а на фьючерсы - 50? Кто это так решил?
Глубина стакана на акциях., Способы увеличения глубины стакана акций
 
Цитата
serggio написал:
Какой в этом практический смысл кроме вашего "хочу"?А есть еще айсберг заявки, их полностью невидно в стакане по определению
Смысл у каждого свой. Мне нужен анализ полного стакана. Да есть айсберг-заявки, знаю, что не всё видно, но это суть не меняет.
Обновление пользовательской таблицы/окна
 
Прочитал тему. Поднимаю вопрос в 2022 году. Проблема как была, так и осталась. У меня вообще наипростейший скрипт - SetCell в main заполняет ячейки, без всяких там подсветок. Поставил как рекомендовали sleep(100) не помогает. Перепробовал разные задержки - ничего не меняется. Чтобы таблица обновилась нужно либо ткнуть мышкой в неё в любое место, либо навести курсор мыши на верхнюю часть окна с заголовком. По другому никак. Это не порядок. Проблему надо решать. Что хочу сказать разработчикам. Причина - не прорисовка окна. Насколько мне помнится, чтобы заставить окно перерисоваться принудительно, есть такая функция, UpdateWindow когда пишешь на C, она отправляет сообщение WM_PAINT непосредственно в процедуру указанного окна, обходя очередь приложения. Неужели нельзя для qlua разработчикам сделать аналог? У вас всё для этого есть. Квик создаёт окно таблицы для пользователя, у вас все хэндлы всех окон есть и окна таблицы пользователя тоже. Вот сама функция на C:
BOOL UpdateWindow([in] HWND hWnd);
Напишите же свою функцию для qlua и внутри неё воткните UpdateWindow. Вам это совсем просто сделать, так как вы знаете hWnd окна таблицы. А нам где его брать? Вобщем думаю вы можете это сделать. А то переписывал весь день с qpile скрипт на lua. переписал, а тут такой косяк. На qpile и то стабильней работает. Там выставил 1 сек период расчёта и хотя бы раз в секунду будет обновляться окно. Хотя заметил, что на qpile обновление окна тоже идёт только в самом конце скрипта независимо делаем мы add_item из мапа или нет, он только буфер таблицы заполняет, а непосредственно прорисовка окна в самом конце скрипта идёт. Надеюсь проблему решите.
PS. Вы разработчики саму программу quik на каком языке пишите?
Глубина стакана на акциях., Способы увеличения глубины стакана акций
 
Цитата
Anzhelika Belokur написал:
Alexander,добрый день.

Что Вы понимаете под полным стаканом?
Если  у Вас в терминале по ФР и ВР показывает 20 строк покупки и 20 продажи это количество и транслируется с биржи (если у Вас не стоит настройка на уменьшение вкладка "Система"-Настройки-Параметры инструментов, глубина стакана), больше  стакан Вы не увидите. Если Вам нужно увеличить глубину стакана на СР, Вам необходимо обратиться к Вашему брокеру по данному вопросу.
Под полным стаканом я понимаю весь стакан, который есть на бирже. Я могу ставить заявки в стакан на любую цену какую хочу, лишь бы она была в пределах MAX - MIN(регулирует биржа) по инструменту. Так вот поэтому я могу выставить заявку с такой ценой, что она будет принята биржей, т.е.попадёт в её стакан, но я её у себя в стакане в квике не увижу. Т.е. она может попасть за пределы 20 лучших. Вот поэтому я и хочу видеть не какой-то там огрызок стакана, а весь стакан целиком.
Глубина стакана на акциях., Способы увеличения глубины стакана акций
 
Цитата
Anzhelika Belokur написал:
Alexander, добрый день.

Глубина стакана на фондовом и валютном рынке транслируется биржей.
На срочном рынке может изменяться настройками брокера.
Т.е. Вы хотите сказать, что полный стакан получить невозможно?
Глубина стакана на акциях., Способы увеличения глубины стакана акций
 
В Настройках параметров инструментов для всех классов и всех инструментов выставил глубину стакана 1000. Для акций ничего не изменилось - как было 20 туда-сюда, так и осталось, для фьючерсов увеличилось с 20 до 50. Я только так и не понял - это биржа так ограничивает стакан или брокер? Можно ли увидеть весь стакан полностью, какой он есть на самой бирже?
getParamEx
 
Цитата
Alexander написал:
Цитата
Mikhail написал:
Перед подачей заявки на бирже у мен стоит такая функция, работает как часы.
 
Код
      local   tostring_  =  tostring
  local   math_tointeger  =  math.tointeger

  function    t_ (x)
  return   tostring_(math_tointeger(x)   or   x)
  end      
 
Этот код будет работать. Но...
1) Зачем здесь вводить переменную tostring_ и загонять в неё адрес функции tostring и потом вызывать косвенно tostring через tostring_, когда можно сразу вызвать напрямую саму tostring?
2) Если в используемой версии Lua есть функция math.tointeger, то проблем не будет, адрес функции будет и присвоится переменной, а если нет? Косяк... Функция появилась в 5.3 версии.

На смартлабе нашёл вот такой код;

    local tointeger = math.tointeger or (function(x) return x end)

   function tryInt(x)
       return tointeger(x) or x
   end

Работает чётко. Мой разбор синтаксиса такой: в  tointeger  присваивается адрес либо  math.tointeger (если таковая есть в используемой версии), либо адрес безымянной функции, возвращающей то же число, что ей передано(имени нет, но адрес то есть, только он и нужен по сути) на этапе интерпретации скрипта.  return  косвенно вызывает либо  math.tonteger  либо безымянную функции в зависимости что попало в переменную  tointeger . В случае косвенного вызова через  tointeger  безымянной функции ошибок не будет и в любом случае вызов  tointeger(x)  вернёт целое значение, оно и вернётся при любом  x , а вторая часть " or x " в return не сработает. В случае же косвенного вызова через  tointeger  функции  math.tointeger  если без ошибок сработает, то вернётся целое число и так же вторая часть " or x " не сработает, но если вернёт ошибку, то сработает как раз вторая часть " or x " и она вернёт исходное  x . Думаю, что этот вариант лучше и надёжнее. Дальнейшее преобразование в строку через  tostring()  это уже по надобности.
А...да. Тут ещё добавлю, что если вызов tryInt в выражении, то ничего более не надо, а если в чистом виде, то пришлось добавлять в качестве выражения ещё +0(ноль число), тогда чётко работает. Это придётся учитывать.
getParamEx
 
Что касаемо типов данных в Lua, то считаю, что Владимир прав. На сайте Lua по этому поводу так прямо и написано: "Lua is a dynamically typed language. This means that variables do not have types; only values do. There are no type definitions in the language. All values carry their own type." Так что никаких integer в природе у него нет. Как он там конкретно хранит целые и вещественные и как он их преобразует из одних в другие - только ему и известно. Всё это типа для "упрощения" программирования замутили.
getParamEx
 
Цитата
Mikhail написал:
Перед подачей заявки на бирже у мен стоит такая функция, работает как часы.
Код
   local  tostring_ = tostring
 local  math_tointeger = math.tointeger

 function   t_ (x)
 return  tostring_(math_tointeger(x)  or  x)
 end   
Этот код будет работать. Но...
1) Зачем здесь вводить переменную tostring_ и загонять в неё адрес функции tostring и потом вызывать косвенно tostring через tostring_, когда можно сразу вызвать напрямую саму tostring?
2) Если в используемой версии Lua есть функция math.tointeger, то проблем не будет, адрес функции будет и присвоится переменной, а если нет? Косяк... Функция появилась в 5.3 версии.

На смартлабе нашёл вот такой код;

   local tointeger = math.tointeger or (function(x) return x end)

  function tryInt(x)
      return tointeger(x) or x
  end

Работает чётко. Мой разбор синтаксиса такой: в tointeger присваивается адрес либо math.tointeger(если таковая есть в используемой версии), либо адрес безымянной функции, возвращающей то же число, что ей передано(имени нет, но адрес то есть, только он и нужен по сути) на этапе интерпретации скрипта. return косвенно вызывает либо math.tonteger либо безымянную функции в зависимости что попало в переменную tointeger. В случае косвенного вызова через tointeger безымянной функции ошибок не будет и в любом случае вызов tointeger(x) вернёт целое значение, оно и вернётся при любом x, а вторая часть "or x" в return не сработает. В случае же косвенного вызова через tointeger функции math.tointeger если без ошибок сработает, то вернётся целое число и так же вторая часть "or x" не сработает, но если вернёт ошибку, то сработает как раз вторая часть "or x" и она вернёт исходное x. Думаю, что этот вариант лучше и надёжнее. Дальнейшее преобразование в строку через tostring() это уже по надобности.
getParamEx
 
Цитата
Alexander написал:
Кто подскажет как выкрутиться? Вызов getParamEx по инструменту CHZ2(фьючерс на Северсталь) по "OFFER"  Беру результат param_value(число), прибавляю к нему целое число. Отправляю транзакцию с этой суммой в цене(через tostring()). Транзакция не проходит. Не правильно указана цена "75941.0" Сообщение об ошибке: Число не может содержать знак разделителя дробной части. Пытаюсь использовать вместо param_value -> param_image(строка с числом без точки и знаков после неё). Но к стрингу не прибавляет число, прогоняю его через tonumber(), - возвращает ошибку nil. Как конкретно взять целое число, сложить и отправить стринг без дробной части? Неужели извращаться и обрезать строку? Вообще не понятно почему не работает tonumber() по параметру param_image? Если просто например написать tonumber("7777777"), то всё нормально - возвращает число. Просто бред какой-то.
Написал тестовый код:
        PriceBaseSell = tonumber(getParamEx(ClassCodeBase, SecCodeBase, "BID").param_image) - SpredOnSellBase
        PriceFutBuy = tonumber(getParamEx(ClassCodeFutures, SecCodeFutures, "OFFER").param_image) + SpredOnBuyFut
        local row  =   InsertRow (tbl.t_id, -  1 )
        SetCell (tbl.t_id, row,  1 ,  tostring(PriceBaseSell), PriceBaseSell)
        SetCell (tbl.t_id, row,  2 , tostring(PriceFutBuy), PriceFutBuy)
Результат с ошибкой:
scripts\test2.lua:56: attempt to perform arithmetic on a nil value

Если поменять param_image на param_value то будеn работать, но в таблицу выводит числа с дробной часть после точки.
getParamEx
 
Кто подскажет как выкрутиться? Вызов getParamEx по инструменту CHZ2(фьючерс на Северсталь) по "OFFER"  Беру результат param_value(число), прибавляю к нему целое число. Отправляю транзакцию с этой суммой в цене(через tostring()). Транзакция не проходит. Не правильно указана цена "75941.0" Сообщение об ошибке: Число не может содержать знак разделителя дробной части. Пытаюсь использовать вместо param_value -> param_image(строка с числом без точки и знаков после неё). Но к стрингу не прибавляет число, прогоняю его через tonumber(), - возвращает ошибку nil. Как конкретно взять целое число, сложить и отправить стринг без дробной части? Неужели извращаться и обрезать строку? Вообще не понятно почему не работает tonumber() по параметру param_image? Если просто например написать tonumber("7777777"), то всё нормально - возвращает число. Просто бред какой-то.
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
Цитата
nikolz написал:
Ответ есть в указанном разделе.
Ваш ответ похоже соответствует действительности. Я пришёл к такому же выводу. Но... Так как описано в документации квика, это нечто. Там нет разделения описания по акциям и по фьючерсам. В этом самом 5-ом разделе есть подраздел  "Вввод заявки", а в нём подподраздел "Окно «Ввод заявки»", там есть пункты 4 и 5 и там так написано, что ничего конкретного относительно акций и фьючерсов и вообще как попало написано
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
Цитата
nikolz написал:
читайте Раздел 5. Торговые операции клиента. Руководство пользователя QUIK.там все написано.
Ничего путнего там не написано. Я это читал раньше. На мой вопрос там ответа нет.
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
Цитата
Nikolay написал:
Цитата
Alexander написал:
Вот ещё хочу тут спросить старожилов по такому поводу. Скрипт на Lua сначала делает продажу акций Лукойл по рынку в шорт 10 шт через sendTransaction() при этом естественно ставлю TYPE="M", PRICE="0".
Транзакция проходит, заявка исполнилась нормально. Следующая транзакция на покупку фьючерса "LKZ2", т.е. LKOH-12.22 в количестве 1шт так же по рынку, где в sendTransaction() установлено так же TYPE="M", PRICE="0". Но при этом транзакция с ошибкой: Ошибка создания заявки. [GW][332] "Нехватка средств по лимитам клиента." Пытаюсь купить данный фьючерс вручную в квике, установив галочку в окне ввода заявки "Рыночная" - результат опять та же самая ошибка!
В результате фьючерс купил таки вручную, указав цену на покупку из стакана равную лучшей цене продажи. Транзакция прошла без ошибок и заявка тут же исполнилась. Да мог бы поставить цену покупки и выше чем лучшая цена продажи на несколько пунктов, это я знаю, и заявка ушла бы так по лучшей рыночной цене.
Но вопрос: почему sendTransaction() работает на покупку/продажу акций по рынку с значениями TYPE="M", PRICE="0", а на  покупку/продажу фьючерса с значениями TYPE="M", PRICE="0" выдаёт ошибку: "Нехватка средств по лимитам клиента." и я вынужден ставить цену хуже рынка, чтобы заявка ушла по рынку? Заявка то в конечном итоге прошла, значит средств достаточно!
Рыночных заявок на срочном рынке нет, на самом деле. Брокер Они отправит их по верхней|нижней границе допустимого ценового диапазона. Так происходит, потому что размер ГО, блокируемого под сделку, зависит от цены сделки. И чем дальше цена от цены последнего клиринга, там ГО будет выше. Хотя реальная сделка и будет не так далеко, но расчет ГО у брокера будет по цене ордера. Так что на сделку в 200 пунктах от цены клиринга может и хватает, а вот уже на сделку в 2000 пунктах - нет. Но такое происходит, если торговать на границе доступных средств. Когда средств достаточно, то и "по рынку" пройдет сделка.
Ну как бы есть или нет на срочном рынке заявки по рынку это вопрос отдельный, потому как например фьючерсы на юань у меня спокойно скрипт покупал и продавал по рынку по 1 шт(от шёлка мышкой, так просто для ускорения исполнения писал, чтобы не вводить вручную). Я так же склонялся и склоняюсь к тому, что ГО разное на разных ценах и по границам Min/Max оно скорее всего превысило - об этом подумал сразу. Но, что интересно, раньше вроде бы, если мне память не изменяет было такое, да - вручную ввод заявки по фьючерсу на одной цене - ГО показывает одно, на другой цене дальше к границе стакана - ГО другое. Но сейчас хоть на какой цене ни щёлкай - ГО одно и то же показывает в окне ввода заявки, оно точно соответствует тому ГО, что в ТТТ для инструмента. Поэтому и решил здесь спросить.
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
Вот ещё хочу тут спросить старожилов по такому поводу. Скрипт на Lua сначала делает продажу акций Лукойл по рынку в шорт 10 шт через sendTransaction() при этом естественно ставлю TYPE="M", PRICE="0".
Транзакция проходит, заявка исполнилась нормально. Следующая транзакция на покупку фьючерса "LKZ2", т.е. LKOH-12.22 в количестве 1шт так же по рынку, где в sendTransaction() установлено так же TYPE="M", PRICE="0". Но при этом транзакция с ошибкой: Ошибка создания заявки. [GW][332] "Нехватка средств по лимитам клиента." Пытаюсь купить данный фьючерс вручную в квике, установив галочку в окне ввода заявки "Рыночная" - результат опять та же самая ошибка!
В результате фьючерс купил таки вручную, указав цену на покупку из стакана равную лучшей цене продажи. Транзакция прошла без ошибок и заявка тут же исполнилась. Да мог бы поставить цену покупки и выше чем лучшая цена продажи на несколько пунктов, это я знаю, и заявка ушла бы так по лучшей рыночной цене.
Но вопрос: почему sendTransaction() работает на покупку/продажу акций по рынку с значениями TYPE="M", PRICE="0", а на  покупку/продажу фьючерса с значениями TYPE="M", PRICE="0" выдаёт ошибку: "Нехватка средств по лимитам клиента." и я вынужден ставить цену хуже рынка, чтобы заявка ушла по рынку? Заявка то в конечном итоге прошла, значит средств достаточно!
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
Цитата
Владимир написал:
1. Я уже говорил, что Ваше выставление и снятие 200 тысяч заявок за 4 часа иллюстрирует лишь полную беспомощность алгоритма торговли - у нормальных людей заявки ставятся не для того, чтобы их снимать, а для того, чтобы они исполнялись. Мои заявки, например, исполняются в 90% случаев и более.
Владимир, а может быть nikolz специально ставит в стакан заявки и потом их снимает не для того, чтобы исполнить, а может быть для того, чтобы сбить с толку других роботов, заставить их сработать, или нет, мало ли?
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
Цитата
nikolz написал:
Цитата
Alexander написал:
 
Цитата
Alexey Danin  написал:
Здравствуйте.
Но я спрашиваю конкретно для своего наипростейшего случая, что описал выше. Например - покупка 1 лота. Нужен контроль того, что покупка 1-го лота 100% прошла и только тогда подавать на продажу того же 1-го лота. Какой алгоритм контроля применить посоветует техподдержка? Уж куда проще то? Мой алгоритм подойдёт? Или можно его упростить, например - вообще не использовать OnTrade()? Достаточно проверить OnOrder() где баланс = 0? Сейчас использую и то и то. А надо ли? Вроде работает.
Объясняю как я делаю это.
--------------------------------
Например, циклический тест  выставления и снятия заявки.
Это тест подобен Вашей задаче.
Отличие лишь в том, что я контролировал снятие заявки, а Вы контролируете исполнение заявки.
Но алгоритм , описанный ниже решает обе задачи.
================
Результат тестирования алгоритма,
показал его безошибочную работу при случайном выставлении и снятии заявки по 200 инструментам.
За 4 часа теста на демо сервере выставлено и снято 200 тысяч заявок без единой ошибки.
==================
Алгоритм:
------------------------------
Преамбула:
Робот - это конечный автомат, который изменяет свое состояние в зависимости от внешних сигналов и своей цели.
Источником внешних сигналов являются колбеки.
------------------------
В моем роботе задействованы все колбеки, описанные в документации библиотеки QLua
Заверяю Вас, что лишних колбеков нет.
Вы можете не использовать какие-либо колбеки, но это подобно тому, что у человека отключить какой-либо орган.
-------------------------------
Если Вы колбек выкидываете, то ваш робот не видит многих событий и просто зависнет в один прекрасный момент.
===========
Если инструмент, по которому я хотел бы выставить заявку активен
,т е произошло событие по данному инструменту ( сделка, изменение заявки),
то проверяем по таблице заявок есть ли активная и  по таблице транзакций есть ли активная   по этому инструменту.
----------------------
Если есть активная , то новая заявка не выставляется, иначе выставляется.
-----------------
В более продвинутом алгоритме выполняется анализ актуальности текущего состояния , но это уже другая задача.
Ну я собственно использую большинство колбэков, и для контроля исполнения использую и OnOrder() и OnTrade() впаре чисто для повышения надёжности. Хотя уверен, что и OnTrade() было бы вполне достаточно. Работает и ладно.
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
Цитата
Alexey Danin написал:
Здравствуйте.

Цитата
Alexander написал:
Какой алгоритм контроля применить посоветует техподдержка? Уж куда проще то? Мой алгоритм подойдёт? Или можно его упростить, например - вообще не использовать OnTrade()? Достаточно проверить OnOrder() где баланс = 0? Сейчас использую и то и то. А надо ли?
Вы можете протестировать Ваши алгоритмы, проанализировать и выбрать более эффективный для Вас. Протестировать можно на учебном сервере  QUIK Junior .
О как! Интересно. Даже не знал, что есть такая возможность. Учтём.
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
А я вот решил почему-то ещё и ждать прихода самой сделки, использую OnTrade(). Может это и не надо. Что скажут разработчики? Нужен ли двойной контроль?
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
Цитата
Владимир написал:
Alexander, У меня заявки могут исполняться за произвольное количество сделок, так что любой приход OnTrade, не отфильтрованный как дубль, корректирует оставшееся количество лотов в заявке, а сам элемент стека удаляется уже в другом месте - либо по снятию, либо действительно по нулевому остатку.
Ваш алгоритм в принцине понял. В конечном итоге полное исполнение всё равно идёт по балансу в OnOrder().
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
У меня сейчас для заявки в 1 лот алгоритм такой. OnOrder(): если для моей заявки balance == 0 - ставлю один флаг. Пришёл OnTrade()[сделка прошла значит] с моей заявкой - ставлю другой флаг и беру цену из него и в переменную. Функция контроля иcполнения ждёт появления обоих флагов, если пришли, то цену беру из переменной. Так же внутри OnOrder()  и OnTrade() использую ещё свои флаги для того чтобы отбрасывать ненужные их вызовы - по сути OnOrder() как только пришёл в балансе ноль - ставлю флаг, следующий вызов проверяет этот флаг и если он есть, то игнорирую вызов, так же и в OnTrade(), как пришла моя сделка - ставлю флаг, чтобы отсекать другие возможные её вызовы. Вот и думаю, может просто достаточно только OnOrder() и брать из неё цену исполнения и достаточно?
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
Цитата
Владимир написал:
Alexander, Почему нельзя? Можно. Только вот мой личный "рекорд" в ожидании подтверждения исполнения заявки составляет семнадцать с половиной минут, и это наверняка не предел. А робот, тем не менее, написан и работает "вот прям ща". Не со 100%-ной уверенностью, поменьше, но работает. И написан он с головы до пят на чистейшем Lua. ::

Нет, Вы не путайте заявку и сделку. Если заявка именно в 1 лот, то остаток гарантированно в нуле, и сам факт прихода OnTrade говорит о том, что заявка исполнена (обычно в трёх экземплярах). По большому счёту, гарантирует идентификацию только совпадение trans_id, поскольку order_num формируется не нами, и я его, как правило, вообще не знаю. А вот для контроля исполнения заявки лично у меня заведён специальный стек активных заявок, из которого полностью исполненные или снятые заявки удаляются уже по таймеру.
Контроль исполнения заявки, которая например в вашем стеке у которой 1 лот контролируется по balanse == 0?
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
Короче, ещё спрошу так. Отправил заявку например на покупку 1 лота. В OnTrade() проверил, что  order.trans_id == моему TRANS_ID и order.order_num == TRANSACTION_COMPLETED[tostring(order.trans_id)], короче отфильтровал по своей заявке и проверил что order.balance == 0. Этого достаточно для контроля исполнения заявки?
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
Цитата
Владимир написал:
И я уже говорил, что самый первый вызов OnTrade вовсе не означает, что данные там правильные, и проверка цены на ноль тоже ничего не гарантирует.
Если оно так, то получается что просто нет возможности в квике сделать контроль исполнения заявки. А раз так, то получается, что всё остальное просто не имеет никакого смысла. Какой смысл писать робота или ещё чего, если нельзя осуществить контроль исполнения заявки? Нет уверенности в исполнении - дальше ничего делать нельзя!!! Либо есть возможность со 100%-ной уверенностью программно определить, что заявка исполнена, либо вообще тогда надо закрывать все обсуждения, да и вообще тогда теряет смысл программирования на этом самом Lua.
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
Цитата
Alexey Danin написал:
Здравствуйте.

Цитата
Alexander написал:
Вопросы:1) Возможен ли вызов OnTransReply() на мою поданную заявку с моим TRANS_ID, с trans_reply.trans_id == 0, nil, "0", "" или же trans_reply.trans_id всегда содержит номер заявки? Этот номер заявки измениться не может?2) OnTransReply() вызывается только один раз?3) Возможен ли случай, когда сначала первой будет вызов OnOrder(), а потом уже вызов OnTransReply()? Вроде бы как-то один раз такое проскочило, когда скрипт вылетел с ошибкой исполнения. Но точно не помню, возможно было и так, даже скорее всего так, что был вызов только OnTrade(), а  OnTransReply() не вызвался, хотя по факту заявка выставилась. Из-за этого дублирую сохранение номера заявки не только в OnTransReply(), но и в OnOrder().4) Могу ли я быть уверен, что имея самый первый OnOrder() c order.balance == 0, последующие OnOrder() не изменят значение  order.balance?5) Могут ли приходить сначала OnTrade() без  trade.price, а потом с  trade.price? От этого зависит какие именно я могу использовать вызовы OnTrade(), т.е. нужно ли вообще проверять установлено ли в них поле  trade.price, или это поле заполнено ценой всегда и не меняется в следующих вызовах?6) Могу ли я быть уверен, что имея самый первый OnTrade() с ценой исполнения trade.price, последующие OnOrder() не изменят значение trade.price? 7) Могу ли я с учётом своего алгоритма контроля исполнения использовать только самые первые вызовы OnOrder(), OnTrade(), OnTransReply(), отфильтровывая все последующие, где я фактически смотрю только на изменение баланса в заявке и жду появления сделки с номером заявки?8) Может быть вообще как-то по другому изменить алгоритм контроля исполнения заявки(приход сделки)? Какой алгоритм контроля посоветуют разработчики с учётом всех этих многочисленных вызовов?
1. Всегда содержит trans_id и этот параметр не меняется.
2. Да.
3. Возможен. В связи с тем, что различные биржи предоставляют интерфейс подключения к своим системам по разным протоколам и разным схемам, в некоторых заявки и сделки доставляются разными не синхронизированными потоками, также не нужно исключать факт потери пакетов. Таким образом возможны ситуации, когда первым будет вызван OnOrder().
4. Если пришёл OnOrder с balance = 0 - значит заявка исполнилась полностью, т.е. сделки на всё количество в заявке, и что дальше происходит с balance в OnOrder по данной заявке не важно.
5. Да, данный параметр не меняется в последующих вызовах.
6. Да, данный параметр не меняется в последующих вызовах. Если речь об одной заявке и только об одной сделке по ней - то цена не должна меняться. Если же по заявке может быть заключено больше одной сделки - то у каждой сделки может быть своя цена, которая может быть выгоднее цены в заявке.
7. Нет.
8. К сожалению, посоветовать какой-либо алгоритм контроля исполнения заявки мы не можем. Как уже верно заметил выше nikolz - общая рекомендация для сделок и заявок - не "затачивать" алгоритм на определенный порядок вызова OnOrder/OnTrade и их количество.  
Хорошо. По пункту 8 вы не советуете конкретный алгоритм. Но это в общем случае не советуете, поскольку вариантов может быть много. Но я спрашиваю конкретно для своего наипростейшего случая, что описал выше. Например - покупка 1 лота. Нужен контроль того, что покупка 1-го лота 100% прошла и только тогда подавать на продажу того же 1-го лота. Какой алгоритм контроля применить посоветует техподдержка? Уж куда проще то? Мой алгоритм подойдёт? Или можно его упростить, например - вообще не использовать OnTrade()? Достаточно проверить OnOrder() где баланс = 0? Сейчас использую и то и то. А надо ли? Вроде работает.
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
Цитата
Владимир написал:
Alexander, Кроме своего TRANS_ID использовать просто нечего - ничто другое не гарантирует, что транзакция наша. Да и эта айдишка не гарантирует  - иногда туда прилетают нули или явно левые айдишки вроде 10, 25 и т.п. Контроль исполнения у меня только по OnTrade, не вижу никакого смысла в использовании ни OnTransReply, ни OnOrder. Никакой очерёдности здесь не соблюдается от слова совсем - задержки в приходе прерываний или изменения содержимого таблиц Квика могут составлять 10 минут и более. Я присобачил какую-то пародию на нечёткий поиск, и у меня точность идентификации заявки, по которой пришла сделка, близка к 100%, но здесь мне очень помогает блокировка: подача заявки запрещена, если предыдущая заявка по этому тикеру не исполнена или не снята. И не только колбэки могут отправляться по нескольку раз, но и заявки могут исполняться в несколько сделок, причём прерывания по ним приходят крест-накрест собачьим шагом. А вот цена в разных сделках по одной заявке может и отличаться. И, наконец, Вы НИ В ЧЁМ не можете быть уверены. В частности, самые первые вызовы OnTrade (остальное прерывания я не использую) могут содержать как раз бракованные данные, а самые вторые или самые третьи - правильные. А могут врать и все до единого. И проверка полей таблиц trans_id со своим номером транзакции не поможет. Я делаю подобную проверку только при снятии неисполненных или частично исполненных заявок, и далеко не всегда там правильные значения, а заявки я снимаю через три минуты активности.
Владимир, привет. Вот и в этой ветке встретились. Мне бы весь этот сыр-бор с колбеками свести к решению моей простой задачи. Мне собственно(во всяком случае пока) надо реализовать элементарный алгоритм. Покупка лота - 1 шт, т.е. автоматом отпадает возможность срабатывания только части заявки потому как 1 лот это 1 лот и его частично исполнить нельзя. Это намного упрощает задачу. Далее всё, что мне нужно это контроль исполнения этой заявки на покупку. Всё. Я должен быть на 100% быть уверен, что моя заявка исполнилась. И если исполнилась, то только тогда подаю следующую уже на продажу, так что тут такой же принцип блокировки - пока не сработает покупка - никакой продажи. На QPILE я это делал так - в цикле пробегал по таблице заявок в поиске своей заявки с номером который мне возвратила send_transaction() в своём результате, смотрел значения поля баланса когда станет равно нулю, как только оно стало равно нулю, то потом в цикле пробегал по таблице сделок и как только в ней появлялась запись с номером моей заявки, я считал что сделка исполнена. Не знаю насколько хорош такой алгоритм, но он работал всегда. Возможно, что достаточно было просто увидеть ноль на балансе в таблице заявок и плюнуть на таблицу сделок, не знаю. Или наоборот, может достаточно было бы и того что сделка появилась в таблице сделок. Но я для надёжности решил использовать и то и то. Перейдя на Lua сначала обрадовался, что есть колбэки и не надо бегать в цикле по таблицам в поиске нужного номера заявки, но не тут то было. С одной стороны всё просто. С другой стороны - куча вопросов. А есть ли гарантия? На данный момент меня интересует пока только одно, могу ли я использовать самый первый вызов OnOrder(), в котором на балансе появился ноль вместо единицы и отбросить все остальные вызовы? Могу ли я использовать только самый первый вызов OnTrade(), который мне показал, что в нём появился номер моей заявки, взять из него цену и быть уверенным, что эта цена не меняется в следующих вызовах, и что вообще есть ли гарантия, что эта цена будет в самом первом этом вызове, т.е. надо ли проверять что цена не ноль, а остальные вызовы отбросить?
Если так можно, то суть контроля исполнения оставляю ту же - приход нуля в балансе заявки и(AND) появление сделки. Открытым в принципе остаётся вопрос, а надо ли вообще делать 2 проверки или может быть достаточно только какой-то одной из них? Если вызовы колбэков идут вразнобой, может заменить AND на OR? Может вообще как-то изменить сам алгоритм контроля исполнения? Как? Как лучше?

PS. Разработчики накуралесили конечно знатно, оставив пользователям самим разбираться во всём, потому как много непоняток и нет однозначности. Не мешало бы самим этим разработчикам в документации привести хотя бы элементарный пример контроля исполнения заявки использую колбэки!
Зависание QUIK
 
Цитата
Владимир написал:
Alexander, Я не знаю, что там происходит - знаю только, что глюков там дохренища, и от версии к версии это число растёт. С загрузкой-то можно и потерпеть, если достаточно редко отключать скрипт, а работа с ТТТ организована вполне себе терпимо, она реально быстрая, и у меня никогда не было проблем со скоростью, даже при очень большом количестве тикеров. Если, конечно, не пользоваться ни стаканами, ни графиками, ни обезличенными сделками - для торговли ничего из этого не требуется. Вот что иногда вылетает, скотина - это сильно раздражает. Время от времени прилетает nil, в т.ч. там, где его уж никак быть не может. Ставлю проверки на nil в тех местах - обычно помогает. Но, по большому счёту, весь софт надо переписывать с нуля, хотя никто этого не делает и делать не собирается.
Ну на меня собственно пока только загрузка долгая давит и тормоза по ходу работы с вкладками и окнами. По самим скриптам пока больших глюков самого квика я не заметил, потому как не так давно начал их писать. А начал я сдуру с QPILE, уж больно хотелось мне видеть разную информацию по опционам в виде отличном от доски опционов, да спреды разные между фьючерсами и базовыми активами в реальном времени с расчётом всяких вариантов купи-продай их и расчётом гарантированной прибыли в процентах годовых. То есть задачи довольно простые. Ах, да ещё надо было скрипт такой чтобы быстро например щёлк мышкой - купил, щёлк - продал, без всяких там окон ввода заявок, чтобы быстро. Вот пришлось по быстрому это накатать на QPILE. Понял, что это такое и что коряво на нём всё, хотя для простых задач пойдёт и это. Но его ограничения в 1 сек на перезапуск скрипта, и даже через какой-то изврат делать замкнутый цикл в отсутствие простого while как-то мне это совсем не в тему. И вот пришлось опять же по быстрому этот Lua познать и переписать скрипты на него. Но по мере написания на этом самом Lua начали появляться свои заморочки, о чём приходится спрашивать опять же на этом форуме. Так что пока в принципе по скорости всё нормально и зависаний как таковых много не было. А простой алгоритм робота у меня и на QPILE нормально и быстро работал. Но раз уж взялся за Lua, то и его переписал, всяких там зависаний тоже пока не замечено.
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
 
 Отправляю заявку через скрипт Lua - 1 лот, использую свой TRANS_ID на транзакцию. Задача - если сделка произошла, значит надо отправить другую заявку. Т.е. мне нужен контроль исполнения заявки(сделка). Логи показывают, что сначала первой всегда откликается OnTransReply(), потом могут идти 3 вызова OnTrade() и 2 вызова OnOrder() в разной очерёдности. Логика контроля исполнения заявки(по сути приход сделки) была такая:
1) В OnOrder() если пришло изменение заявки, т.е. order.balance == 0 , то -> флаг is_nul = true.
2) В OnTrade() если trade.order_num == номеру моей заявки(получаю его через OnTransReply(), или в OnOrder() если пришла моя TRANS_ID если этот OnOrder() вызвался раньше OnTransReply()[мало ли?] , то -> флаг  is_trade = true.
3) Далее если if is_nul and is_trade then -> выставляем нужную заявку.

Я не рассчитывал на то, что колбэки могут отправляться по нескольку раз. Прочитал эту тему, понял, что могут и причём неограниченное число раз. Я не заморачивался и не тестил чем конкретно отличаются пришедшие в колбэках таблицы, но вижу, что OnOrder() где order.balance == 0 - 2 раза, и OnTrade() 3 раза и слава богу цена в нём одна и та же.

Вопросы:
1) Возможен ли вызов OnTransReply() на мою поданную заявку с моим TRANS_ID, с trans_reply.trans_id == 0, nil, "0", "" или же trans_reply.trans_id всегда содержит номер заявки? Этот номер заявки измениться не может?
2) OnTransReply() вызывается только один раз?
3) Возможен ли случай, когда сначала первой будет вызов OnOrder(), а потом уже вызов OnTransReply()? Вроде бы как-то один раз такое проскочило, когда скрипт вылетел с ошибкой исполнения. Но точно не помню, возможно было и так, даже скорее всего так, что был вызов только OnTrade(), а  OnTransReply() не вызвался, хотя по факту заявка выставилась. Из-за этого дублирую сохранение номера заявки не только в OnTransReply(), но и в OnOrder().
4) Могу ли я быть уверен, что имея самый первый OnOrder() c order.balance == 0, последующие OnOrder() не изменят значение  order.balance?
5) Могут ли приходить сначала OnTrade() без  trade.price, а потом с  trade.price? От этого зависит какие именно я могу использовать вызовы OnTrade(), т.е. нужно ли вообще проверять установлено ли в них поле  trade.price, или это поле заполнено ценой всегда и не меняется в следующих вызовах?
6) Могу ли я быть уверен, что имея самый первый OnTrade() с ценой исполнения trade.price, последующие OnOrder() не изменят значение trade.price?
7) Могу ли я с учётом своего алгоритма контроля исполнения использовать только самые первые вызовы OnOrder(), OnTrade(), OnTransReply(), отфильтровывая все последующие, где я фактически смотрю только на изменение баланса в заявке и жду появления сделки с номером заявки?
8) Может быть вообще как-то по другому изменить алгоритм контроля исполнения заявки(приход сделки)? Какой алгоритм контроля посоветуют разработчики с учётом всех этих многочисленных вызовов?

Все эти 0, nil, "0", "", которые могут прийти в trans_id в разных частных случаях в OnTrade() или в OnOrder() как я понял для меня не критичны, так как во всех колбэках я проверяю поля таблиц trans_id со своим номером транзакции TRANS_ID.
Зависание QUIK
 
Цитата
Владимир написал:
А вот при начальной загрузке квик долго загружается - это проблема. Была, потом была подавлена, сейчас опять проявилась у одного из брокеров. И лог засирается со страшной силой - сотни мегов за десятки минут. Чем эта сволочь занимается, мне неведомо.
Вот, грузится точно так же оооочень долго. Умный способ думаю убирать нет смысла, так как он видимо и так лишнего сам загружать не будет. Его как поставил, так и стоит. Обезличенные сделки оставлено только неторговые поручения. Из-за этого вряд ли будет сильно тормозить. А вот что ещё можно изменить? Может быть можно вручную откорректировать какие-нибудь конфигурационные файлы квика? Как я понимаю квик при загрузке тянет с сервера дофига ненужной информации, например возможно данные для графиков или ещё что. Вот это если убрать, то может и ускорится загрузка?
Зависание QUIK
 
Цитата
Владимир написал:
Alexander, Был тут такой Антон, очень толковый и сильный программист. К сожалению, давно его не вижу. Насколько я помню, он когда-то рассказывал почему всё так происходит, но меня это мало интересовало, и я пропускал всё это мимо ушей. Покопайтесь в его сообщениях, если интересно.

У меня дохлейший по современным меркам комп, специально для торговли купленный. Два гига ОЗУ, два ядра по два гигагерца, два Квика от двух брокеров, в которых болтается несколько сотен тикеров на обслуживании. Нигде никаких особых тормозов не наблюдал - по крайней мере при нагрузках до тысячи тикеров на Квик. Кстати, насколько я помню, настройки "умным способом" и "по существующим таблицам" - разные вещи: ум есть - таблиц не надо.   ::  
Хорошо. Будет время покопаюсь, может найду сообщения этого Антона. По настройка там так - либо умным способом(там он квик сам смотрит по таблицам} либо по выбранным классам(классы сам выбираешь). Вот поэтому и думаю, что может из-за того, что много вкладок открыто (17 шт.) и на каждой вкладке несколько окон(где-то и 11 шт. есть), то поэтому и подтормаживает. Бывает даже так - сначала например окна двигаешь, мышкой нажимаешь  - всё нормально работает , потом бывает просто паузу делаешь - не нажимаешь ничего и потом просто например окно двинуть надо или закрыть его, крестик нажимаешь например на окно сообщения, а оно не закрывается сразу, а закрывается через паузу. Иногда сразу закрывается, а иногда через паузу. И при начальной загрузке у меня квик долго загружается. Не засекал время, но минуты точно. Это нормально?
Зависание QUIK
 
И вообще квик как-то приторможенно работает. Это интересно у всех так? То вроде шустро, то после переключения окон или ещё чего делаешь действие, например двинуть окно или закрыть окно, а оно тупит-висит, квик думает-думает и только после какой-то задержки срабтывает. Вроде и проц толком не загружет, а тормоза есть. Всё остальное - куча открытых программ всё работает шустро. Память 8 Гб, AMD Athlon™ X4 860K Quad Core Processor 3.70 GHz. Может настройки какие поменять? У мненя загрузка потоков данных в настройках стоит умным способом по существующим таблицам. Неужели из-за того, что много данных приходится онлайн подтягивать с сервера и обрабатывать? Стояло 10 сек, потом ставил на 1 сек время обновления данных.
Зависание QUIK
 
Цитата
Владимир написал:
Занимайтесь торговыми алгоритмами, господа, а не написанием нафиг никому не нужных тестов. И будет вам ЩАСТЬЕ!
Согласен. Этим и занимаемся. Просто столкнулся с такой ситуацией, которой как бы быть не должно, но она есть. Пытался понять почему такое у них вообще есть. Для себя просто поставил sleep(50) - всё работает. Но понять хотелось логику работы QUIK что они там замутилитакое  и почему, что без задержки ну никак.
Зависание QUIK
 
Цитата
nikolz написал:
разработчики рекомендуют ставить sleep  чайникам и буратинам, как самый простой способ
исключить практически монопольный захват процессора одним потоком.
В своё время сталкивался и с потоками на C и всякими там атомарными функциями и прочее. Но это было давно. Сейчас задача простая - написать скрипт и чтобы он не вис. Я просто пытаюсь понять какого хрена если main() это реально отдельный поток в OC, то почему он не виснет если есть sleep() и виснет если его нет? Ну нет sleep() и что? Ну циклится быстро и что? Время выполнения от захода в цикл до повторного захода в него минимально и что? И даже не факт что этот поток будет на 100% грузить одно из ядер процессора. Даже если разрабы API функцией(сейчас даже названий не помню и искать не хочу) вешают main() на отдельное ядро проца и что? OS сама решает какие ещё потоки будут последовательно работать на этом же ядре. И только OS может используя свои привилегии сделать так, что бы какой-то отдельный поток мог один занять ресурсы одного ядра, т.е. чтобы только он один выполнялся на этом ядре а не пользовательский поток QUIK это решает. Так что и без sleep() ничего виснуть не должно по идее и main() должен спокойно работать наравне с другими потоками, которые сочтёт нужным OS. Могу только предположить что есть какие-то прерывания от самого квика, которые во время своего выполнения что-то там делают, не пойми что и мешают main() нормально работать, просто main() по какой-то причине просто не получает управлении из-за того, что-то там у них в прерываниях циклится и не выходит из прерывания.
Зависание QUIK
 
Цитата
s_mike@rambler.ru написал:
Потоки, о которых пишут разработчики не есть потоки операционной системы в чистом виде. Если не вдаваться в дебри, sleep() нужен обязательно. Поставьте sleep(50) и все станет хорошо, ничего тормозить не будет
Да я тоже начал склоняться к такому, что потоки квика - это явно не потоки ОС.
Зависание QUIK
 
Т.е. по поводу поста выше если как говорят разрабы main() работает в отдельном потоке, то вообще ничего виснуть не должно. Хоть есть задержка, хоть нет. На то он и отдельный поток. Зачем разрабы рекомендуют ставить sleep(100)? Что не так с потоком?
Зависание QUIK
 
У меня из main() вызывается простая функция в которой в цикле while жду появления 2-х флагов. Флаги устанавливаются по событиям из 2-х разных коллбэков, один флаг из одного, другой из другого. Скрипт наглухо виснет если в функции while чисто цикл без задержки. Если поставить в цикл sleep(), то не виснет. По этому поводу даже есть пример в файле "Использование Lua в Рабочем месте QUIK.pdf" от разработчиков квика с подобным циклом while и там написано, что: "Если убрать вызов функции sleep() внутри цикла, то скрипт будет загружать на 100% одно из ядер процессора, что позволит увеличить скорость обработки сценариев внутри цикла, но приведёт к более интенсивному использованию ресурсов компьютера."
Дело в том, что у меня срабатывает коллбэк OnTransReply(trans_reply) и он выводит message и это окно с message виснет не отвечает, а скрипт работает в цикле. Так почему  виснет, а не грузит проц на сто процентов ядро? Вообще почему должно виснуть или грузить проц на 100% одно ядро если main() работает в отдельном потоке? main() вызывает простые функции и они значит тоже работают в одном потоке с ним. Или не так? какая разница вообще не пойму есть задержка в цикле или нет?
Моя функция c  циклом:
function order_done()
   while is_run do
        if is_nul and is_trade then
             is_nul = false
             is_trade = false
            return OrderPrice
        end
   end
end
А вот пример из файла про который пишут разрабы квика из их файла, который находится в каталоге Квик\Doc\Lua\Использование Lua в Рабочем месте QUIK.pdf:
is_run = true

function OnStop()
  is_run = false
end

function main()
  while is_run do
     sleep(100)
  end
end
Страницы: Пред. 1 2 3 4 5
Наверх