Empty Results in Strategy Tester

 

Ok.
Here's my scenario.

I have built my first EA successfully...it opens and closes trades. However, it does this based on instructions it obtains from my first Custom Indicator. (using "iCustom()" function)

ok...everything seems to be working, but when I back test using the Strategy tester, I get NO results...nothing...zip!

Is it because the signals are originated in my custom indicator and not in the Expert itself?


Thanks,

R.

 

Tenners wrote >>

...everything seems to be working, but when I back test using the Strategy tester, I get NO results...nothing...zip!

Is it because the signals are originated in my custom indicator and not in the Expert itself?

Did u download data for the symbol/dates tested (u can check in the history center)?

Do u have any errors in the journal/experts logs?

 

What is the indicator and did you provide the indicator's parameters in your Icustom call?

Right click on the optimize results tab and select show useless results.

 
gordon:

Did u download data for the symbol/dates tested (u can check in the history center)?

Do u have any errors in the journal/experts logs?


gordon,

yes I did download the data from the History center. No errors in my experts logs either...everything seems normal there.

I am printing to the logs at various steps in the EA and it seems to show that everything is running fine.

 
WHRoeder:

What is the indicator and did you provide the indicator's parameters in your Icustom call?

Right click on the optimize results tab and select show useless results.


Yes WHRoeder,

I did provide the parameters in my iCustom call. When running on my demo acct. it behaves as it should.

It just yields nothing in the back test...

 
Have you put a print out just before each order send command because if it gets there it must either take a trade or give an error.
 

Most likely your problem is either OrderSend() is never triggered (signal forming problem) or OrderSend() has errors (OrderSend() inputs problem).

As Ruptor suggests, just put Print() statements in strategic locations to pinpoint the problem.
 
gordon:

Most likely your problem is either OrderSend() is never triggered (signal forming problem) or OrderSend() has errors (OrderSend() inputs problem).

As Ruptor suggests, just put Print() statements in strategic locations to pinpoint the problem.

Thanks gordon and Ruptor,

I have been writing to debug logs but I can't seem to decipher where the problem is yet. I will try the Print() function.

 
gordon:

Most likely your problem is either OrderSend() is never triggered (signal forming problem) or OrderSend() has errors (OrderSend() inputs problem).

As Ruptor suggests, just put Print() statements in strategic locations to pinpoint the problem.

Ok guys,

I've tried everything I thought could be the issue....I'm posting my code here for both my EA and my CustomIndicator....Please run them and see if you can help me figure out what the issue is.

I really think I need another set of eyes....


Thanks,

R.


//////////////// Expert Advisor ////////////////////////

//////////////// Expert Advisor ////////////////////////

//////////////// Expert Advisor ////////////////////////


//---- Description-----------------------------------+
/*
Trading Setup:
1. First Moving average with period 20 is applied to the close price. We
use moving averages to help us identify a new trend as early as possible.


Trading Rules
Stop Loss = 30 pips

Entry Rules
1. Enter long (Buy signal) if:
The current candle opens above the 20 MA and the previous candle crossed above the 20 MA and closed above the 20 MA

2. Enter short (Sell signal) if:
The current candle opens below the 20 MA and the previous candle crossed below the 20 MA and closed below the 20 MA

Exit Rules
Exit when the current candle crosses the 20 EMA in the opposite direction of your trade
*/

#include <stdlib.mqh>

//---- Global Variables --------------------------------------------+
//---- Trading Parameters ----------------------------------------+
extern string ____Trade_Options_____;
extern int TakeProfit = 100; // TakeProfit (in Pips); 0 - is not used
extern int StopLossPercent = 0; // StopLossPercent (%); 0 - is not used
extern int StopLoss = 25; // Only used if StopLossPercent == 0;
extern bool OnlyAfterCloseBar = false; // signal checking type: true - only first tick on just closed bar, false - on every tick
//---- FAST Moving Average Variables --------------------------------------+
extern string ____MA________________;
extern int MA_Period = 20; // Fast MA Period
extern int MA_Method = 1; // Type of MA: 0-Simple, 1-Exponential, 2-Smoothed, 3-Weighted
extern int MA_Price = 0; // Price of Fast MA: 0-6 PRICE_CLOSE,PRICE_OPEN,PRICE_HIGH,PRICE_LOW,PRICE_MEDIAN,PRICE_TYPICAL,PRICE_WEIGHTED
//---- Money Management MM ----------------------------------------------+
extern string _____Size_of_lots_____;
extern bool UseMM = false; // turn on/off the autoLot MM: false = fixed (Lots); true = we use % of free margin (VolumePosition)
extern double Lots = 0.1; // lot size if UseMM = false
extern double VolumePosition = 1.5; // % of free margin used to open new positions
//---- Technical Parameters ---------------------------------------+
extern string _____Others___________;
//extern int MagicNumber = 20081103; // "Magic number
extern int MagicNumber = 20100217; // "Magic number"
extern string ExpertComment = "RD_TestEA_2.3"; // Comments in LOG
extern color ColorBuy = Green; // Color for Long
extern color ColorSell = Red; // Color for Short
extern bool WriteLog = true; // true - writes log
extern bool WriteDebugLog = true; // true - writes debug log

//----- Global variables ---------------------------------------+
static bool first_run = true;
static bool inBuy = false;
static bool inSell = false;
static int digits;
static datetime bartime;
static double maxlots;
static double minlots;
static double MarginForLotStep;
static double LotStep;
static double point;
static string symbol;
static int maxOpenDirectionalTradesLimit = 2; //ONE trade per direction at any time!!!
int existingBuyTradeCount = 0;
int existingSellTradeCount = 0;


double MA_;
double MA_1;
double MA_2;




//---- Initialization of Expert Advisor --------------------------------------+
int init()
{
if(WriteLog || WriteDebugLog) Print("*************************** init() ***************************");
symbol = Symbol();
maxlots = MarketInfo(symbol,MODE_MAXLOT);
minlots = MarketInfo(symbol,MODE_MINLOT);
LotStep = MarketInfo(symbol,MODE_LOTSTEP);
digits = MarketInfo(symbol,MODE_DIGITS);
MarginForLotStep = MarketInfo(symbol,MODE_MARGINREQUIRED)*LotStep;

if(Digits < 4)
{
point = 0.01;
digits = 2;
}
else
{
point = 0.0001;
digits = 4;
}

if(first_run)
{
bartime = Time[0];
first_run = false;
}


//---- initialization done

return(0);
}

//---- Deinitialization ------------------------------------+
int deinit()
{
if(WriteLog || WriteDebugLog) Print("************************** deinit() **************************");
return(0);
}

//----Every Tick Function --------------------------------------------+
int start()
{
if(WriteLog || WriteDebugLog) Print("************************** start() **************************");
//MA_ = 0;

//*** Initiate StopToUse
int StopToUse = StopLoss;

//---- Checking if trading is allowed ----------------------------+
if(!IsTradeAllowed())
{
if(!IsExpertEnabled()) if(WriteLog || WriteDebugLog) Print("For EA the trade is not allowed.");
if(IsTradeContextBusy()) if(WriteLog || WriteDebugLog) Print("Trade context is busy.");
return(0);
}
datetime c_time = Time[0];
if(OnlyAfterCloseBar)
{
if(bartime == c_time) return(0);
bartime = c_time;
int shift = 1;
if(WriteDebugLog) Print("---------------- Have a start New Bar at ",TimeToStr(bartime)," ----------------");
}
else
{
shift = 0;
if(WriteDebugLog) Print("---------------- Have a new tick at ",TimeToStr(TimeCurrent(),TIME_DATE|TIME_MINUTES|TIME_SECONDS)," ----------------");
}
//---- Signal for closure ---------------------------------+


//---- Main Signal
//--------------------------------------------------------------- 5 --
// Trading criteria (Used in communication with Custom Indicator "RD_CustInd_1.3"
int B = 9999999999; // Amount of bars in calc. history
int P = MA_Period; // Period of calculation MA
int T = MA_Method; // Amount of bars for rate calc.
int Pr = MA_Price; // Part of Candle Stick used for calc. (Close, Open, etc.)
double CP = Period(); //Chart Period/timeframe
//-------------------------------------------------------------- 5a --
// Determine If there is a buy or sell signal
int trade_signal = 0;
int signal;
double arrowUp = iCustom(symbol,CP,"RD_CustInd_1.3",B,P,T,Pr,CP,WriteLog,WriteDebugLog,0,0); //buy if != 0
double arrowDown = iCustom(symbol,CP,"RD_CustInd_1.3",B,P,T,Pr,CP,WriteLog,WriteDebugLog,1,0); //sell if != 0

int au = NormalizeDouble(arrowUp,1);
int ad = NormalizeDouble(arrowDown,1);

Print("au:",au);
Print("ad:",ad);

if(WriteLog || WriteDebugLog) Print("*** ArrowUP: ",arrowUp," | ArrowDown: ",arrowDown," ***");

if( au == 0 && ad > 0 ){ // We have a down Arrow
trade_signal = -1;
signal = OP_SELL;
}
if( au > 0 && ad == 0 ){ // We have an up Arrow
trade_signal = 1;
signal = OP_BUY;
}
if(trade_signal == 0)
signal = -10; // No buy or sell

if(WriteLog || WriteDebugLog) Print("*** Signal: ",signal," ***");
//------------------------------------------------------------------
//------------------------------------------------------------------
//------------------------------------------------------------------
//------------------------------------------------------------------
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// Trading Steps:
//1. Check if there are any open trades
//2. (a) If there are open trades in the opposite direction of new signal
// - close them all (active & pending)
// - open new trade
// (b) If there are open trades in the same direction of new signal
// - open new trade
// (c) If there are NO OPEN TRADES
// - open new trade

if(signal != -10)
{
if( CloseOppositePositions(signal) < 0 ) // Close any opposite positions
{
if(WriteDebugLog) Print("Open Positions Successfully closed.");
}

if( StopLossPercent > 0 )
StopToUse = MathRound(TakeProfit*(StopLossPercent/100));

if( OpenPosition(signal, StopToUse, TakeProfit ) > 0 ) // Place new order
{
if(WriteDebugLog) Print("Position Taken Successfully!");
}
else
{
if(WriteDebugLog) Print("Position/Trade NOT Taken!");
}
}

return(0);
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//------------------------------------------------------------------
//------------------------------------------------------------------
//------------------------------------------------------------------
//------------------------------------------------------------------



////////////////////////////// Functions /////////////////////////////////////



//---- CloseOppositePositions -------------------------------------------+
int CloseOppositePositions(int a)
{
RefreshRates();
if(a == OP_BUY) color CloseColor = ColorBuy;
else CloseColor = ColorSell;
int numpos = 0;
int return_code = 0;
int spread = MarketInfo(symbol,MODE_SPREAD);
int total = OrdersTotal() - 1;
for(int i=total; i>=0; i--)
{
if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(WriteDebugLog) Print("CloseHavePositions: OrderSelect() error = ",GetLastError());
continue;
}
if(OrderMagicNumber() != MagicNumber) continue;
if(OrderSymbol() != symbol) continue;
if(OrderType() == a) // *** if current Order is same type as new signal -- leave it!
{
numpos++;
continue;
}
else // *** if current Order is opposite type of new signal --- close it!
{
while(!IsTradeAllowed()) Sleep(1000);
bool error = OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),spread,CloseColor);
if(!error)
{
if(WriteDebugLog)
{
if(a == OP_BUY) string ot = "OP_BUY";
else ot = "OP_SELL";
Print("CloseHavePositions: OrderClose(",ot,") error = ",GetLastError());
}

//*** Decrease Existing Opposite Trade count
if(a == OP_BUY)
existingSellTradeCount--;
else
existingBuyTradeCount--;

if(existingSellTradeCount < 0)
existingSellTradeCount = 0;
if(existingBuyTradeCount < 0)
existingBuyTradeCount = 0;

return_code = -1;
}
}
}
if(return_code != 0) return(return_code);
return(numpos);
}



