MA Cross Strategy

 

How does a MA cross strategy fail?

I've been trying to optimize and backtest the Moving Average EA and no matter what I do it always comes up a failure. When I try to optimize for periods from 5 to 65 for a six year span, all periods end with ten consecutive losses. When I randomly backtest for any period from as low as 1 to as high as 1560, the graphs are relatively all the same smooth decline to 0. My understanding is that profit should increase going long when price is above the moving average and going short when price is below the moving average. No matter how much is lost during the price return to the moving average, so long as the moving average has moved a little either up or down, more should have been made than was lost resulting in profit. Under such conditions, profit should only be able to steadily decline from the spreads and/or commissions to accompany a majority of whipsaws. Either the strategy tester isn't working correctly or more than likely there is some fundamental aspect to the market that I've somehow never managed to come across or comprehend when I did come across it. Whatever it is, not recognizing something that major has got me totally baffled.

 
No mind readers here, no code, no comment.
 

> ...more than likely there is some fundamental aspect to the market that I've somehow never managed to come across or comprehend...

Thats the one - well there's several aspects actually :)

An inherent problem with all flavours of moving average is lag

Also consider that:-

- looking at one timeframe alone will limit success - think of the daily or weekly situation and trade in that direction

- most strategies will need time-of-day to filter trades, also time-of-year and maybe time-of-month

- if you get a good trade going with a moving average, use something else to indicate close point - either a trend weakening indicator or a retrace warning like the SFX_MA_On_CCI

See here & here for another members ideas on not using moving averages!

IIRC - even the sample MACD EA gives a better curve than the MA EA - dont use either on live accounts though!

-BB-

 
WHRoeder:
No mind readers here, no code, no comment.

//+------------------------------------------------------------------+
//|                                               Moving Average.mq4 |
//|                      Copyright © 2005, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#define MAGICMA  20050610

extern double Lots               = 0.1;
extern double MaximumRisk        = 0.02;
extern double DecreaseFactor     = 3;
extern double MovingPeriod       = 12;
extern double MovingShift        = 6;
//+------------------------------------------------------------------+
//| Calculate open positions                                         |
//+------------------------------------------------------------------+
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++;
        }
     }
//---- return orders volume
   if(buys>0) return(buys);
   else       return(-sells);
  }
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double LotsOptimized()
  {
   double lot=Lots;
   int    orders=HistoryTotal();     // history orders total
   int    losses=0;                  // number of losses orders without a break
//---- select lot size
   lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);
//---- calcuulate number of losses orders without a break
   if(DecreaseFactor>0)
     {
      for(int i=orders-1;i>=0;i--)
        {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; }
         if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue;
         //----
         if(OrderProfit()>0) break;
         if(OrderProfit()<0) losses++;
        }
      if(losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
     }
//---- return lot size
   if(lot<0.1) lot=0.1;
   return(lot);
  }
//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
void CheckForOpen()
  {
   double ma;
   int    res;
//---- go trading only for first tiks of new bar
   if(Volume[0]>1) return;
//---- get Moving Average 
   ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);
//---- sell conditions
   if(Open[1]>ma && Close[1]<ma)  
     {
      res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);
      return;
     }
//---- buy conditions
   if(Open[1]<ma && Close[1]>ma)  
     {
      res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);
      return;
     }
//----
  }
//+------------------------------------------------------------------+
//| Check for close order conditions                                 |
//+------------------------------------------------------------------+
void CheckForClose()
  {
   double ma;
//---- go trading only for first tiks of new bar
   if(Volume[0]>1) return;
//---- get Moving Average 
   ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,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;
      //---- check order type 
      if(OrderType()==OP_BUY)
        {
         if(Open[1]>ma && Close[1]<ma) OrderClose(OrderTicket(),OrderLots(),Bid,3,White);
         break;
        }
      if(OrderType()==OP_SELL)
        {
         if(Open[1]<ma && Close[1]>ma) OrderClose(OrderTicket(),OrderLots(),Ask,3,White);
         break;
        }
     }
//----
  }
//+------------------------------------------------------------------+
//| Start function                                                   |
//+------------------------------------------------------------------+
void start()
  {
//---- check for history and trading
   if(Bars<100 || IsTradeAllowed()==false) return;
//---- calculate open orders by current symbol
   if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
   else                                    CheckForClose();
//----
  }
//+------------------------------------------------------------------+
 
BarrowBoy:

> ...more than likely there is some fundamental aspect to the market that I've somehow never managed to come across or comprehend...

Thats the one - well there's several aspects actually :)

An inherent problem with all flavours of moving average is lag

Also consider that:-

- looking at one timeframe alone will limit success - think of the daily or weekly situation and trade in that direction

- most strategies will need time-of-day to filter trades, also time-of-year and maybe time-of-month

- if you get a good trade going with a moving average, use something else to indicate close point - either a trend weakening indicator or a retrace warning like the SFX_MA_On_CCI

See here & here for another members ideas on not using moving averages!

IIRC - even the sample MACD EA gives a better curve than the MA EA - dont use either on live accounts though!

-BB-


Thank you very much for your suggestions.
Reason: