Помощь написание советник!

 
Здравствуйте уважаемые форумчане!
Хочу написать советник, как и все начинающие пробую с простого для изучения взял стратегию основанную на индикаторе ВВ с добавлением различных фильтров таких как MACD, ATR, Stoch.

Стратегию входов и выходов по индикаторам:
Открытие позиции на продажу: Цена касается или пробивает верхнюю полосу Bollinger. Далее проверяет показания индикатора Stoch, если он находится в зоне перекупленности (80), когда линия нижней границы пересекает и входит в рынок на открытие следующей свечи. Остальные индикаторы MACD, ATR, реализовать их в стратегию.

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

 


Файлы:
Origenal.mq4  16 kb
 

И сразу учимся писать в новом стиле, для более легкого перехода на язык MQL5

 

//+------------------------------------------------------------------+
//|               МОДИФИКАЦИИ И ОБНОВЛЕНИЕ СОВЕТНИКА                 |
//+------------------------------------------------------------------+
//|07.01.17 Sergey Gritsay                                           |
//|https://www.mql5.com/ru/users/sergey1294                          |
//|1. Модификация скрипта советника, доп. параметры: SL, TP, CS, SP  |
//|                                                                  |
//|                                                                  |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Origenal"
#property link      ""
#property version   "1.00"
#property strict
//===========================================================================
sinput string s1                   = "Параметры TP / SL"; /* земенил тип переменной extern на sinput*/
input int             StopLoss     = 300;        // Стоп Лосс (Пипс)
input int             TakeProfit   = 500;        // Тейк Профит (Пипс)
input int             Slippage     = 10;         // Проскальзование (Пипс)
//===========================================================================
sinput string s2                   = "Параметры объема лота"; /* земенил тип переменной extern на sinput*/
input double          Lot          = 0.01;       // Объем лота
//===========================================================================
sinput string s3                   = "Параметры индикаторов"; /* земенил тип переменной extern на sinput*/
input bool            CloseSignal  = false;     // закрытие по сигналу ( false - выкл, true - вкл)
input int             BBPeriod     = 20;         // Период ВВ
input double          BBDev        = 2.0;        // Отклонение ВВ
input int             MAPeriod     = 20;         // Период МА
input ENUM_TIMEFRAMES TimeFrameMA  = PERIOD_D1;  // Тайм Фрейм МА
//===========================================================================
sinput string s4                   = "Параметры Magic / Coment"; /* земенил тип переменной extern на sinput*/
input int             MagicNumber  = 20110315;   // Номер копии
input string          CommentOrder = "Origenal"; // Комментарий к ордеру
//===========================================================================

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   if(TotalOrder()==0)OrderOpen(GetSignalOpen());
   else
     {
      ModifySL(StopLoss);
      ModifyTP(TakeProfit);
      if(CloseSignal)OrderClose(GetSignalClose());
     }
  }
//+------------------------------------------------------------------+
int GetSignalOpen()
  {
   double bbh=iBands(NULL,0,BBPeriod,BBDev,0,PRICE_CLOSE,MODE_UPPER,0);
   double bbl=iBands(NULL,0,BBPeriod,BBDev,0,PRICE_CLOSE,MODE_LOWER,0);
   double ma=iMA(NULL,TimeFrameMA,MAPeriod,0,MODE_SMA,PRICE_CLOSE,0);
   double ma1=iMA(NULL,TimeFrameMA,MAPeriod,0,MODE_SMA,PRICE_CLOSE,1);

   if(Ask<bbl && ma>ma1) return(OP_BUY);
   if(Bid>bbh && ma<ma1) return(OP_SELL);
   return(WRONG_VALUE);
  }
//+------------------------------------------------------------------+
int GetSignalClose()
  {
   double bbh=iBands(NULL,0,BBPeriod,BBDev,0,PRICE_CLOSE,MODE_UPPER,0);
   double bbl=iBands(NULL,0,BBPeriod,BBDev,0,PRICE_CLOSE,MODE_LOWER,0);

   if(Bid>bbh)return(OP_BUY);
   if(Ask<bbl)return(OP_SELL);
   return(WRONG_VALUE);
  }