//---- Open Position ------------------------------------------------+
int OpenPosition(int cmd, double sl, double tp)
{
//*** Print What Open Position Params are
if(WriteLog || WriteDebugLog) Print("--> OpenPosition Params: cmd:",cmd," | sl:",sl," | tp:",tp," <--");

//*** Check to see if we already have the limit of open trades in the signal direction
if(cmd == OP_BUY)
{
if(existingBuyTradeCount == maxOpenDirectionalTradesLimit)
{
if(WriteLog || WriteDebugLog) Print("OpenPosition: Already have ",maxOpenDirectionalTradesLimit," trades open in this direction!");
return(-1);
}
}
if(cmd == OP_SELL)
{
if(existingSellTradeCount == maxOpenDirectionalTradesLimit)
{
if(WriteLog || WriteDebugLog) Print("OpenPosition: Already have ",maxOpenDirectionalTradesLimit," trades open in this direction!");
return(-1);
}
}


bool goodBuy = false;
bool goodSell = false;
string soundFileBuy = "/rdc/button-5.wav";
string soundFileSell = "/rdc/beep-3.wav";
string soundToPlay;
double Lot = LotsOptimized();

if(AccountFreeMarginCheck(symbol,cmd,Lot) <= 0 || GetLastError() == 134) //ERR_NOT_ENOUGH_MONEY
{
if(WriteLog || WriteDebugLog) Print("OpenPosition: you don\'t have free margin.");
return(-1);
}
RefreshRates();
int stoplevel = NormalizeDouble((MarketInfo(symbol,MODE_STOPLEVEL))*point,digits); //Min. Distance

if(cmd == OP_BUY) // Buy Signal
{
double price = NormalizeDouble(Ask,digits);
color cmd_color = ColorBuy;
if(sl == 0) double stoploss = 0;
else
{
if(sl <= stoplevel)
{
if(WriteLog || WriteDebugLog){
Print("OpenPosition: it is impossible to open a position: stop-loss is near to the open price.");
Print("+++ sl: ",sl," && market stoplevel: ",stoplevel," +++ BuyAttempt +++");
}
return(0);
}
stoploss = NormalizeDouble(price - sl*point,digits); //calculate actual Stop Loss Price Value
}
if(tp == 0) double takeprofit = 0;
else
{
if(tp <= stoplevel)
{
if(WriteLog || WriteDebugLog) Print("OpenPosition: it is impossible to open a position: take-profit is near to the open price.");
return(0);
}
takeprofit = NormalizeDouble(price + tp*point,digits);
//PlaySound(""); //Buy Sound
soundToPlay = soundFileBuy;
goodBuy = true;
}
}
else
{
price = NormalizeDouble(Bid,digits);
cmd_color = ColorSell;
if(sl == 0) stoploss = 0;
else
{
if(sl <= stoplevel)
{
if(WriteLog || WriteDebugLog){
Print("OpenPosition: it is impossible to open a position: stop-loss is near to the open price.");
Print("--- sl: ",sl," && market stoplevel: ",stoplevel," --- SellAttempt ---");
}
return(0);
}
stoploss = NormalizeDouble(price + sl*point,digits);
}
if(tp == 0) takeprofit = 0;
else
{
if(tp <= stoplevel)
{
if(WriteLog || WriteDebugLog) Print("OpenPosition: it is impossible to open a position: take-profit is near to the open price.");
return(0);
}
takeprofit = NormalizeDouble(price - tp*point,digits);
//PlaySound(""); //Sell Sound
soundToPlay = soundFileBuy;
goodSell = true;
}
}
int ticket = OrderSend(symbol,cmd,Lot,price,MarketInfo(symbol,MODE_SPREAD),stoploss,takeprofit,ExpertComment,MagicNumber,0,cmd_color);
if(ticket < 0)
{
if(WriteLog || WriteDebugLog)
{
if(cmd == OP_BUY) string ot = "OP_BUY";
else ot = "OP_SELL";
Print("OpenPosition: OrderSend(",ot,") error = ",ErrorDescription(GetLastError()));
Print("+++ sl: ",sl," && market stoplevel: ",stoplevel," +++ TradeAttempt +++");
}
}
else
{
if(goodBuy)
existingBuyTradeCount++;
if(goodSell)
existingSellTradeCount++;

if(goodBuy || goodSell) //Play sound to indicate successful buy or sell position opening
PlaySound(soundToPlay);
}

return(ticket);
}


