Рассчитываем стоп–лосс, тейк–профит и проскальзывание на MQL4

Есть несколько способов расчета цены для стоп-лосcа и тейк-профита. Самый распространенный — указать количество пунктов от цены открытия ордера. Также мы можем использовать значение индикатора, внешний параметр или использовать какой-либо другой тип расчета цены.

Расчет стоп-лосса и тейк-профита в пунктах

Для расчета стоп-лосса и тейк-профита в пунктах мы можем использовать внешнюю переменную.

extern int StopLoss = 50;
extern int TakeProfit = 100;

В этом примере мы установили размер стоп-лосса равным 50 пунктов и тейк-профита равным 100 пунктам.

Чтобы рассчитать стоп-лосс, нам нужно добавить или вычесть 50 пунктов от цены открытия нашего ордера. Для этого нам нужно преобразовать целое значение 50 в дробное значение, которое мы будем использовать для добавления или вычитания от цены открытия. Для пар с йеной 50 пунктов будет равно 0,50. Для всех остальных пар это значение будет 0,0050.

Чтобы преобразовать целое число в соответствующее дробное значение, нам нужно умножить нашу внешнюю переменную StopLoss на предопределенную переменную Point.

Point — это предопределенная переменная в MQL4, которая возвращает наименьшую единицу цены торгового инструмента в зависимости от количества десятичных знаков. Для валютной пары с 4 десятичными знаками Point равен 0,0001. Для пары с йеной Point будет равен 0,01.

Давайте рассчитаем значение стоп-лосса для ордера на покупку. Мы назначим текущую цену Ask для переменной OpenPrice и будем использовать ее в качестве цены открытия ордера. Далее умножим StopLoss на Point и вычтем полученное значение из OpenPrice. Результат будет сохранен в переменную BuyStopLoss.

double OpenPrice = Ask;
double BuyStopLoss = OpenPrice – (StopLoss * Point);
// К примеру, 1.4600 - (50 * 0.0001) = 1.4550.

Для пятизначных котировок размер Point будет равен 0,00001. Если мы будем использовать значение пункта 0,00001 в нашем примере расчета стоп-лосса, стоп-лосс будет рассчитываться как 5 пунктов от цены открытия, а не 50 пунктов. Чтобы получить правильное значение, мы должны добавить дополнительный ноль к нашему стоп-лоссу, то есть StopLoss = 500.

Создадим функцию PipPoint, которая всегда будет возвращать 0,01 или 0,0001.

Нам понадобится функция MarketInfo(), которая возвращает различную информацию о финансовых инструментах. Вот ее синтаксис:

double  MarketInfo(
   string           symbol,     // символ инструмента
   int              type        // тип информации
   );
  • symbol — символ торгового инструмента. Для текущего символа графика можно использовать функцию Symbol(). Для других символов вам нужно указать символ, например, EURJPY.
  • type — целочисленная константа, которая представляет собой информацию, запрашиваемую у функции. Полный список констант можно найти в справочнике по MQL4.
double PipPoint (string Currency)
{
int CalcDigits = MarketInfo (Currency,MODE_DIGITS); 
if(CalcDigits == 2 || CalcDigits == 3) double CalcPoint = 0.01; 
else if(CalcDigits == 4 || CalcDigits == 5) CalcPoint = 0.0001;
return(CalcPoint);
}

Функция MarketInfo() с параметром MODE_DIGITS возвращает количество десятичных цифр для данной валютной пары. Оператор if-else назначает соответствующее значение переменной CalcPoint в зависимости от количества цифр.

Вот пример использования этой функции:

double UsePoint = PipPoint(EURUSD);
// Result is 0.0001
double UsePoint = PipPoint(USDJPY);
// Result is 0.01

Расчет проскальзывания

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

int GetSlippage(string Currency, int SlippagePips)
      {
int CalcDigits = MarketInfo(Currency,MODE_DIGITS);
if(CalcDigits == 2 || CalcDigits == 4) double CalcSlippage = SlippagePips;
else if(CalcDigits == 3 || CalcDigits == 5) CalcSlippage = SlippagePips * 10; return(CalcSlippage);
}

Мы передаем символ валюты и параметр внешнего проскальзывания в качестве аргументов. Если валюта использует 2 или 4 цифры, мы используем неизмененный аргумент SlippagePips в качестве параметра проскальзывания. Если валюта использует 3 или 5 цифр, мы умножаем SlippagePips на 10. Вот как мы используем эту функцию в OrderSend():

    extern int Slippage = 5;
    OrderSend(Symbol(),OP_BUY,LotSize,Ask,GetSlippage(Symbol(),Slippage),BuyStopLoss, BuyTakeProfit,"Buy Ордер",MagicNumber,0,Green);

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

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

 // Глобальные переменные.
    double UsePoint;
    int UseSlippage;
int init() {
        UsePoint = PipPoint(Symbol());
        UseSlippage = GetSlippage(Symbol(),Slippage);
      }

Рассчитываем стоп-лосс

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

Вот наш предыдущий расчет стоп-лосса для ордера на покупку с добавленной переменной UsePoint. Обратите внимание, что мы присвоили цену Ask переменной OpenPrice:

double OpenPrice = Ask;
double BuyStopLoss = OpenPrice – (StopLoss * UsePoint);

А вот и расчет для ордера на продажу:

double OpenPrice = Bid;
double SellStopLoss = OpenPrice + (StopLoss * UsePoint);

Для отложенных ордеров стоп-лосс будет рассчитываться относительно цены отложенного ордера.

Рассчитываем тейк-профит

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

double BuyTakeProfit = OpenPrice + (TakeProfit * UsePoint);
double SellTakeProfit = OpenPrice - (TakeProfit * UsePoint);

Альтернативный метод расчета стоп-лосса

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

Допустим, мы используем торговую систему, которая размещает стоп-лосс на 2 пункта ниже минимума текущего бара. Мы используем предопределенный ценовой массив Low[], чтобы получить минимум бара. Low[0] — минимум текущего бара, Low [1] — минимум предыдущего бара и т. д.

Как только мы определили минимум текущего бара, мы умножим 2 на UsePoint, чтобы получить десятичное значение, далее вычтем его из нашего минимума:

double BuyStopLoss = Low [0] - (2 * UsePoint);

Таким образом, если минимум бара составляет 1,4760, стоп-лосс будет размещен на 1,4758.

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

Вот пример того, как мы можем использовать функцию iLowest() для поиска самого низкого минимума последних 10 баров. Разберем эту функцию:

int  iLowest(
   string           symbol,          // символ
   int              timeframe,       // период
   int              type,            // идентификатор таймсерии
   int              count,           // число элементов
   int              start            // индекс
  );
  • symbol — торговый инструмент. NULL означает, что мы используем текущий символ.
  • timeframe — период графика. 0 относится к текущему периоду.
  • type — идентификатор таймсерии, который может принимать значения: MODE_OPEN, MODE_LOW, MODE_HIGH, MODE_CLOSE.
  • count — это количество баров, которые мы хотим использовать.
  • start — это индекс. 0 означает текущий бар. Предыдущий бар равен 1, бар до этого — 2 и т. д.

Результат работы функции iLowest() представляют собой целое число, которое указывает наименьшее найденное значение.

Наш пример может быть следующим:

    int CountBars = 10;
    int LowestShift = iLowest (NULL, 0, MODE_LOW, CountBars, 0);
    double BuyStopLoss = Low [LowestShift];

Если вы хотите рассчитать стоп-лосс для ордера на продажу, мы можем использовать функцию iHighest(), которая работает точно так же.

Допустим, у нас есть скользящая средняя, и мы хотим использовать линию скользящего среднего для постановки стоп-лосса. Мы можем использовать переменную MA для получения значения скользящей средней текущего бара. Все, что вам нужно сделать, это присвоить текущее значение скользящей средней стоп-лоссу:

     double BuyStopLoss = MA;

Если линия скользящего среднего в настоящее время находится на уровне 1.6894, это и будет наш стоп-лосс.