//+------------------------------------------------------------------+
void OrderOpen(int type)
  {
   double price_open=0.0;
   if(type==WRONG_VALUE)return;
   if(!IsTradeAllowed())return;

   if(type==OP_BUY)price_open = NormalizeDouble(Ask,_Digits);
   if(type==OP_SELL)price_open = NormalizeDouble(Bid,_Digits);

   int ticket=OrderSend(_Symbol,type,Lot,price_open,Slippage,0,0,CommentOrder,MagicNumber);
   if(ticket<0)Print("Ошибка открытия ордера № - ",GetLastError());
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OrderClose(int type)
  {
   double price_close=0.0;
   if(type==WRONG_VALUE)return;
   if(!IsTradeAllowed())return;
   int total=OrdersTotal();
   for(int i=total-1; i>=0; i--)
     {
      if(!OrderSelect(i,SELECT_BY_POS))continue;
      if(OrderMagicNumber()!=MagicNumber)continue;
      if(OrderSymbol()!=_Symbol)continue;
      if(OrderType()!=type)continue;
      if(type==OP_BUY)price_close=NormalizeDouble(Bid,_Digits);
      if(type==OP_SELL)price_close=NormalizeDouble(Ask,_Digits);
      bool res=OrderClose(OrderTicket(),OrderLots(),price_close,Slippage);
      if(!res)Print("Ошибка закрытия ордера № - ",GetLastError());
     }
  }
//+------------------------------------------------------------------+
int TotalOrder()
  {
   int value=0;
   int total=OrdersTotal();
   for(int i=total-1; i>=0; i--)
     {
      if(!OrderSelect(i,SELECT_BY_POS))continue;
      if(OrderSymbol()!=Symbol())continue;
      if(OrderMagicNumber()!=MagicNumber)continue;
      if(OrderType()>1)continue;
      value++;
     }
   return(value);
  }
//+------------------------------------------------------------------+
void ModifySL(double sl)
  {
   if(sl<=0)return;
   double price_sl=0.0;
   int total=OrdersTotal();
   for(int i=total-1; i>=0; i--)
     {
      if(!OrderSelect(i,SELECT_BY_POS))continue;
      if(OrderMagicNumber()!=MagicNumber)continue;
      if(OrderSymbol()!=_Symbol)continue;
      if(OrderType()>1)continue;
      if(OrderStopLoss()==0)
        {
         if(OrderType()==OP_BUY)price_sl=NormalizeDouble(OrderOpenPrice()-sl*_Point,_Digits);
         if(OrderType()==OP_SELL)price_sl=NormalizeDouble(OrderOpenPrice()+sl*_Point,_Digits);
         if(price_sl<=0)continue;
         bool res=OrderModify(OrderTicket(),OrderOpenPrice(),price_sl,OrderTakeProfit(),0);
         if(!res)Print("Ошибка модификации стоп лосса ордера № - ",GetLastError());
        }
     }
  }
//+------------------------------------------------------------------+
void ModifyTP(double tp)
  {
   if(tp<=0)return;
   double price_tp=0.0;
   int total=OrdersTotal();
   for(int i=total-1; i>=0; i--)
     {
      if(!OrderSelect(i,SELECT_BY_POS))continue;
      if(OrderMagicNumber()!=MagicNumber)continue;
      if(OrderSymbol()!=_Symbol)continue;
      if(OrderType()>1)continue;
      if(OrderTakeProfit()==0)
        {
         if(OrderType()==OP_BUY)price_tp=NormalizeDouble(OrderOpenPrice()+tp*_Point,_Digits);
         if(OrderType()==OP_SELL)price_tp=NormalizeDouble(OrderOpenPrice()-tp*_Point,_Digits);
         if(price_tp<=0)continue;
         bool res=OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),price_tp,0);
         if(!res)Print("Ошибка модификации тейк профита ордера № - ",GetLastError());
        }
     }
  }
//+------------------------------------------------------------------+

 ...

 

не вдаваясь в логику советника :

  • "if(OrderType()>1)continue;" - так делать ненадо, это моветон в любом языке. У вас есть именованные константы для таких целей.
  • лучше сразу учиться писать свои классы, а не процедуры.
  • сразу незабываем проверять торговые условия и достаточность средств !!
 
Maxim Kuznetsov:

не вдаваясь в логику советника :

  • "if(OrderType()>1)continue;" - так делать ненадо, это моветон в любом языке. У вас есть именованные константы для таких целей.
  • лучше сразу учиться писать свои классы, а не процедуры.
  • сразу незабываем проверять торговые условия и достаточность средств !!
Спасибо за помощь в этом.
 

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

 

//+------------------------------------------------------------------+
//|               МОДИФИКАЦИИ И ОБНОВЛЕНИЕ СОВЕТНИКА                 |
//+------------------------------------------------------------------+
//|07.01.17 Sergey Gritsay                                           |
//|https://www.mql5.com/ru/users/sergey1294                          |
//|1. Модификация скрипта советника, доп. параметры: SL, TP, CS, SP  |
//|                                                                  |
//|                                                                  |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Origenal"
#property link      ""
#property version   "1.01"
#property strict
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
enum TYPE_SIGNAL_BB
  {
   VARIANT_1,
   VARIANT_2
  };

//===========================================================================
sinput string         s1           = "Параметры TP / SL";
input int             StopLoss     = 300;            // Стоп Лосс (Пипс)
input int             TakeProfit   = 500;            // Тейк Профит (Пипс)
input int             Slippage     = 10;             // Проскальзование (Пипс)
//===========================================================================
sinput string         s2           = "Параметры объема лота";
input double          Lot          = 0.01;           // Объем лота
//===========================================================================                                      
sinput string         s3="Параметры индикаторов";
input int             BBPeriod     = 20;             // Период ВВ
input ENUM_TIMEFRAMES TimeFrameBB  = PERIOD_CURRENT; // Тайм Фрейм BB
input double          BBDev        = 2.0;            // Отклонение ВВ
input TYPE_SIGNAL_BB  VariantBB    = VARIANT_1;      // Вариант сигнала
input int             MAPeriod     = 20;             // Период МА
input ENUM_TIMEFRAMES TimeFrameMA  = PERIOD_D1;      // Тайм Фрейм МА
//===========================================================================
sinput string         s4           = "Параметры Советника";
input int             MagicNumber  = 20110315;       // Номер копии
input string          CommentOrder = "Origenal";     // Комментарий к ордеру
input bool            CloseSignal  = false;          // закрытие по сигналу ( false - выкл, true - вкл)
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   if(TotalOrder()==0)OrderOpen(GetSignalOpen());
   else
     {
      ModifySL(StopLoss);
      ModifyTP(TakeProfit);
      if(CloseSignal)OrderClose(GetSignalClose());
     }
  }
//+------------------------------------------------------------------+
//|   функция определения сигнала для входа                          |                                    
//+------------------------------------------------------------------+
int GetSignalOpen()
  {
   if(GetSignalMA()==OP_BUY && GetSignalBB()==OP_BUY) return(OP_BUY);
   if(GetSignalMA()==OP_SELL && GetSignalBB()==OP_SELL) return(OP_SELL);
   return(WRONG_VALUE);
  }
//+------------------------------------------------------------------+
//| функция определения сигнала индикатора BB                        |                                        
//+------------------------------------------------------------------+
int GetSignalBB()
  {
   double bbh=iBands(_Symbol,TimeFrameBB,BBPeriod,BBDev,0,PRICE_CLOSE,MODE_UPPER,1);
   double bbl=iBands(_Symbol,TimeFrameBB,BBPeriod,BBDev,0,PRICE_CLOSE,MODE_LOWER,1);
  
   if(VariantBB==VARIANT_1)
     {
      if(Low[1]<=bbl) return(OP_BUY);
      if(High[1]>=bbh) return(OP_SELL);
     }
   if(VariantBB==VARIANT_2)
     {
      if(Close[2]<=bbl && Close[1]>=bbl) return(OP_BUY);
      if(Close[2]>=bbh && Close[1]<=bbh) return(OP_SELL);
     }
   return(WRONG_VALUE);
  }
//+------------------------------------------------------------------+
//|  Функция определения сигнала MA                                  |                            
//+------------------------------------------------------------------+
int GetSignalMA()
  {
   double ma=iMA(_Symbol,TimeFrameMA,MAPeriod,0,MODE_SMA,PRICE_CLOSE,1);
   double close=iClose(_Symbol,TimeFrameMA,1);
   if(close>ma) return(OP_BUY);
   if(close<ma) return(OP_SELL);
   return(WRONG_VALUE);
  }
//+------------------------------------------------------------------+
//| Функция определения сигнала для закрытия                         |                                        
//+------------------------------------------------------------------+
int GetSignalClose()
  {
   if(GetSignalBB()==OP_SELL)return(OP_BUY);
   if(GetSignalBB()==OP_BUY)return(OP_SELL);
   return(WRONG_VALUE);
  }
//+------------------------------------------------------------------+
void OrderOpen(int type)
  {
   double price_open=0.0;
   if(type==WRONG_VALUE)return;
   if(!IsTradeAllowed())return;

   if(type==OP_BUY)price_open = NormalizeDouble(Ask,_Digits);
   if(type==OP_SELL)price_open = NormalizeDouble(Bid,_Digits);

   int ticket=OrderSend(_Symbol,type,Lot,price_open,Slippage,0,0,CommentOrder,MagicNumber);
   if(ticket<0)Print("Ошибка открытия ордера № - ",GetLastError());
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OrderClose(int type)
  {
   double price_close=0.0;
   if(type==WRONG_VALUE)return;
   if(!IsTradeAllowed())return;
   int total=OrdersTotal();
   for(int i=total-1; i>=0; i--)
     {
      if(!OrderSelect(i,SELECT_BY_POS))continue;
      if(OrderMagicNumber()!=MagicNumber)continue;
      if(OrderSymbol()!=_Symbol)continue;
      if(OrderType()!=type)continue;
      if(type==OP_BUY)price_close=NormalizeDouble(Bid,_Digits);
      if(type==OP_SELL)price_close=NormalizeDouble(Ask,_Digits);
      bool res=OrderClose(OrderTicket(),OrderLots(),price_close,Slippage);
      if(!res)Print("Ошибка закрытия ордера № - ",GetLastError());
     }
  }
//+------------------------------------------------------------------+
int TotalOrder()
  {
   int value=0;
   int total=OrdersTotal();
   for(int i=total-1; i>=0; i--)
     {
      if(!OrderSelect(i,SELECT_BY_POS))continue;
      if(OrderSymbol()!=Symbol())continue;
      if(OrderMagicNumber()!=MagicNumber)continue;
      if(OrderType()>1)continue;
      value++;
     }
   return(value);
  }
//+------------------------------------------------------------------+
void ModifySL(double sl)
  {
   if(sl<=0)return;
   double price_sl=0.0;
   int total=OrdersTotal();
   for(int i=total-1; i>=0; i--)
     {
      if(!OrderSelect(i,SELECT_BY_POS))continue;
      if(OrderMagicNumber()!=MagicNumber)continue;
      if(OrderSymbol()!=_Symbol)continue;
      if(OrderType()>1)continue;
      if(OrderStopLoss()==0)
        {
         if(OrderType()==OP_BUY)price_sl=NormalizeDouble(OrderOpenPrice()-sl*_Point,_Digits);
         if(OrderType()==OP_SELL)price_sl=NormalizeDouble(OrderOpenPrice()+sl*_Point,_Digits);
         if(price_sl<=0)continue;
         bool res=OrderModify(OrderTicket(),OrderOpenPrice(),price_sl,OrderTakeProfit(),0);
         if(!res)Print("Ошибка модификации стоп лосса ордера № - ",GetLastError());
        }
     }
  }
//+------------------------------------------------------------------+
void ModifyTP(double tp)
  {
   if(tp<=0)return;
   double price_tp=0.0;
   int total=OrdersTotal();
   for(int i=total-1; i>=0; i--)
     {
      if(!OrderSelect(i,SELECT_BY_POS))continue;
      if(OrderMagicNumber()!=MagicNumber)continue;
      if(OrderSymbol()!=_Symbol)continue;
      if(OrderType()>1)continue;
      if(OrderTakeProfit()==0)
        {
         if(OrderType()==OP_BUY)price_tp=NormalizeDouble(OrderOpenPrice()+tp*_Point,_Digits);
         if(OrderType()==OP_SELL)price_tp=NormalizeDouble(OrderOpenPrice()-tp*_Point,_Digits);
         if(price_tp<=0)continue;
         bool res=OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),price_tp,0);
         if(!res)Print("Ошибка модификации тейк профита ордера № - ",GetLastError());
        }
     }
  }