//---- LotsOptimized ------------------------------------------------+
double LotsOptimized()
{
if(!UseMM) double lot = Lots;
else lot = NormalizeDouble(MathFloor(((AccountFreeMargin()*VolumePosition)/100)/MarginForLotStep)*LotStep,2);
if(lot < minlots) lot = minlots;
if(lot > maxlots) lot = maxlots;
return(lot);
}

 
gordon:

Most likely your problem is either OrderSend() is never triggered (signal forming problem) or OrderSend() has errors (OrderSend() inputs problem).

As Ruptor suggests, just put Print() statements in strategic locations to pinpoint the problem.

///////////////////////////////////// Custom Indicator ///////////////////////////////////////////////////

///////////////////////////////////// Custom Indicator ///////////////////////////////////////////////////

///////////////////////////////////// Custom Indicator ///////////////////////////////////////////////////


#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Aqua //up
#property indicator_color2 HotPink //down
#property indicator_color3 Yellow //MA

//---- input parameters
extern int barsToProcess = 10000;
extern int MA_Period = 20; //This value sets the Period for the Moving Average (Exponential)
extern int MA_Type = 1; //0=SMA, 1=EMA
extern int MA_Price = 0; //0=PRICE_CLOSE
extern double chartPeriod = 0;
extern string symbol = "none";
extern bool WriteLog = false; // true - writes log
extern bool WriteDebugLog = false; // true - writes debug log

double MA_;
double MA_1;
double MA_2;
double MA_LINE[];
double ArrowUp[];
double ArrowDown[];
string LastArrow[];
static int digits;
static double point;
static double apos;
double pVar;

//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
if( chartPeriod == 0)
chartPeriod = Period();

if( symbol == "none")
symbol = Symbol();

//if(WriteLog || WriteDebugLog) Print("*** symbol(indicator): ",symbol," ***");
//if(WriteLog || WriteDebugLog) Print("*** chartPeriod(indicator): ",chartPeriod," ***");

if(Digits < 4)
{
point = 0.01;
digits = 2;
pVar = ipm(chartPeriod);

apos = point*pVar; //20;
//Print("Period is ", Period());

}
else
{
point = 0.0001;
digits = 4;
pVar = ipm(chartPeriod);
//Print("Period is ", Period());

apos = point*pVar; //20;
}

//---- indicator buffers mapping
SetIndexBuffer(0, ArrowUp);
SetIndexBuffer(1, ArrowDown);
SetIndexBuffer(2, MA_LINE);
//---- indicators
SetIndexStyle(0, DRAW_ARROW);
SetIndexArrow(0, 233); //225
SetIndexStyle(1, DRAW_ARROW);
SetIndexArrow(1, 234); //226
SetIndexStyle(2,DRAW_LINE,STYLE_SOLID,2);
//SetIndexDrawBegin(2,MA_LINE);

//----
return(0);
}

//+------------------------------------------------------------------+
//| Time Frame Determination |
//+------------------------------------------------------------------+

int ipm(double p) //indicatorPositionMultiplier
{
if (p == PERIOD_M1 ) return (5);
if (p == PERIOD_M5 ) return (10);
if (p == PERIOD_M15) return (20);
if (p == PERIOD_M30) return (20);
if (p == PERIOD_H1 ) return (20);
if (p == PERIOD_H4 ) return (30);
if (p == PERIOD_D1 ) return (200);
if (p == PERIOD_W1 ) return (400);
if (p == PERIOD_MN1) return (800);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
ObjectsDeleteAll();
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
//----
int i;
int i1;
int i2;
int limit;
if(counted_bars < 0)
return(-1);
if(counted_bars > 0)
counted_bars--;
limit = Bars - counted_bars;

if(limit > barsToProcess)
limit = barsToProcess;

for(i=0; i<=limit; i++)
{
SetIndexDrawBegin(2,i);

i1 = i+1;
i2 = i+2;
MA_ = iMA(symbol,0,MA_Period,0,MA_Type,MA_Price,i);
MA_1 = iMA(symbol,0,MA_Period,0,MA_Type,MA_Price,i1);
MA_2 = iMA(symbol,0,MA_Period,0,MA_Type,MA_Price,i2);
MA_LINE[i] = MA_;
//MA1_ = iMA(Symbol(),0,MA_Period,0,MA_Type,PRICE_CLOSE,i);

/*------ Potential Buy */
if( MA_1 >= Open[i1] && MA_1 < Close[i1] ){
/*if( (MA_ <= Open[i]) && (MA_ <= Close[i]) && (Open[i] < Close[i]) )
{
if( (MA_1 >= Open[i1] && MA_1 <= Close[i1]) || (MA_1 <= Open[i1] && MA_1 <= Close[i1]) )
{
if( (Close[i2] > Open[i2]) && (MA_2 >= Close[i2]) )
{*/
if(i>0){
if(LastArrow[i-1] == "down")
ArrowUp[i] = Low[i] - apos;
if(LastArrow[i-1] == "up")
ArrowUp[i] = 0;
else
ArrowUp[i] = Low[i] - apos;
}
else
ArrowUp[i] = Low[i] - apos;

LastArrow[i] = "up";
/*}
}*/
}
/*------ Potential Sell */
if( MA_1 <= Open[i1] && MA_1 > Close[i1] ){
/*if( (MA_ >= Open[i]) && (MA_ >= Close[i]) && (Open[i] > Close[i]) )
{
if( (MA_1 <= Open[i1] && MA_1 > Close[i1]) || (MA_1 >= Open[i1] && MA_1 >= Close[i1]) )
{
if( (Close[i2] < Open[i2]) && (MA_2 <= Close[i2]) )
{*/

if(i>0){
if(LastArrow[i-1] == "up")
ArrowDown[i] = High[i] + apos;
if(LastArrow[i-1] == "down")
ArrowDown[i] = 0;
else
ArrowDown[i] = High[i] + apos;
}
else
ArrowDown[i] = High[i] - apos;

LastArrow[i] = "down";
/*}
}*/
}


}//end for loop

//----
return(0);
}
//+------------------------------------------------------------------+

 
gordon:

Most likely your problem is either OrderSend() is never triggered (signal forming problem) or OrderSend() has errors (OrderSend() inputs problem).

As Ruptor suggests, just put Print() statements in strategic locations to pinpoint the problem.

What I think is happening is that my iCustom() call returns the same value at every tick that it is called by the Expert.

In my Custom Indicator...it seems to work properly...arrows are placed on the chart where they are supposed to be...this is done by considering the following:

1. When conditions are met for a signal...an arrow is placed in the array for that buffer

2. If no signal...the value of the array at that moment is '0'


So...if my iCustom() call should get both ZERO and NON-ZERO values depending on the tick on the chart....not so?

But it seems to get the arrow value at every single tick in my back test.


what am I missing here?

Please help...

Reason: