Sorry Steve, I started this long post right before you added yours above but it took me a while to finish, hence I'm unfortunately saying all this right after you've created a new version. Nevermind, there's no point rushing this stuff...
EDIT: Actually hold fire on making any of the following changes - the reason it's running fast for me now is that it's no longer finding _any_ zones. I'll need to look into this a bit deeper.
Ok, so another thing that's very inefficient about the EA right now is its use of SSSR_UpdateZones(). On every occasion its called, the first parameter is "false", which means the library will recalculate all the S/R zones - a very expensive operation and a completely unnecessary one if it just did the same thing the previous tick.
I'd suggest adding the following function:-
Code: Select all
void CheckSRZones( bool avoidRecalc,
int &res_zone,
int &sup_zone,
int &res_strength,
int &sup_strength,
double &res_hi,
double &res_lo,
double &sup_hi,
double &sup_lo,
bool &InsideResistance,
bool &InsideSupport )
{
//////////////////////////////////////////////////////////////
// Reading the SS_SupportResistance Indi //
//////////////////////////////////////////////////////////////
if(UseSuppRes)
{
//This is an implementation of Andrew Sumner's Support/Resistance Indicator
//To be found at http://www.stevehopwoodforex.com/phpBB3/viewtopic.php?f=27&t=514
SSSR_UpdateZones(avoidRecalc, Symbol(), SRTimeFrame);
res_hi=0; res_lo=0; sup_hi=0; sup_lo=0;
//Finding the support & resistance zones closest to the ask/bid price
res_zone = SSSR_FindZoneV2(SSSR_UP, true, Bid, res_hi, res_lo, res_strength);
sup_zone = SSSR_FindZoneV2(SSSR_DN, true, Bid, sup_hi, sup_lo, sup_strength);
if (res_zone == -1 || sup_zone == -1)
{
SSSR_UpdateZones(true, Symbol(), SRLongerTimeFrame);
if (res_zone == -1)
res_zone = SSSR_FindZoneV2(SSSR_UP, true, Bid, res_hi, res_lo, res_strength);
if (sup_zone == -1)
sup_zone = SSSR_FindZoneV2(SSSR_DN, true, Bid, sup_hi, sup_lo, sup_strength);
}
//Test for being inside a zone.
//Resistance zone cancels buys.
InsideSupport = false;
InsideResistance = false;
if (Bid <= NormalizeDouble(res_hi, Digits) && Bid >= NormalizeDouble(res_lo, Digits))
InsideResistance = true;
//Support zone cancels sells
else if (Bid <= NormalizeDouble(sup_hi, Digits) && Bid >= NormalizeDouble(sup_lo, Digits))
InsideSupport = true;
//Test the Ask
if (Ask <= NormalizeDouble(res_hi, Digits) && Ask >= NormalizeDouble(res_lo, Digits))
InsideResistance = true;
else if (Ask <= NormalizeDouble(sup_hi, Digits) && Ask >= NormalizeDouble(sup_lo, Digits))
InsideSupport = true;
}//if(UseSuppRes)
}
In the places where SSSR_UpdateZones is called, in ReadIndicatorValues() and DisplayUserFeedback(), replace that code with a call to CheckSRZones as follows:-
Code: Select all
//Test for being inside a SR zone.
if (UseSuppRes)
{
double res_hi=0, res_lo=0, sup_hi=0, sup_lo=0;
bool InsideSupport=false, InsideResistance=false, InsideZone=false;
int sup_zone = -1, res_zone = -1, res_strength = 0, sup_strength = 0;
CheckSRZones(true, res_zone, sup_zone, res_strength, sup_strength, res_hi, res_lo, sup_hi, sup_lo, InsideResistance, InsideSupport);
Note that I'm calling it with "true" as the first parameter, which it passes on to the SSSR library telling it not to recalculate the zones unless a new candle has been created since it was previously called.
There is one instance where you may want the EA to call it with a "false" parameter, forcing a zone recalc, and that's right before a new trade is to be sent. I suggest the following in the LookForTradingOpportunities function:-
Code: Select all
}//if (SendShort)
}//if (!SendLong)
////////////////////////////////////////////////////////////////////////////////////////
if (UseSuppRes)
{
if (SendLong || SendShort)
{
double res_hi=0, res_lo=0, sup_hi=0, sup_lo=0;
bool InsideSupport=false, InsideResistance=false, InsideZone=false;
int sup_zone = -1, res_zone = -1, res_strength = 0, sup_strength = 0;
CheckSRZones(false, res_zone, sup_zone, res_strength, sup_strength, res_hi, res_lo, sup_hi, sup_lo, InsideResistance, InsideSupport);
// NOTE: The following lines are called almost exactly in ReadIndicatorValues(), so I suggest
// splitting it off into its own function rather than duplicating it as I've done here.
if (InsideSupport || InsideResistance)
InsideZone = true;
if (DontOpenTradesInsideSRZones && InsideZone)
{
SendLong = false;
SendShort = false;
}
if (OpenSomeTradesInsideSRZones)
{
if (SendLong)
if (Bid <= NormalizeDouble(res_hi, Digits) && Bid >= NormalizeDouble(res_lo, Digits))
SendLong = false;
if (SendShort)
if (Ask <= NormalizeDouble(sup_hi, Digits) && Ask >= NormalizeDouble(sup_lo, Digits))
SendShort = false;
}
}
}//if (UseSuppRes)
////////////////////////////////////////////////////////////////////////////////////////
//Long
if (SendLong)
{
This will force the zones to be recalculated and double-checked before any trades are sent to market. Once I implemented the above in my version, Empty4's CPU usage has dropped to negligible levels except for when the candle changes on the hour, or on the odd occasion when the EA wants to place a trade.