вопрос к программистам, не могу найти алгоритмическую ошибку в советнике

 
#define MAGICMA  20080530
 
extern double Lots               = 1:
extern double BUY_HIGH           = 5:
extern double SELL_LOW           = 5;
extern double MovingPeriod       = 5;
 
double ma1, ma2, ma3, ma4;
 
int CalculateCurrentOrders(string symbol)
  {
   int buys=0,sells=0;
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)
        {
         if(OrderType()==OP_BUY)  buys++;
         if(OrderType()==OP_SELL) sells++;
        }
     }
   if(buys>0) return(buys);
   else       return(-sells);
  }
void CheckForOpen()
  {
   double ma;
   int    res;
   if(Volume[0]>1) return;
   ma=iMA(NULL,0,MovingPeriod,0,MODE_EMA,PRICE_CLOSE,0);
   if(Open[1]<ma && Close[1]>ma) { ma1=ma;}
   if((ma1-ma)>=(SELL_LOW*Point)){
      res=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,0,"",MAGICMA,0,Red);
      return;
     }
  if(Open[1]>ma && Close[1]<ma) { ma2=ma;}
  if(ma2!=0){
  if((ma-ma2)>=(BUY_HIGH*Point)){
      res=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,0,"",MAGICMA,0,Blue);
      return;
     }
    }
  }
void CheckForClose()
  {
   double ma; 
   int    res;
  if(Volume[0]>1) return;
   ma=iMA(NULL,0,MovingPeriod,0,MODE_EMA,PRICE_CLOSE,0);
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)        break;
      if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;
      if(OrderType()==OP_BUY)
        {
         if(Open[1]<ma && Close[1]>ma){ ma3=ma;}
         if((ma3-ma)>=(SELL_LOW*Point)) {   
            OrderClose(OrderTicket(),OrderLots(),Bid,3,White);
            res=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,0,"",MAGICMA,0,Red);
         ma3=0;
         }
         break;
        }
      if(OrderType()==OP_SELL)
        {
         if(Open[1]>ma && Close[1]<ma) {ma4=ma;}
         if(ma4!=0){
         if((ma-ma4)>=(BUY_HIGH*Point)){
         OrderClose(OrderTicket(),OrderLots(),Ask,3,White);
         res=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,0,"",MAGICMA,0,Blue);
         ma4=0;
         }
         }         
         break;
        }
     }
  }
void start()
  {
   if(Bars<100 || IsTradeAllowed()==false) return;
   if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
   else                                    CheckForClose();
  }

Вот, собственно, в коде выше и есть загвоздка. А состоит она вот в чем: по условиям советника, он должен открывать ордер после пересечения EMA с графиком и при увеличении (или уменшении) значения EMA на 5 пунктов (после пересечения). Но открывает он невпопад и ордера подолгу держит открытыми, хотя они должны быть уже закрытыми.

 

ma=iMA(NULL,0,MovingPeriod,0,MODE_EMA,PRICE_CLOSE,0);

Не правильней ли использовать для сравнения такой вариант?

ma1=iMA(NULL,0,MovingPeriod,0,MODE_EMA,PRICE_CLOSE,1);

 
D500_Rised:

ma=iMA(NULL,0,MovingPeriod,0,MODE_EMA,PRICE_CLOSE,0);

Не правильней ли использовать для сравнения такой вариант?

ma1=iMA(NULL,0,MovingPeriod,0,MODE_EMA,PRICE_CLOSE,1);

Хм, не особо помогла, конечно :) (на тестере еще меньше стало профит показывать), но Ваша мысль подтолкнула к тому, чтобы учитывать еще значение Open текущего бара. После небольших манипуляций пришел к тому же результату, который выдавал исходный код :) то есть где-то в корне ошибся :( (хотя явных ошибок не замечаю что-то :( ). кто еще может помочь? :)

 

Посмотрите на это условие:


if(Open[1]<ma && Close[1]>ma) { ma1=ma;}
   if((ma1-ma)>=(SELL_LOW*Point)){

Если первое условие верно, то ма1 присваивается значение ма (которое вычислено и известно).

Тогда второе условие (ма1-ма) не выполняется так как результат условия равен нулю а не

(SELL_LOW*Point)

А если же первое условие не выполнено, то ma1 либо равно нулю (с момента инициализации) либо равно давнему значению ma.

Тогда второе условие (

(ma1-ma)

либо равно -ma (минус) либо опять нулю.

Может лучше проводить проверку на открытие позиции например так:

ma=iMA(NULL,0,MovingPeriod,0,MODE_EMA,PRICE_CLOSE,0);
ma1=iMA(NULL,0,MovingPeriod,0,MODE_EMA,PRICE_CLOSE,1);
...

...

if(ma1>ma+SELL_LOW*Point && ma>Close[0]){
...
}