Условия исполнения ордеров и работа с индикаторами в MQL4

В этой статье мы рассмотрим, как можно заставить советника торговать по нашей торговой системе как можно точнее. Нам нужно будет определить условия для открытия и закрытия ордеров, а также цены для стоп-лосса и тейк-профита. Почти каждая торговая система использует данные о текущих ценах или показаниях индикаторов. Давайте рассмотрим, как мы можем получить доступ к этой информации и использовать ее в наших советниках.

Данные о цене

Наряду с текущей ценами Bid или Ask, вам может понадобиться использовать данные о цене свечи, а именно, максимума, минимума, открытия или закрытия. Для текущего графика вы можете использовать предопределенные массивы High[], Low[], Open[] и Close[].

Массив — это переменная, которая содержит несколько значений. Вы перебираете значения, изменяя индекс, который содержится в квадратных скобках. Например, Open[0] — это цена открытия текущего бара. 0 — это индекс, и, изменив его, мы можем получить цену открытия других баров. Бар, предшествующий текущему бару, будет иметь индекс 1 и т. д. Мы часто будем использовать либо текущий бар, либо значения цены предыдущего бара.

Если вам нужно использовать максимальное, минимальное, цену открытия или закрытия значение для символа, отличного от текущего графика, или если вам нужны ценовые данные за определенный период, вы можете использовать функции iHigh(), iLow(), iOpen() и iClose().

double iClose(string Symbol, int Period, int Shift)
  • Symbol — символ используемой валютной пары.
  • Period — период графика в минутах.
  • Shift — смещение назад относительно текущего бара.

Мы будем использовать iClose(), чтобы получить цену закрытия для другого периода графика. Например, мы используем 1-часовой график, но мы хотим проверить цену закрытия предыдущего бара на 4-часовом графике:

double H4Close = iClose(NULL,PERIOD_H4,1);

NULL относится к текущему символу графика. PERIOD_H4 — это целочисленная константа, которая относится к периоду графика H4. 1 — наш сдвиг, который является баром, предшествующим текущему бару.

Давайте использовать другой пример, который возвращает закрытие текущего бара на другом графике:

double GBPClose = iClose(GBPUSD,0,0);

GBPUSD — это символ, который мы используем. Мы указали 0 в качестве нашего периода, поэтому период графика, который мы проверяем по GBPUSD, будет таким же, как наш текущий график. Сдвиг 0 является текущим баром.

Вы можете использовать оператор цикла, например for или while, чтобы увеличить параметр Shift и циклически перемещаться по истории графика. Этот цикл for извлекает цену закрытия для каждого из последних десяти баров и выводит ее в журнал:

for(int Count = 0; Count <= 9; Count++) {
double CloseShift = iClose(NULL,0,Count);
Print(Count+" "+CloseShift); 
}

Индикаторы

Большинство торговых систем используют индикаторы для определения торговых сигналов. MetaTrader включает в себя более 20 общих индикаторов, включая скользящее среднее, MACD, RSI и стохастик. Также вы также можете использовать пользовательские индикаторы в своем советнике.

Трендовые индикаторы

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

double iMA(string Symbol, int Timeframe, int MAPeriod, int MAShift, int MAMethod, int MAPrice, int Shift)
  • Symbol — символ графика, к которому применяется скользящая средняя.
  • Timeframe — период времени графика, к которому применяется скользящая средняя.

Каждая индикаторная функция в MQL начинается с этих двух параметров. После этого идут специфичные для индикатора значения. Они соответствуют содержимому вкладки «Параметры» в свойствах индикатора.

  • MAPeriod — период скользящей средней. Почти у каждого индикатора есть хотя бы один параметр периода. Большинство индикаторов рассчитываются с использованием ценового ряда, взятого из предыдущих баров. Например, установка периода в 10 будет означать, что индикатор использует ценовые данные из последних десяти баров для расчета значения индикатора.
  • MAShift — смещение вперед линии скользящей средней, в барах.
  • MAMethod — метод расчета скользящей средней. Выбор включает в себя простой, экспоненциальный, сглаженный или линейный взвешенный.
  • MAPrice — массив цен, используемый при расчете скользящей средней. Это может быть закрытие, открытие, максимум, минимум или некоторый тип среднего; например, средний, типичный или взвешенный.
  • Shift — обратное смещение бара. Параметр Shift является последним параметром в любой индикаторной функции. Это индекс бара, для которого нужно вернуть значение индикатора. Значение 0 возвращает значение индикатора для текущего бара. Значение 3 вернет значение индикатора от 3 баров назад.

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

Вы также можете генерировать торговые сигналы, когда текущая цена находится выше или ниже линии индикатора. Например, индикатор полос Боллинджера может использоваться для генерации торговых сигналов на основе местоположения цены по сравнению с верхней или нижней полосой.

Осцилляторы

Другой основной тип индикатора — это осциллятор. Осцилляторы рисуются в отдельном окне, и, как следует из их названия, они колеблются между минимумами и максимумами цены. Осцилляторы либо центрированы вокруг нейтральной оси (обычно 0), либо они связаны верхним или нижним экстремумами (такими как 0 и 100).

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

Давайте посмотрим на популярный осциллятор стохастик. Стохастик состоит из двух линий: стохастической линии (также называемой линией% K) и сигнальной линии (линия% D). Стохастик колеблется между 0 и 100. Когда стохастик выше 70, говорят, что он находится в состоянии перекупленности и возможен разворот цены. Если он находится ниже 30, говорят, что он перепродан.

double iStochastic(string Symbol, int Timeframe, int KPeriod, int Dperiod, int Slowing, int MAMethod, int PriceField, int Mode, int Shift)

Мы уже знакомы с первыми двумя параметрами, Symbol и Timeframe. Давайте рассмотрим другие параметры индикатора:

  • KPeriod — период для линии K.
  • DPeriod — период для линии D.
  • Slowing — значение замедления для стохастика. Более низкое значение указывает на более быстрый стохастик, а более высокое значение указывает на более медленный.
  • MAMethod — к линии D применяется метод скользящего среднего. Это та же настройка, что и для скользящей средней.
  • PriceField — определяет данные о ценах, используемые для линии K. Это либо 0 либо 1. Значение 1 повышает вероятность того, что стохастик будет торговаться на своих крайних значениях.
  • Mode — определяет стохастическую линию для расчета — линия 1:K или линия 2:D.

Давайте поговорим о параметре Mode. Некоторые индикаторы рисуют несколько линий на графике. Стохастик имеет две линии. Нам потребуется вызвать функцию iStochastic() для линий %K и %D:

double KLine = iStochastic(NULL,0,KPeriod,DPeriod,Slowing,MAMethod,Price,0,0);
double DLine = iStochastic(NULL,0,KPeriod,DPeriod,Slowing,MAMethod,Price,1,0);

Обратите внимание, что параметр Mode равен 0 для линии %K и 1 для линии %D. В справочнике по MQL перечислены допустимые целочисленные константы для различных индикаторов, которые используют параметр Mode.

Вы можете генерировать торговые сигналы на основании отношения между линиями индикатора и определенными уровнями, такими как уровни перекупленности и перепроданности 70 и 30 соответственно. Вы также можете оценить торговые сигналы, основываясь на отношении линий индикатора друг к другу. Например, вы можете открыть ордер на покупку, только когда линия %K будет выше линии %D.

    if(KLine < 70)
    if(KLine > DLine)

Встроенные функции индикатора находятся в справочнике по MQL в разделе «Технические индикаторы».

Пользовательские индикаторы

Сотни пользовательских индикаторов для MetaTrader доступны онлайн. Если вы решите использовать пользовательский индикатор в своем советнике, вам придется немного поработать. Лучше всего, если у вас есть файл исходного кода .mq4 при использовании пользовательского индикатора. Хотя можно использовать пользовательский индикатор и без него, наличие исходного кода облегчит определение индексов буфера для параметра Mode.

MQL имеет встроенную функцию для обработки пользовательских индикаторов — iCustom(). Вот ее синтаксис:

double iCustom(string Symbol, int Timeframe, string IndicatorName, Indicator Parameters,
int Mode, int Shift);

Вы уже знакомы с символами, таймфреймами, режимами и сдвигами, описанными ранее в этой главе Давайте начнем с IndicatorName. Это имя файла индикатора в том виде, в котором оно отображается в списке пользовательских индикаторов в окне навигатора.

Параметры индикатора — это место, куда мы вставляем параметры для пользовательского индикатора. Вкладка «Входные данные» в окне «Свойства пользовательского индикатора» покажет параметры для пользовательского индикатора. Значки слева от каждого параметра будут указывать тип данных. Если у вас нет файла .mq4 для индикатора, вам придется определить параметры индикатора из диалогового окна.

окно настроек индикатора

Более простой способ найти параметры — проверить внешние переменные в начале файла исходного кода индикатора. Здесь будут перечислены все параметры индикатора, их типы данных и значения по умолчанию. Вы можете просто скопировать и вставить этот код в раздел внешних переменных вашего советника.

Каждая внешняя переменная в пользовательском индикаторе должна иметь соответствующий параметр в функции iCustom(), и они должны быть в том порядке, в котором они отображаются в индикаторе. Вы можете использовать константу для параметров, которые не нужно изменять (например, информационные строки или несущественные настройки).

Популярный пользовательский индикатор Slope Direction Line имеет эти внешние переменные, перечисленные в исходном коде. Мы создадим внешние переменные для этих настроек в нашем советнике:

//---- input parameters
extern int period=80; 
extern int method=3; // MODE_SMA
extern int price=0; // PRICE_CLOSE

Мы будем использовать идентификаторы SlopePeriod, SlopeMethod и SlopePrice для внешних переменных.

// Внешние переменные
int SlopePeriod = 80; 
extern int SlopeMethod = 3; 
extern int SlopePrice = 0;

Вот как будет выглядеть функция iCustom() для этого конкретного индикатора вместе с внешними переменными:

iCustom(NULL,0,"Slope Direction Line",SlopePeriod,SlopeMethod,SlopePrice,0,0);

NULL указывает, что мы используем текущий символ графика, а 0 — текущий период графика. «Slope Direction Line» — это имя файла индикатора. SlopePeriod, SlopeMethod и SlopePrice являются тремя параметрами индикатора. Мы используем индекс режима по умолчанию 0, а Shift — это текущий бар.

Хотя индикатор Slope Direction Line нарисован как одна линия, он фактически состоит из двух разных буферов. В зависимости от того, движется ли цена индикатора вверх или вниз, цвет (и буфер) меняются.

Если вы прикрепите индикатор к графику и увидите окно данных в MetaTrader, вы увидите два значения для линии направления наклона. Первое значение отображает цену, когда значение индикатора увеличивается. Линия по умолчанию синяя. Второе значение отображает цену, когда значение индикатора уменьшается. Эта строка по умолчанию красная.

окно с данными

Нам нужно определить индекс режима для обеих этих строк. Самый простой способ сделать это — посмотреть на исходный код. В функции init() вы увидите несколько строк кода, которые используются для объявления и установки свойств индикаторных буферов:

SetIndexBuffer(0, Uptrend); 
SetIndexBuffer(1, Dntrend); 
SetIndexBuffer(2, ExtMapBuffer);
... 
SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,2); 
SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,2);

Первая функция SetIndexBuffer() устанавливает индикаторный буфер с индексом 0 и использует массив Uptrend. По названию массива мы можем догадаться, что это относится к синей индикаторной линии. Вторая функция действует аналогично для массива DnTrend. Обратите внимание на функции SetIndexStyle() внизу, которая устанавливают буферы 0 и 1 для рисования сплошной линии.

Третий буфер с индексом 2 и массивом ExtMapBuffer используется только для расчета. Поэтому мы можем сделать вывод, что 0 и 1 — это буферные индексы, которые содержат информацию о ценах нашего индикатора. На основе идентификаторов массива 0 — это линия восходящего тренда, а 1 — нисходящий тренд. Вот как мы объявляем наши показатели:

double SlopeUp = iCustom(NULL,0,"Slope Direction Line",SlopePeriod,SlopeMethod, SlopePrice,0,1);
double SlopeDown = iCustom(NULL,0,"Slope Direction Line",SlopePeriod,SlopeMethod, SlopePrice,1,1);

Обратите внимание, что для параметра Mode, следующего за последним, был задан соответствующий индекс буфера индикатора — 0 для SlopeUp и 1 для SlopeDown. Параметр Shift был установлен в 1, что проверяет значение закрытия последнего бара.

Это хорошая идея, чтобы дважды проверить, что вы используете правильные параметры режима. Добавьте функцию Print() в свой эксперт и запустите бэк-тест в тестере стратегий, используя в качестве модели тестирования «Только цены открытия». Убедитесь, что для параметра Shift установлено значение 1 в функции iCustom().

Print("Slope Up: "+SlopeUp+", Slope Down: "+SlopeDown+" Time: "+TimeToStr(Time[1]));

Функция Print() выводит значение наших индикаторных буферов в журнал вместе со временем и датой предыдущего бара. Вы можете просмотреть журнал на вкладке Журнал в окне тестера стратегий. Вот пример вывода функции Print() в журнале:

Slope Up: 2147483647.00000000, Slope Down: 1.50483900 Time: 2009.11.26 16:00

Значение для SlopeUp, 2147483647, является очень большим целым числом, которое представляет состояние EMPTY_VALUE пользовательского индикатора. Вы можете фактически использовать его как условие торговли. SlopeDown возвращает значение индикатора предыдущего бара. Время указывает бар, который мы хотим найти на графике.

Нажмите кнопку «Открыть график» в окне «Тестер стратегий», чтобы открыть график с уже примененным индикатором. Найдите строку, указанную в журнале по времени, и убедитесь, что значения индикаторов в окне данных совпадают со значениями, напечатанными в журнале. Если нет, настройте параметр Mode в функции iCustom(), пока не найдете нужный буфер.

Вот как мы будем использовать индикатор Slope Direction Line в нашем советнике. Если уклон имеет тенденцию к росту, SlopeUp вернет значение цены, а SlopeDown вернет EMPTY_VALUE или 2147483647.

if(SlopeUp != EMPTY_VALUE && SlopeDown == EMPTY_VALUE) // Покупка
if(SlopeUp == EMPTY_VALUE && SlopeDown != EMPTY_VALUE) // Продажа

Эти условия проверяют, какая строка равна EMPTY_VALUE, а какая нет.

Таймфреймы

Многие функции в MQL, включая функции индикатора и цены, принимают параметр таймфрейма. Как указывалось ранее, если мы используем параметр Timeframe, равный 0, будет использоваться текущий период графика. Если мы хотим использовать другие временные рамки, нам нужно будет указать временные рамки в минутах. Например, M5 равно 5, H1 равно 60, а H4 равно 240. Мы также можем использовать следующие константы для указания периода времени:

  • PERIOD_M1 – 1 минута.
  • PERIOD_M5 – 5 минут.
  • PERIOD_M15 – 15 минут.
  • PERIOD_M30 – 30 минут.
  • PERIOD_H1 – 1 час (60 минут).
  • PERIOD_H4 – 4 час (240 минут).
  • PERIOD_D1 – 1 день (1440 минут).

Цена

Применяемый параметр индикатора цены указывает ценовой ряд, который будет использоваться при расчете значения индикатора. Обычно вы будете использовать значение close для расчета значений индикатора, хотя вы можете использовать и другие значения. Вот список ценовых рядов и связанных с ними констант, а также целочисленное значение:

  • PRICE_CLOSE — 0: цена закрытия.
  • PRICE_OPEN — 1: цена открытия.
  • PRICE_HIGH — 2: самая высокая цена.
  • PRICE_LOW — 3: самая низкая цена.
  • PRICE_MEDIAN — 4: медианная цена, (максимум + минимум) / 2.
  • PRICE_TYPICAL — 5: типичная цена (High + Low + Close) / 3.
  • PRICE_WEIGHTED — 6: взвешенная цена (High + Low + Close + Close) / 4.

Методы рассчета скользящей средней

Индикаторы, которые используют скользящую среднюю в качестве части своих расчетов, могут иметь параметр для настройки метода расчета скользящей среднй. Линия скользящей средней будет нарисована по-разному в зависимости от метода расчета. Вот константы метода скользящего среднего с соответствующими им целочисленными значениями:

  • MODE_SMA — 0: простая скользящая средняя. Рассчитывает среднее значение ценовых данных.
  • MODE_EMA — 1: экспоненциальная скользящая средняя. Придает больший вес последним данным о ценах и
    экспоненциально меньший вес для более старых ценовых данных.
  • MODE_SMMA — 2: сглаженная скользящяя средняя. Простая скользящяя средняя, рассчитанная по уравнению сглаживания. Создает плавную, но менее отзывчивую линию.
  • MODE_LWMA — 3: линейно взвешенная скользящяя средняя. Похожа на экспоненциальную скользящую среднюю, но придает больший вес текущей цене.

Оценка условий торговли

Мы используем условные операторы, чтобы оценить наши торговые условия.

Оператор if оценивает истинное или ложное условие. Если условие истинно, код выполняется сразу после оператора if. Если условие ложно, оно пропустит код, следующий за блоком if:

if(BuyCondition == true) {
OpenBuyOrder(...); 
}

Если после оператора if есть только один оператор, его можно записать в одну строку:

if(BuyCondition == true) OpenBuyOrder(...);

Несколько операторов должны быть заключены в фигурные скобки.

Оператор else оценивает альтернативное условие при условии, что предыдущий оператор if ложен. Вы можете комбинировать else и if для создания альтернативного условия, которое будет выполняться только в том случае, если оно истинно.

Например, этот код оценивает три условия по порядку. Если один из них верен, будет выполнен только этот блок кода. Если ни один из них не верен, ни один из них не будет выполнен:

if(Condition1 == true) // Выполнить условие 1 
elseif(Condition2==true) // Выполнить условие 2 
elseif(Condition3==true) // Выполнить условие 3

Оператор else может использоваться в конце последовательности if-else, чтобы указать условие, которое будет выполнено по умолчанию, если все остальные операторы ложны. Как указано выше, будет выполнено только одно из условий:

if(Condition1 == true) // Выполнить условие 1 
elseif(Condition2==true) //Выполнить условие 2 
else {
// Выполнить условие 3
}

Если у вас есть несколько операторов if без каких-либо других операторов, каждый из них будет выполнен, если он истинен — не имеет значения, является ли следующий оператор if истинным или ложным:

if(Condition1 == true) // Выполнить условие 1 
if(Condition2 == true) // Выполнить условие 2

Математические операции

Мы начинаем оценивать истинные и ложные условия, сравнивая значения, используя больше, меньше, равно, не равно и так далее.

== — Равно — если x == y, условие выполняется.
> — Больше чем — если x > y, условие истинно.
< - Меньше, чем - если x < y, условие выполняется. >= — Больше или равно — если x >= y, условие выполняется.
<= - Меньше или равно - если x <= y, условие выполняется. != - Не равно - если x != Y, условие выполняется. Обратите внимание, что оператор равенства (==) не совпадает с оператором присваивания (=). Оператор присваивания используется при присваивании значения переменной. Оператор равенства используется для оценки условия истина / ложь. Это распространенная синтаксическая ошибка, которую следует остерегаться. Вы можете сравнивать любые два значения, если они имеют одинаковый тип данных. Вы можете сравнить логическое значение с константами true или false. Вы можете сравнить строковую, целочисленную или двойную переменную с соответствующим значением константы или с другой переменной того же типа.

Логические операторы

Мы используем логические операторы И (&&) и ИЛИ (||) для объединения операций отношения. Оператор И оценивает, все ли условия выполняются. Если так, то все утверждение верно. Если любое из условий ложно, все утверждение ложно.

if(BooleanVar1 == true && Indicator1 > Indicator2) {
        // Открыть ордер
      }

Если BooleanVar1 равно true, а Indicator1 больше, чем Indicator2, оператор оценивается как true, и выполняется код между фигурными скобками. Если какое-либо из этих условий ложно, весь оператор оценивается как ложный, и код в фигурных скобках не выполняется. Может быть проверено любое количество условий, объединенных вместе с оператором &&, и все они должны иметь значение true.

Оператор ИЛИ оценивает, выполняется ли какое-либо из условий. Если хотя бы одно условие является истинным, весь оператор оценивается как истинный. Если все условия ложны, утверждение оценивается как ложное.

if(BooleanVar1 == true || Indicator1 > Indicator2)

Если BooleanVar1 равен true или Indicator1 больше, чем Indicator2, оператор оценивается как true. Если оба эти условия ложны, утверждение оценивается как ложное.

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

if((BooleanVar1 == true && Indicator1 > Indicator2) || BooleanVar1 == false)

Оператор (BooleanVar1 == true && Indicator1> Indicator2) вычисляется первым. Если оба эти условия верны, оператор оценивается как истина, и у нас остается операция ИЛИ:

if(true || BooleanVar1 == false)

Это утверждение автоматически оценивается как истинное, поскольку одно из условий уже выполнено. Но что если (BooleanVar1 == true && Indicator1> Indicator2) оценивается как ложное?

if(false || BooleanVar1 == false)

Если условие BooleanVar1 == false оценивается как истинное, тогда весь оператор является истинным.

Включение и выключение индикатора

Вы можете использовать И / ИЛИ для включения и выключения индикатора. Допустим, ваш советник использует несколько индикаторов, и вы хотели бы иметь возможность включать и выключать индикаторы. Вот как мы это делаем. Сначала давайте объявим внешнюю логическую переменную для использования в качестве переключателя вкл / выкл. Мы будем использовать индикатор стохастик в этом примере:

extern bool UseStochastic = true;

Мы определяем два набора условий для нашего индикатора — состояние «включено» и «выключено». Состояние on состоит из переменной on / off, установленной в true, вместе с условием открытия ордера. Состояние off состоит из переменной on / off, установленной в false.

if((UseStochastic == true && Kline > Dline) || UseStochastic == false) {
// Ордер на покупку
 }

Оператор (UseStochastic == true && Kline> Dline) является нашим состоянием «включено». Если для внешней переменной UseStochastic установлено значение true, а условие торговли Kline> Dline равно true, тогда условие стохастического ордера будет истинным.

UseStochastic == false — это наше состояние «выключено». Если для внешней переменной UseStochastic установлено значение false, то (UseStochastic == true && Kline> Dline) оценивается как false, а UseStochastic == false оценивается как true.

Поскольку состояния «включено» и «выключено» связаны оператором ИЛИ, только одно из них должно быть истинным, чтобы все утверждение было истинным.

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

if(((UseStochastic == true && Kline > Dline) || UseStochastic == false) && FastMA > SlowMA)

В этом примере мы добавили условие пересечения скользящей средней, FastMA > SlowMA. Обратите внимание, что мы добавили еще один набор скобок вокруг стохастического условия, поскольку весь оператор в скобках должен быть оценен в первую очередь.

Сначала мы оцениваем оператор внутри самого внутреннего набора скобок: (UseStochastic == true && Kline> Dline). Если для параметра UseStochastic установлено значение true, а Kline > Dline оценивается как true, первая часть оператора будет истинной.

if((true || UseStochastic == false) && FastMA > SlowMA)

Условие UseStochastic == false оценивается как ложное. Нам остается операция ИЛИ, и поскольку одно из условий уже выполнено, все условие оценивается как истинное:

    if((true || false) && FastMA > SlowMA)
    if(true && FastMA > SlowMA)

Если FastMA > SlowMA оценивается как true, все условия торговли равны true, и ордер размещается. Если это ложь, оператор оценивается как ложный, и заказ не размещается.

Что произойдет, если условие стохастической торговли ложно? Если UseStochastic установлен в true, а Kline> Dline оценивается как false, все условие становится ложным:

if((false || UseStochastic == false) && FastMA > SlowMA) 
 
if((false || false) && FastMA > SlowMA)
 
if(false && FastMA > SlowMA)

Независимо от того, как FastMA> SlowMA оценивает, все условие сделки ложно.

Допустим, что для UseStochastic установлено значение false. В этом случае оператор (UseStochastic == true && Kline> Dline) оценивается как ложное:

if((false || UseStochastic == false) && FastMA > SlowMA)

Поскольку оператор UseStochastic == false имеет значение true, условие оценивается как true.

if((false || true) && FastMA > SlowMA)
if(true && FastMA > SlowMA)

Это означает, что если FastMA > SlowMA также оценивается как true, ордер будет размещен. В этом случае стохастическое условие даже не рассматривалось, за исключением оценки состояния индикатора.

Сравнение значений индикаторов

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

Мы используем параметр Shift индикаторной функции, чтобы определить, для какого бара вернуть значение индикатора. Параметр Shift всегда является последним параметром в функции индикатора. Текущий бар имеет смещение 0, предыдущий бар имеет смещение 1 и так далее. Функции скользящего среднего ниже приведут значение скользящего среднего для текущего и предыдущего бара:

double MA = iMA(NULL,0,MAPeriod,0,MAMethod,MAPrice,0); 
double LastMA = iMA(NULL,0,MAPeriod,0,MAMethod,MAPrice,1);

В этом примере MA — это переменная, которая содержит значение индикатора текущего бара, а LastMA содержит значение индикатора предыдущего бара. Обратите внимание, что параметр Shift равен 0 для текущего бара и 1 для предыдущего бара.

Вот код для определения, движется ли линия скользящего среднего вверх или вниз:

    if(MA > LastMA)
      {
        // MA движется вверх
      }
    else if(MA < LastMA)
      {
        // MA движется вниз
      }

Если значение индикатора текущего бара (MA) больше, чем значение предыдущего бара (LastMA), мы можем заключить, что индикатор движется вверх. Обратное верно, когда значение индикатора текущего бара меньше значения индикатора предыдущего бара.

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

Например, скажем, ваша торговая система дает торговый сигнал, когда стохастик проходит выше 30 или ниже 70. Вот код, чтобы проверить это:

double Stoch = iStochastic(NULL,0,KPeriod,DPeriod,Slowing,MAMethod,Price,0,0); 
double LastStoch = iStochastic(NULL,0,KPeriod,DPeriod,Slowing,MAMethod,Price,0,1);
    if(Stoch > 30 && LastStoch < 30)
      {
        // Открыть ордер на покупку
      }
    if(Stoch < 70 && LastStoch > 70)
      {
        // Открыть ордер на продажу
      }

Stoch — значение индикатора текущего бара, а LastStoch — значение индикатора предыдущего бара. Если Stoch больше 30, а LastStoch меньше 30, мы можем заключить, что индикатор пересек уровень выше уровня перепроданности на последнем баре. Меняя операторы сравнения, мы можем проверить недавний кросс ниже постоянного значения, такого как уровень перекупленности 70.

Вот еще один пример использования скользящих средних. Мы создадим условие для открытия ордера, только когда FastMA и SlowMA пересеклись в последнем баре:

double FastMA = iMA(NULL,0,FastMAPeriod,0,0,0,0);
double SlowMA = iMA(NULL,0,SlowMAPeriod,0,0,0,0);
 
double LastFastMA = iMA(NULL,0,FastMAPeriod,0,0,0,1);
double LastSlowMA = iMA(NULL,0,SlowMAPeriod,0,0,0,1);
 
if(FastMA > SlowMA && LastFastMA <= LastSlowMA && BuyMarketCount(Symbol(),MagicNumber) == 0) {
        // Ордер на покупку
      }
if(FastMA < SlowMA && LastFastMA >= LastSlowMA && SellMarketCount(Symbol(),MagicNumber) == 0) {
        // Ордер на продажу
      }

В этом примере мы сравниваем отношение двух индикаторов друг к другу. LastFastMA и LastSlowMA возвращают значения скользящей средней для предыдущего бара. Если LastFastMA меньше или равна LastSlowMA, а FastMA в настоящее время больше, чем SlowMA, то мы знаем, что линия быстрого скользящего среднего пересекла линию медленного скользящего среднего в последнем баре.

Это обеспечивает более надежный торговый сигнал, поскольку мы можем ограничить размещение нашего ордера сразу после пересечения. Вы можете изменить значение Shift для функций LastFastMA и LastSlowMA, если вы хотите увеличить количество баров, чтобы оглянуться назад при поиске пересечения индикатора.

Мы добавили сравнение LastFastMA и LastSlowMA в условия заказа на покупку и продажу в нашем советнике. Теперь мы можем удалить чек BuyTicket и SellTicket, поскольку этот метод более надежен, чем проверка сохраненного номера тикета ордера.