//+------------------------------------------------------------------+

 ....

Файлы:
Origenal.mq4  19 kb
 

Исправляем косяки и приближаем код по максимуму к MQL5. Исправил функции GetSignalBB() и GetSignalMA()

 

//+------------------------------------------------------------------+
//| функция определения сигнала индикатора BB                        |                                        
//+------------------------------------------------------------------+
int GetSignalBB()
  {
   double bbh=iBands(_Symbol,TimeFrameBB,BBPeriod,BBDev,0,PRICE_CLOSE,MODE_UPPER,1);
   double bbl=iBands(_Symbol,TimeFrameBB,BBPeriod,BBDev,0,PRICE_CLOSE,MODE_LOWER,1);

   MqlRates rates[];
   ArraySetAsSeries(rates,true);
   if(CopyRates(_Symbol,TimeFrameBB,1,2,rates)<2)return(WRONG_VALUE);

   if(VariantBB==VARIANT_1)
     {
      if(rates[1].low<=bbl) return(OP_BUY);
      if(rates[1].high>=bbh) return(OP_SELL);
     }
   if(VariantBB==VARIANT_2)
     {
      if(rates[2].close<=bbl && rates[1].close>=bbl) return(OP_BUY);
      if(rates[2].close>=bbh && rates[1].close<=bbh) return(OP_SELL);
     }
   return(WRONG_VALUE);
  }
//+------------------------------------------------------------------+
//|  Функция определения сигнала MA                                  |                            
//+------------------------------------------------------------------+
int GetSignalMA()
  {
   double ma=iMA(_Symbol,TimeFrameMA,MAPeriod,0,MODE_SMA,PRICE_CLOSE,1);

   MqlRates rates[];
   ArraySetAsSeries(rates,true);
   if(CopyRates(_Symbol,TimeFrameMA,1,1,rates)<1)return(WRONG_VALUE);

   if(rates[1].close>ma) return(OP_BUY);
   if(rates[1].close<ma) return(OP_SELL);
   return(WRONG_VALUE);
  }

 ...

Файлы:
Origenal.mq4  19 kb
 

Выход за пределы массива

   if(rates[1].close>ma) return(OP_BUY);


 Если [0] то в порядке

   if(rates[0].close>ma) return(OP_BUY);


 

 
FXwin:

Выход за пределы массива

   if(rates[1].close>ma) return(OP_BUY);


 Если [0] то в порядке

   if(rates[0].close>ma) return(OP_BUY);


 

Спасибо совсем забыл, про это. Поправил
Файлы:
Origenal.mq4  19 kb