function OnTrade(trade)
local key = trade.trans_id
if working
and key~=sdelka.id
--and trade.sec_code==symbol
--and trade.class_code==class
then
local i=tonumber(sdelka[0]); i=i+1; ---- новый размер стека сделок из прерывания
sdelka[0]=i; ---- записываем изменение стека:
---- сохраняем новую сделку;
sdelka[i]={}; -- заводим новый элемент стека
sdelka[i][0]=sdelka[0];
sdelka[i][1]=trade.trans_id; -- ID транзакции
sdelka[i][2]=get_date(trade.datetime)
sdelka[i][3]=get_time(trade.datetime)
-- по умолчанию это покупка
sdelka[i][4]="B"; if bit.band(trade.flags,4)~=0 then sdelka[i][4]="S"; end;
local dir = sdelka[i][4]=="B" and 1 or sdelka[i][4]=="S" and -1 or 0;
sdelka[i][5]=trade.qty*dir; -- количество в сделке (в лотах)
sdelka[i][6]=trade.price; -- цена сделки
----- comission
sdelka[i][7]=trade.clearing_comission+trade.exchange_comission+trade.tech_center_comission;
sdelka[i][8]=trade.order_num;
sdelka[i][9]=trade.trade_num;
sdelka[i][10]=trade.sec_code; -- тикер
---- Защита от повторений:
sdelka.id=trade.trans_id;
end
end;
Получаю в функции робот обрабатываю.
Пользователь
Сообщений: Регистрация: 15.06.2023
10.08.2023 11:59:03
Цитата
VPM написал: И что это было 1 час в борьбе за подключение к сервера? Да уж.
А было это графики.
Вернул расчеты алгоритмов в main убрал лишние графики и вот оно чудо. Все грузится. Идея вести расчеты в квик, подходит для для единичных инструментов.
Цитата
Владимир написал: Господи, канал-то здесь при чём?
Пользуюсь HackTrade version 1.4 все прекрасно работает.
Пользователь
Сообщений: Регистрация: 05.08.2015
10.08.2023 12:06:29
VPM,Понял, но это не то. Я то думал сам удалось модифицировать на работу со сделками. Просто order.position не всегда оперативно обновляется после сделки. Видимо колбэки запаздывают.
Пользователь
Сообщений: Регистрация: 15.06.2023
10.08.2023 12:12:01
Цитата
uuh написал: Я то думал сам hacktrade удалось модифицировать на работу со сделками.
А зачем? hacktrade занимается своей работой, а в ф. робот я веду учет текущей позиции.
Пользователь
Сообщений: Регистрация: 15.06.2023
10.08.2023 12:17:18
Цитата
uuh написал: Просто order.position не всегда оперативно обновляется после сделки. Видимо колбэки запаздывают.
Что пришло от терминала только это и может обработать, быстрее не откуда взять.
Пользователь
Сообщений: Регистрация: 15.06.2023
10.08.2023 12:19:06
Цитата
uuh написал: Давно пользуюсь этой штукой в боевых роботах
написал: Я то думал сам hacktrade удалось модифицировать на работу со сделками.
А зачем? hacktrade занимается своей работой, а в ф. робот я веду учет текущей позиции.
Ну так hacktrade набирает позицию в рамках своих знаний о ней. А эти его знания можно посмотреть в order.position. Если обновлять заявку order:update в рамках своих знаний о текущей позиции, то робот то выставит на биржу заявку в соответствии со своими знаниями о позиции. А если колбэки о сделке еще не пришли, order.position не обновился, то и количество лотов в заявке может быть не тем, которое задумывалось. По моим наблюдениям, информация в таблице "trades" зачастую появляется быстрее, чем приходят колбэки. Вот если бы допилить hacktrade чтобы умел и с этой таблицей тоже работать, было бы здорово. Я начал было исследования в эту сторону, да забросил. Других дел хватает. Ну а из замечаний - вот это и еще иногда пытается снимать уже снятые заявки. Терминал ругается. Но вроде не критично. В остальном классная штука.
Пользователь
Сообщений: Регистрация: 15.06.2023
10.08.2023 13:03:40
Цитата
uuh написал: Ну так hacktrade набирает позицию в рамках своих знаний о ней. А эти его знания можно посмотреть в order.position.Если обновлять заявку order:update в рамках своих знаний о текущей позиции, то робот то выставит на биржу заявку в соответствии со своими знаниями о позиции.
Ну подождите, по порядку: В начале до основного цикла формируем заявки им присваивается уникальный номер, согласно этого номера и действуем. Нужно при следующем обращении поменять цену, меняем, нужно поменять количество меняем, нужно снять снимаем. Если исполняется у нее есть два статуса активна и исполнена, активная цена ушла снимаем.
На исполнена придет OnTrade мы его отловим, если не вся заявка исполнена она будет добиваться,
Так что два параллельных мира. мы управляем ценой и количеством (т.е денюшкой) в ордере, А hacktrade исполнением ордера и взаимодействует с терминалом.
Все как в лучших домах!
Пользователь
Сообщений: Регистрация: 15.06.2023
10.08.2023 13:04:38
Цитата
uuh написал: А если колбэки о сделке еще не пришли, order.position не обновился, то и количество лотов в заявке может быть не тем, которое задумывалось.
Не может если не поменяли.
Пользователь
Сообщений: Регистрация: 15.06.2023
10.08.2023 13:09:49
Цитата
uuh написал: Ну а из замечаний - вот это и еще иногда пытается снимать уже снятые заявки. Терминал ругается. Но вроде не критично.
Я добавил проверку на ошибку reply[i][6]=trans_reply.status; reply[a][6]~=3 если заругался выхожу из цикла. Пока так.
Пользователь
Сообщений: Регистрация: 05.08.2015
10.08.2023 13:12:00
VPM,я описал логику работ hacktrade так как я ее понимаю на основании своего опыта работы с ним и того описания, что дал автор-создатель hacktrade. А вот кто и как и где формирует заявки то мне не ведомо, да и не имеет значения в данном контексте. Если все получается и ошибок нет, то хорошо. Возможно и так будет работать. Время покажет.
Пользователь
Сообщений: Регистрация: 15.06.2023
10.08.2023 13:25:23
Так я и описал логику автора вот
Код
dofile("hacktrade.lua") ---Загруили
function Robot()
----- Получили т.тек.торгов
feed = MarketData{
market="QJSIM",
ticker="SBER",
}
----- создаем ордера
order = SmartOrder{
account="NL0011100043",
client="74808",
market="QJSIM",
ticker="SBER",
}
----- Получили индикаторы
ind = Indicator{
tag="MAVG",
}
----- Торгуем
while true do
if feed.last > ind[-1] then
order:update(feed.last, 10)
else
order:update(feed.last, -10)
end
Trade()
end
end
"Это пример реверса по скользящей средней.
Пример тривиальный, но надёжный. Робот догоняет цену.
Если снимите заявку, он выставит количество, которое не успел купить/продать."
Пользователь
Сообщений: Регистрация: 05.08.2015
10.08.2023 13:40:45
VPM,отлично, хороший пример. Вот робот отправил заявку купить 10 лотов - order:update(feed.last, 10) Прошла сделка на 7. Позиция в терминале увеличилась на 7. Но колбэк об этом еще не пришел, значит order.position = 0 Робот считает текущую позицию только по колбэкам. Другой информацией он не пользуется.
В такой ситуации робот перевыставит заявку на те же 10 лотов. И есть шанс вместо 10 купить 17 лотов. Он может не реализоваться, но он есть и далеко не нулевой.
Пользователь
Сообщений: Регистрация: 15.06.2023
10.08.2023 13:46:20
Цитата
uuh написал: В такой ситуации робот перевыставит заявку на те же 10 лотов.И есть шанс вместо 10 купить 17 лотов.Он может не реализоваться, но он есть и далеко не нулевой.
Нет в этой реализации не каких 17 не может быть, ордер знает 10 и пока ему не подтвердит кщлбек исполнение будет стоять 10 или набираться частями до 10.
Пользователь
Сообщений: Регистрация: 15.06.2023
11.08.2023 13:18:09
Что то я совсем не могу понять, что средствами qlua нельзя получить стоимость контракта на fut?
Пользователь
Сообщений: Регистрация: 27.01.2017
11.08.2023 13:42:38
Цитата
VPM написал: Что то я совсем не могу понять, что средствами qlua нельзя получить стоимость контракта на fut?
Вы про какую стоимость спрашиваете? Про размер ГО, уплаченный по сделке или стоимость в в валюте цены? Если про ГО, то это величина, рассчитываемая по формуле, зависящей от многих параметрах, спецификации контракта. На этом форуме уже обсуждалось и приводился пример такого метода.
Пользователь
Сообщений: Регистрация: 15.06.2023
11.08.2023 13:45:49
Нет я про реальную цену контракта на рынке, чтоб рычаг считать.
Пользователь
Сообщений: Регистрация: 27.01.2017
11.08.2023 13:54:08
Цитата
VPM написал: Нет я про реальную цену контракта на рынке, чтоб рычаг считать.
Формализуйте термин "Реальная цена контракта". Есть цена в момент времени в валюте цены контракта. Если речь про это. В чем проблема ее получить?
Пользователь
Сообщений: Регистрация: 15.06.2023
11.08.2023 13:55:21
Nikolay, Чтоб точно ГО считать мне пока не нужно, достаточно получать его, все равно необходим зазор чтоб позиция дышала. стоимость контракта = price_last * pos_qty* lot ?
Пользователь
Сообщений: Регистрация: 27.01.2017
11.08.2023 13:58:41
Свою позицию Вы знаете. Размер лота и цену последней сделки получите из потока данных (условно Таблицы текущих торгов) через метод getParamEx. В документации все методы qlua описаны.
Пользователь
Сообщений: Регистрация: 15.06.2023
11.08.2023 14:01:34
Да я сообразил, просто думал что готовый параметр может быть., Спасибо
Пользователь
Сообщений: Регистрация: 15.06.2023
13.08.2023 14:32:54
Всем добрый день!
Стоит задача вывод меток на график, чтоб их вывести необходимо задать идентификатор графика, куда эти метки выводить.
Раньше я делал просто
tag={}; for i=1, #sec do tag[i] = tostring( 'J'..i) end
где, sec - массив тикеров в работе. J - обозначение таймфрейма.
Для небольшого массива вроде и нечего , но если порядок тикеров в массиве поменялся нужно переписывать идентификатор графика.
Для автоматизации процесса удобней вместо индекса добавлять первые два символа тикера
На пример: тикер NGQ3, идентификатор графика tostring( 'J'..'NG')
Как правильно от тикера отделить первые два символа?
Пользователь
Сообщений: Регистрация: 15.06.2023
13.08.2023 15:57:40
Ну вроде такой вариант работает:
string.sub (sec, 0,2 )
Пользователь
Сообщений: Регистрация: 30.01.2015
13.08.2023 19:23:20
Строки в Lua индексируются с 1 (а не 0, как в C). Индексы могут быть отрицательными и интерпретируются как индекс с конца строки. Т.е. последний символ имеет позицию -1, и т.д.
Пользователь
Сообщений: Регистрация: 30.01.2015
13.08.2023 19:29:09
На всякий случай ссылка на документацию
6.4 – Работа со строками
Эта библиотека предоставляет общие функции для работы со строками, такие как поиск, извлечение подстрок и сопоставление шаблонов. Когда индексируются строки в Lua, первый символ находится на позиции 1 (не на 0, как в C). Допускаются негативные индексы, они интерпретируются как индексирование обратно (задом наперед), с конца строки. Таким образом, последний символ находится на позиции -1 и так далее.
local tag={} sec = { 'NGQ3', 'EDU3', -- 9.6 p; ГО 6598; 'RMU3', -- RTSM-9.23 Индекс РТС (мини) Расчетный фьючерс на RTSI. Стоимость пункта цены 18,46 p; ГО 3546; 'NAU3', -- NASD-9.23 Nasdaq 100 Расчетный фьючерс на Invesco QQQ ETF Trust Unit Series Стоимость пункта цены 0,92p; ГО 1799; };
for i=1,#sec do tag[i] = 'J'..string.sub( sec[i], 1,2 ) print(type(tag[i]), tag[i]) end
Так тоже ошибку не давал? string.sub( sec[i], 0,2 )
Пользователь
Сообщений: Регистрация: 22.02.2023
14.08.2023 13:33:59
Цитата
VPM написал: стоимость контракта = price_last * pos_qty* lot ?
С контрактом на индекса мосбиржи (MXI) такая формула не работает.
Всё пройдет. Но это не точно.
Пользователь
Сообщений: Регистрация: 15.06.2023
14.08.2023 13:42:50
Цитата
Ziveleos написал: С контрактом на индекса мосбиржи (MXI) такая формула не работает
А как?
Пользователь
Сообщений: Регистрация: 15.06.2023
14.08.2023 15:47:05
При тестировании стратегий на исторических свечах. При выводе меток приходит такая ошибка;
Цитата
Ошибка при создании метки: Группа или ресурс не находятся в нужном состоянии для выполнения требуемой операции.
Ни чего по ней найти не возможно, по смыслу что со свечами не то?
написал: При тестировании стратегий на исторических свечах. При выводе меток приходит такая ошибка;
Цитата
Ошибка при создании метки: Группа или ресурс не находятся в нужном состоянии для выполнения требуемой операции.
Ни чего по ней найти не возможно, по смыслу что со свечами не то?
Скорее не со свечами, а с метками. Файлы картинок для меток используются?
Добрый день!
Опять выскакивает "как черт из табакерки" эта ошибка?
Цитата
Ziveleos написал: Скорее не со свечами, а с метками. Файлы картинок для меток используются?
Поясните в чем причина, и что с этим делать?
Пользователь
Сообщений: Регистрация: 15.06.2023
18.08.2023 13:48:03
Цитата
VPM написал: Файлы картинок для меток используются?
Да используется.
Пользователь
Сообщений: Регистрация: 22.02.2023
18.08.2023 14:14:39
Причина в том, что в новых версиях квик каждый раз при отрисовке метки обращается за картинкой к диску, даже если картинка одна и та же, и, видимо, у него не всегда это получается.
Что с этим делать - не знаю.
Всё пройдет. Но это не точно.
Пользователь
Сообщений: Регистрация: 15.06.2023
19.08.2023 08:36:16
Ziveleos, У себя по отключал метки, все равно иногда проявляется, думаю что то с параметрами, обложил логами.
Пользователь
Сообщений: Регистрация: 15.06.2023
19.08.2023 09:51:38
Вот лог
Label_Image: I=22329; graph= JMM; d= 20230811; t= 130000; text= xS; q= 0.0; p= 3168.1 [Fri Aug 18 16:03:47 2023] Trace: params[FONT_FACE_NAME] = Arial; string [Fri Aug 18 16:03:47 2023] Trace: params[TRANSPARENT_BACKGROUND] = 1; number [Fri Aug 18 16:03:47 2023] Trace: params[TEXT] = ; string [Fri Aug 18 16:03:47 2023] Trace: params[R] = 0; number [Fri Aug 18 16:03:47 2023] Trace: params[FONT_HEIGHT] = 6; number [Fri Aug 18 16:03:47 2023] Trace: params[TIME] = 130000; string [Fri Aug 18 16:03:47 2023] Trace: params[DATE] = 20230811; string [Fri Aug 18 16:03:47 2023] Trace: params[IMAGE_PATH] = ; string [Fri Aug 18 16:03:47 2023] Trace: params[G] = 0; number [Fri Aug 18 16:03:47 2023] Trace: params[YVALUE] = 3168.1; number [Fri Aug 18 16:03:47 2023] Trace: params[HINT] = 20230811,130000,xS,1,3168.1; string [Fri Aug 18 16:03:47 2023] Trace: params[ALIGNMENT] = LEFT; string [Fri Aug 18 16:03:47 2023] Trace: params[B] = 0; number [Fri Aug 18 16:03:47 2023] Trace: label id: nil; xS [Fri Aug 18 16:03:47 2023] Trace: t_label Проблема? JMM = nil [Fri Aug 18 16:03:47 2023] Trace: label_id[MMU3]= nil
В некоторых случаях не выполнялось условие, вот причина params[TEXT] = ; string. Проверил это моя лексическая. Надеюсь что с этим все.
Пользователь
Сообщений: Регистрация: 15.06.2023
19.08.2023 10:35:34
Почему важно. Встраиваю в проект Backtesting, я им раньше пользовался, по сути перенес функции из старых наработок, изменений минимально и тут началось. Упала визуализация.
В квике 2 варианта визуализации. 1) На открывать графики, наставить индикаторы и получать их скриптом. Сильно зависит от количества графиков и пропускной способности канала. Отказался. 2) Алгоритмически считать индикаторы скриптом и пользоваться сервисом вывода меток на график. Даже удивил (если не считать данную ошибку). Потребление памяти не изменилось это все те же 500кб. Быстродействие отстоял сессию с замедление 1мс. т.е. скрипт отлично чистится не каких протеканий. Правда, лог не смог открыть из за его объема блокнотом (Гб).
Чем больше пользуюсь HT тем больше нравится.
Допишу Backtesting нужно стратегии оценивать.
Пользователь
Сообщений: Регистрация: 15.06.2023
23.08.2023 14:54:10
Backtesting - проверка торговых стратегий на исторических (прошлых) данных.
Задача сводится к определению параметров устойчивости стратеги, на разных инструментах, при разных рыночных условиях. И предположению, что будет какое то время, оставаться такой же надежной и в будущем.
Казалось бы, простая реализация задачи сводится: загрузил данные, в цикле прокатился по ним с выполнением правил торговой стратегии. Сохранил результаты сделок, расчитал показатели данной стратегии. Сравнил. При необходимости оптимизировал.
Но каждый раз при реализации задачи на тыкаюсь на одну и туже проблему. Это синхронизация графиков разных таймфремов (система нескольких окон)!
Ну это когда младший график двигается в промежуток времени старшего таймфрема и совместно сдвигаются.
Каждый раз "леплю очередной огород". Возможно есть готовое решение, или идеи по реализации в виде модуля?
Пользователь
Сообщений: Регистрация: 15.06.2023
23.08.2023 20:40:53
А чем собственно разговор?
Как мы получаем интерисующию нас нас цену на конкретном баре.
из Руководство пользователя QLua Версия 10.3: "Функции в качестве параметра принимают индекс свечи и возвращают соответствующее значение№.
Open = ds:O(1); High = ds:H(1); Low = ds:L(1); Close = ds:C(1); Volume = ds:V(1)
А где взять индекс? Разработчики скромно промолчали.
Пользователь
Сообщений: Регистрация: 15.06.2023
23.08.2023 21:06:31
Ну это еще пол беды,
из Руководство пользователя QLua Версия 10.3: Свечки графика. Описание параметров свечки графика:
Параметр Тип Описание open NUMBER Цена открытия close NUMBER Цена закрытия high NUMBER Максимальная цена сделки low NUMBER Минимальная цена сделки volume NUMBER Объем последней сделки datetime TABLE Формат даты и времени doesExist NUMBER Признак расчета индикатора при наличии свечки. Возможные значения: «0» – индикатор не рассчитан; «1» – индикатор рассчитан
Вопрос, а где тут индекс? Ну зато появляется массив - datetime TABLE Формат даты и времени.
Вот она наконец удача, знаем дату, знаем время (до миллисекунд) можно вернуть интересующею нас нас цену на конкретном баре!
Но не тут то было!
Пользователь
Сообщений: Регистрация: 15.06.2023
23.08.2023 21:13:35
Не зная индекса текущего можно получить значение цен за интервал времени.
А зная время вернуть цены нельзя (ну или дело совсем не простое).
Во, чудеса! Все об этом знают, свыклись и молчат?
Пользователь
Сообщений: Регистрация: 27.01.2017
23.08.2023 21:25:20
Алгоритм синхронизация разных ТФ достаточно прост. Синхронизация идет по времени бара, т.к. время это общее что связывает ТФ. Надо определить наименьший ТФ. Далее есть точка отсчета как отметка времени. Необходимо установить младший ТФ и все старшие на эту начальную точку, т.е. найти тот индекс в каждом ТФ, который соответствует этой отметке.
Теперь необходим итератор по индексам младшего ТФ, от начальной точки.
Переходим на следующий индекс. Проверяем старшие ТФ: новая отметка времени требует увеличения индекса старшего ТФ? Если да, то увеличить.
Таким образом, на каждой итерации текущий индекс каждого ТФ будет соответствовать текущему времени итерирования.
Для примера ТФ 1 мин, 5 минут.
Стартуем от 10:00.
Увеличиваем индекс ТФ1 на 1. Это будет 10:01. Для ТФ 5 минут все еще длится бар 10:00. Значит по нему увеличения индекса нет. Так доходим до 10:05. В этот момент для ТФ 5 минут выполнится условие нового бара. Значит по нему увеличиваем индекс на 1.