Главная > Торговый робот > Торговый робот для QUIK «Пробойный». Часть четвертая

Торговый робот для QUIK «Пробойный». Часть четвертая

19 апреля 2009

Функции QPILE

Функции нужны для того, чтоб исполнять определенные задачи, которые часто встречаются в алгоритме, либо просто чтобы вынести определенный код отдельно от основного алгортима. Вызываются функции по своему имени, при необходимости при их вызове мы может передавать какие-либо параметры в функцию. Для начала, немного теории о функциях (подпрограммах) в QPILE. Конструктивно как они выглядят мы уже знаем:

FUNC название(параметр1,параметр2,...,параметрN)
код подпрограммы
END FUNC

ORDER(0,LOTS,OP,"LIMIT",TRID)

Это функция из третьей части нашего робота. ORDER — имя, и в скобках мы передаем параметры, обозначенные в описании самой функции:

FUNC ORDER(FPRICE,FLOTS,FDIRECTION,FTYPE,FTRID)

Мы передаем цену, количество лотов, направление, тип заявки, и идентификационный номер транзакции.

Правильное использование функций значительно упрощает программирование, а также визуальное восприятие кода. Я всегда стараюсь правильно организовать код, чтоб если понадобится через год опять его поднять и разобраться — можно было сразу понять что куда.

Итак, вернемся к четвертой части нашего робота для QUIK «Пробойный». Код:

Код на QPILE доступен только зарегистрированным пользователям.

Постарайтесь разобраться в каждой строчке кода. Тут есть уже знакомые нам функции получения котировок из графика QUIK, функции перевода даты и времени в текстовый формат и пр. Если Вы разберетесь с данным кодом, потом сможете менять условия и построить своего собственного робота.

В следующий раз мы обсудим как открывать учебный счет и приступим к тестированию!

Евгений Торговый робот , , , ,

  1. Dr. Livsey
    3 Май 2009 в 01:41 | #1

    Добрый день. А можно более подробно прокомментировать строчки 8-9. А то никак не могу врубиться. что мы тут делаем.

  2. Евгений
    3 Май 2009 в 10:14 | #2

    Это функция получения котировок по номеру бара.

    в 7 строке мы получаем текущей значение «минут», например 49;

    в 8 строке мы округляем значение минут до нашего интервала(например 5-ти минутки): 5*округлениевниз(49/5)=45:

    в 9 строке мы получаем целочисленное значение окончания цикла, которое зависит от установок DAYTOFIND (сколько дней назад ищем котировки)

    подробнее об этом процессе читайте в статье: www.hirobot.ru/2009/03/ka...iz-grafika-quik/

  3. User
    25 Май 2009 в 15:18 | #3

    Скажите, пожалуйста, а что такое (' ДЕЛАЕМ ПСЕВДОМАРКЕТ)?

    Евгений Reply:

    На рынке ФОРТС нет понятия маркетной, или рыночной заявки, но ее можно имитировать путем завышения, или занижения цены, в зависимости от того, какую операцию нам нужно сделать. Таким образом торговая система, при исполнении таких заявок, собирает нужное нам кол-во лотов по стакану. Обычно я к цене LAST добавляю или отнимаю определенное кол-во пунктов.

  4. User
    25 Май 2009 в 15:50 | #4

    При загрузке портфеля выдает ошибку при расчете:

    Unknown identifier CLASSCODELIST [CANDLE=GET_CANDLE(CLASSCODELIST,INSTRUMENT, "", INTERVAL & "", "PRICE", TEXTDATA, TEXTTIME)]

    там не может быть ошибки в функции OHLC, в самом цикле?

    Евгений Reply:

    CLASSCODELIST="SPBFUT" вставьте эту строку в начало программы, где определяется инструмент. Забыл...

  5. User
    25 Май 2009 в 17:04 | #5

    Спасибо, вроде все по

    TRANS_PARAMS = SET_VALUE (TRANS_PARAMS, «PRICE», (FPRICE+(1000*SIGN))&"")

    а 1000 — это не круто для маркетного отступа?

    или он не здесь задается?

    Кстати, с High, Low тоже самое:

    Unknown identifier HIGH [CURRENTHIGH=HIGH]"

    Может в другом месте их задать надо?

    Евгений Reply:

    1000, или иное значение зависит от лимитов дневной цены.

  6. User
    25 Май 2009 в 18:58 | #6

    Что то я действительно не понял, а как правильно задать переменные —

    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:

    OHLC (CANDLETOFIND) — это убираем;

    в начале программы, где определяются переменные, укажите:

    HIGH=0

    LOW=0

    п.с. эти коды — вырезки из более мощной системы, может чего «недорезал» :)

  7. АндрейН
    7 Июнь 2009 в 11:19 | #7

    Евгений, добрый день.

    Скачал в апреле робота «пробойный», стал его изменять, а вот сейчас понадобилось сравнить с оригиналом твоим и не вижу, где он выложен.

    Еще вопрос: если впоследствии обнаруживаются ошибки в кодах роботов, ты их правишь? или они выложены по состоянию на момент выхода статьи?

    Евгений Reply:

    Привет. Ошибки правлю, пишите где. С сайта ничего не удалял, просто «пробойный» в объединенном виде не выкладывал, его надо собирать по частям в публикациях. Вообще я преследую цель научить, а не дать «халяву», прошу прощения за выражение, поэтому выкладываю коды от 99% до 100% готовности, каждый дорабатывает под себя. Я уверен что даю 100% нужной для этого информации.

  8. АндрейН
    9 Июнь 2009 в 01:27 | #8

    А, точно. Я его и собрал из кусочков.

    У меня при копировании со странички вылезли & в тексте робота, убирал руками.

  9. qsn
    8 Октябрь 2009 в 17:54 | #9

    Добрый день Евгений.

    FUNC ORDER (FPRICE,FLOTS,FDIRECTION,FTYPE,FTRID) ' ФУНКЦИЯ ОТПРАВКИ ТРАНЗАКЦИЙ В ТОРГОВУЮ СИСТЕМУ 198.

    199.IF FTYPE="LIMIT" 200.

    201.FPRICE=PRICE

    203.END IF

    Для чего введен префикс F в формальных параметрах и откуда взялся PRICE в строке 201

    И еще. Почему не используете регистр для имен переменных?

    QPILE это позволяет.

    Евгений Reply:

    Привет.

    Префикс F введен чтоб не путаться в переменных, можно не использовать но мне так удобнее, и я знаю что с этим префиксом переменные я использую внутри функции отправки транзакций.

    FPRICE=PRICE — это атавизм от более навороченной функции. Насколько я помню при вызове этой функции мы вместо цены передаем ноль, а внутри функции уже присваиваем FPRICE значение цены последней сделки. Я уже не помню для чего я делал таким образом... В этом случае можно вообще ничего не передавать, а внутри функции вместо FPRICE использовать сразу переменную PRICE. Если PRICE — это цена последней сделки нашего инструмента.

    Насчет регистра не понял... Наверное имеете в виду почему все прописными буквами пишу? Мне так удобнее код читать. :)

  10. qsn
    9 Октябрь 2009 в 10:56 | #10

    Добрый день Евгений.

    Я так и не понял. Price это какая-то глобальная переменная?

    201.FPRICE=PRICE

    Сохранит ли FPRICE присвоенное значение после выхода из функции?

    Про регистр Вы все правильно поняли. Не используете — жаль. Это существенно избавляет от ошибок в листинге еще до отладки. Для QPILE с его отладчиком и редактором крайне важно!

    Евгений Reply:

    PRICE — в самом начале робота этой переменной должна присваиваться цена последней сделки из табл текпарам для нашего инструмента. FPRICE будет сохранять присвоенное значени пока мы его сами не поменяем.

  11. qsn
    9 Октябрь 2009 в 20:08 | #11

    Спасибо, понял — попробую.

  12. pocemon
    22 Ноябрь 2009 в 17:08 | #12

    Евгений, объясните, пожалуйста, функцию FUNC KILLALLSTOP.

    Не очень поимаю зачем там ключ с цифрой 3

    N3=GET_NUMBER_OF («STOP_ORDERS»)

    и в номере транзакции что означает amp

    TRANS_PARAMS = SET_VALUE (TRANS_PARAMS, «TRANS_ID», «0»&TIME)

    Евгений Reply:

    amp — это дурацкий движок блога вписывает вместо «&»

    N3 — ничего не значит, это переменная.

    pocemon Reply:

    Спасибо.

  13. chelny07
    18 Декабрь 2009 в 17:51 | #13

    Евгений я собрал все разделы робота в одно целое и у меня вылетает ошибка, я напишу полностью что вылетает:

    "Произошла ошибка при загрузке формулы расчета портфеля «PROBOY», идентификатор организации «ALL_FIRMS» сообщение об ошибке "File: (null), line: 513. END iif missing "

    уже час ковыряюсь и не могу разобраться в чем дело. Помогите пожалуйста)

    Евгений Reply:

    Где то пропустили оператор END IF. Посчитайте количество «начал» операторов условия IF и их окончаний.

    Евгений Reply:

    В догонку: час — это ничто... Я годы потратил чтоб разбираться в этом языке. Не сдавайтесь и не паникуйте раньше времени :)

    chelny07 Reply:

    спасибо сейчас буду смотреть)

    chelny07 Reply:

    Евгений еще вопросик? теперь ошибка: Unknown identifier DATE [ TRID=DATE&TIME] С этим что делать? Я так понимаю не хватает переменной чтоли?

    Евгений Reply:

    Да.

  14. KentAVP
    24 Декабрь 2009 в 11:09 | #14

    Объясните значение

    OUTPUT=SET_VALUE (OUTPUT,"GO",GO)

    PARAMETER GO;

    PARAMETER_TITLE GO;

    PARAMETER_DESCRIPTION GO;

    PARAMETER_TYPE NUMERIC (10,0);

    END

    программа выдавала ошибку, убрав эти параметры, она заработала

    Евгений Reply:

    GO — гарантийное обеспечение. В первоначальной версии был модуль расчета позиции в % от доступного капитала. Скоро выложу функцию.

    KentAVP Reply:

    С остальными ошибками разобрался. Quik теперь выдает мне сообщение «MUST BUY FIRST» или «MUST SELL FIRST».

    Уже который час мучаюсь, объясните как решить эту проблему?

    Евгений Reply:

    Эти сообщения робот выдает при отправке транзакции, если сделка не проходит то:

    1. неверный код инструмента

    2. нулевое либо не положительное кол-во лотов

    3. неверная цена

    Расширенная диагностика MESSAGE (RESULT,1) должна написать в чем конкретно причина.

    KentAVP Reply:

    у меня пожалуй еще вопрос.

    есть строки

    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:

    Нет, в первоначальном блоке все верно. Просто это элегантное решение, подсказанное мне моим другом.

    Изначально переменная SIGN=-1 и лишь в том случае если у нас покупка переменная меняет знак, а если продажа то условие не срабатывает и переменная остается отрицательной! Ускорение работы программы, пусть небольшое но все же.

    :)

    KentAVP Reply:

    Я сделал, как Вы сказали. За сообщением «MUST SELL FIRST» шло следющее «110000». Это очень походит на значение TIME, в тот момент времени, когда я работал.

    Как исправить эту ошибку

    Евгений Reply:

    Отследите по коду, какой оператор посылает это сообщение. Расширенная диагностика что пишет? Полистайте окно сообщений. Проследите отладчиком значения переменных.

    KentAVP Reply:

    не могли бы вы помочь пожалуйста? у меня счетчик TP постоянно на нуле, даже при открытой позиции. с чем это может быть связано?

    Евгений Reply:

    1. Неверный код инструмента (если рынок ФОРТС, то у разных брокеров инструменты либо короткие коды либо длинные: RIH0 или RTS-3.10, попробуйте оба кода)

    2. Если площадка ФОРТС — неверная строка в таблице Позиции клиента

    3. Если ММВБ — неверная строка в таблице лимитов по бумагам.

    ...

    Напишите код получения ТП с указанием инструмента и площадки.

    KentAVP Reply:

    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:

    Попробуйте поменять «SEC_SHORT_NAME» на «SECCODE»

    KentAVP Reply:

    спасибо,проблема решена!

  15. KentAVP
    14 Январь 2010 в 15:22 | #15

    я наверное надоел вам со своими сообщениями :) ) но вот у меня вопрос. я первоначально поставил настройки для SRH0, и потом захотел поменять на SiH0. из квика удалил портфель и заново его загрузил, то есть обновленный.

    так вот для SiH0 пишет что неизвестный параметр HIGH в строке CURRENTHIGH=HIGH. очень странно вернув настройки для SRH0 все работает снова.

    с чем может быть это связано?

    Евгений Reply:

    Попробуйте SIH0 т.е. написать код инструмента ПРОПИСНЫМИ буквами.

    KentAVP Reply:

    пробовал, не помогает. самое интересное, другие контракты работают, например, GZH0, RIH0, а доллар не работет... странно...

    Евгений Reply:

    Может попробовать длинный код?

    KentAVP Reply:

    проблема решена.

    надо между заголовком и телом программы добавить:

    USE_CASE_SENSITIVE_CONSTANTS

Необходимо войти на сайт, чтобы написать комментарий.