Стратегия форекс на дневных графиках

Эксперт на дневных графиках

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

Реализации подлежит простая стратегия на дневном тайм-фрейме. На график устанавливаются две простые скользящие средние с периодом 5 по ценам LOW и HIGH. Получаем своеобразный канал. Сделка на покупку открывается когда последняя свеча открывается ниже нижней линии и закрывается внутри канала. Сделка на продажу открывается когда последняя свеча открывается выше верхней линии и закрывается внутри канала. Стоп-лосс для сделок на покупку устанавливается на 25 пунктов ниже цены LOW последних 2-х свечей, на продажу — выше HIGH последних 2-х свечей. Тейк-профит устанавливаем в 4 раза больше чем стоп-лосс. Если цена проходит расстояние больше 1,5 стоп-лосс, то сделка переводится в безубыток и траллится на уровне 100 пунктов.

 

Daily BUY

Пример сделки на покупку

Daily SELL

Пример сделки на продажу

Для реализации используем опубликованный ранее шаблон советников, слегка поправив условия открытия позиций. У меня это заняло не более 15 минут. Ниже отчет о прогоне полученного советника в тестере стратегий. Это, кстати, пример, когда грамотное управление капиталом позволяет получать прибыль даже в случае низкого процента прибыльных сделок. Итак, имея всего 42% прибыльных сделок мы получаем фактор прибыльности 1.6 и максимальную просадку около 13%

Daily Repport

Отчет о прогоне советника

Ну и, наконец, код советника. Здесь изменены функции Signal_Buy() и Signal_Sell() в плане условий проверки сигналов и возвращения уровня стоп-лосс, функция CheckForOpen() в плане установки SL и TP, из функции OnTick() удалена проверка времени начала-окончания, т.к. мы работаем по дням.

#property copyright "Copyright 2015, SergDeev"
#property description "EA Moving Average High-Low"
#property link      "http://fx-prog.ru"
#property version   "1.0"
#property strict

extern double startLot = 0.2,MaxRisk = 2,noLoss_factor = 1.5,takeProfit_factor = 4;
extern int stopLoss_shift = 25,trailStop = 100,trailStep = 5;
extern int ma_period = 5;
extern ENUM_MA_METHOD ma_method = MODE_SMA;
extern int slippage = 5, MAGIC = 20161210;

int OnInit() { // функция инициализации
 if (Digits == 5) { // пересчет параметров сопровождения для 5-знака
  trailStop *= 10; trailStep *= 10; slippage *= 10; stopLoss_shift *= 10;
 }
 return(INIT_SUCCEEDED);
}
double NormalizeLots(double v) { // функция нормализации объема торговли
 double max_lot = MarketInfo(Symbol(),MODE_MAXLOT);
 double min_lot = MarketInfo(Symbol(),MODE_MINLOT);
 double lot_step = MarketInfo(Symbol(),MODE_LOTSTEP);
 double x = NormalizeDouble((v/lot_step),0) * lot_step;
 if (v > max_lot) v = max_lot;
 if (x < min_lot) x = min_lot;
 return(x);
}

bool Signal_Buy(double &x) { // формирование сигнала на покупку
 if (Close[1] > Open[1])
 if (Open[1] < iMA(NULL,0,ma_period,0,ma_method,PRICE_LOW,1))
 if (Close[1] > iMA(NULL,0,ma_period,0,ma_method,PRICE_LOW,1))
 if (High[1] < iMA(NULL,0,ma_period,0,ma_method,PRICE_HIGH,1))
 {
  x = Low[iLowest(NULL,0,MODE_LOW,3)];
  return(true);
 }
 return(false);
}

bool Signal_Sell(double &x) { // формирование сигнала на продажу
 if (Close[1] < Open[1])
 if (Open[1] > iMA(NULL,0,ma_period,0,ma_method,PRICE_HIGH,1))
 if (Close[1] < iMA(NULL,0,ma_period,0,ma_method,PRICE_HIGH,1))
 if (Low[1] > iMA(NULL,0,ma_period,0,ma_method,PRICE_LOW,1))
 {
  x = High[iHighest(NULL,0,MODE_HIGH,3)];
  return(true);
 }
 return(false);
}

void CheckForOpen(int mode) { // проверка сигналов открытия сделок
   double SL,TP,lot,x;
   if (Volume[0] > 1) return; // выполняется только на открытии нового бара
   if (mode==OP_BUY && Signal_Buy(x)) { // покупка
    TP = 0; SL = x - stopLoss_shift * Point;
    if (takeProfit_factor > 0) TP = Bid + takeProfit_factor * (Bid-SL);
    if (SL != 0 && (Bid-SL)/Point < MarketInfo(NULL,MODE_STOPLEVEL)) SL = Bid - 1.1 * MarketInfo(NULL,MODE_STOPLEVEL) * Point;
    if (TP != 0 && (TP-Ask)/Point < MarketInfo(NULL,MODE_STOPLEVEL)) TP = Ask + 1.1 * MarketInfo(NULL,MODE_STOPLEVEL) * Point;
    if ((MaxRisk > 0) && (SL != 0)) lot = (AccountFreeMargin()*MaxRisk/100)/((Ask-SL)/Point*MarketInfo(Symbol(),MODE_TICKVALUE));
    else lot = startLot;
    if (AccountFreeMargin()<lot*MarketInfo(NULL,MODE_MARGINREQUIRED)) Print("No FreeMargin");
    else {
      if (OrderSend(Symbol(),OP_BUY,NormalizeLots(lot),Ask,slippage,NormalizeDouble(SL,Digits),NormalizeDouble(TP,Digits),MQLInfoString(MQL_PROGRAM_NAME),MAGIC,0,Blue)==-1)
      Print(__FUNCTION__," BUY_ORDER_SEND Ask:",Ask," SL:",SL," TP:",TP," lot:",lot,_LastError);
    }
   }
   if (mode==OP_SELL && Signal_Sell(x)) { // продажа
    TP = 0; SL =  SL = x + stopLoss_shift * Point;
    if (takeProfit_factor > 0) TP = Ask - takeProfit_factor * (SL-Ask);
    if (SL != 0 && (SL-Ask)/Point < MarketInfo(NULL,MODE_STOPLEVEL)) SL = Ask + 1.1 * MarketInfo(NULL,MODE_STOPLEVEL) * Point;
    if (TP != 0 && (Bid-TP)/Point < MarketInfo(NULL,MODE_STOPLEVEL)) TP = Bid - 1.1 * MarketInfo(NULL,MODE_STOPLEVEL) * Point;
    if ((MaxRisk > 0) && (SL != 0)) lot = (AccountFreeMargin()*MaxRisk/100)/((SL-Bid)/Point*MarketInfo(Symbol(),MODE_TICKVALUE));
    else lot = startLot;
    if (AccountFreeMargin()<lot*MarketInfo(NULL,MODE_MARGINREQUIRED)) Print("No FreeMargin");
    else {
     if (OrderSend(Symbol(),OP_SELL,NormalizeLots(lot),Bid,slippage,NormalizeDouble(SL,Digits),NormalizeDouble(TP,Digits),MQLInfoString(MQL_PROGRAM_NAME),MAGIC,0,Red)==-1)
     Print(__FUNCTION__," SELL_ORDER_SEND Bid:",Bid," SL:",SL," TP:",TP," lot:",lot," ",_LastError);
    }
   }
}

//+------------------------------------------------------------------+
void CheckForClose() { // сопровождение сделок
   double SL,x;
   
   for(int i=0;i<OrdersTotal();i++) { // цикл по всем ордерам терминала
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if ((OrderMagicNumber() != MAGIC) || (OrderSymbol() != Symbol())) continue;
      if (OrderType()==OP_BUY) { // ордер на покупку
        if (OrderStopLoss()<OrderOpenPrice() && noLoss_factor > 0) { // перевод в безубыток
         x = OrderOpenPrice() + noLoss_factor * (OrderOpenPrice()-OrderStopLoss());
         if (Ask > x) {
          SL = OrderOpenPrice() + MarketInfo(NULL,MODE_SPREAD)*Point;
          SL = NormalizeDouble(SL,Digits);
          if (!OrderModify(OrderTicket(),OrderOpenPrice(),SL,OrderTakeProfit(),0)) Print(__FUNCTION__," BUY_NOLOSS_ERROR SL:",SL," ",_LastError);
         }
        }
        if (OrderStopLoss() > OrderOpenPrice() && trailStop > 0) { // трейлинг-стоп
         SL = NormalizeDouble((Bid-trailStop*Point),Digits);
         if (((SL-OrderStopLoss())/Point) > trailStep) {
          if (!OrderModify(OrderTicket(),OrderOpenPrice(),SL,OrderTakeProfit(),0)) Print(__FUNCTION__," BUY_TRAIL_STOP_ERROR SL:",SL," ",_LastError);
          else continue;
         }
        }
      }
      if (OrderType()==OP_SELL) { // ордер на продажу
        if (OrderStopLoss() > OrderOpenPrice() && noLoss_factor > 0) { // перевод в безубыток
         x = OrderOpenPrice() - noLoss_factor * (OrderStopLoss()-OrderOpenPrice());
         if (Bid < x) {
          SL = OrderOpenPrice() - MarketInfo(NULL,MODE_SPREAD)*Point;
          SL = NormalizeDouble(SL,Digits);
          if (!OrderModify(OrderTicket(),OrderOpenPrice(),SL,OrderTakeProfit(),0,clrRed)) Print(__FUNCTION__," SELL_NOLOSS_ERROR SL:",SL," ",_LastError);
         }
        }
        if (OrderStopLoss() < OrderOpenPrice() && trailStop > 0) { // трейлинг-стоп
         SL = NormalizeDouble((Ask+trailStop*Point),Digits);
         if (((OrderStopLoss()-SL)/Point) > trailStep) {
          if (!OrderModify(OrderTicket(),OrderOpenPrice(),SL,OrderTakeProfit(),0,clrRed)) Print(__FUNCTION__," BUY_TRAIL_STOP_ERROR SL:",SL," ",_LastError);
          else continue;
         }
        }
      }
   }
}

int CalculateCurrentOrders(int mode) { // подсчет открытых ордеров
   int num=0;
   for(int i=0;i<OrdersTotal();i++) {
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if (OrderMagicNumber() == MAGIC)
      if (OrderSymbol() == Symbol())
      if ((OrderType()==mode) || (mode==-1)) num++;
     }
   return(num);
}

void OnTick() { // выполняется на каждом тике
   if(Bars<100 || IsTradeAllowed()==false) return;
   if (CalculateCurrentOrders(OP_BUY) == 0) CheckForOpen(OP_BUY); // проверка открытия BUY
   if (CalculateCurrentOrders(OP_SELL) == 0) CheckForOpen(OP_SELL); // проверка открытия SELL
   if (CalculateCurrentOrders(-1) > 0) CheckForClose(); // сопровождение сделок
   Comment("\nProfit :",DoubleToString((AccountEquity()-AccountBalance()),2), // вывод сводной информации
           "\nAccountBalance: ",DoubleToString(AccountBalance(),2),
           "\nAccountEquity: ",DoubleToString(AccountEquity(),2),
           "\nAccountMargin: ",DoubleToString(AccountMargin(),2),
           "\nAccountFreeMargin: ",DoubleToString(AccountFreeMargin(),2),
           "\nMargeenLevel: ",DoubleToString(AccountInfoDouble(ACCOUNT_MARGIN_LEVEL),2));
  }

 

Вы можете оставить комментарий, или ссылку на Ваш сайт.

Оставить комментарий

Вы должны быть авторизованы, чтобы разместить комментарий.