Hardware for Optimization

 
For the purposes of EA development/testing, Im using my Macbook Pro 2.53Gigs/4GB RAM.. I've got Windows 7 running on a virtual machine and all I ever use it for is running metatrader...works very well for the most part except when running backtests & optimizing, it is time-consuming to a point I find unsatisfactory.. I hear the fan in my Macbook start blowing full force and my CPU usage goes up to 100%. Is it really that resource consuming to run a 2000 line program a couple of million times?? I realize how that sounds but c'mon its 2011 for gods sake! Theres more computing power in one square centimeter of my cellphone than there was in the entire Saturn 5 rocket! I cant help but think that if I wasn't doing all of this on a virtual machine, I would see much better performance. I have an old laptop that I leave running to trade a live account but its on its last leg.. running an EA in realtime is about all it can handle... 30 sec of full-speed backtesting and it crashes. I feel like I need to go out and buy a modern PC in order to complete the optimization tasks I need but dont want to jump the gun. What is your hardware like & how fast are your backtests/optimization? Anyone think I should spring for a PC??
 

You're running a (2000 line program plus every indicator/parameter combination called [ima,iatr,icustom]) for 100,000 ticks per test * 100-12000 tests (optimization) * N (mql4 interpreter) * M (VM interpreter). So yes it can take a lot. I've had a full optimization run take about 7 days.

The best way is to not process ticks that can not change anything and don't do unnecessary things.

extern bool     Show.Comments               = true;
int     init(){
    if (IsTesting() && !IsVisualMode()){    Show.Comments   = false;
                                            Show.Objects    = false;    }
...
//+------------------------------------------------------------------+
//| Skip useless ticks                                               |
//+------------------------------------------------------------------+
double  CA.below,   CA.above=0;         // Export to start
void    CallAgain(double when){
    if (when>=Bid && CA.above > when) CA.above = when;
    if (when<=Bid && CA.below < when) CA.below = when;
    return;
}
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int     start(){
    static datetime Time0;                              #define INF 0x7FFFFFFF
    if (Time0 != Time[0] || Bid < CA.below || Bid > CA.above){  // Important
        CA.below = 0;   CA.above = INF;     Time0 = Time[0];
        need2refresh    = false;                // New tick, data is fresh.
        Analyze();                              // Affects ModifyStop and Decide
    }   // Important
    if (Show.Comments) {
        Comment(...

void    Analyze(){
...
    oo.OP = pattern.trigger;
    double  delta = (Bid-oo.OP)*DIR;
    if (delta <= 0){        CallAgain(oo.OP);       return; }   // Below
    if (delta > 0.5*atr){   CallAgain(oo.OP);       return; }   // Gapped above
...
void    ModifyStops(){...
    for(pos = OrdersTotal()-1; pos >= 0 ; pos--) if (
        OrderSelect(pos, SELECT_BY_POS)                 // Only my orders w/
    &&  OrderMagicNumber()  == magic.number             // my magic number
    &&  OrderSymbol()       == Symbol() ){              // and my pair.
        ...
        if(...) ... OrderModify(...)
        CallAgain(oo.SL +stop.to.Bid);
        CallAgain(oo.TP +stop.to.Bid);
...
void TLine( string name, datetime T0, double P0, datetime T1, double P1
          , color clr, bool ray=false ){
    if (!Show.Objects)  return;
    /**/ if(ObjectMove( name, 0, T0, P0 ))      ObjectMove(name, 1, T1, P1);
    else if(!ObjectCreate( name, OBJ_TREND, WINDOW_MAIN, T0, P0, T1, P1 ))
...
 
can you explain how this works a little bit? is this code of an EA or an EA to speed up backtesting?
 

I can't say I entirely understand what this code is doing. In my EAs I use:

int start()
{ 

   if( now != Time[0] )
   { 
      now = Time[0]
      ...update indicators
   }
...
}

I use this to update indicators that are based on the previous bar or later so they are not being processed unnecessarily. My primary signal indicator happens outside of this block so that it updates with every tick.

I also make sure that my position sizing is only being calculated when I call OrderSend. I do this with a function I call getPositionSize(); I use it as the lots argument in OrderSend.

What I haven't figured out is how to avoid enumerating my orders on every tick. It seems necessary to do that in order to have trailing stops...

 
Anomalous:

...

What I haven't figured out is how to avoid enumerating my orders on every tick. It seems necessary to do that in order to have trailing stops...

As trailing stops (should) only move one way, the chances are that you only need check/adjust them when PriceNow causes a HigherHigh or LowerLow in current bar

I also allow price to move a small fraction beyond these limits before actually adjusting SL. Actual code snippet follows

int OrderProcessing.AdjustTSL()
{
// only adjust SL if a higher hi or lower lo this bar
   int ix = 0;
   static double sdBarHi, sdBarLo;
   // if 1st tick of bar, reset Hi & Lo markers
   // NB also reset on new order!
   if(gsdtAdjTSLBarTime != Time[ix])
   {
      gsdtAdjTSLBarTime = Time[ix];
      sdBarHi = 0;
      sdBarLo = 999999999;
   }
   double MinMovement = MarketInfo(Symbol(), MODE_STOPLEVEL) * SLCheckAsPercentOfMinSL / 100.0;
   bool skipTick=true;
   if(sdBarLo - MinMovement > Low[ix])
   {
      skipTick=false;
      sdBarLo = Low[ix];
   }
   if(sdBarHi + MinMovement < High[ix])
   {
      skipTick=false;
      sdBarHi = High[ix];
   }
   if(skipTick)
      return(0);
... check & maybe adjust SLs
 
Anomalous:
What I haven't figured out is how to avoid enumerating my orders on every tick. It seems necessary to do that in order to have trailing stops...

https://www.mql5.com/en/forum/133186

Reason: