Торговый робот «Ретранслятор»
Всем привет! Пора отпусков закончена — едем дальше!
Достаточно часто у меня спрашивают: как переносить торговые сигналы из сторонних систем теханализа/трейдинга в QUIK? Самый простой способ — это импорт транзакций через текстовый файл. Эта функция давно присутствует в QUIK и прекрасно работает. Но, как обычно, есть одно «но» — в таком случае система теханализа представление не имеет о том, как сложилась «судьба» и отправленного торгового сигнала, исполнился ли он, или система его отклонила и т.д. Я, например, столкнулся с задачей как переносить торговый сигнал из МетаТрейдера в QUIK. Поступил следующим образом: МетаТрейдер при возникновении сигнала, который мне был важен, записывал в текстовый файл единицу если это был сигнал к покупке, или минус единицу, если к продаже. Затем специальный торговый робот в QUIK просматривал этот файл и производит торговые действия непосредственно в QUIK. Стратегия была реверсная. Итак — код торгового робота. Обратите внимание на функцию чтения данных из файла, для ее использования надо заранее завести переменную ERROR, что видно в блоке «Переменные». Также я всегда использую контроль данных: если LAST=0 значит либо неверно указан код инструмента, либо QUIK глюканул и шлет нулевые данные. Реализован блок «Закрытие позиций по времени», которому посвящена отдельная публикация.
Код на QPILE доступен только зарегистрированным пользователям.
Спасибо!
Давно назревала эта идея, не доходили руки.
Евгений, а проверку вы реализовывали? Исполнилась, не исполнилась заявка?
И потом в MT (МетаТрейдер) не передавали результат?
Если есть вариант было бы не плохо написать.
Евгений Reply:
сентября 26, 2010 at 14:11
Привет.
В МТ результат не передавал, МТ просто транслировал сигнал. хотя и механизм передачи можно также организовать.
В вышеприведенном коде конечно же есть проверка исполнения сигнала от МТ.
Зачем функции BUY и SELL принимают единичку в качестве аргумента KEYS?
Евгений Reply:
ноября 23, 2010 at 20:55
Привет.
Дело в том, что функция совсем без аргументов не работает, поэтому просто передаем никому не нужный аргумент KEYS в виде единички.
В свете изменения механизма получения информации в QPILE (www.quik.ru/forum/qpile/62030/62030/) оправдана ли функция PAUSE? Правильно я понимаю, что без получения результата (положительного или отрицательного) об отправленной заявки далее остаток кода выполняться не будет (т.е. это синхронная заявка)? Видит ли остаток кода заявку в соответствующих таблицах или пару сек подождать всё таки придётся?
Евгений Reply:
ноября 25, 2010 at 19:15
Привет.
Паузу в этом виде я применяю только для того, чтоб заявка успела дойти до сервера. Вообще при отправке транзакции есть два (теперь уже три) пути:
1. проверять результат отправки транзакции сразу в цикле, пока результат не равен единице — не выходим из цикла. Но бывают случаи когда отправленную транзакцию сервер вообще не получает — тогда робот зависает в цикле. Можно конечно цикл делать на 100 проверок.
2. Ставить паузу как это я делаю — просто ждем. И в следующей итерации если транзакция не дошла — отправляет еще раз. Что сравнимо и проще чем п.1.
3. Сразу после отправки транзакции опять проверять текпоз и таблицу заявок — усложняет код, и тем более что как правило в своих роботах я делаю отправку транзакции в самом конце логики, чтоб дальше шла только следующая итерация, и так и так проверится текпоз и таблица заявок.
На самом деле здесь вопрос не сколько в методе, сколько в качестве связи квика у пользователя. Если она плохая то ничего не поделаешь.
mercator Reply:
ноября 25, 2010 at 19:22
А как реализовать п.1, т.е. зависнуть пока из функции отправки не придёт какой-то ответ?
Евгений Reply:
ноября 26, 2010 at 11:40
Сама функция отправки выдает МАР, в котором есть переменная:
RESULT DOUBLE Результат выполнения операции. Возможные значения:
«1» – выполнено успешно, «0» – произошла ошибка
FOR RESULT_PROBE FROM 1 TO 100 IF GET_VALUE(TRANS_RESULT, "RESULT")+0=1 RESULT_PROBE=100 ' ВЫХОДИМ ИЗ ЦИКЛА, ТРАНЗАКЦИЯ УСПЕШНА ELSE IF RESULT_PROBE=100 MESSAGE(GET_VALUE(TRANS_RESULT, "DESCRIPTION"),1) END IF END IF END FORЧто то вроде этого. Но этот блок либо получит единицу сразу, либо не получит ее совсем. Поэтому я просто применяю паузу.
mercator Reply:
ноября 25, 2010 at 19:30
Проблема то в том, что заявка может зависнуть где-то в пути аж на минуту. Так получается за это время робот 60 заявок отправит.
Евгений Reply:
ноября 26, 2010 at 11:32
Если Квик повисает надолго — связь обрывается — а в роботе есть контроль соединения с сервером, он просто останавливается.
Евгений Reply:
ноября 25, 2010 at 19:57
В догонку: пауза нужна для того, чтоб робот не увидев изменение текпоза и/или активной заявки не отправлял повторную транзакцию.
mercator Reply:
ноября 27, 2010 at 13:59
В итоге паузу я реализовал следующим образом:
N = GET_NUMBER_OF («ORDERS»)
''' пуляем транзакцию '''
FOR K FROM 1 TO 100000
IF N < GET_NUMBER_OF ("ORDERS")+0
MESSAGE ("(k="& K &") "&RESULT,1)
K = 100000
ELSE
IF K = 99999
MESSAGE ("Транзакция №"& TRID &" хер знает где зависла",2)
END IF
END IF
END FOR
Статистика показала, что заявка становится видимой после 5-20 тыс итераций на 3,3 GHz процессоре. Имхо так лучше, т.к. пауза по времени — это вопрос вероятности, а нужны гарантии, что заявка прошла.
Евгений Reply:
ноября 27, 2010 at 21:27
Интересный подход. Следующая публикация будет на эту тему, со ссылкой на Вас
Евгений, доброй ночи.
В Ваше коде надо кое-что чуть чуть подправить:
1) 039. TRID=TIME&DATE заменить на TRID=TIME, т.к. выдает ошибку: «неправильно указан идентификатор транзакции»
2) 026.IF LAST=0
027.MESSAGE («НЕВЕРНАЯ НАСТРОЙКА КОДА БУМАГИ ИЛИ ФИЛЬТРА!»,1)
028.RETURN
029.END IF
Вообще надо удалить, т.к. на клиринге каждую секунду выдает MESSAGE. Сегодня из-за этого не мог ничего сделать и как в компьютерных игрушках пытался на несколько миллисекунд опередить MESSAGE и ввести логин и пароль по одной букве в Quik ))).
Удалить, т.к. Контроль клирингов ничего не даст, т.к. на Фортсе он пор времени плавающий.
Евгений Reply:
июня 4, 2011 at 20:51
Привет.
1. TRID=TIME => да, привильно. В новых версиях квика разработчики изменили разрядность идентификатора транзакций: уменьшили.
2. Насчет клиринга: клиринги надо все таки фильтровать, я использую такую конструкцию:
'========= КОНТРОЛЬ КЛИРИНГОВIF TIME>=135959 AND TIME<140301RETURNEND IFIF TIME>=184459 AND TIME<190001RETURNEND IF3. На ФОРТС клиринги фиксированные.
bsk Reply:
июня 5, 2011 at 16:21
3. Вы правы, но иногда пишут такое сообщение: «Торги начнутся в 191000»
Евгений Reply:
июня 5, 2011 at 16:23
А, ну да