Главная > Торговый робот > Функция перестановки заявок в торговых роботах

Функция перестановки заявок в торговых роботах

1 мая 2009

moveordersВ QUIK есть функционал, позволяющий посредством программы на QPILE переставить заявку, или говоря проще одним разом сделать два действия: отменить активную заявку и выставить вместо нее новую с номым количеством и/или ценой. Родная функция называется MOVE_ORDERS, и работает (в текущей версии) только на площадке ФОРТС. Но неуниверсальность этой функции по наведению (только ФОРТС) а также некоторое неудобство ее работы, а именно то, что посредством этой функции нужно менять только сразу две заявки, подтолкнули меня на создание собственной функции, обладающей большей универсальностью. Алгоритм простой: с помощью пользовательской функции «KILL ALL ORDERS», и функции постановки новой заявки, уже рассмотренных на этом сайте, мы заменяем  MOVE_ORDERS:

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


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

Функцию можно скачать.

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

  1. Дмитрий
    1 Май 2009 в 22:52 | #1

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

    Единственный вопрос, не лучше ли передавать INSTRUMENT аргументом функции?

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

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

    INSTRUMENT можно передавать и как аргумент функции. Но если робот работает с одним и тем инструментом, то на мой взгляд удобнее так. Но тут дело хозяйское :)

  3. Pulsarr
    2 Май 2009 в 12:20 | #3

    А что делает стандартная квиковская команда ?

    Почему она переставляет сразу две заявки ? Хочу реализовать следящий стоп (trailing stop)...

    а если не давать значение SECOND_ORDER_NUMBER, SECOND_ORDER_NEW_PRICE ?

    С Уважением.

    Евгений Reply:

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

    SECOND_ORDER_NUMBER и SECOND_ORDER_NEW_PRICE — обязательные переменные, попробуйте поэкспериментировать с ними.

    П.С. случайно удалил оба ваших комментария с кодом — не могу найти, повторите, пожалуйста.

  4. Антон611
    2 Май 2009 в 16:07 | #4

    Здраствуйте, Евгений!

    У меня вопрос, идущий в разрез с данной темой.

    Возможно ли реализовать ниже приведенные индикаторы на qpile?

    Positive Directional Indicator (+DI)

    Negative Directional Indicator (-DI)

    Если да,то не могли бы вы привести пример програмного кода для данных индикаторов.

    Спасибо.

    Евгений Reply:

    «Индикатор ADX выведен из двух других, которые также разработаны Уайлдером. Один индикатор называется Positive Directional Indicator (в большинстве случаев иногда обозначается „+DI“), второй индикатор это- Negative Directional Indicator (обозначается как „-DI“). На выбранном временном промежутке +DI- показывает силу движений вверх, а -DI наоборот показывает силу движений вниз за определенный период. Индикатор ADX показывает силу тренда и соединяет в себе +DI и -DI сглаживая затем данные скользящей средней. Так как ADX использует данные +DI и -DI не указывает направление тренда.»

    Может проще использовать стандартный ADX который есть в QUIK? Если да, то почитайте статью www.hirobot.ru/2009/04/in...orgovyx-robotax/

    Если нет — пишите, будем разбираться.

    Антон611 Reply:

    Спасибо за ответ.

    Использование этих индикаторов совместно с ADX показало довольно неплохие результаты в MetaTrader 4.Решил попробовать их написать для Quik.Нашел формулы для расчетов:lenivets-trader.ru/adx.

    Но возникли трудности вот с этим:

    +DIi = EMAi (+SDI, N)

    -DIi = EMAi (-SDI, N)

    Не знаю как это реализовать в программном коде.

    Заранее спасибо.

    Евгений Reply:

    По данной Вами ссылке все написано, как получается SDI, EMA мы знаем как получить. Сопоставляйте данные из формулы и такие же данные из QUIK. Пишите формулу обычными слова, что откуда берем — потом напишем код.

  5. Pulsarr
    2 Май 2009 в 23:14 | #5

    Функция LowestLow за NUMBER свечек:

    FUNC LOWESTLOW (NUMBER) ' НАША ФУНКЦИЯ

    M=0 ' СЧЕТЧИК НАЙДЕННЫХ ЗНАЧЕНИЙ

    LOWEST=99999999999

    CURYEAR=GET_VALUE (GET_DATETIME (), «YEAR») ' ПОЛУЧАЕМ ЗНАЧЕНИЯ ГОДА, МЕСЯЦА, ДНЯ И Т.Д.

    CURMONTH=GET_VALUE (GET_DATETIME (), «MONTH»)

    CURDAY=GET_VALUE (GET_DATETIME (), «DAY»)

    CURHOUR = GET_VALUE (GET_DATETIME (), «HOUR»)

    CURMIN = GET_VALUE (GET_DATETIME (), «MIN»)

    CURMIN = INTERVAL*FLOOR (CURMIN/INTERVAL) ' ОКРУГЛЯЕМ МИНУТЫ ДО «ИНТЕРВАЛЬНЫХ»

    N=(DAYTOFIND*24)*(FLOOR (60/INTERVAL)) ' ЗНАЧЕНИЕ ОКОНЧАНИЯ ЦИКЛА

    FOR I FROM 1 TO N

    TEXTDATA=FTEXTDATA (CURYEAR,CURMONTH,CURDAY) &"" ' ВЫЗЫВАЕМ ФУНКЦИИ

    TEXTTIME=FTEXTTIME (CURHOUR,CURMIN) & ""

    CANDLE=GET_CANDLE (CLASSCODELIST,INSTRUMENT, "", INTERVAL & "", «PRICE», TEXTDATA, TEXTTIME)

    LOW=GET_VALUE (CANDLE, «LOW»)+0

    IF LOW>0 ' ЕСЛИ ЧТО-ТО НАШЛИ

    M=M+1 ' СЧИТАЕМ НАЙДЕННЫЕ ДАННЫЕ СЧЕТЧИКОМ

    IF M<=NUMBER

    DATE=TEXTDATA ' ПРИСВАИВАЕМ ПЕРЕМЕННЫМ НАЙДЕННЫЕ ДАННЫЕ

    TIME=TEXTTIME

    LOW=GET_VALUE (CANDLE, «LOW»)+0

    IF LOW<LOWEST

    LOWEST=LOW+0

    END IF

    END IF

    END IF

    ' ОТКАТ НА «ИНТЕРВАЛ» НАЗАД, ОБЯЗАТЕЛЬНО РАЗБЕРИТЕСЬ В ЭТОМ КОДЕ — ВАЖНО ДЛЯ ПОНИМАНИЯ РАБОТЫ ВСЕЙ ФУНКЦИИ!

    CURMIN=CURMIN-INTERVAL

    IF CURMIN<0

    CURMIN=60+CURMIN

    CURHOUR=CURHOUR-1

    IF CURHOUR<0

    CURHOUR=23

    CURDAY=CURDAY-1

    IF CURDAY<1

    CURDAY=31

    CURMONTH=CURMONTH-1

    IF CURMONTH<1

    CURMONTH=12

    CURYEAR=CURYEAR-1

    IF CURYEAR<0

    MESSAGE («НЕ НАЙДЕНЫ КОТИРОВКИ ДО РОЖДЕСТВА ХРИСТОВА! :-D »,1)

    END IF

    END IF

    END IF

    END IF

    END IF

    END FOR

    END FUNC

  6. Pulsarr
    2 Май 2009 в 23:15 | #6

    Функция HighestHigh за NUMBER свечек:

    FUNC HIGHESTHIGH (NUMBER) ' НАША ФУНКЦИЯ

    M=0 ' СЧЕТЧИК НАЙДЕННЫХ ЗНАЧЕНИЙ

    HIGHEST=0

    CURYEAR=GET_VALUE (GET_DATETIME (), «YEAR») ' ПОЛУЧАЕМ ЗНАЧЕНИЯ ГОДА, МЕСЯЦА, ДНЯ И Т.Д.

    CURMONTH=GET_VALUE (GET_DATETIME (), «MONTH»)

    CURDAY=GET_VALUE (GET_DATETIME (), «DAY»)

    CURHOUR = GET_VALUE (GET_DATETIME (), «HOUR»)

    CURMIN = GET_VALUE (GET_DATETIME (), «MIN»)

    CURMIN = INTERVAL*FLOOR (CURMIN/INTERVAL) ' ОКРУГЛЯЕМ МИНУТЫ ДО «ИНТЕРВАЛЬНЫХ»

    N=(DAYTOFIND*24)*(FLOOR (60/INTERVAL)) ' ЗНАЧЕНИЕ ОКОНЧАНИЯ ЦИКЛА

    FOR I FROM 1 TO N

    TEXTDATA=FTEXTDATA (CURYEAR,CURMONTH,CURDAY) &"" ' ВЫЗЫВАЕМ ФУНКЦИИ

    TEXTTIME=FTEXTTIME (CURHOUR,CURMIN) & ""

    CANDLE=GET_CANDLE (CLASSCODELIST,INSTRUMENT, "", INTERVAL & "", «PRICE», TEXTDATA, TEXTTIME)

    HIGH=GET_VALUE (CANDLE, «HIGH»)+0

    IF HIGH>0 ' ЕСЛИ ЧТО-ТО НАШЛИ

    M=M+1 ' СЧИТАЕМ НАЙДЕННЫЕ ДАННЫЕ СЧЕТЧИКОМ

    IF MHIGHEST

    HIGHEST=HIGH+0

    END IF

    END IF

    END IF

    ' ОТКАТ НА «ИНТЕРВАЛ» НАЗАД, ОБЯЗАТЕЛЬНО РАЗБЕРИТЕСЬ В ЭТОМ КОДЕ — ВАЖНО ДЛЯ ПОНИМАНИЯ РАБОТЫ ВСЕЙ ФУНКЦИИ!

    CURMIN=CURMIN-INTERVAL

    IF CURMIN<0

    CURMIN=60+CURMIN

    CURHOUR=CURHOUR-1

    IF CURHOUR<0

    CURHOUR=23

    CURDAY=CURDAY-1

    IF CURDAY<1

    CURDAY=31

    CURMONTH=CURMONTH-1

    IF CURMONTH<1

    CURMONTH=12

    CURYEAR=CURYEAR-1

    IF CURYEAR<0

    MESSAGE («НЕ НАЙДЕНЫ КОТИРОВКИ ДО РОЖДЕСТВА ХРИСТОВА! :-D »,1)

    END IF

    END IF

    END IF

    END IF

    END IF

    END FOR

    END FUNC

    Евгений Reply:

    Отличные функции! Включаем в библиотеку! www.hirobot.ru/skachat/

    Евгений Reply:

    Только в функции HIGHEST не правилен момент:

    IF HIGH>0 ' ЕСЛИ ЧТО-ТО НАШЛИ

    M=M+1 ' СЧИТАЕМ НАЙДЕННЫЕ ДАННЫЕ СЧЕТЧИКОМ

    IF MHIGHEST

    HIGHEST=HIGH+0

    END IF

    END IF

    END IF

  7. Pulsarr
    4 Май 2009 в 02:46 | #7

    Да, действительно... Исходный код взял с этого сайта, отредактировал, но на комментарии не обращал внимания... Не отредактировал, а надо было...

    Евгений Reply:

    Ждем исправленную версию!

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