![Ордерные стратегии. Универсальный автомат](https://c.mql5.com/i/articles/overlay.png)
Ордерные стратегии. Универсальный автомат
Введение
Основным и начальным элементом торговой стратегии является анализ цены и технических индикаторов, на основе чего выполняется открытие позиции. Назовем такой анализ анализом рыночной ситуации, т.е. того, что происходит на рынке и не зависит от нас.
Кроме этого, стратегии могут требовать и другого типа анализа. Назовем его анализом текущей торговой ситуации. Он включает в себя анализ состояния торговой позиции и анализ наличия/отсутствия отложенных ордеров (если они используются в стратегии). В результате этого анализа принимается решение о необходимости выполнения каких-либо действий с позицией или ордерами, например, закрытие, перенос Стоп Лосса, установка отложенных ордеров или их удаление и т.п. Другими словами, в этот анализ входит изучение того, что мы выполняем на рынке, и действия в соответствии с созданной нами (или экспертом) ситуацией и правилами применяемой стратегии.
Известный всем трейлинг стоп в какой-то мере можно отнести ко второму типу элементов торговой стратегии. Выполняется анализ: если есть открытая позиция, ее прибыль выше установленной в настройках, а Стоп Лосс отсутствует или дальше указанной в настройках дистанции от текущей цены, то выполняется перенос Стоп Лосса.
Трейлинг стоп является довольно простой функцией, чтобы представлять особый интерес. Кроме того, его можно отнести к совсем другой категории элементов, составляющих торговую стратегию, - к функциям сопровождения позиции. Таким образом, торговая стратегия может включать в себя три категории элементов:
-
Анализ рыночной ситуации и выполнение действий на его основе.
-
Анализ торговой ситуации и выполнение действий на его основе.
-
Сопровождение позиции.
Целью данной статьи является рассмотрение стратегий, активно использующих отложенные ордера (кратко назовем их ордерными стратегиями), и создание метаязыка для их описания, а также создание универсального инструмента (эксперта) для работы по этим описаниям.
Примеры ордерных стратегий
Исходным действием любой торговой работы является открытие начальной позиции. Возможно несколько вариантов ее открытия:
-
Открытие рыночной позиции:
-
По направлению, указываемому индикаторами.
-
По направлению, выбираемому пользователем в окне свойств эксперта.
-
На основе результатов закрытия последней позиции. Такая позиция может являться не начальной позицией, а промежуточной фазой работы.
-
Два противоположных стоп ордера. При срабатывании одного из ордеров, второй ордер удаляется.
-
Два противоположных лимитных ордера. При срабатывании одного из ордеров, второй ордер удаляется.
-
Лимитный и стоп ордер одного направления. В этом случае необходимо определиться с направлением ордеров так же, как в п.1.
После открытия начальной позиции возможно применение различных ордерных стратегий.
Доливка лимитами (Рис. 1.)
Открывается начальная позиция, устанавливается один или несколько лимитных ордеров того же направления с увеличивающимся лотом. По мере срабатывания лимитных ордеров выставляются новые лимитные ордера до тех пор, пока позиция не будет закрыта по Тейк Профиту. При закрытии позиции по Тейк Профиту выполняется удаление оставшихся отложенных ордеров.
Рис. 1. Доливка лимитами
Стоп-переворот (Рис. 2.)
Открывается начальная позиция, на уровне ее Стоп Лосса устанавливается противоположный стоп ордер с увеличенным лотом. При закрытии позиции по Стоп Лосс срабатывает отложенный ордер, а на его Стоп Лосс также устанавливается противоположный стоп ордер - и так до тех пор, пока позиция не закроется по Тейк Профиту. При закрытии позиции по Тейк Профиту выполняется удаление оставшегося отложенного ордера.
Рис. 2. Стоп-перворот
Пирамидинг (Рис. 3.)
Открывается начальная позиция, если она уходит в прибыль, выполняется увеличение ее объема (доливка) и переносится Стоп Лосс на уровень безубытка. Если позиция закроется по Тейк Профиту, у нее к этому моменту будет довольно крупный объем и, соответственно, прибыль, если же на промежуточном этапе сработает Стоп Лосс, то просто не будет прибыли.
Рис. 3. Пирамидинг
Переоткрытие (Рис. 4.)
Открывается рыночная позиция. При ее закрытии по Стоп Лосс выполняется новое открытие с увеличенным лотом. Выполняется до тех пор, пока не произойдет закрытие по Тейк Профиту. Эта стратегия подобна доливке лимитами.
Рис. 4. Переоткрытие
Вполне возможно сочетание всех вышеперечисленных стратегий. Если позиция идет в прибыль, в работу вступает пирамидинг, если же сразу в убыток - доливка лимитами. Доливка лимитами может выполняться не постоянно, а например, три раза, затем несколько раз стоп-переворот, снова доливка лимитами и т.д.
Практически, программирование ордерных стратегий является довольно трудоемким занятием не только из-за объема самого кодинга, но и из-за необходимости своего творческого подхода в каждом конкретном случае. Попробуем облегчить задачу программирования таких стратегий путем создания универсального эксперта, позволяющего реализовать работу по любой ордерной стратегии.
Основной принцип
Основным принципом при программировании ордерных стратегий является идентификация текущей фазы работы по стратегии и выполнение каких-либо действий, соответствующих этой фазе.
Рассмотрим пример: требуется открыть рыночную позицию, пусть будет покупка. После открытия позиции требуется установить два отложенных ордера: сверху - стоп ордер, снизу - лимит ордер. В начале работы на рынке нет ни позиции, ни ордеров - идентифицируется начальная фаза работы, на которой необходимо открыть позицию. Наличие рыночной позиции означает следующую фазу работы. Всего получаются такие фазы:
-
Нет позиции и нет ордеров. Надо открыть позицию.
-
Есть позиция, нет ни одного ордера. Надо установить стоп-ордер.
-
Есть позиция, есть стоп-ордер. Надо установить лимит-ордер.
Работа по таким правилам будет гарантированно выполнена, однако, для ее завершения потребуется три тика: на одном тике выявлено отсутствие позиции и открыта позиция, на следующем выявлена позиция и отсутствие ордеров, на третьем выявлена позиция и один ордер. В соответствии с требованиями стратегии все три действия должны выполняться за один раз.
Поэтому следует попытаться выполнить все действия сразу: если нет позиции и нет ордеров, необходимо открыть позицию, если позицию удалось открыть, то отправить запрос на установку стоп-ордера и отправить запрос на установку лимит-ордера. Вполне возможно, что ни одна заявка на отложенный ордер не будет принята (может быть обрыв связи, отсутствие цен и т.п.), но торговая ситуация перешла в другую фазу - имеется открытая позиция. Значит, необходимо предусмотреть все возможные промежуточные фазы работы:
-
Нет позиции. Необходимо открыть позицию. Если позицию удалось открыть, необходимо отправить запросы на установку стоп-ордера и лимит-ордера.
-
Есть позиция, но нет ни одного отложенного ордера. Необходимо отправить запросы на установку стоп-ордера и лимит-ордера.
-
Есть позиция и стоп-ордер, но нет лимит-ордера. Необходимо отправить запрос на установку лимит-ордера.
-
Есть позиция и лимит-ордер, но нет стоп-ордера. Необходимо отправить запрос на установку стоп-ордера.
Обратите внимание, в этом примере для идентификации фазы необходимо полное соответствие торговой ситуации изложенным правилам идентификации. Должны присутствовать конкретные наборы ордеров: только позиция и никаких ордеров, или позиция и один какой-то ордер, и никак иначе. Описание фаз работы стратегии по такому принципу может получиться объемным, а сам процесс создания описания очень трудоемким, так как потребуется предусмотреть все возможные варианты, что практически может оказаться невыполнимым делом. Для приведенного примера можно записать правила работы несколько иначе:
-
Нет позиции. Необходимо открыть позицию. Если позицию удалось открыть, необходимо отправить запросы на установку стоп-ордера и лимитного ордера.
-
Есть позиция. В этом случае в рынке должно быть еще два отложенных ордера. Проверяем, есть ли в рынке стоп-ордер, если нет, то выставим его. Проверяем, есть ли в рынке лимит-ордер, если нет, то выставим его.
В этом случаем мы имеем минимальный набор правил для идентификации фазы работы и полное описание торговой ситуации, в которой мы должны находиться в этой фазе.
При использовании такого принципа потребуется способ идентификации самой позиции, чтобы отличить, является ли позиция начальной или же уже произошло срабатывание какого-то ордера. В этом случае уже не нужно будет пытаться выставить второй ордер, поскольку система перешла в новую фазу работы. Также потребуется и идентификация ордеров. Об идентификации позиции и ордеров поговорим немного позже, а сейчас сформулируем основной принцип описания ордерных стратегий более четко и кратко:
-
Требуется способ идентификации текущей фазы работы с минимально возможным объемом информации.
-
Для каждой фазы работы стратегии должно иметься полное описание ситуации, соответствующей этой фазе.
-
Если на какой-то фазе требуется выполнение рыночных действий (открытие, закрытие, доливка, сокращение объема позиции и т.п.) и выставление отложенных ордеров, то такая фаза разделяется на две фазы: до выполнения рыночного действия и после (чтобы иметь возможность выполнить все действия за раз и продублировать неудачные попытки действий с отложенными ордерами).
-
Если на какой-то фазе требуется выполнение рыночных действий (открытие, закрытие, доливка, сокращение объема позиции и т.п.) и выставление отложенных ордеров, работа с отложенными ордерами выполняется только после успешного выполнения рыночного действия.
-
Одной фазе может соответствовать только одно рыночное действие и любое количество действий с отложенными ордерами.
Идентификация позиции и ордеров
Идентифицировать позицию и ордера можно несколькими способами: использовать запись в комментарии ордера, магический номер, глобальные переменные. Воспользуемся комментариями. Основными проблемами использования комментариев является то, что размер комментария ограничен, и то, что брокер может добавлять к комментарию свою запись. Если для записи брокера не будет хватать места, часть комментария будет обрезана.
Поэтому следует стараться занимать как можно меньше места в комментарии и каким-то образом отделить его от возможных записей брокера. Каждому ордеру достаточно всего лишь одного идентификатора. На практике это будет 1-2 цифры или буква и одна две цифры. В конце идентификатора поместим какой-нибудь знак, пусть будет "=" (не было замечено, чтобы брокер использовал этот знак в своих записях). Получается максимум 4 знака. Для извлечения идентификатора из комментария можно воспользоваться следующей функцией:
//+------------------------------------------------------------------+ //| Функция извлечения идентификатора из строки aComment | //+------------------------------------------------------------------+ string GetID(string aComment) { int p =StringFind(aComment,"=",0); // Определяем позицию в которой находится разделитель string id=StringSubstr(aComment,0,p); // Извлекаем подстроку расположенную до разделителя return(id); } //+------------------------------------------------------------------+
Если необходимо проверить соответствие позиции или ордера известному идентификатору, это можно сделать следующей функцией:
//+------------------------------------------------------------------+ //| Проверка соответствия комментария заданному идентификатору | //+------------------------------------------------------------------+ bool FitsID(string aID,string aComment) { return(StringFind(aComment,aID+"=",0)==0); } //+------------------------------------------------------------------+
Метаязык описания ордерных стратегий
Теперь определимся со способом записи ордерных стратегий. Способ должен быть кратким, четким, легко понятным человеку и в тоже время должен быть как бы "параллелен" языку MQL5, чтобы исполнение его команд было максимально быстрым без лишних вычислений. Насколько это получилось, судить конечно читателям.
Описание стратегии выполняется в текстовом файле, файл подключается к эксперту путем указания его имени в окне свойств эксперта.
Одна строка в файле соответствует одной фазе работы системы. Строка разделена на два поля. В первом поле указываются правила идентификации фазы. Во втором поле находится список действий. Для разделения полей используется вертикальная черта "|". Правила идентификации и пункты списка действий перечисляются через точку с запятой ";".
Кроме команд, в каждой строке, в правой части может находиться комментарий, который отделяется знаком "#", например:
Nothing | Buy(M1,1,0,0) #Если в рынке нет ни позиций, ни ордеров, то открыть позицию Buy, пометить ее комментарием "М1", с лотом 1, без Стоп Лосса и без Тейк Профита.
Идентификация фазы
Для идентификации фазы может потребоваться информация о текущей рыночной позиции, об отложенных ордерах, о последней сделке. Кроме информации о наличии позиции, могут потребоваться и некоторые подробности: ее цена, прибыль, наличие Стоп Лосса, величина Стоп Лосса и пр. О последней сделке может потребоваться узнать, с каким результатом она была выполнена. Для отложенных ордеров может потребоваться узнать цену их открытия, Стоп Лосса, Тейк Профита (скорее, это потребуется на стадии выполнения действий).
Получение этих данных выполняется посредством команд доступа к торговым данным. У большинства этих команд может быть два параметра: первый параметр - идентификатор позиции или ордера, второй - идентификатор параметра. Если идентификатор параметра не указывается, это означает, что проверяется только существование торгового объекта, указанного командой и идентификатором.
Например, команда Buy(M1) означает, что в рынке должна существовать позиция с идентификатором "M1". Команда Buy() (или просто Buy без скобок) означает, что должна существовать позиция Buy с любым идентификатором. Если указать идентификатор параметра, то это будет означать значение этого параметра, например, Buy(M1,StopLossInPoints) - это величина Стоп Лосса в пунктах у позиции Buy с идентификатором "M1". Если идентификатор не указан - Buy(,StopLossInPoints), это означает Стоп Лосс позиции бай с любым идентификатором (лишь бы была позиция Buy).
Полученное значение может использоваться в выражении проверки условий, например Buy(M1,StopLossInPoints)>=0 - позиция находится в безубытке. Если позиции нет, или есть позиция с другим идентификатором, то фаза, имеющая такую запись, в правилах идентификации не будет идентифицироваться, то есть нет необходимости записывать два условия: для проверки существования позиции и для проверки значения Стоп Лосса. Однако, в данном случае потребуется предварительно выполнить проверку существования Стоп Лосса - Buy(M1,StopLossExists); Buy(M1,StopLossInPoints)>=0.
При проверке значений могут использоваться все варианты сравнения: ">=", "<=", "==", "!=", ">", "<". Значение в правой части выражения сравнения может указываться непосредственно числом, могут использоваться специальные переменные: Var1, Var2 ... Var20. Если после числа или переменной добавить букву "p" это будет означать, что значение дополнительно будет умножаться на величину пункта (переменную _Point).
В правой части выражения сравнения может быть и более сложное арифметическое выражение. Оно может быть представлено такой схемой: X1*X2+X3*X4 (вместо знака "+", разумеется, может использоваться "-"), где X1, X2, X3, X4 может быть числом, переменной или командой доступа к данным. Приведенный ниже пример, в принципе, является правильным (если не обращать внимание на его практическую пользу):
-BuyStop(BS1,StopLossInPoints)*-SellLimit(SL1,StopLossInPoints)+-SellStop(SS1,StopLossInPoints)*-BuyLimit(SL1,StopLossInPoints)
В таблице 1 приведен список всех команд доступа.
Таблица 1. Команды доступа к данным
Индекс | Команда | Возможные параметры | Назначение |
---|---|---|---|
0 | Nothing | Нет параметров | В рынке нет ничего, ни позиции ни отложенных ордеров |
1 | NoPos | Нет параметров | В рынке нет позиции |
2 | Pending | Идентификатор объекта, идентификатор параметра ордера | Любой отложенный ордер с указанным идентификатором объекта. Если идентификатор объекта не указан, то любой отложенный ордер независимо от значения идентификатора объекта |
3 | Buy | Идентификатор объекта, идентификатор параметра позиции | Позиция Buy с указанным идентификатором объекта. Если идентификатор объекта не указан, то просто позиция Buy |
4 | Sell | Идентификатор объекта, идентификатор параметра позиции | Позиция Sell с указанным идентификатором объекта. Если идентификатор объекта не указан, то просто позиция Sell |
5 | BuyStop | Идентификатор объекта, идентификатор параметра ордера | Ордер BuyStop с указанным идентификатором объекта. Если идентификатор объекта не указан, то просто ордер BuyStop |
6 | SellStop | Идентификатор объекта, идентификатор параметра ордера | Ордер SellStop с указанным идентификатором объекта. Если идентификатор объекта не указан, то просто ордер SellStop |
7 | BuyLimit | Идентификатор объекта, идентификатор параметра ордера | Ордер BuyLimit с указанным идентификатором объекта. Если идентификатор объекта не указан, то просто ордер BuyLimit |
8 | SelLimit | Идентификатор объекта, идентификатор параметра ордера | Ордер SellLimit с указанным идентификатором объекта. Если идентификатор объекта не указан, то просто ордер SellLimit |
9 | BuyStopLimit | Идентификатор объекта, идентификатор параметра ордера | Ордер BuyStopLimit с указанным идентификатором объекта. Если идентификатор объекта не указан, то просто ордер BuyStopLimit |
10 | SellStopLimit | Идентификатор объекта, идентификатор параметра ордера | Ордер SellStopLimit с указанным идентификатором объекта. Если идентификатор объекта не указан, то просто ордер SellStopLimit |
11 | LastDeal | Пустой, идентификатор параметра сделки | Самая последняя сделка |
12 | LastDealBuy | Пустой, идентификатор параметра сделки | Самая последняя сделка является сделкой Buy |
13 | LastDealSell | Пустой, идентификатор параметра сделки | Самая последняя сделка является сделкой Sell |
14 | NoLastDeal | Нет параметров | В истории нет данных о сделке, необходимо на случай, когда эксперт только начал свою работу на счете |
15 | SignalOpenBuy | Нет параметров | Сигнал индикаторов на открытие покупки |
16 | SignalOpenSell | Нет параметров | Сигнал индикаторов на открытие продажи |
17 | SignalCloseBuy | Нет параметров | Сигнал индикаторов на закрытие покупки |
18 | SignalCloseSell | Нет параметров | Сигнал индикаторов на закрытие продажи |
19 | UserBuy | Нет параметров | Команда пользователя к выполнению покупки |
20 | UserSell | Нет параметров | Команда пользователя к выполнению продажи |
21 | Bid | Нет параметров | Цена Bid |
22 | Ask | Нет параметров | Цена Ask |
23 | ThisOpenPrice | Нет параметров | Цена открытия ордера, для которого рассчитывается параметр. Применяется в командах действия к отложенным ордерам, кроме ордеров типа StopLimit |
24 | ThisOpenPrice1 | Нет параметров | Цена открытия-1 ордера, для которого рассчитывается параметр. Применяется в командах действия к отложенным ордерам типа StopLimit |
25 | ThisOpenPrice2 | Нет параметров | Цена открытия-2 ордера, для которого рассчитывается параметр. Применяется в командах действия к отложенным ордерам типа StopLimit |
26 | LastEADeal | Идентификатор объекта, идентификатор параметра сделки | Самая последняя сделка, совершенная экспертом. Выполняется поиск в истории последней сделки, имеющей в комментарии знак "=", и у этой сделки проверяется соответствие с идентификатором объекта |
27 | LastEADealBuy | Идентификатор объекта, идентификатор параметра сделки | Самая последняя сделка, совершенная экспертом, является сделкой Buy. Выполняется поиск в истории последней сделки, имеющей в комментарии знак "=", и у этой сделки проверяется соответствие с идентификатором объекта и направлением сделки |
28 | LastEADealSell | Идентификатор объекта, идентификатор параметра сделки | Самая последняя сделка, совершенная экспертом, является сделкой Sell. Выполняется поиск в истории последней сделки, имеющей в комментарии знак "=", и у этой сделки проверяется соответствие с идентификатором объекта и направлением сделки |
29 | NoTradeOnBar | Нет параметров | На последнем баре не было никаких сделок |
Приведенные в таблице 1 команды позволяют осуществлять доступ к следующим типам торговых объектов: позициям, ордерам, сделкам и устанавливаемым ордерам. У различных объектов различные наборы параметров.
В таблице 2 приведены все идентификаторы параметров, с указанием типов объектов, к которым могут применяться эти идентификаторы.
Таблица 2. Идентификаторы доступа к данным.
Индекс | Идентификатор | Назначение | Тип торгового объекта |
---|---|---|---|
0 | ProfitInPoints | Прибыль в пунктах | Позиция |
1 | ProfitInValute | Прибыль в валюте депозита | Позиция, сделка |
2 | OpenPrice | Цена открытия | Позиция, отложенные ордера (кроме ордеров StopLimit) |
3 | LastPrice | Цена | Сделка |
4 | OpenPrice1 | Цена перехода ордера StopLimit в Limit | Отложенные ордера типа StopLimit. При переходе ордера в Limit, будет действовать идентификатор OpenPrice |
5 | OpenPrice2 | Цена перехода ордера StopLimit в позицию | Отложенные ордера типа StopLimit. При переходе ордера в Limit, будет действовать идентификатор OpenPrice |
6 | StopLossValue | Цена Стоп Лосса | Позиция, отложенные ордера |
7 | TakeProfitValue | Цена Тейк Профита | Позиция, отложенные ордера |
8 | StopLossInPoints | Стоп Лосс в пунктах | Позиция, отложенные ордера |
9 | TakeProfitInPoints | Тейк Профит в пунктах | Позиция, отложенные ордера |
10 | StopLossExists | Существование Стоп Лосс | Позиция, отложенные ордера |
11 | TakeProfitExists | Существование Тейк Профит | Позиция, отложенные ордера |
12 | Direction | Направление. 1 - Buy, -1 - Sell | Позиция, отложенные ордера, сделка |
Описание действий
В действия входит открытие рыночной позиции, ее закрытие, установка отложенных ордеров, их удаление, модификация, исполнение функций сопровождения: трейлинг стоп, безубыток, трейлинг отложенного ордера (любых других функций сопровождения позиций).
Открытие позиции, установка ордеров подразумевает наличие параметров, с которыми выполняются эти действия, эти параметры будут указываться после команды в круглых скобках, точно так же, как обычно вызываются функции. Первым параметром для всех команд будет идентификатор. При указании параметров можно использовать не только числовые значения, переменные, но и параметры существующей позиции или ордера. Для всех параметров команд действий могут использоваться рассмотренные в разделе идентификации фазы арифметические выражения типа X1*X2+X3*X4.
В таблице 3 приведены все команды действий.
Таблица 3. Команды действий
Индекс | Команда | Назначение |
---|---|---|
0 | Buy(ID,Lot,StopLoss,TakeProfit) | Открытие рыночной позиции Buy |
1 | Sell(ID,Lot,StopLoss,TakeProfit) | Открытие рыночной позиции Sell |
2 | Close(ID) | Закрытие рыночной позиции |
3 | BuyStop(ID,Lot,Price,StopLoss,TakeProfit) | Установка ордера BuyStop |
4 | SellStop(ID,Lot,Price,StopLoss,TakeProfit) | Установка ордера SellStop |
5 | BuyLimit(ID,Lot,Price,StopLoss,TakeProfit) | Установка ордера BuyLimit |
6 | SellLimit(ID,Lot,Price,StopLoss,TakeProfit) | Установка ордера SellLimit |
7 | BuyStopLimit(ID,Lot,Price1,Price2,StopLoss,TakeProfit) | Установка ордера BuyStopLimit |
8 | SellStopLimit(ID,Lot,Price1,Price2,StopLoss,TakeProfit) | Установка ордера SellStopLimit |
9 | Delete(ID) | Удаление отложенного ордера |
10 | DeleteAll(ID,BuyStop,SellStop,BuyLimit,SellLimit,BuyStopLimit,SellStopLimit) | Удаление указанных типов отложенных ордеров |
11 | Modify(ID,Price1,Price2,StopLoss,TakeProfit) | Модификация позиции или ордера |
12 | TrailingStop | Работа функции трейлинг стопа. Параметры функции определяются в окне свойств эксперта |
13 | BreakEven | Работа функции безубытка. Параметры функции определяются в окне свойств эксперта |
В таблице 4 приведено описание параметров команд действия.
Таблица 4. Параметры команд действий
Параметр | Назначение |
---|---|
ID | Идентификатор торгового объекта (позиции, ордера) |
Lot | Объем ордера в условных единицах. В окне свойств эксперта имеется переменная Lots, определяющая величину условной единицы |
StopLoss | Цена стоплосса |
TakeProfit | Цена тейкпрофита |
Price | Цена отложенного ордера (кроме ордеров типа StopLimit) |
Price1 | Цена перехода ордера StopLimit в Limit |
Price2 | Цена перехода ордера StopLimit в позицию |
Теперь попробуем записать приведенные ранее ордерные стратегии на нашем новом метаязыке.
Примеры ордерных стратегий на метаязыке
Программы изложены в таблицах, все команды идентификации фаз и действий изложены в столбик, чтобы было удобней их понимать, и прокомментированы. В приложении к статье имеются все программы в текстовых файлах в том виде, как они должны использоваться в эксперте.
Доливка лимитами
Начальная позиция будет открываться в соответствии с направлением, указанным пользователем в окне свойств. Максимально будет допускаться 5 доливок (лимитных ордеров). В рынке одновременно должны находиться только три ордера.
Таблица 5. Метапрограмма "Доливка лимитами"
Номер фазы | Идентификация фазы | Действия | Комментарий |
---|---|---|---|
1 | Nothing; UserBuy | Buy(1,1,0,Ask+Var1p); BuyLimit(2,2,Buy(1,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p); BuyLimit(3,4,BuyLimit(2,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p); BuyLimit(4,8,BuyLimit(3,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p) | Если в рынке нет ни позиции, ни ордеров, в параметрах советника указано направление покупки - открыть позицию с начальным лотом. Если позиция открылась, будут попытки установки трех лимитных ордеров. Причем, последующий ордер получится установить, только если установлен предыдущий, потому что цена ордера отсчитывается от цены предыдущего ордера. |
2 | Buy(1) | BuyLimit(2,2,Buy(1,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p); BuyLimit(3,4,BuyLimit(2,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p); BuyLimit(4,8,BuyLimit(3,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p) | Если в фазе 1 удалось открыть позицию, но не все отложенные ордера, будут продолжаться попытки установить отложенные ордера. |
3 | Buy(2) | BuyLimit(3,4,Buy(2,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p); BuyLimit(4,8,BuyLimit(3,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p); BuyLimit(5,16,BuyLimit(4,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p) | Если сработал первый лимитный ордер (с идентификатором 2), выполняются попытки установить два ордера, которые должны быть установлены в предыдущих фазах (если их так и не удалось установить), и будет устанавливаться еще один ордер, чтобы в рынке всегда было три лимитных ордера. |
4 | Buy(3) | BuyLimit(4,8,Buy(3,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p); BuyLimit(5,16,BuyLimit(4,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p); BuyLimit(6,32,BuyLimit(4,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p) | Сработал еще один лимитный ордер, здесь, так же как в предыдущей фазе, обеспечивается наличие в рынке трех лимитных ордеров. |
5 | Buy(4) | BuyLimit(5,16,Buy(4,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p); BuyLimit(6,32,BuyLimit(5,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p) | В этой фазе обеспечивается наличие только двух отложенных ордеров, потому что общее количество ордеров приближается к допустимому количеству ордеров. |
6 | Buy(5) | BuyLimit(6,32,Buy(5,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p) | В этой фазе только один ордер, последний. |
7 | Buy(6) | Modify(6,,,Buy(6,OpenPrice)-Var4p,) | Если последний ордер сработал, ему выставляется Стоп Лосс. |
8 | Nothing; UserSell | Sell(1,1,0,Var1p); SellLimit(2,2,Sell(1,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p); SellLimit(3,4,SellLimit(2,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p); SellLimit(4,8,SellLimit(3,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p) | Аналогично фазе 1, но для направления продажи. |
9 | Sell(1) | SellLimit(2,2,Sell(1,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p); SellLimit(3,4,SellLimit(2,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p); SellLimit(4,8,SellLimit(3,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p) | Аналогично фазе 2, но для направления продажи. |
10 | Sell(2) | SellLimit(3,4,Sell(2,OpenPrice)+Var2p,0,Var3); SellLimit(4,8,SellLimit(3,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p); SellLimit(5,16,SellLimit(4,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p) | Аналогично фазе 3, но для направления продажи. |
11 | Sell(3) | SellLimit(4,8,Sell(3,OpenPrice)+Var2p,0,Var3); SellLimit(5,16,SellLimit(4,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p); SellLimit(6,32,SellLimit(4,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p) | Аналогично фазе 4, но для направления продажи. |
12 | Sell(4) | SellLimit(5,16,Sell(4,OpenPrice)+Var2p,0,Var3); SellLimit(6,32,SellLimit(5,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p) | Аналогично фазе 5, но для направления продажи. |
13 | Sell(5) | SellLimit(6,32,Sell(5,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p) | Аналогично фазе 6, но для направления продажи. |
14 | Sell(6) | Modify(6,,,Sell(6,OpenPrice)+Var4p,) | Аналогично фазе 7, но для направления продажи. |
15 | NoPos; Pending | DeleteAll(,0,0,1,1,0,0) | Нет позиции, но есть отложенные ордера, это случается при срабатывании Тейк Профита позиции. В этом случае необходимо удалить ордера. После удаления ордеров система перейдет в фазу 1 или 9. Если же пользователь в процессе работы системы отключил начальное направление, никаких действий выполняться не будет. |
Использование переменных: Var1 - Тейк Профит начального ордера, Var2 - уровень установки лимитных ордеров относительно цены открытия предыдущего ордера, Var3 - Стоп Лосс последнего ордера.
На рис. 5 показан график, полученный в результате работы по этой метапрограмме.
Рис. 5. Результаты работы по метапрограмме "Доливка лимитами"
Обратите внимание: отдельно записаны правила для направления покупки и направления продажи. Уровень каждого последующего отложенного ордера отсчитывается от уровня предыдущего ордера. Если какой-то ордер не удалось установить, то следующий не будет установлен по причине отсутствия требуемого параметра. Отсчитывать уровень от цены рыночной позиции было бы неправильно. В этом случае, какой-нибудь из ордеров может оказаться пропущенным.
Стоп-переворот
Работа начинается с двух отложенных стоп-ордеров. Допускается пять переворотов.
Таблица 6. Метапрограмма "Стоп-переворот"
Номер фазы | Идентификация фазы | Действия | Комментарий |
---|---|---|---|
1 | Nothing | BuyStop(1,1,Ask+Var1p,ThisOpenPrice-Var2p,ThisOpenPrice+Var3p); SellStop(1,1,Bid-Var1p,ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) | В рынке нет ни позиции, ни ордеров, пытаемся установить два стоп-ордера с идентификатором 1. |
2 | NoPos; BuyStop(1) | SellStop(1,1,Bid-Var1p,ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) | Нет позиции и есть BuyStop с идентификатором 1, значит должен быть SellStop с идентификатором 1. |
3 | NoPos; SellStop(1) | BuyStop(1,1,Ask+Var1p,ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) | Нет позиции и есть SellStop с идентификатором 1, значит должен быть BuyStop с идентификатором 1. |
4 | Buy(1) | Delete(1); SellStop(2,2,Buy(1,StopLossValue),ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) | В рынке позиция Buy с идентификатором 1, в этом случае других ордеров с идентификатором 1 не должно быть, но должен быть SellStop с идентификатором 2. |
5 | Sell(1) | Delete(1); BuyStop(2,2,Sell(1,StopLossValue),ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) | Аналогично фазе 4, но сработал первый SellStop. |
6 | Buy(2) | SellStop(3,4,Buy(2,StopLossValue),ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) | Сработал второй BuyStop, нужно установить третий SellStop. |
7 | Sell(2) | BuyStop(3,4,Sell(2,StopLossValue),ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) | Сработал второй SellStop, нужно установить третий BuyStop. |
8 | Buy(3) | SellStop(4,8,Buy(3,StopLossValue),ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) | Сработал третий BuyStop, нужно установить четвертый SellStop. |
9 | Sell(3) | BuyStop(4,8,Sell(3,StopLossValue),ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) | Сработал третий SellStop, нужно установить четвертый BuyStop. |
10 | Buy(4) | SellStop(5,16,Buy(4,StopLossValue),ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) | Сработал четвертый BuyStop, нужно установить пятый SellStop. |
11 | Sell(4) | BuyStop(5,16,Sell(4,StopLossValue),ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) | Сработал четвертый SellStop, нужно установить пятый BuyStop. |
12 | Buy(5) | SellStop(6,32,Buy(5,StopLossValue),ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) | Сработал пятый BuyStop, нужно установить шестой SellStop. |
13 | Sell(5) | BuyStop(6,32,Sell(5,StopLossValue),ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) | Сработал пятый SellStop, нужно установить шестой BuyStop. |
14 | NoPos; BuyStop(2) | Delete(2) | Нет позиции, но остался BuyStop, это может случиться при закрытии позиции по Тейк Профиту. В этом случае оставшийся ордер удаляется, и система переходит в фазу 1. |
15 | NoPos; SellStop(2) | Delete(2) | Аналогично фазе 14. |
16 | NoPos; BuyStop(3) | Delete(3) | Аналогично фазе 14. |
17 | NoPos; SellStop(3) | Delete(3) | Аналогично фазе 14. |
18 | NoPos; BuyStop(4) | Delete(4) | Аналогично фазе 14. |
19 | NoPos; SellStop(4) | Delete(4) | Аналогично фазе 14. |
20 | NoPos; BuyStop(5) | Delete(5) | Аналогично фазе 14. |
21 | NoPos; SellStop(5) | Delete(5) | Аналогично фазе 14. |
22 | NoPos; BuyStop(6) | Delete(6) | Аналогично фазе 14. |
23 | NoPos; SellStop(6) | | Delete(6) | Аналогично фазе 14. |
Использование переменных: Var1 - уровень установки начальных ордеров от текущей рыночной цены, Var2 - Стоп Лосс, Var3 - Тейк Профит.
На рис. 6 показан график, полученный в результате работы по этой метапрограмме.
Рис. 6. Результаты работы по метапрограмме "Стоп-реверс"
Пирамидинг
Начальная позиция открывается по сигналу индикаторов. Допускается пять доливок.
Таблица 7. Метапрограмма "Пирамидинг"
Номер фазы | Идентификация фазы | Действия | Комментарий |
---|---|---|---|
1 | Nothing; SignalOpenBuy | Buy(1,1,Ask-Var1p,Ask+Var2p*6) | В рынке нет ни позиции, ни ордеров, есть сигнал индикаторов к открытию покупки, выполняется открытие позиции. Тейк Профит выставляется на дистанции Var2p*6, на следующем шаге Тейк Профит будет на дистанции Var2p*5 и т.д., чтобы Тейк Профит находился примерно на одном ценовом уровне. |
2 | Buy(1); Buy(1,ProfitInPoints)>=Var3 | Buy(2,1,Ask-Var1p,Ask+Var2p*5) | Есть покупка, и у нее достаточная прибыль, выполняется доливка. |
3 | Buy(2) | Modify(2,,,Buy(2,OpenPrice),) | В рынке позиция с индексом 2, значит, это не начальная позиция, выполнялась доливка, стоплосс должен находиться в безубытке. |
4 | Buy(2); Buy(2,ProfitInPoints)>=Var3 | Buy(3,1,Ask-Var1p,Ask+Var2p*4) | Снова позиция в прибыли, выполняется доливка. |
5 | Buy(3) | Modify(3,,,Buy(3,OpenPrice),) | При каждой доливке Стоп Лосс переносится на уровень безубытка позиции. |
6 | Buy(3); Buy(3,ProfitInPoints)>=Var3 | Buy(4,1,Ask-Var1p,Ask+Var2p*3) | Аналогично фазе 4. |
7 | Buy(4) | Modify(4,,,Buy(4,OpenPrice),) | Аналогично фазе 5. |
8 | Buy(4); Buy(4,ProfitInPoints)>=Var3 | Buy(5,1,Ask-Var1p,Ask+Var2p*2) | Аналогично фазе 4. |
9 | Buy(5) | Modify(5,,,Buy(5,OpenPrice),) | Аналогично фазе 5. |
10 | Buy(5); Buy(5,ProfitInPoints)>=Var3 | Buy(6,1,Ask-Var1p,Ask+Var2p) | Аналогично фазе 4. |
11 | Buy(6) | Modify(6,,,Buy(6,OpenPrice),) | Аналогично фазе 5. |
12 | Nothing; SignalOpenSell | Sell(1,1,Bid+Var1p,Bid-Var2p*6) | Аналогично фазе 1, но для продажи. |
13 | Sell(1); Sell(1,ProfitInPoints)>=Var3 | Sell(2,1,Bid+Var1p,Bid-Var2p*5) | Аналогично фазе 2, но для продажи. |
14 | Sell(2) | Modify(2,,,Sell(2,OpenPrice),) | Аналогично фазе 3, но для продажи. |
15 | Sell(2); Sell(2,ProfitInPoints)>=Var3 | Sell(3,1,Bid+Var1p,Bid-Var2p*4) | Аналогично фазе 4, но для продажи. |
16 | Sell(3); | Modify(3,,,Sell(3,OpenPrice),) | Аналогично фазе 5, но для продажи. |
17 | Sell(3); Sell(3,ProfitInPoints)>=Var3 | Sell(4,1,Bid+Var1p,Bid-Var2p*3) | Аналогично фазе 6, но для продажи. |
18 | Sell(4); | Modify(4,,,Sell(4,OpenPrice),) | Аналогично фазе 7, но для продажи. |
19 | Sell(4); Sell(4,ProfitInPoints)>=Var3 | Sell(5,1,Bid+Var1p,Bid-Var2p*2) | Аналогично фазе 8, но для продажи. |
20 | Sell(5); | Modify(5,,,Sell(5,OpenPrice),) | Аналогично фазе 9, но для продажи. |
21 | Sell(5); Sell(5,ProfitInPoints)>=Var3 | Sell(6,1,Bid+Var1p,Bid-Var2p) | Аналогично фазе 10, но для продажи. |
22 | Sell(6); | Modify(6,,,Sell(6,OpenPrice),) | Аналогично фазе 11, но для продажи. |
Использование переменных: Var1 - начальный Стоп Лосс, Var2 - Тейк Профит последнего ордера, Var3 - прибыль в пунктах, при которой выполняется доливка и перенос Стоп Лосса в бузубыток.
На рис. 7 показан график, полученный в результате работы по этой метапрограмме.
Рис. 7. Результаты работы по метапрограмме "Пирамидинг"
Переоткрытие
Сначала устанавливаются два лимитных ордера. При срабатывании одного второй удаляется. Далее, при срабатывании Стоп Лосса выполняется открытие новой позиции, пока не будет получен Тейк Профит или не отработано допустимое количество позиций (5 шт.).
Таблица 8. Метапрограмма "Переоткрытие"
Номер фазы | Идентификация фазы | Действия | Комментарий |
---|---|---|---|
1 | Nothing; NoLastDeal | BuyLimit(1,1,Ask-Var1p,ThisOpenPrice-Var2p,ThisOpenPrice+Var3p); SellLimit(1,1,Bid+Var1p,ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) | В рынке нет ни позиции, ни ордеров, в истории счета по символу нет сделок. Значит, это самое начало работы системы. Выполняются начальные действия - установка двух лимитных ордеров. |
2 | Nothing; LastDeal(,ProfitInValute)>0 | BuyLimit(1,1,Ask-Var1p,ThisOpenPrice-Var2p,ThisOpenPrice+Var3p); SellLimit(1,1,Bid+Var1p,ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) | В рынке нет ни позиции, ни ордеров, но в истории есть сделка, закрытая с прибылью. Значит, предыдущая серия работы закончена, начинаем сначала - ставим два лимитных ордера, так же как в фазе 1. |
3 | Nothing; LastEADeal(5) | BuyLimit(1,1,Ask-Var1p,ThisOpenPrice-Var2p,ThisOpenPrice+Var3p); SellLimit(1,1,Bid+Var1p,ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) | В рынке нет ни позиции, ни ордеров, но в истории есть сделка с последним идентификатором. В этом случае прибыль сделки не интересует, серия все равно считается законченной, начинаем сначала - ставим два лимитных ордера, так же как в фазе 1. |
4 | NoPos; BuyLimit(1) | SellLimit(1,1,Bid+Var1p,ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) | В рынке нет позиции, но известно, что есть один лимитный ордер, значит, должен быть и второй. |
5 | NoPos; SellLimit(1) | BuyLimit(1,1,Ask-Var1p,ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) | Аналогично фазе 4. |
6 | Buy(1); SellLimit(1) | Delete(1) | Есть позиция с идентификатором 1. Это значит, что сработал один из лимитных ордеров, второй ордер необходимо удалить. |
7 | Sell(1); BuyLimit(1) | Delete(1) | Аналогично фазе 6. |
8 | Nothing; LastDeal(1,ProfitInValute)<=0; LastEADeal(1,Direction)==1 | Buy(2,2,Ask-Var2p,Ask+Var3p) | Нет позиции, последняя сделка с убытком. Проверяем направление последней сделки эксперта: если это покупка, значит, открываем следующую позицию на покупку. |
9 | Nothing; LastDeal(1,ProfitInValute)<=0; LastEADeal(1,Direction)==-1 | Sell(2,2,Bid+Var2p,Bid-Var3p) | Нет позиции, последняя сделка с убытком. Проверяем направление последней сделки эксперта: если это продажа, значит, открываем следующую позицию. |
10 | Nothing; LastDeal(2,ProfitInValute)<=0; LastEADeal(2,Direction)==1 | Buy(3,4,Ask-Var2p,Ask+Var3p) | Аналогично фазе 8. |
11 | Nothing; LastDeal(2,ProfitInValute)<=0; LastEADeal(2,Direction)==-1 | Sell(3,4,Bid+Var2p,Bid-Var3p) | Аналогично фазе 9. |
12 | Nothing; LastDeal(3,ProfitInValute)<=0; LastEADeal(3,Direction)==1 | Buy(4,8,Ask-Var2p,Ask+Var3p) | Аналогично фазе 8. |
13 | Nothing; LastDeal(3,ProfitInValute)<=0; LastEADeal(3,Direction)==-1 | Sell(4,8,Bid+Var2p,Bid-Var3p) | Аналогично фазе 9. |
14 | Nothing; LastDeal(4,ProfitInValute)<=0; LastEADeal(4,Direction)==1 | Buy(5,16,Ask-Var2p,Ask+Var3p) | Аналогично фазе 8. |
15 | Nothing; LastDeal(4,ProfitInValute)<=0; LastEADeal(4,Direction)==-1 | Sell(5,16,Bid+Var2p,Bid-Var3p) | Аналогично фазе 9. |
Использование переменных: Var1 - уровень установки лимитных ордеров от рыночной цены, Var2 - Стоп Лосс, Var3 - Тейк Профит.
На рис. 8 показан график, полученный в результате работы по этой метапрограмме.
Рис. 8. Результаты работы по метапрограмме "Переоткрытие"
Еще несколько простых программ для тестирования функций работы по торговым сигналам, трейлинга и безубытка.
Торговые сигналы
Вход и выход выполняются по торговым сигналам.
Таблица 9. Метапрограмма "Торговые сигналы"
Номер фазы | Идентификация фазы | Действия | Комментарий |
---|---|---|---|
1 | Nothing; SignalOpenBuy; NoTradeOnBar | Buy(1,1,0,0) | В рынке нет ни позиции, ни ордеров, есть сигнал к открытию покупки. На текущем баре не было сделок, открывается покупка. |
2 | Nothing; SignalOpenSell; NoTradeOnBar | Sell(1,1,0,0) | В рынке нет ни позиции, ни ордеров, есть сигнал к открытию продажи. На текущем баре не было сделок, открывается продажа. |
3 | SignalCloseBuy; Buy(1) | Close(1); | Есть сигнал к закрытию покупки, есть покупка, выполняется ее закрытие. |
4 | SignalCloseSell; Sell(1) | Close(1); | Есть сигнал к закрытию продажи, есть продажа, выполняется ее закрытие. |
На рис. 9 показан график, полученный в результате работы по этой метапрограмме.
Рис. 9. Результаты работы по метапрограмме "Торговые сигналы"
Торговые сигналы с трейлингом
Таблица 10. Метапрограмма "Торговые сигналы с трейлингом"
Номер фазы | Идентификация фазы | Действия | Комментарий |
---|---|---|---|
1 | Nothing; SignalOpenBuy; NoTradeOnBar | Buy(1,1,0,0) | В рынке нет ни позиции, ни ордеров, есть сигнал к открытию покупки. На текущем баре не было сделок, открывается покупка. |
2 | Nothing; SignalOpenSell; NoTradeOnBar | Sell(1,1,0,0) | В рынке нет ни позиции, ни ордеров, есть сигнал к открытию продажи. На текущем баре не было сделок, открывается продажа. |
3 | SignalCloseBuy; Buy(1) | Close(1); | Есть сигнал к закрытию покупки, есть покупка, выполняется ее закрытие. |
4 | SignalCloseSell; Sell(1) | Close(1); | Есть сигнал к закрытию продажи, есть продажа, выполняется ее закрытие. |
5 | Buy(1) | TrailingStop | В рынке есть покупка, должна работать функция трейлинга. |
6 | Sell(1) | TrailingStop | В рынке есть продажа, должна работать функция трейлинга. |
На рис. 10 показан график, полученный в результате работы по этой метапрограмме.
Рис. 10. Результаты работы по метапрограмме "Торговые сигналы с трейлингом"
Торговые сигналы с безубытком
Таблица 11. Метапрограмма "Торговые сигналы с безубытком"
Номер фазы | Идентификация фазы | Действия | Комментарий |
---|---|---|---|
1 | Nothing; SignalOpenBuy; NoTradeOnBar | Buy(1,1,0,0) | В рынке нет ни позиции, ни ордеров, есть сигнал к открытию покупки, на текущем баре не было сделок, открывается покупка. |
2 | Nothing; SignalOpenSell; NoTradeOnBar | Sell(1,1,0,0) | В рынке нет ни позиции, ни ордеров, есть сигнал к открытию продажи, на текущем баре не было сделок, открывается продажа. |
3 | SignalCloseBuy; Buy(1) | Close(1); | Есть сигнал к закрытию покупки, есть покупка, выполняется ее закрытие. |
4 | SignalCloseSell; Sell(1) | Close(1); | Есть сигнал к закрытию продажи, есть продажа, выполняется ее закрытие. |
5 | Buy(1) | BreakEven | В рынке есть покупка, должна работать функция безубытка. |
6 | Sell(1) | BreakEven | В рынке есть продажа, должна работать функция безубытка. |
На рис. 11 показан график, полученный в результате работы по этой метапрограмме.
Рис. 11. Результаты работы по метапрограмме "Торговые сигналы с безубытком"
Интерпретатор команд
Вышеприведенный метод формализации ордерных стратегий позволяет не только лучше разобраться в этих стратегиях и подготовить алгоритм эксперта для их кодирования, но также позволяет непосредственно интерпретировать эти правила и исполнять их. Для этой цели был создан эксперт eInterpretator (см. файлы приложения). В таблице 12 приведены все параметры эксперта с их описанием.
Таблица 12. Параметры эксперта eInterpretator:
Параметры | Назначение |
---|---|
Lots | Объем ордера при коэффициенте лота равном 1. |
UserTradeDir | Торговое направление, указанное пользователем (проверяется при исполнении команд UserBuy и UserSell при идентификации фазы). |
ProgramFileName | Имя файла с метапрограммой (при работе на счете). При выполнении тестирования или оптимизации метапрограмма должна находиться в файле с именем TesterMetaProgram.txt |
DeInterpritate | Выполнить обратную интерпретацию команд. При ее выполнении в каталоге Files появится файл с приставкой "De_", можно проверить как эксперт "понял" метапрограмму из файла ProgramFileName. |
User Variables | |
Var1 - Var20 | Пользовательские переменные. |
Trailing Stop | |
TR_ON | Включение функции трейлинга. |
TR_Start | Прибыль позиции в пунктах, при которой начинает работать трейлинг. |
TR_Level | Уровень трейлинга. Расстояние в пунктах от текущей рыночной цены до Стоп Лосса. |
TR_Step | Шаг в пунктах, с которым выполняется модификация Стоп Лосса. |
Break Even | |
BE_ON | Включение функции безубытка. |
BE_Start | Прибыль позиции в пунктах, при которой срабатывает безубыток. |
BE_Level | Уровень, на который переносится Стоп Лосс при срабатывании безубытка. Фиксируется BE_Start-BE_Level пунктов прибыли. |
Open Signals | |
OS_ON | Включение сигналов открытия. |
OS_Shift | Бар, на котором проверяются индикаторы: 0 - формирующийся, 1 - сформированный. |
OS_TimeFrame | Таймфрейм индикаторов. |
OS_MA2FastPeriod | Период быстрой MA. |
OS_MA2FastShift | Смещение быстрой MA. |
OS_MA2FastMethod | Метод быстрой MA. |
OS_MA2FastPrice | Цена быстрой MA. |
OS_MA2SlowPeriod | Период медленной MA. |
OS_MA2SlowShift | Смещение медленной MA. |
OS_MA2SlowMethod | Метод медленной MA. |
OS_MA2SlowPrice | Цена медленной MA. |
Close Signals | |
CS_ON | Включение сигналов закрытия. |
CS_Shift | Бар, на котором проверяются индикаторы: 0 - формирующийся, 1 - сформированный. |
CS_TimeFrame | Таймфрейм индикаторов. |
CS_CCIPeriod | Период CCI. |
CS_CCIPrice | Цена CCI. |
CS_CCILevel | Верхний уровень CCI (для закрытия покупки). Сигнал закрытия покупки возникает при пересечении уровня сверху вниз. Для закрытия продажи - все наоборот. |
Принцип работы эксперта
На запуске эксперт загружает метапрограмму из файла, разбирает и анализирует ее. В случае грубых ошибок в метапрограмме открывается окно сообщения с подсказкой об ошибке. При разборе метапрограммы экспертом заполняются структуры данных числовыми значениями, соответствующими текстовым командам, чтобы обеспечить максимально возможное быстродействие эксперта. В случае успешного анализа метапрограммы в журнал выводится сообщение "Инициализация интерпретатора выполнена".
Если включить переменную DeInterpritate, эксперт выполнит проверочную деинтерпретацию команд (при этом он отсоединится от графика, если выполняется тестирование в Тестере стратегий, то оно прервется). При деинтерпретации эксперт преобразует числовые значения из структур в текстовые команды. При этом записи команд в файле будут отличаться, но по деинтерпретированной метапрограмме можно более наглядно увидеть, как в эксперте выполняется анализ команд.
Рассмотрим на примере следующей строки из файла метапрограммы:
Buy(6) | Modify(6,,,ThisOpenPrice-Var4p,)
После деинтерпретации эта строка имеет следующий вид:
Buy(6)==1*1+0*0; | Modify(6,,,ThisOpenPrice()*1-0.0025*1,)
Как видим, простая команда Buy(6) преобразована в выражение сравнения, в правой части которого вычисляется арифметическое выражение X1*X2+X3*X4, дающее в результате единицу. В поле действий пользовательская переменная заменена числовым значением.
Советы по доработке эксперта
Наверняка, кому-нибудь захочется выполнить доработки этого эксперта, добавить свои команды как для анализа фазы, так и для выполнения действий, функции сопровождения позиции. Структура эксперта позволяет вполне просто выполнить эти доработку, иначе бы работа над этим экспертом не имела смысла.
Добавление команды получения данных
Список команд получения данных находится в массиве InfoCommand. Команды расположены в столбик, по пять команд в строке, что позволяет легко сосчитать их количество и определить значение индекса для добавляемой команды.
После добавления команды в массив InfoCommand находим функцию SetValue(), в ней конструкцию switch, добавляем в нее еще один case, соответствующий индексу новой команды. Для получения значения, сначала необходимо выделить объект, с которого требуется получить значение, затем получить это значение. В зависимости от типа объекта, с которого происходит получение данных, используются различные функции выделения объекта. Эти функции приведены в таблице 13.
Таблица 13. Функции эксперта для выделения торговых объектов
Функция | Назначение и параметры |
---|---|
Pos.Select(_Symbol) | Выделение позиции. Метод стандартного класса, аналогичный функции PositionSelect(). |
SelectOrder(long aType,string aID,bool & aSelected) | Функция выделения ордера по символу, на котором работает эксперт, по типу (aType) и значению идентификатора (aID). Если объект найден и выделен, в переменной aSeleted по ссылке возвращается true. |
bool SelectLastDeal(int aType,bool & aSelected) | Функция выделения последней сделки по символу, на котором работает эксперт, и по типу (aType). Если объект найден и выделен, в переменной aSeleted по ссылке возвращается true. |
SelectLastEADeal(int aType,string aID,bool & aSelected) | Функция выделения последней выполненной экспертом сделки по символу, на котором работает эксперт, и по типу (aType). Если объект найден и выделен, в переменной aSeleted по ссылке возвращается true. |
Просто последняя сделка и последняя сделка, выполненная экспертом, отличаются тем, что в последние сделки входят сделки срабатывания Стоп Лосса и Тейк Профита. Данные по последней сделке могут потребоваться для определения результата закрытия последней позиции, а данные по последней сделке эксперта - для определения последнего направления торговли или фазы работы эксперта.
Кроме доступа к данным торговых объектов, может выполняться доступ к рыночным данным, например, к цене, да и к любым другим вообще. Важно убедиться, что данные могут быть получены. После попытки выделения объекта убеждаемся, что объект выделен (проверяем значение aSelected), получаем нужный параметр, присваиваем его значение переменной Val.Value, возвращаем true.
Для получения параметров различных торговых объектов используются различные функции, приведенные в таблице 14.
Таблица 14. Функции эксперта для получения параметров выделенного торгового объекта
Функция | Назначение и параметры |
---|---|
double SelPosParam(int aIndex) | Получение параметра позиции по заданном индексу aIndex. |
double SelOrdParam(int aIndex) | Получение параметра ордера по заданном индексу aIndex. |
double SelDealParam(int aIndex) | Получение параметра сделки по заданном индексу aIndex. |
В функции передается индекс идентификатора получаемых даных. Значение индекса находится в переменной Val.InfoIdentifierIndex.
При добавлении новой команды доступа может потребоваться добавить и идентификатор получаемых данных, либо может потребоваться добавить только идентификатор извлекаемых данных.
Добавление идентификатора данных
Список идентификаторов находится в массиве InfoIdentifier. Добавляем новый идентификатор в массив, отсчитываем его индекс, затем дорабатываем функции SelPosParam(), SelOrdParam(), SelDealParam(). Дорабатываются все функции или некоторые, в зависимости от того, ко всем ли торговым объектам может применяться новый идентификатор. Доработка функций заключается в добавлении в конструкцию switch нового case, соответствующего индексу нового идентификатора.
Добавление команды действия
Команда действия добавляется в массив ActCommand. В этом массиве команды расположены в строку, будет несколько сложнее отсчитать индекс. Элементы расположены в строку, потому что, кроме добавления команды, необходимо указать количество ее параметров и тип. Количество параметров указывается в массиве ActCmndPrmCnt, тип - в массиве ActCmndType. Возможны такие типы: 0 - рыночное действие, 1 - действия с отложенным ордером, 2 - сопровождение позиции.
После добавления команды в массив находим функцию DoAction() и добавляем к ней в switch еще один case, в котором выполняется вызов новой функции. Новая функция должна иметь тип bool и возвращать true в случае ее успешного выполнения, false - в случае ошибки. Если проверка результата работы функции не требуется, например, как в функции терйлинга, пусть она просто возвращает true.
Не забывайте, что в функциях, работающих с отложенным ордерами, как, например, в функциях по их установке, требуется предварительная проверка существования ордера.
Изменение функций торговых сигналов
Вся работа по получению торговых сигналов в эксперте выполняется в двух функциях (две для сигналов закрытия, две для сигналов открытия).
Функции CloseSignalsInit() (инициализация сигналов закрытия) и OpenSignalsInit() (инициализация сигналов открытия) вызываются из функции OnInit() эксперта. В этих функциях выполняется загрузка индикаторов. Основные функции CloseSignalsMain() (определение торговых сигналов закрытия) и OpenSignalsMain() (определение торговых сигналов открытия) вызываются из функции OnTick() на каждом тике.
В начале выполнения функции необходимо присвоить переменным GlobalCloseBuySignal, GlobalCloseSellSignal (сигналы закрытия) и GlobalOpenBuySignal, GlobalOpenSellSignal (сигналы открытия), значения false, затем true, при соответствующих показаниях индикаторов.
Кроме этого, в функции OnDeinit() эксперта необходимо выполнить IndicatorRelease().
Файлы приложения
-
eInterpretator.mq5 - эксперт, должен располагаться в каталоге MQL5/Experts каталога данных терминала.
-
LimitAdd.txt - метапрограмма доливки лимитами.
-
StopRev.txt - метапрограмма стоп-переворот.
-
Piramiding.txt - метапрограмма пирамидинг.
-
ReOpen.txt.txt - метапрограмма переоткрытия.
-
TradeSignals.txt - метапрограмма работы по торговым сигналам.
-
TradeSignalsTR.txt - метапрограмма работы по торговым сигналам с трейлингом.
-
TradeSignalsBE.txt - метапрограмма работы по торговым сигналам с безубытком.
-
limitadd.set - файл параметров доливки лимитами.
-
stoprev.set - файл параметров стоп-переворота.
-
piramiding.set - файл параметров примидинга.
-
reopen.set - файл параметров переоткрытия.
-
tradesignals.set - файл параметров работы по торговым сигналам.
-
tradesignalstr.set - файл параметров работы по торговым сигналам с трейлингом.
-
tradesignalsbe.set - файл параметров работы по торговым сигналам с безубытком.
Примечание. При использовании программ с торговыми сигналами, трейлингом, безубытком, не забывайте включать соответствующие функции в окне свойств эксперта. При тестировании стратегий в тестере копируйте файлы с метапрограммами в файл TesterMetaProgram.txt (это необходимо для обеспечения возможности использования удаленных агентов тестирования), файл должен располагаться в каталоге MQL5/Files каталога данных терминала (можно открыть из терминала: Главное меню -> Файл -> Открыть каталог данных).
В файлах параметров находятся параметры, с которыми получены графики, расположенные в разделе "Примеры ордерных стратегий на метаязыке". Тестирование выполнялось за последний месяц (на момент времени 2012.08.29), на EURUSD H1, модель OHLC на M1.
Заключение
Программирование ордерных стратегий, в первый момент, часто вызывает замешательство - с чего начать, что предусмотреть, как обеспечить устойчивую работу эксперта в реальных условиях, как объединить вместе исполнение алгоритма торговой стратегии и его надежность работы?
Эта статья должна как минимум помочь с выполнением начальной формализации стратегии как программистам, так и трейдерам, заказывающим работу по написанию экспертов, а также понять, на какие стадии может разделяться работа по стратегии, что может произойти на каждой стадии и что нужно предусмотреть. Благодаря эксперту eIntepretar открываются огромные возможности по проведению начальных экспериментов с ордерными стратегиями с минимальными затратами времени и труда.
Хотелось бы выразить огромное восхищение терминалом MetaTrader5. Быстродействие эксперта eIntepretar в тестере превзошло все ожидания!
![Как купить торгового робота в MetaTrader Market и установить его?](https://c.mql5.com/2/0/MQL5_market__1.png)
![Основы статистики](https://c.mql5.com/2/0/statistic.png)
![Быстрый старт: краткий курс для начинающих](https://c.mql5.com/2/0/start_ava.png)
![Статистический Carry Trading](https://c.mql5.com/2/0/ava_Carry_trade.png)
![MQL5 - Язык торговых стратегий для клиентского терминала MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Может надо не в ту папку в которой терминал установлен. Надо в папку данных терминала, она может быть совсем не там, где терминал. Делаем так: в терминале - Главное меню - Файл - Открыть каталог данных... отсюда танцуем.
Сделал так открывается корневая папка каталога где установлен терминал, ну так на всякий случай там тоже есть этот файлик.
Еще сделал скрин самого файла, а точнее что у него внутри, ну мало ли, мож я че не то скопировал в него.
Ну спасибо что хоть попытались помочь. Видимо этот эксперт не для моих мозгов :) не осилил я местоположение этого файла.