Promising, simple CCI based EA.

 

Well I've been learning MQL4 for about a month now, and I'd like to share my first EA. I have intentionally created something very simple. It maintains a decent profit factor over all the historical intervals I've tested for both M5 and M15 time frames on EURUSD. For 04/10/2009 through 04/10/2011 it achieves a profit factor of 1.28. I've removed all risk management and position sizing, and both takeprofit and sloploss are 100 pips. It's edge comes strictly from trading signals.

It works by trailing a 14 period CCI with a variable I call CCItrigger. If CCI goes beyond 100/-100 the trigger is set, and then continues to follow CCI in much the same way a trailing stop follows price. Once CCI retraces to 65% of CCItrigger's greatest excursion beyond 100/-100 we have a buy/sell signal. These same signals are used for closing open positions if SL or TP are never reached.

The faults I find with the signals so far is that it is possible to be in really long, flat trades. I had coded an exit strategy that prevented this but it also knocked me out of too many good trades.

This EA is built strictly for use in the tester, and does not have the order management or error handling features you should expect from an EA used in live trading. It trades minimum position sizes strictly for the purpose of finding signals that lend themselves to a consistent edge. Further development will include increasing this edge with position sizing and risk management.

I'm open to all comments and criticism. Thanks!

Code:

//+------------------------------------------------------------------+
//|                                                   BasicCCIea.mq4 |
//|                                                     Chad Howarth |
//+------------------------------------------------------------------+
#property copyright "Chad Howarth"

////////////////////I N P U T   P A R A M E T E R S////////////////////
extern int     magic       = 19810518;

extern int     MAXorders   = 1;
extern double  MAXlots     = 0.1;

extern double  CCIlimit    = 100.0;
extern double  CCIrebound  = 0.65;
extern int     CCIperiod   = 14;

extern double  TP          = 100;
extern double  SL          = 100;

////////////////////G L O B A L   V A R I A B L E S////////////////////
double   CCItrigger,
         pips2dbl,
         _MINLOT,
         _LOTSTEP,
         _MAXLOT;
        
/////////////////////I N I T ( )   F U N C T I O N/////////////////////
int init()
{
   CCItrigger = 0;

   if( Digits == 5 || Digits == 3 ) pips2dbl = Point * 10;
   else pips2dbl = Point;
     
   SL *= pips2dbl; //adjust stoploss to broker digits
   TP *= pips2dbl; //adjust takeprofit to broker digits
   
   _MINLOT  =  MarketInfo( Symbol(), MODE_MINLOT );
   _LOTSTEP =  MarketInfo( Symbol(), MODE_LOTSTEP );   
   _MAXLOT  =  MarketInfo( Symbol(), MODE_MAXLOT );

   return( 0 ); //end init() function
}

///////////////////D E I N I T ( )   F U N C T I O N///////////////////
int deinit()
{
   return( 0 ); //end deinit() function
}

////////////////////S T A R T ( )   F U N C T I O N////////////////////
int start()
  {
   double CCIsignal = iCCI( NULL, 0, CCIperiod, PRICE_WEIGHTED, 0 );
   
   bool BUYsignal = false, SELLsignal = false;
   
   if( MathAbs( CCIsignal ) > CCIlimit )
   {
      if( MathAbs( CCIsignal ) > MathAbs( CCItrigger ))
         CCItrigger = CCIsignal * CCIrebound;
      else
      {
         if( CCItrigger < 0 ) BUYsignal = true; 
         else if( CCItrigger > 0 ) SELLsignal = true;
         CCItrigger = 0;
      }
   }
   
/*------ check market exit conditions ------*/
   int orders = 0;
   
   for( int i = OrdersTotal() - 1; i >= 0; i-- )
   {
      if( OrderSelect( i, SELECT_BY_POS ))
      {
         if( OrderSymbol() == Symbol() && OrderMagicNumber() == magic )
         {
            double stop;
                       
            if( OrderType() == OP_BUY ) //either close the order or tighten the stops
            {
               if( SELLsignal )
               {
                  OrderClose( OrderTicket(), OrderLots(), Bid, 3, Blue );
               }
               else
               {
                  orders++;
               
               /*---tighten stops---*/
                  stop = getStop();
                  if( OrderStopLoss() < stop )
                     OrderModify( OrderTicket(), OrderOpenPrice(), stop, OrderTakeProfit(), 0, White );
               }
            }
            else if( OrderType() == OP_SELL ) //either close the order or tighten the stops
            {
               if( BUYsignal )
               {
                  OrderClose( OrderTicket(), OrderLots(), Ask, 3, Blue );
               }
               else
               {
                  orders++;
               
               /*---tighten stops---*/
                  stop = getStop();
                  if( OrderStopLoss() > stop )
                     OrderModify( OrderTicket(), OrderOpenPrice(), stop, OrderTakeProfit(), 0, White );
               }               
            }
         }
      }        
   }
   
/*---- check market entrance conditions ----*/
   if( orders < MAXorders ) 
   {
      int ticket;
      
      if( BUYsignal )
      {
         ticket = OrderSend( Symbol(), OP_BUY, getPositionSize(), Ask, 3, 0, 0, "Basic CCI EA", magic, 0, Green );
         OrderModify( ticket, OrderOpenPrice(), Ask - SL, Ask + TP, 0 );
      }
      else if( SELLsignal )
      {
         ticket = OrderSend( Symbol(), OP_SELL, getPositionSize(), Bid, 3, 0, 0, "Basic CCI EA", magic, 0 , Red );
         OrderModify( ticket, OrderOpenPrice(), Bid + SL, Bid - TP, 0 );
      }
   }
   return( 0 ); //end start() function
}

////////////////////H E L P E R   F U N C T I O N S////////////////////
double getPositionSize()
{
   double x = MathMin( MAXlots, MathMax( 0.1, NormalizeDouble( 0.1 * MathSqrt( AccountBalance() / 300.0 ), 1 )));
   return( x );
}

double getStop()
{
   double x;
   if( OrderType() == OP_BUY ) x = Ask - SL;
   else if( OrderType() == OP_SELL ) x = Bid + SL;
   
   return( x );
}
 
Were you by chance born 1981-05-18? Well your EA performed poorly on my data for whatever that's worth.
 

A

The snag with any oscillator is that extended trends do cause them to wave about without conclusive signal - there is usually no absolute overbought level

Even so, for CCI +/- 100 seems very early to be looking for anything significant

IMHO, CCI is one of the better ones for Fx but you are better looking for the CCI to cut back through its moving average to end the trend or start a retrace

See the various free indicators http://www.selectfx.net/free_stuff_ind.htm

Any of them might give you ideas but in particular, look for SFX_MA_On_CCI

Good Luck

-BB-

 
ubzen:
Were you by chance born 1981-05-18? Well your EA performed poorly on my data for whatever that's worth.


Nope, that's actually my girlfriend's birthday. ;) I just turned 35 a week ago.

What data did you test on, out of curiosity?

 
BarrowBoy:

A

The snag with any oscillator is that extended trends do cause them to wave about without conclusive signal - there is usually no absolute overbought level

Even so, for CCI +/- 100 seems very early to be looking for anything significant

IMHO, CCI is one of the better ones for Fx but you are better looking for the CCI to cut back through its moving average to end the trend or start a retrace

See the various free indicators here

Any of them might give you ideas but in particular, look for SFX_MA_On_CCI

Good Luck

-BB-


Thanks for the tips. I have noticed the problem with long, slow trends. I am sold on CCI, though. I get better signals than I do with any other single indicator I've tried. I've made several attempts at improving this EA, but most of them simply result in a drastic decrease in the number of trades it makes. Profit factor may go up, but the number of trades is reduced by a factor of 5 or more. At one point I had an exit signal that would trigger on a count of CCI crosses beyond 175/-175. I was also calculating something I called "profit slope" to identify those long flat trades, and I would use it to set stops that would get me out of them. The code above is the cleaned up, untangled mess that I salvaged from all my attempts to improve it.

I will look at the indicator you have suggested. Thanks!

 
Anomalous:


Nope, that's actually my girlfriend's birthday. ;) I just turned 35 a week ago.

What data did you test on, out of curiosity?


Here's the data I'm currently using.
Reason: