Советники: TrailingStopAndTake

 

TrailingStopAndTake:

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

Работает только на счетах с хеджингом.

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

Имеется возможность задать тип позиции - любая/покупка/продажа, символ позиции (любой или указанный), магик (любой или указанный) или тикет позиции (любой или указанный). Также возможно указать режим трейлинга в убыточной зоне - если режим не задан, то стоп-приказы не будут подтягиваться в зоне убытка. Размер безубытка можно указать в настройках.

Для проверки работы трейлинга во всех режимах, в советник добавлено открытие позиций на каждом новом баре. Открытие позиций работает только в тестере стратегий.
При выставлении стоп лосса или тейк профита (а так же отложенных ордеров) существует минимально разрешенная дистанция установки стоп-приказов - StopLevel. Т.е., стоп лосс или тейк профит (или отложенный ордер) должны быть выставлены не ближе этой дистанции к цене. Если же StopLevel задан нулевым, то, в основном, это не говорит об его отсутствии, а говорит о том, что StopLevel плавающий. В этом случае минимальной дистанцией чаще всего является спред*2, но иногда двойного спреда не достаточно. Поэтому и введен параметр - число, на которое советник будет умножать спред для расчета минимальной дистанции установки стопов.

Рис.1 Начальный StopLoss 600, начальный TakeProfit 1200, размер TrailingStop 300, трейлинг тейк профит отключен, в убыточной зоне не подтягивает.


Автор: Scriptor

 
//+------------------------------------------------------------------+
//| Возвращает корректный StopLoss относительно StopLevel            |
//+------------------------------------------------------------------+
double CorrectStopLoss(const string symbol_name,const ENUM_POSITION_TYPE position_type,const int stop_loss) {
   if(stop_loss==0) return 0;
   double pt=SymbolInfoDouble(symbol_name,SYMBOL_POINT);
   if(pt==0) return 0;
   double price=(position_type==POSITION_TYPE_BUY ? SymbolInfoDouble(symbol_name,SYMBOL_ASK) : SymbolInfoDouble(symbol_name,SYMBOL_BID));
   int lv=StopLevel(symbol_name),dg=(int)SymbolInfoInteger(symbol_name,SYMBOL_DIGITS);
   return
     (position_type==POSITION_TYPE_BUY ?
      NormalizeDouble(::fmin(price-lv*pt,price-stop_loss*pt),dg) :
      NormalizeDouble(::fmax(price+lv*pt,price+stop_loss*pt),dg)
     );
}
//+------------------------------------------------------------------+
//| Прверяет StopLoss на корректность относительно StopLevel         |
//+------------------------------------------------------------------+
bool CheckCorrectStopLoss(const string symbol_name,const ENUM_POSITION_TYPE position_type,const double stop_loss)
  {
   if(stop_loss==0) return true;
   double pt=SymbolInfoDouble(symbol_name,SYMBOL_POINT);
   if(pt==0) return false;
   double price=(position_type==POSITION_TYPE_BUY ? SymbolInfoDouble(symbol_name,SYMBOL_ASK) : SymbolInfoDouble(symbol_name,SYMBOL_BID));
   int lv=StopLevel(symbol_name),dg=(int)SymbolInfoInteger(symbol_name,SYMBOL_DIGITS);
   return
     (
      position_type==POSITION_TYPE_BUY ? 
      NormalizeDouble(stop_loss-price-lv*pt,dg)<0 :
      NormalizeDouble(stop_loss-price+lv*pt,dg)>0
     );
  }

Выделены ошибки.

 
fxsaber:

Выделены ошибки.

   double price=(position_type==POSITION_TYPE_BUY ? SymbolInfoDouble(symbol_name,SYMBOL_ASK) : SymbolInfoDouble(symbol_name,SYMBOL_BID));
   int lv=StopLevel(symbol_name),dg=(int)SymbolInfoInteger(symbol_name,SYMBOL_DIGITS);
   return
     (position_type==POSITION_TYPE_BUY ?
      NormalizeDouble(::fmin(price-lv*pt,price-stop_loss*pt),dg) :
      NormalizeDouble(::fmax(price+lv*pt,price+stop_loss*pt),dg)
     );

В чём ошибка?

 
Artyom Trishkin:

В чём ошибка?

Цена неверная используется.

 
fxsaber:

Цена неверная используется.

Обоснуйте.
 
Artyom Trishkin:
Обоснуйте.
OrderSend(_Symbol, OP_BUY, 1, Ask, 100, 0, Bid);

Сработает при StopLevel == 0.

 

Отличная работа! Спасибо большое!