Вычитание из числа округленного до сотых числа округленного до сотых, В скрипте две переменных, округленные до сотых. Из одной вычитается другая. Результаты математической операции ниже:
Вычитание из числа округленного до сотых числа округленного до сотых, В скрипте две переменных, округленные до сотых. Из одной вычитается другая. Результаты математической операции ниже:
Sergey Gorokhov написал: Здравствуйте, Это известная проблема с использованием типа данных с плавающей точкой. Рекомендуем добавить функцию округления до заданной точности.
Сергей, здравствуйте! Собственно мой вопрос в этом и заключался. Каким образом это реализовать? Прошу сильно не пинать, лучше если есть такая возможность - скиньте пример.
Вычитание из числа округленного до сотых числа округленного до сотых, В скрипте две переменных, округленные до сотых. Из одной вычитается другая. Результаты математической операции ниже:
В скрипте две переменных, округленных до сотых. Из одной вычитается другая. Результаты математических операции ниже: 0.14999999999999 0.099999999999994 0.13000000000001 0.040000000000006 Видел похожую тему с 0.000000001, но в моем случае результаты еще интересней. Подскажите каким образом получить нормальный результат?
Zoya Skvorcova написал: Если одно из условий удовлетворено, вторая заявка снимается.
Это я знаю. Вопрос в том, что в конкретном случае оба условия будут удовлетворены, т.к. стопцена и цена отступа от тейка, как я уже писал выше, будут равны.
Добрый день! По стратегии после входа в сделку выставлена стопзаяка типа "стоп и тейк". При достижении тейка, активируется счет отступа от (макс./мин.), иными словами при достижении тейка включается трейлинг. В данном случае тейк-отступ= стоп-цена, поэтому не совсем ясно, что исполнится первым. Исполнится стоп? Исполнится тейк? Исполнится и то и другое (знаю, что при исполнении тейка снимается стоп и наоборот, но тут они на одной цене)? Будет отвергнута ТС? Также интересно, изменится ли статус стопзаявки если тейк активирован, но цена еще не достигла отступа?
В примере конечно же 75.35 покупка и 75.36 продажа, т.е. движение 20 шагов цены. Набирал с телефона, заметил только сейчас. Скрин обязательно сделаю и выложу.
Egor Zaytsev написал: Информация в ТТП, в стакане и на графике это разные потоки данных. График и не должен успевать за стаканом. Сделайте скриншот проблемы.
Как понять график не должен успевать? Стоит цена на 75.51 покупка 75.52 продажа - далее резкое движение в стакане его сразу вижу. К примеру в стакане уже покупка 71.35 продажа 71.36, т.е. сделки прошли и объём не хилый, а график стоит на месте и через некоторое время отрисовывает свечу. Пользуюсь кивком 3 года, а эта беда последние 1.5 месяца. Думал у меня косяк какой, но нет. Винда и квик чистые, ничем не нагружены, а график тормозит и тормозит не в час-пик, а хз по какой причине.
sav 312 написал: Последние 1.5 месяца график сильно отстаёт от стакана. Временами все приходит в норму. Установил чистый квик на чистом выделенном сервере. Скриптов нет, индикаторов нет. Открыт всего один инструмент - нефть. Тормозит... График на пару секунд отстаёт от стакана, иногда больше, редко приходит в норму. Темы по оптимизации производительности изучены и опробованы - результата не дали. Проблема квика? Брокера? Биржи? Да, кстати, мой брокер - Сбер.
Добрый день.
Какую информацию вы сравниваете? На графике отображаются обезличенные сделки, а в стакане заявки.
Я прекрасно понимаю, что в стакане заявки, но... К примеру в стакане вижу цену покупки 75.51, продажи 75.52 т.е спрэд равен шагу цены, последняя цена в ТТП 75,52, а на графике другие значения. Спустя пару секунд вижу верный результат и так постоянно, за редким исключением. Такая фича появилась 1.5 месяца назад, раньше запаздывания не было.
Последние 1.5 месяца график сильно отстаёт от стакана. Временами все приходит в норму. Установил чистый квик на чистом выделенном сервере. Скриптов нет, индикаторов нет. Открыт всего один инструмент - нефть. Тормозит... График на пару секунд отстаёт от стакана, иногда больше, редко приходит в норму. Темы по оптимизации производительности изучены и опробованы - результата не дали. Проблема квика? Брокера? Биржи? Да, кстати, мой брокер - Сбер.
Sergey Gorokhov написал: sav 312 , По возможности тяжелые циклы лучше не использовать вне main. Т.к. всё кроме main крутится в основном потоке терминала. А значит пока цикл не закончится новая информация в терминале не обработается.
Всем спасибо за подсказки. Все, что хотел - сделал. Сейчас возникает вопрос правильности размещения данного участка кода в самом скрипте. Написал функцию, в которой при каждом изменениии в стакане сканируется ТВС за последние 30 секунд. Правильно ли вызывать мою функцию из OnQuote() или в OnQuote() нужно устанавливать флаг, а по нему вызывать мою функцию из main? Можно ли использовать цикл в моей функции или его нужно вытаскивать в main? Прошу не пинать начинающего, за возможно глупые вопросы))
sav 312 написал: Подскажите пожалуйста как перевести время из строки ТВС в секунды.
Не понятно с чем возникла сложность. Получить время можно из параметра datetime, там есть hour, min, sec см документацию QLUA.chm глава "Структуры данных" - "Обезличенные сделки"
Далее умножаете часы на 3600 минуты на 60 и складываете полученную цифру с секундами.
Считал что есть более простой способ, чем на каждой строке ТВС делать пересчёт. К примеру os.time() сразу выдаёт время в секундах, вот и предположил, что можно из ТВС вытащить время сразу в нужном формате.
Сделать выборку через SearchItems и в функции fn добавить нужное условие. При этом надо обязательно добавить условие на нужный класс, т.к. время на разных рынках может не совпадать друг с другом.
Цитата
sav 312 написал: В каком виде нужно получать время в каждой из строк ТВС и с каким временем его сравнивать?
Проще всего перевести время в секунды и сравнить с текущим временем. А вот с чем сравнивать, это уже сложнее. Время os.time или os.date это время Вашего компьютера, которое вполне честно может не совпадать с временем биржи. Время SERVERTIME из getInfoParam это время сервера QUIK, уже лучше, но только если Вы уверены в своем брокере и качестве интернет соединения, если не уверены, лучше не пытаться. Остается два варианта, либо сравнивать со временем самой последней строки в ТВС, либо максимально точно синхронизировать время Вашего компьютера с временем биржи.
Подскажите пожалуйста как перевести время из строки ТВС в секунды.
Добрый день. Необходимо обработать все сделки за последние 30 секунд. Для этого буду перебирать ТВС с конца таблицы и прерывать цикл при выходе за пределы 30 секунд. Как лучше это реализовать? В каком виде нужно получать время в каждой из строк ТВС и с каким временем его сравнивать?
Sergey Gorokhov написал: При таком сценарии, отследить задержку можно по времени биржи, которое можно взять например в Таблице Обезличенных Сделок.
Могу предположить, что обезличенные сделки грузились без задержки, т.к. и в стакане и на графике все было нормально
Цитата
Sergey Gorokhov написал: Именно в Вашем случае, самым надежным способом было бы отслеживание времени ответа на транзакцию.
Не совсем понял. Если робот отправит транзакцию на вход и потом, спустя заданный интервал времени не получит отклик, то что он должен будет сделать? Отменить транзакцию? Если так, то может получится, что сигнал на отмену дойдет до биржи уже после исполнения транзакции на вход. Или Вы имели ввиду другой алгоритм? У меня была другая идея. Каким-либо образом перед отправкой транзакции на вход проверять доступность биржи. Весь вопрос как это реализовать. Есть ли это будет реализовано, то прекрасно понимаю, что доступность в данную секунду, не гарантирует доступность в момент отправки транзакции. Похоже тупик?
Добрый день. В четверг после клиринга, а в пятницу до него с серверами Сбера были проблемы. Вкладки не переключались, заявки не отправлялись и не снимались, хотя потом, как оказалось, команды на снятие и отправку все же ушли и были исполнены минут через 10, обратите внимание - не секунд, МИНУТ, при этом время сервера не отставало от времени системы и на графике и в стакане все тоже было без задержек. Т.е. если бы в этом момент был сигнал на вход и робот отправил транзакцию, то исполнилась бы она через 10 минут. Это, как вы понимаете мягко говоря не очень хорошо. Каким образом в луа-скрипте предусмотреть защиту от входов в сделку в момент тормозов? По какому параметру луа-скрипт может отследить их наличие или отсутствие?
Michael Bulychev написал: Добрый день. у Вас ошибка в коде. Вместо bit.band(stop_order.flags,0x400)==0x1 надо проверять bit.band(stop_order.flags,0x400) ~= 0 Результат битового AND нужно сравнивать не с единицей, а на неравенство с нулем.
sav 312 написал: Станислав, спасибо. Разобрался самостоятельно.
Похоже поторопился я с выводами. Ошибку в коде исправил, но флаги на отвергнутые заявки так и не срабатывают. В любом случае в логах вижу, что стоп-заявка исполнена, но когда заявка рождённая стоп-заявкой выставляется, то запоминается ее номер и т.д. ,а когда отвергнута ТС реакции никакой.
Код
if bit.band(stop_order.flags,0x2)==0x0 and bit.band(stop_order.flags,0x1)==0x0 then
to_log(tostring(SECCODE).." OnStopOrder(): Cтоп-заявка № "..tostring(NO).." исполнена.")
if stop_order.linkedorder > 0 then
OrderNum_CLOSE = stop_order.linkedorder;
to_log(tostring(SECCODE).." OnStopOrder(): Запоминаем номер созданной стоп-заявкой заявки - № "..tostring(OrderNum_CLOSE))
close_pos = 2
elseif bit.band(stop_order.flags,0x400)==0x1 then
to_log(tostring(SECCODE).." OnStopOrder(): Стоп-заявка № "..tostring(NO).." сработала, но была отвергнута торговой системой.")
close_pos = 1
elseif bit.band(stop_order.flags,0x800)==0x1 then
to_log(tostring(SECCODE).." OnStopOrder(): Стоп-заявка № "..tostring(NO).." сработала, но не прошла контроль лимитов.")
close_pos = 1
end
end
sav 312 написал: Почему не сработали флаги, указанные выше?
Для ответа на Ваш вопрос нужно знать все данные о выставляемых Вами заявках. Рекомендуем посмотреть на параметр "Результат" таблицы стоп-заявок и проверить, соответствует ли он тому, что было возвращено в OnStopOrder.
Цитата
sav 312 написал: Где отлавливать данную ситуацию 4. Еслиловить в OnTransReply, то по какому параметру? Номера заявки, выставленной стоп-заявкой нет. trans_id тоже не знаю т.к. заявку выставляет не робот, а стоп-заявка, возможно будет = trans_id_stop?
Данную диагностику возвращает Торговая система. По причинам ее появления рекомендуем обратиться к Вашему брокеру.
Станислав, спасибо, что наконец обратили внимание на мой пост. Ответы к сожалению, Вы дали как-то избирательно. Да и в указанной Вами ветке, ответов на мои вопросы нет. Кстати, прочитал я её, ещё до обращения к Вам. Давайте попробуем иначе... Помогите пожалуйста разобраться с причиной не срабатывания флагов, а дальше самостоятельно решать буду. В таблице стоп-заявок результат - отвергнута ТС.
if bit.band(stop_order.flags,0x400)==0x1 then to_log(tostring(SECCODE).." OnStopOrder(): Стоп-заявка № "..tostring(NO).." сработала, но была отвергнута торговой системой.") end
if bit.band(stop_order.flags,0x800)==0x1 then to_log(tostring(SECCODE).." OnStopOrder(): Стоп-заявка № "..tostring(NO).." сработала, но не прошла контроль лимитов.") end
На указанные выше флаги реакции никакой.
Ниже по коду есть ещё 1 флаг:
if bit.band(stop_order.flags,0x2)==0x0 and bit.band(stop_order.flags,0x1)==0x0 then to_log(tostring(SECCODE).." OnStopOrder(): Cтоп-заявка № "..tostring(NO).." исполнена.") end
Он чётко отработал. Вот и непонятно мне почему, флаги сигнализирующие об исполнении заявки срабатывают, а о том, что отвергнута ТС нет.
Stanislav Tvorogov написал: Для выставления рыночной заявки можно использовать заявку вида: "TAKE_PROFIT_AND_STOP_LIMIT_ORDER", в которой можно заполнить данные только для нужного Вам типа стоп-заявки (стоп-лимит или тейк профит).
Не совсем понял зачем нужно ещё раз использовать стоп-лимит и тейк-профит, пусть даже нужного мне вида. Моя стоп-заявка, выставленная роботом исполнилась, но лимитка, выставленная исполненной стоп-заявкой была отвергнута, т.е. она даже не появлялась в таблице заявок. В моем скрипте ловится номер заявки, которая была рождена исполненной стоп-заявкой и мониторится ее исполнение, с последующей отправкой смс-уведомления. В моем случае нет номера, т.к. и заявки нет. Возникает несколько вопросов: 1. Почему не сработали флаги, указанные выше? (Моя ошибка или глюк?) Ответ на это вопрос сильно упростил бы мою задачу. 2. Где отлавливать данную ситуацию, раз уж флаги не срабатывают. Как вариант, если в течение определённого времени (ну скажем 5 секунд) не верно условие if stop_order.linkedorder > 0 (т.е. не получили номер заявки, т.к. она не была создана), то кроем позу аварийно. 3. Как закрыть позу аварийно? При выставление роботом рыночной заявки (лимитка с отклонением в несколько шагов от текущей цены) получим такой же результат - нехватка средств по лимитам. Когда ситуация произошла - крыл руками, сначала на 1 лот меньше общего количества, потом оставшийся 1 лот. Совсем не нравится данная логика. 4. Еслиловить в OnTransReply, то по какому параметру? Номера заявки, выставленной стоп-заявкой нет. trans_id тоже не знаю т.к. заявку выставляет не робот, а стоп-заявка, возможно будет = trans_id_stop?
Пока все молчат дополню... В функции OnStopOrder имеются флаги, но первые два из указанных ниже никак себя не проявили, сработал только последний.
if bit.band(stop_order.flags,0x400)==0x1 then to_log(tostring(SECCODE).." OnStopOrder(): Стоп-заявка № "..tostring(NO).." сработала, но была отвергнута торговой системой.") end
if bit.band(stop_order.flags,0x800)==0x1 then to_log(tostring(SECCODE).." OnStopOrder(): Стоп-заявка № "..tostring(NO).." сработала, но не прошла контроль лимитов.") end
if bit.band(stop_order.flags,0x2)==0x0 and bit.band(stop_order.flags,0x1)==0x0 then to_log(tostring(SECCODE).." OnStopOrder(): Cтоп-заявка № "..tostring(NO).." исполнена.") end
Добрый день. Вчера тестировал скрипт на демо, умышленно на всю котлету. Как и предполагал не зря. При исполнении стоп-заявки робот выставил лимитку, с небольшим отклонением от цены условия срабатывания. Лимитка была отвергнута по причине нехватки средств. (Бред, т.к. нужно было закрыть то количество, которое фактически уже было куплено/продано, но этот вопрос не к вам). Подскажите где отлавливать данный факт и самое главное, как закрывать позицию по рынку, ведь новая лимитная заявка, аврийно-выставленная роботом с отклонением в несколько пунктов от текущей цены также будет отвергнута.
sav 312 написал: При перемещении стоп-заявки на графике изменяется стоп-лимит цена, при этом цена выставляемой заявки при исполнении условия остаётся неизменной. К примеру изначальный стоп выставлялся с проскальзыванием в 10 шагов цены. Решили увеличить стоп на 10 шагов, тянем линию на графике и получаем на выходе стоп-лимит цену равную цене, т.е. проскальзывание = 0. Предлагаю сделать так, чтобы при перемещении стоп-заявки, изменялась и стоп-лимит цена и цена, т.е. величина проскальзывания всегда оставалась неизменной.
Добрый день. Используйте при перемещении клавишу "Ctrl". Если при перемещении линии нажата клавиша «Ctrl», то изменяются как стоп-цена, так и цена лимитированной заявки, выставляемой при исполнении условной заявки. Если при перемещении линии клавиша «Ctrl» не нажата, то изменяется только значение стоп-цены.
При выборе другого инструмента в таблице, в панели торговли стакана очищается окно с количеством. Это очень неудобно, т.к. на каждом торгуемом инструменте количество разное. Предлагаю, чтобы количество введённое в вышеуказанное окно сохранялось. К примеру кликнули в таблице на нефть в стакане ввели количество 10. Кликнули на евробакс - ввели 15. Кликнули опять на нефть - количество 10 уже в соответствующем окне.
При перемещении стоп-заявки на графике изменяется стоп-лимит цена, при этом цена выставляемой заявки при исполнении условия остаётся неизменной. К примеру изначальный стоп выставлялся с проскальзыванием в 10 шагов цены. Решили увеличить стоп на 10 шагов, тянем линию на графике и получаем на выходе стоп-лимит цену равную цене, т.е. проскальзывание = 0. Предлагаю сделать так, чтобы при перемещении стоп-заявки, изменялась и стоп-лимит цена и цена, т.е. величина проскальзывания всегда оставалась неизменной.
Sergey Gorokhov написал: Здравствуйте, Не рекомендуем использовать циклы в колбеках. Т.к. колбеки выполняются в основном потоке терминала, т.е. пока колбек не закончит работу, терминал будет виснуть. Все тяжелые циклы, следует использовать только в main. В самом же колбеке, следует добавить флаг, приводящий к нужным действиям в main Пример
Код
work = false
function OnStopOrder ( .. .)
work = true
end
function main ()
.. .
if work then
.. .
end
.. .
end
Спасибо за совет. Сейчас переделаю и буду тестить.
После срабатывания стопзаявки, запоминаем номер созданной заявки, по этому номеру путем перебора таблицы сделок находим нашу. Запоминаем цену исполнения сделки. Иногда все срабатывает как надо, а иногда скрипт подвешивает квик. Логи иногда заканчиваются строкой "стопзаявка исполнена", а иногда "запомнили номер заявки".
Кусочек скрипта:
if bit.band(stop_order.flags,0x2)==0x0 and bit.band(stop_order.flags,0x1)==0x0 then to_log(tostring(SECCODE).." Cтоп-заявка № "..tostring(NO).." исполнена.")
if stop_order.linkedorder > 0 then OrderNum_CLOSE = stop_order.linkedorder; to_log(tostring(SECCODE).." Запоминаем номер созданной стоп-заявкой заявки - № "..tostring(OrderNum_CLOSE)) while Run and close_pos == 0 do for i=0,getNumberOf("trades")-1 do local trade = getItem("trades", i); if trade.order_num == OrderNum_CLOSE then EPSL = trade.price to_log(tostring(SECCODE).." Цена исполнения стоп-заявки - "..tostring(EPSL)) close_pos = 2 break; end; end; sleep(100); end end end
Sergey Gorokhov написал: sav 312 , А зачем все? сравнивайте текущее значение с предыдущим вот и всё
Сергей, я понимаю, что мои вопросы вызывают, как минимум улыбку. Если не трудно, добавьте заветную пару строк в мой пример. Ну начинающий я)) То, что уже изучил - не забуду, а здесь торможу что-то..
Функция getCandlesByIndex умеет получать тиковые данные. В связи с чем, не совсем понятно в чем состоит проблема.
Делал так, но получаю максимум и минимум последней свечи. Прошу сильно не пинать)) local N2 = getNumCandles(CODE_INT); t2,n2,i2 = getCandlesByIndex(CODE_INT, 0, 0, N2);
for i2 = n2 - 33, n2 - 3 do local bar = t2[i2] if bar then mx = max(bar.high) mn = min(bar.low) end end
Sergey Gorokhov написал: sav 312 , Начнем с того что функции math.min и math.max принимают только список аргументов, не таблицы. И тем более они не понимают таблицы состоящие из некоторого набора параметров. А getCandlesByIndex как раз таки возвращает таблицы состоящие из параметров. Т.е. чтобы найти min/max Вам в любом случае придется делать цикл, который пробежится по всем свечкам которые вернул getCandlesByIndex. А раз будет цикл, то и функции math.min и math.max применять нет особого смысла, ибо в этом же цикле можно определить min/max через банальный if. Т.е. через getCandlesByIndex запрашиваете все нужные свечки. Потом цикл который берет из них значение и ищет min/max Вот и весь алгоритм.
Сергей, спасибо. К сожалению не совсем понятно как через if. Может примерчик есть какой? Свечи нужные через getCandlesByIndex я выбрал. А вот дальше....
Добрый день! Подскажите, как через getCandlesByIndex получить максимум и минимум за определенное количество свечей. В моем случае нужно выбрать все максимумы свечей от свечи n2 - 33 до свечи n2 - 3 и выбрать из них максимальное значение. Из минимумов соответственно минимальное значение.
sav 312 написал: Я приводил два примера обнуления позиций в 15:47 и в 13.00.
Да, и на это уже был ответ:
Цитата
Sergey Gorokhov написал: Другой вопрос в том почему 21го числа клиринг был в 15:00, а 22го уже в 13:00 и на этот вопрос у нас к сожалению нет ответа. Видимо это какая-то особенность игрового контура биржи.
Цитата
Sergey Gorokhov написал: поправка, 21го клиринг был в 15:45
Цитата
sav 312 написал: Может ли на боевом счёте происходить кратковременное обнуление позиций в течение торговой сессии, т.е. не во время клиринга?
нет
Спасибо за "развёрнутый" ответ. Можно было ограничиться последним "НЕТ". Ответ понятен, дополнять не следует.
Sergey Gorokhov написал: О каком обнулении во время сессии идет речь?
Я приводил два примера обнуления позиций в 15:47 и в 13.00. По факту, такие обнуления происходили в разное время. В 15.47 - стабильно, а в 13 и 14 с определённой хаотичностью. Давайте, чтобы сильно не углубляться, сформулирую вопрос по-другому. Может ли на боевом счёте происходить кратковременное обнуление позиций в течение торговой сессии, т.е. не во время клиринга? В настоящее время в моем скрипте сброс параметров при обнулении позиций происходит по следующему алгоритму: STATUS_TORGOV = tonumber(getParamEx(CLASSCODE,SECCODE,"STATUS").param_value); if TOTAL_NET == 0 and STATUS_TORGOV == 1 then ENTER_PRICE = 0 killStopOrders(SECCODE) и т.д. Но этот алгоритм будет давать сбой, если в торговое время хоть на тик обнулиться количество позиций.
Sergey Gorokhov написал: sav 312 , На боевом будет тоже самое, только там клиринг всегда в одно время.
Очень странно все это. Раньше в работе долгое время были роботы на qpl (алгоритм в плане сброса параметров при обнулении позиций тот же) и ничего во время клиринга не сбрасывалось. Прекрасно понимаю, что дело здесь не в qpl и qlua, что-то теперь во время клиринга новое происходит? С клирингом не беда, добавлю к обнулению условие по времени. А как быть с обнулением во время торговой сессии?
Sergey Gorokhov написал: Расследование показало, что обнуление происходит в момент клиринга и это нормально т.к. происходит перерасчет данных. Другой вопрос в том почему 21го числа клиринг был в 15:00, а 22го уже в 13:00 и на этот вопрос у нас к сожалению нет ответа. Видимо это какая-то особенность игрового контура биржи.
С этим все ясно. На боевом счёте такого быть не должно во время клиринга?
sav 312 написал: Sergey Gorokhov написал: так быть не должно. Приведите конкретный пример, время события и UID Вашей учетной записи. UID - 117018. Было 7 открытых позиций. 21.11.17 в 15:47:17 на один тик кол-во=0, а дальше опять 7.