Торговый робот для QUIK «Пробойный». Часть четвертая
Функции нужны для того, чтоб исполнять определенные задачи, которые часто встречаются в алгоритме, либо просто чтобы вынести определенный код отдельно от основного алгортима. Вызываются функции по своему имени, при необходимости при их вызове мы может передавать какие-либо параметры в функцию. Для начала, немного теории о функциях (подпрограммах) в QPILE. Конструктивно как они выглядят мы уже знаем:
FUNC название(параметр1,параметр2,...,параметрN) код подпрограммы END FUNC
ORDER(0,LOTS,OP,"LIMIT",TRID)
Это функция из третьей части нашего робота. ORDER — имя, и в скобках мы передаем параметры, обозначенные в описании самой функции:
FUNC ORDER(FPRICE,FLOTS,FDIRECTION,FTYPE,FTRID)
Мы передаем цену, количество лотов, направление, тип заявки, и идентификационный номер транзакции.
Правильное использование функций значительно упрощает программирование, а также визуальное восприятие кода. Я всегда стараюсь правильно организовать код, чтоб если понадобится через год опять его поднять и разобраться — можно было сразу понять что куда.
Итак, вернемся к четвертой части нашего робота для QUIK «Пробойный». Код:
Код на QPILE доступен только зарегистрированным пользователям.
Постарайтесь разобраться в каждой строчке кода. Тут есть уже знакомые нам функции получения котировок из графика QUIK, функции перевода даты и времени в текстовый формат и пр. Если Вы разберетесь с данным кодом, потом сможете менять условия и построить своего собственного робота.
В следующий раз мы обсудим как открывать учебный счет и приступим к тестированию!

Добрый день. А можно более подробно прокомментировать строчки 8-9. А то никак не могу врубиться. что мы тут делаем.
Это функция получения котировок по номеру бара.
в 7 строке мы получаем текущей значение «минут», например 49;
в 8 строке мы округляем значение минут до нашего интервала(например 5-ти минутки): 5*округлениевниз(49/5)=45:
в 9 строке мы получаем целочисленное значение окончания цикла, которое зависит от установок DAYTOFIND (сколько дней назад ищем котировки)
подробнее об этом процессе читайте в статье: www.hirobot.ru/2009/03/ka...iz-grafika-quik/
Скажите, пожалуйста, а что такое (' ДЕЛАЕМ ПСЕВДОМАРКЕТ)?
Евгений Reply:
мая 25, 2009 at 15:59
На рынке ФОРТС нет понятия маркетной, или рыночной заявки, но ее можно имитировать путем завышения, или занижения цены, в зависимости от того, какую операцию нам нужно сделать. Таким образом торговая система, при исполнении таких заявок, собирает нужное нам кол-во лотов по стакану. Обычно я к цене LAST добавляю или отнимаю определенное кол-во пунктов.
При загрузке портфеля выдает ошибку при расчете:
Unknown identifier CLASSCODELIST [CANDLE=GET_CANDLE(CLASSCODELIST,INSTRUMENT, "", INTERVAL & "", "PRICE", TEXTDATA, TEXTTIME)]
там не может быть ошибки в функции OHLC, в самом цикле?
Евгений Reply:
мая 25, 2009 at 16:01
CLASSCODELIST="SPBFUT" вставьте эту строку в начало программы, где определяется инструмент. Забыл...
Спасибо, вроде все по
TRANS_PARAMS = SET_VALUE (TRANS_PARAMS, «PRICE», (FPRICE+(1000*SIGN))&"")
а 1000 — это не круто для маркетного отступа?
или он не здесь задается?
Кстати, с High, Low тоже самое:
Unknown identifier HIGH [CURRENTHIGH=HIGH]"
Может в другом месте их задать надо?
Евгений Reply:
мая 25, 2009 at 19:18
1000, или иное значение зависит от лимитов дневной цены.
Что то я действительно не понял, а как правильно задать переменные —
HIGH и LOW?
Снова при расчете портфеля выдает ошибку:
Unknown identifier
HIGH [CURRENTHIGH=HIGH]
кусок из кода:
OHLC (1) '...ДЛЯ ОПРЕДЕЛЕНИЯ ТЕКУЩЕГО ЗНАЧЕНИЯ HIGH И LOW
CURRENTHIGH=HIGH ' ПРИСВАИВАЕМ ПЕРЕМЕННЫМ ЗНАЧЕНИЯ ТЕКУЩИХ HIGH И LOW
CURRENTLOW=LOW
OHLC (CANDLETOFIND) ' ЗАПРАШИВАЕМ КОТИРОВКИ БАРА ПО УСЛОВИЮ
IF CURRENTHIGH>HIGH
HIGH=CURRENTHIGH
END IF
IF (CURRENTLOW0)
LOW=CURRENTLOW
Евгений Reply:
мая 25, 2009 at 19:22
OHLC (CANDLETOFIND) — это убираем;
в начале программы, где определяются переменные, укажите:
HIGH=0
LOW=0
п.с. эти коды — вырезки из более мощной системы, может чего «недорезал»
Евгений, добрый день.
Скачал в апреле робота «пробойный», стал его изменять, а вот сейчас понадобилось сравнить с оригиналом твоим и не вижу, где он выложен.
Еще вопрос: если впоследствии обнаруживаются ошибки в кодах роботов, ты их правишь? или они выложены по состоянию на момент выхода статьи?
Евгений Reply:
июня 7, 2009 at 15:54
Привет. Ошибки правлю, пишите где. С сайта ничего не удалял, просто «пробойный» в объединенном виде не выкладывал, его надо собирать по частям в публикациях. Вообще я преследую цель научить, а не дать «халяву», прошу прощения за выражение, поэтому выкладываю коды от 99% до 100% готовности, каждый дорабатывает под себя. Я уверен что даю 100% нужной для этого информации.
А, точно. Я его и собрал из кусочков.
У меня при копировании со странички вылезли & в тексте робота, убирал руками.
Добрый день Евгений.
FUNC ORDER (FPRICE,FLOTS,FDIRECTION,FTYPE,FTRID) ' ФУНКЦИЯ ОТПРАВКИ ТРАНЗАКЦИЙ В ТОРГОВУЮ СИСТЕМУ 198.
199.IF FTYPE="LIMIT" 200.
201.FPRICE=PRICE
203.END IF
Для чего введен префикс F в формальных параметрах и откуда взялся PRICE в строке 201
И еще. Почему не используете регистр для имен переменных?
QPILE это позволяет.
Евгений Reply:
октября 8, 2009 at 21:49
Привет.
Префикс F введен чтоб не путаться в переменных, можно не использовать но мне так удобнее, и я знаю что с этим префиксом переменные я использую внутри функции отправки транзакций.
FPRICE=PRICE — это атавизм от более навороченной функции. Насколько я помню при вызове этой функции мы вместо цены передаем ноль, а внутри функции уже присваиваем FPRICE значение цены последней сделки. Я уже не помню для чего я делал таким образом... В этом случае можно вообще ничего не передавать, а внутри функции вместо FPRICE использовать сразу переменную PRICE. Если PRICE — это цена последней сделки нашего инструмента.
Насчет регистра не понял... Наверное имеете в виду почему все прописными буквами пишу? Мне так удобнее код читать.
Добрый день Евгений.
Я так и не понял. Price это какая-то глобальная переменная?
201.FPRICE=PRICE
Сохранит ли FPRICE присвоенное значение после выхода из функции?
Про регистр Вы все правильно поняли. Не используете — жаль. Это существенно избавляет от ошибок в листинге еще до отладки. Для QPILE с его отладчиком и редактором крайне важно!
Евгений Reply:
октября 9, 2009 at 19:38
PRICE — в самом начале робота этой переменной должна присваиваться цена последней сделки из табл текпарам для нашего инструмента. FPRICE будет сохранять присвоенное значени пока мы его сами не поменяем.
Спасибо, понял — попробую.
Евгений, объясните, пожалуйста, функцию FUNC KILLALLSTOP.
Не очень поимаю зачем там ключ с цифрой 3
N3=GET_NUMBER_OF («STOP_ORDERS»)
и в номере транзакции что означает amp
TRANS_PARAMS = SET_VALUE (TRANS_PARAMS, «TRANS_ID», «0»&TIME)
Евгений Reply:
ноября 22, 2009 at 18:46
amp — это дурацкий движок блога вписывает вместо «&»
N3 — ничего не значит, это переменная.
pocemon Reply:
ноября 22, 2009 at 20:18
Спасибо.
Евгений я собрал все разделы робота в одно целое и у меня вылетает ошибка, я напишу полностью что вылетает:
"Произошла ошибка при загрузке формулы расчета портфеля «PROBOY», идентификатор организации «ALL_FIRMS» сообщение об ошибке "File: (null), line: 513. END iif missing "
уже час ковыряюсь и не могу разобраться в чем дело. Помогите пожалуйста)
Евгений Reply:
декабря 18, 2009 at 17:56
Где то пропустили оператор END IF. Посчитайте количество «начал» операторов условия IF и их окончаний.
Евгений Reply:
декабря 18, 2009 at 17:57
В догонку: час — это ничто... Я годы потратил чтоб разбираться в этом языке. Не сдавайтесь и не паникуйте раньше времени
chelny07 Reply:
декабря 18, 2009 at 18:00
спасибо сейчас буду смотреть)
chelny07 Reply:
декабря 18, 2009 at 18:35
Евгений еще вопросик? теперь ошибка: Unknown identifier DATE [ TRID=DATE&TIME] С этим что делать? Я так понимаю не хватает переменной чтоли?
Евгений Reply:
декабря 18, 2009 at 18:45
Да.
Объясните значение
OUTPUT=SET_VALUE (OUTPUT,"GO",GO)
PARAMETER GO;
PARAMETER_TITLE GO;
PARAMETER_DESCRIPTION GO;
PARAMETER_TYPE NUMERIC (10,0);
END
программа выдавала ошибку, убрав эти параметры, она заработала
Евгений Reply:
декабря 24, 2009 at 18:19
GO — гарантийное обеспечение. В первоначальной версии был модуль расчета позиции в % от доступного капитала. Скоро выложу функцию.
KentAVP Reply:
декабря 25, 2009 at 14:31
С остальными ошибками разобрался. Quik теперь выдает мне сообщение «MUST BUY FIRST» или «MUST SELL FIRST».
Уже который час мучаюсь, объясните как решить эту проблему?
Евгений Reply:
декабря 25, 2009 at 23:12
Эти сообщения робот выдает при отправке транзакции, если сделка не проходит то:
1. неверный код инструмента
2. нулевое либо не положительное кол-во лотов
3. неверная цена
Расширенная диагностика MESSAGE (RESULT,1) должна написать в чем конкретно причина.
KentAVP Reply:
декабря 26, 2009 at 10:58
у меня пожалуй еще вопрос.
есть строки
SIGN=-1
IF FDIRECTION="B"
SIGN=1
END IF
Получается для OPERATION будет определен только параметр B, а где параметр S?
может для SIGN=-1 сделать также, т.е.
FDIRECTION="S"
SIGN=-1
END IF
FDIRECTION="B"
SIGN=1
END IF
Евгений Reply:
декабря 26, 2009 at 20:58
Нет, в первоначальном блоке все верно. Просто это элегантное решение, подсказанное мне моим другом.
Изначально переменная SIGN=-1 и лишь в том случае если у нас покупка переменная меняет знак, а если продажа то условие не срабатывает и переменная остается отрицательной! Ускорение работы программы, пусть небольшое но все же.
KentAVP Reply:
декабря 28, 2009 at 12:18
Я сделал, как Вы сказали. За сообщением «MUST SELL FIRST» шло следющее «110000». Это очень походит на значение TIME, в тот момент времени, когда я работал.
Как исправить эту ошибку
Евгений Reply:
декабря 28, 2009 at 19:18
Отследите по коду, какой оператор посылает это сообщение. Расширенная диагностика что пишет? Полистайте окно сообщений. Проследите отладчиком значения переменных.
KentAVP Reply:
января 13, 2010 at 12:45
не могли бы вы помочь пожалуйста? у меня счетчик TP постоянно на нуле, даже при открытой позиции. с чем это может быть связано?
Евгений Reply:
января 13, 2010 at 19:30
1. Неверный код инструмента (если рынок ФОРТС, то у разных брокеров инструменты либо короткие коды либо длинные: RIH0 или RTS-3.10, попробуйте оба кода)
2. Если площадка ФОРТС — неверная строка в таблице Позиции клиента
3. Если ММВБ — неверная строка в таблице лимитов по бумагам.
...
Напишите код получения ТП с указанием инструмента и площадки.
KentAVP Reply:
января 13, 2010 at 19:35
INSTRUMENT="SRH0"
LOTS=2
CLASSCODELIST="SPBFUT"
STOPLOSS=10
INTERVAL=10
DAYTOFIND=30
CANDLETOFIND=2
NEW_GLOBAL («FIRSTRUN»,1)
NEW_GLOBAL («FLAGSTOP»,1)
NEW_GLOBAL («FLAGSELL»,1)
NEW_GLOBAL («FLAGBUY»,1)
TP=0
N=GET_NUMBER_OF («FUTURES_CLIENT_HOLDINGS»)+0
IF N>0
FOR I FROM 0 TO N
IF GET_VALUE (GET_ITEM («FUTURES_CLIENT_HOLDINGS», I), «SEC_SHORT_NAME»)=INSTRUMENT
TP=GET_VALUE (GET_ITEM («FUTURES_CLIENT_HOLDINGS»,I), «TOTAL_NET»)+0
END IF
END FOR
END IF
насчет кода. но ведь портфель определяет SRH0. и цены, и данные котировок. сделка совершается по алгоритму, но TP остается на нуле, из-за этого программа посылает снова и снова заявки по условию, хотя не должны
Евгений Reply:
января 13, 2010 at 20:11
Попробуйте поменять «SEC_SHORT_NAME» на «SECCODE»
KentAVP Reply:
января 13, 2010 at 20:30
спасибо,проблема решена!
я наверное надоел вам со своими сообщениями
) но вот у меня вопрос. я первоначально поставил настройки для SRH0, и потом захотел поменять на SiH0. из квика удалил портфель и заново его загрузил, то есть обновленный.
так вот для SiH0 пишет что неизвестный параметр HIGH в строке CURRENTHIGH=HIGH. очень странно вернув настройки для SRH0 все работает снова.
с чем может быть это связано?
Евгений Reply:
января 14, 2010 at 17:20
Попробуйте SIH0 т.е. написать код инструмента ПРОПИСНЫМИ буквами.
KentAVP Reply:
января 14, 2010 at 17:33
пробовал, не помогает. самое интересное, другие контракты работают, например, GZH0, RIH0, а доллар не работет... странно...
Евгений Reply:
января 14, 2010 at 22:07
Может попробовать длинный код?
KentAVP Reply:
января 23, 2010 at 7:46
проблема решена.
надо между заголовком и телом программы добавить:
USE_CASE_SENSITIVE_CONSTANTS