Гляньте пожайлуста советник

 
Простеньки советник, алгоритм работы такой:
Покупка - пересечение быстрой МА медленных снизу вверх.
Продажа - пересечение быстрой МА медленных сверху вниз.
Открытие сделки происходит после закрытия свечи на которой состоялось пересечение.
Быстрая МА, период: 5, метод: exponential, применить: close.
Медленные МА, период 75 и 85, метод: linear weighted, применить: low.
Т/P 100 пунктов, S/L 50 пунктов, при уходе цены в + 40 пунктов S/L переносится в безубыток.
При не достижении цены уровня Т/P и поступает обратный сигнал, закрытие ордера и открытие обратного ордера.
Проблема в следующем, часто открытие происходит когда свеча пересекает медленные МА, что не соответствует алгоритму, также часто при поступлении противоположного сигнала не закрывается открытая сделка и не открывается противоположная.
Подскажите в чем причина?
//+------------------------------------------------------------------+
//|                                    Copyright © 2010, ENSED Team. |
//|                                             http://www.ensed.org |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010, ENSED Team"
#property link      "http://www.ensed.org"

//+-------------------------------------------------------------------------------------------------------------------+
//|                                     внешние переменные (входные параметры)                                        |
extern double Lots            = 0.1;      //рабочий лот
extern int    SL              = 50;       //Stop Loss для открываемых ордеров (в пунктах)
extern int    TP              = 100;       //Take Profit для открываемых ордеров (в пунктах)
extern int    Magic_Number    = 244;      //магическое число. Необходимо роботу для идентификации "своих" ордеров
extern string Order_Comment   = "ensed_forum"; //комментарий, которым снабжаются открываемые ордера
extern int    Slippage        = 100;      //уровень допустимого реквота

extern int Fast_MA_Period  = 5; //период усреднения для вычисления быстрой скользящей средней
extern int Slow_1_MA_Period  = 75; //период усреднения для вычисления первой медленной скользящей средней
extern int Slow_2_MA_Period  = 85; //период усреднения для вычисления второй медленной скользящей средней
extern int MA_Method        = 3; /* метод усреднения: 0 - простое скользящее среднее, 1 - экспонциальное скользящее среднее,
                                    2 - сглаженное скользящее среднее, 3 - линейно-взвешенное скользящее среднее */
extern int Applied_Price    = 1; /* используемая цена: 0 - цена закрытия, 1 - цена открытия, 2 - максимальная цена, 
                                         3 - минимальная цена, 4 - средняя цена ((high+low)/2), 5 - типичная цена ((high+low+close)/3),
                                         6 - взвешанная цена закрятия ((high+low+close+close)/4) */     
                                         
extern int  Profit_to_SL    = 40; //значение прибыли, после которой ставим стоп в безубыток
extern int  SL_Profit_Level = 1;  //величина безубытка
//|                                     внешние переменные (входные параметры)                                        |
//+-------------------------------------------------------------------------------------------------------------------+
//+----------------------------------------------------------------------+
//+                           Трейлинг Стоп                              +

extern bool   UseTrailing   = true;         // включение/выключение трейлинг стопа
extern int    TrailingStop  = 50;           // величина трейлинг стопа
extern int    TrailingStep  = 1;            // шаг трейлинг стопа

//+                           Трейлинг Стоп                              +
//+----------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }

//+-------------------------------------------------------------------------------------------------------------------+
//|                                          функция поиска торговых сигналов                                         |
int fsignals() {
  //поиск сигнала: если на выходе 1 - сигнал на покупку, если 2 - на продажу
  if((iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,1)>iMA(NULL,0,Slow_2_MA_Period,0,MA_Method,Applied_Price,1))
      && ( (iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,1)>iMA(NULL,0,Slow_1_MA_Period,0,MA_Method,Applied_Price,1)) 
            && ( ((iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,2)<iMA(NULL,0,Slow_1_MA_Period,0,MA_Method,Applied_Price,2))
                 || (iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,2)==iMA(NULL,0,Slow_1_MA_Period,0,MA_Method,Applied_Price,2))
                      &&(iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,3)<iMA(NULL,0,Slow_1_MA_Period,0,MA_Method,Applied_Price,3)) 
                )
            )    
         )
    )
    return(1);

  if((iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,1)<iMA(NULL,0,Slow_2_MA_Period,0,MA_Method,Applied_Price,1))
      && ( (iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,1)<iMA(NULL,0,Slow_1_MA_Period,0,MA_Method,Applied_Price,1)) 
            && ( ((iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,2)>iMA(NULL,0,Slow_1_MA_Period,0,MA_Method,Applied_Price,2))
                 || (iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,2)==iMA(NULL,0,Slow_1_MA_Period,0,MA_Method,Applied_Price,2))
                      &&(iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,3)>iMA(NULL,0,Slow_1_MA_Period,0,MA_Method,Applied_Price,3)) 
                )
            )    
         )
    )
    return(2);
  return(-1);  
} //end int fsignals()
//|                                          функция поиска торговых сигналов                                         |
//+-------------------------------------------------------------------------------------------------------------------+

//+-------------------------------------------------------------------------------------------------------------------+
//|                                      функция поиска и учета открытых ордеров                                      |
int find_orders(int type) { //возвращает истину, если найден хотя бы один открытый ордер данного робота
  int i = 0;
  for (i=OrdersTotal()-1; i>=0; i--) {
    if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) break;
    if ((OrderType()==type) && (OrderMagicNumber()==Magic_Number) 
         && OrderSymbol()==Symbol()) {
      return(OrderTicket());
      break;
    } //end if (((OrderType()==OP_BUY) || (OrderType()==OP_SELL)) && (OrderMagicNumber()==Magic_Number))
  } //end for (int i2=OrdersTotal()-1; i2>=0; i2--)

  return(-1);
} //end bool find_orders()
//|                                      функция поиска и учета открытых ордеров                                      |
//+-------------------------------------------------------------------------------------------------------------------+

//+-------------------------------------------------------------------------------------------------------------------+
//|                                  функция расчета величины Stop Loss для ордеров                                   |
double sl(int sl_value, int mode) { //расчет величины Stop Loss для ордеров
  //mode=1 -> покупки
  //mode=2 -> продажи
  if(sl_value<=0) return(0);
  if(mode==1)     return(Ask-sl_value*Point); //для покупок
  if(mode==2)     return(Bid+sl_value*Point); //для продаж
} //end double sl(int sl_value, int mode)
//|                                  функция расчета величины Stop Loss для ордеров                                   |
//+-------------------------------------------------------------------------------------------------------------------+

//+-------------------------------------------------------------------------------------------------------------------+
//|                                 функция расчета величины Take Profit для ордеров                                  |
double tp(int tp_value, int mode) { //расчет величины Take Profit для ордеров
  //mode=1 -> покупки
  //mode=2 -> продажи
  if(tp_value<=0) return(0);
  if(mode==1)     return(Ask+tp_value*Point); //для покупок
  if(mode==2)     return(Bid-tp_value*Point); //для продаж
} //end double tp(int tp_value, int mode)
//|                                 функция расчета величины Take Profit для ордеров                                  |
//+-------------------------------------------------------------------------------------------------------------------+

//+-------------------------------------------------------------------------------------------------------------------+
//|                                              функция открытия ордеров                                             |
void open_positions(int signal, double lot) { //открытие ордеров
  //signal=1 -> сигнал на открытие покупки
  //signal=2 -> сигнал на открытие продажи
  int    i     = 0;
  int    count = 5; //количество попыток открытия ордера в случае, если его не уда\u017eтся совершить сразу
  double price = 0; //цена открытия
  
  if(signal==1) price=Ask; //цена открытия для покупок
  if(signal==2) price=Bid; //цена открытия для продаж
  while(i<=count) {
    int ticket = OrderSend(Symbol(),
                           signal-1,
                           lot,
                           price,
                           Slippage,
                           NormalizeDouble(sl(SL,signal),Digits),
                           NormalizeDouble(tp(TP,signal),Digits),
                           Order_Comment,
                           Magic_Number,
                           0,
                           CLR_NONE);
    if(ticket!=-1)
      break;
    i++;  
  } //end while(i<=count)
} //end void open_positions(int signal)
//|                                              функция открытия ордеров                                             |
//+-------------------------------------------------------------------------------------------------------------------+

//+-------------------------------------------------------------------------------------------------------------------+
//|                                          функция переноса стопа в безубыток                                       |
void stop_to_profit() {
  int i=0, n=0, ticket=0;
  double open_price=0.0;
  for(i=OrdersTotal()-1; i>=0; i--) {
    open_price=OrderOpenPrice();
    if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) break;
    if((OrderSymbol()==Symbol())&&(OrderMagicNumber()==Magic_Number)) {
      if(OrderType()==OP_BUY) {        
        if((MarketInfo(OrderSymbol(),MODE_BID)-open_price<=Profit_to_SL*MarketInfo(OrderSymbol(),MODE_POINT))
           || (NormalizeDouble(OrderStopLoss(),Digits)==NormalizeDouble(OrderOpenPrice()+SL_Profit_Level*MarketInfo(OrderSymbol(),MODE_POINT),Digits))) continue;
        OrderModify(OrderTicket(),
                    OrderOpenPrice(),
                    OrderOpenPrice()+SL_Profit_Level*MarketInfo(OrderSymbol(),MODE_POINT),
                    OrderTakeProfit(),
                    OrderExpiration(),
                    CLR_NONE);        
      } //end if(OrderType()==OP_BUY)

      if(OrderType()==OP_SELL) {
        if((open_price-MarketInfo(OrderSymbol(),MODE_ASK)<=Profit_to_SL*MarketInfo(OrderSymbol(),MODE_POINT))
           || (NormalizeDouble(OrderStopLoss(),Digits)==NormalizeDouble(OrderOpenPrice()-SL_Profit_Level*MarketInfo(OrderSymbol(),MODE_POINT),Digits))) continue;
          OrderModify(OrderTicket(),
                      OrderOpenPrice(),
                      OrderOpenPrice()-SL_Profit_Level*MarketInfo(OrderSymbol(),MODE_POINT),
                      OrderTakeProfit(),
                      OrderExpiration(),
                      CLR_NONE);
      } //end if(OrderType()==OP_SELL)
    } //end if((OrderSymbol()==Symbol())&&(OrderMagicNumber()==Magic_Number))
  } //end for(i=OrdersTotal()-1; i>=0; i--) {
} //end void stop_to_profit()
//|                                          функция переноса стопа в безубыток                                       |
//+-------------------------------------------------------------------------------------------------------------------+

//+-------------------------------------------------------------------------------------------------------------------+
//|                                           функция закрытия сделки по тикету                                       |
bool close_orders(int ticket) {
  bool c_ticket = false;
  int  i        = 0;
  if (OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) {
    if ((OrderType()==OP_BUY) && (OrderMagicNumber()==Magic_Number)) {
      for(i=0;i<=5;i++) {
        c_ticket=OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,CLR_NONE);
        if(c_ticket) break; //если закрытие прошло успешно - выходим из цикла
      } //end for(i=0;i<=5;i++)
    } //end if ((OrderType()==OP_BUY) && (OrderMagicNumber()==Magic_Number))

    if ((OrderType()==OP_SELL) && (OrderMagicNumber()==Magic_Number)) {
      for(i=0;i<=5;i++) {
        c_ticket=OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,CLR_NONE);
        if(c_ticket) break; //если закрытие прошло успешно - выходим из цикла
      } //end for(i=0;i<=5;i++)
    } //end if ((OrderType()==OP_SELL) && (OrderMagicNumber()==Magic_Number))
  }
  return(c_ticket);
} //end close_orders(int signal)
//|                                           функция закрытия сделки по тикету                                       |
//+-------------------------------------------------------------------------------------------------------------------+

//+-------------------------------------------------------------------------------------------------------------------+
//|                                           главная функция (main в C/C++)                                          |
int start() {
  int sig = fsignals();
  int ticket=0;
  if(sig!=-1) { //если есть торговый сигнал и нет открытых ордеров
    if(sig==1)
      ticket=find_orders(1);
    if(sig==2)
      ticket=find_orders(0);      
    if(ticket!=-1)
      close_orders(ticket);
    if(find_orders((sig-1))==-1)    
      open_positions(sig,Lots); //вызываем функцию открытия ордера
  } //end if((sig!=-1)&& (!find_orders()))

  stop_to_profit(); //перенос стопа по прибыльным сделкам в безубыток
  return(0);
} //end int start()
//|                                           главная функция (main в C/C++)                                          |
//+---------------------------------------------------------------------------
 
Готов предложить Вам пищу для размышлений:
Стандартный кусок кода закрытия ордеров - работает...
if(OrdersTotal() > 0)
{
for(ord = 0; ord < OrdersTotal(); ord++)
{
OrderSelect(ord,SELECT_BY_POS,MODE_TRADES);
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == magic)

{

if(OrderType() == OP_BUY)
{

if(Условие закрытия)
{
OrderClose(OrderTicket(),OrderLots(),Bid,3,NONE);



magic - внешняя переменная, значение сохраняется при открытии ордера

 кусок кода открытия ордеров при пересечении МА - работает...

//--------------------------------------------------------------------
// Criterion.mqh
// 
//--------------------------------------------------------------- 1 --
// Функция вычисления торговых критериев.
// Возвращаемые значения:
// 10 - открытие Buy  
// 20 - открытие Sell 
// 11 - закрытие Buy
// 21 - закрытие Sell
// 0  - значимых критериев нет
//--------------------------------------------------------------- 2 --
// Внешние переменные:
extern int Period_MA1 = 24;               // Период расчётной МА1
extern int Period_MA2 = 48;               // Период расчётной МА2
extern int Period_MA3 = 120;              // Период расчётной МА3


//--------------------------------------------------------------- 3 --
int Criterion()                        // Пользовательская функция
  {
   
   double
   MA1_0, MA1_1,                        // Значение MA1 на 0 и 1 барах
   MA2_0, MA2_1,                        // Значение MA2 на 0 и 1 барах
   MA3_0, MA3_1;                         // Значение MA3 на 0 и 1 барах
   
//--------------------------------------------------------------- 4 --
   // Параметры технич. индикат:
   
  MA1_0=iMA(NULL,0,Period_MA1,0,MODE_EMA,PRICE_CLOSE,0); // 0 бар
  MA1_1=iMA(NULL,0,Period_MA1,0,MODE_EMA,PRICE_CLOSE,1); // 1 бар
  MA2_0=iMA(NULL,0,Period_MA2,0,MODE_EMA,PRICE_CLOSE,0); // 0 бар
  MA2_1=iMA(NULL,0,Period_MA2,0,MODE_EMA,PRICE_CLOSE,1); // 1 бар
  MA3_0=iMA(NULL,0,Period_MA3,0,MODE_EMA,PRICE_CLOSE,0); // 0 бар
  MA3_1=iMA(NULL,0,Period_MA3,0,MODE_EMA,PRICE_CLOSE,1); // 1 бар
   
// Вычисление торговых критериев
   
  if (MA1_1 >= MA2_1 && MA2_1 >= MA3_1)
  return(10);                                         // Открытие Buy    
   
  if (MA1_1 < MA2_1 && MA2_1 < MA3_1)
  return(20);                                         // Открытие Sell
   
  
  if (MA1_1 <= MA2_1  || MA2_1 <= MA3_1 || MA1_1<=MA3_1)
  
  return(11);                                         // Закрытие Buy  
     
  if  (MA1_1 >= MA2_1 || MA2_1 >= MA3_1 || MA1_1>=MA3_1)
  return(21);                                         // Закрытие Sell      
//---------------------------------------------------------- 5 --
       
return(0);                          // Выход из пользов. функции
  }
//--------------------------------------------------------------- 7 --
 
Глянул
 

По видимому проблема в этом куске:

//| функция поиска торговых сигналов |
int fsignals() {
  //поиск сигнала: если на выходе 1 - сигнал на покупку, если 2 - на продажу
  if((iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,1)>iMA(NULL,0,Slow_2_MA_Period,0,MA_Method,Applied_Price,1))
  && ( (iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,1)>iMA(NULL,0,Slow_1_MA_Period,0,MA_Method,Applied_Price,1)) 
  && ( ((iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,2)<iMA(NULL,0,Slow_1_MA_Period,0,MA_Method,Applied_Price,2))
  || (iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,2)==iMA(NULL,0,Slow_1_MA_Period,0,MA_Method,Applied_Price,2))
  &&(iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,3)<iMA(NULL,0,Slow_1_MA_Period,0,MA_Method,Applied_Price,3)) 
  )
  )  
  )
  )
  return(1);

  if((iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,1)<iMA(NULL,0,Slow_2_MA_Period,0,MA_Method,Applied_Price,1))
  && ( (iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,1)<iMA(NULL,0,Slow_1_MA_Period,0,MA_Method,Applied_Price,1)) 
  && ( ((iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,2)>iMA(NULL,0,Slow_1_MA_Period,0,MA_Method,Applied_Price,2))
  || (iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,2)==iMA(NULL,0,Slow_1_MA_Period,0,MA_Method,Applied_Price,2))
  &&(iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,3)>iMA(NULL,0,Slow_1_MA_Period,0,MA_Method,Applied_Price,3)) 
  )
  )  
  )
  )
  return(2);
  return(-1);  
} //end int fsignals()

 

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

extern int Fast_MA_Period = 5;
extern int Slow_1_MA_Period = 75;
extern int Slow_2_MA_Period = 85;

extern int MA_Method = 3   (должно быть 3 для Slow_MA_Period и 1 для Fast_MA_Period )

extern int Applied_Price = 1 (должно быть 0 для Fast_MA_Period и 3 для Slow_MA_Period )

 


   if((iMA(NULL,0,Fast_MA_Period,0,MA_Method,Applied_Price,1)>iMA(NULL,0,Slow_2_MA_Period,0,MA_Method, Applied_Price,1))
 
 

 
marvelous:
Для вставки кода есть кнопка специальная, доступная при редактировании. Называется SRC
Причина обращения: