If anyone out there is interested I fixed it.
I had to set the template of the strategy tester to a template that actually included the indicator so that the lines that it was calling values from were actually drawn on the chart.
You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
I have written an EA that uses the iCustom function to call values from 3 BufferArrays from a custom indicator that I also wrote and then the EA decides to enter or exit trades based on these three values. I can confirm that the EA and Indicator are working properly because I have tested them on a Demo account and I use the EA to print these three values to the 'experts' window in mt4. However, when I try to backtest this system using Strategy Tester only the IndRSI value (see below) is correct the other two values are being calculated as '0'. I can confirm this because in the 'Journal' section of the strategy tester, the EA prints out the three values. The code is exactly the same between the Demo account and the Strategy Tester.
Initially I thought that there may have been an error with the iCustom function and that it may not be compatible with Strategy Tester; however, once I checked the 'Journal' section of the Strategy Tester I noticed that the IndRSI variable was being passed correctly from the Indicator to the EA.
The three BufferArrays from the Inidicator are as follows, I have also included a short description of what each BufferArray is:
{
if(Bars > OldBars) //if there is a new bar then...
{
OldBars = Bars;
//--------GET DATA---------//
LongTLRSI = iCustom(NULL, 0, "RSI Local Peaks & Troughs_C1 - Trade", 3, 1);
ShortTLRSI = iCustom(NULL, 0, "RSI Local Peaks & Troughs_C1 - Trade", 4, 1);
IndRSI = iCustom(NULL, 0, "RSI Local Peaks & Troughs_C1 - Trade", 2, 1);
Print("Previous Bar's RSI Value is " + IndRSI);
Print("Previous Bar's Long Trendline RSI is " + LongTLRSI);
Print("Previous Bar's Short Trendline RSI is " + ShortTLRSI);
IndRSI -----------------> Value of the RSI at the previous bar
LongTLRSI -----------------> Value of 'long' trendline drawn on the RSI subwindow at the previous bar
ShortTLRSI -----------------> Value of 'short' trendline drawn on the RSI subwindow at the previous bar
Here is a screenshot showing the printed values from the above code when tested on a Demo account in realtime - from the 'Experts' section
Here is a screenshot showing the printed values from the above code when backtested using Strategy Tester - from the 'Journal' section
I have included the indicator code below. I can also provide the EA code; however, I do not think that the issue lies in the EA because clearly the values that the EA is being provided from the iCustom function are incorrect.
PLEASE HELP!!!!!
#property link "http://www.the-lazy-trader.com"
#property description "Hidden and regular RSI divergence indicator"
#property version "1.0"
#property indicator_separate_window
#property indicator_buffers 6
#property indicator_level1 30
#property indicator_level2 70
#property indicator_minimum -10
#property indicator_maximum 90
#define arrowsDisplacement 0.0003
input string RSI_settings = "----------------------------------------------------------------------";
input int RSI_period = 14;
input ENUM_APPLIED_PRICE RSI_applied_price = 0;
input string Indicator_settings = "----------------------------------------------------------------------";
input bool DrawIndicatorTrendLines = true;
input bool DrawPriceTrendLines = true;
input bool DisplayAlert = false;
input bool DisplayClassicalDivergences = true;
input bool DisplayHiddenDivergences = false;
input color LongColour = clrLimeGreen;
input color ShortColour = clrDeepPink;
input uchar LongArrowCode = 233;
input uchar ShortArrowCode = 234;
input int ArrowSize = 0;
input color RSIColour = clrGoldenrod;
input ENUM_LINE_STYLE RSIStyle = 0;
input int RSIWidth = 1;
//---- buffers
//double bullishDivergence[];
//double bearishDivergence[];
double rsi[];
double divergencesType[];
double LongTLRSI[];
double ShortTLRSI[];
//----
static datetime lastAlertTime;
static string indicatorName;
string RSITroughLine,RSIPeakLine;
string OldLongTLName, OldShortTLName;
void OnInit()
{
int t1;
//---- indicators
SetIndexStyle(2,DRAW_LINE,RSIStyle,RSIWidth,RSIColour);
t1=3;
while(t1<=0)
{
SetIndexStyle(t1,DRAW_NONE);
t1++;
}
//----
SetIndexBuffer(2, rsi);
SetIndexBuffer(3, LongTLRSI);
SetIndexBuffer(4, ShortTLRSI);
//----
indicatorName=StringConcatenate("RSI Trendlines (",RSI_period,", ",RSI_applied_price,")");
SetIndexDrawBegin(3,RSI_period);
IndicatorDigits(Digits() + 2);
IndicatorShortName(indicatorName);
RSITroughLine = "RSI Trough Line";
RSIPeakLine = "RSI Peak Line";
}
void OnDeinit(const int reason)
{
if (!IsTesting()) {RemoveObjects("RSIDiv ");}
}
int start()
{
int countedBars = IndicatorCounted();
if (countedBars < 0)
countedBars = 0;
CalculateIndicator(countedBars);
return(0);
}
void CalculateIndicator(int countedBars)
{
for(int i = Bars - countedBars; i >= 0; i--)
{
CalculateRSI(i);
DrawLongTrends(i + 2);
DrawShortTrends(i + 2);
GetLongTrendVal(i + 1);
GetShortTrendVal(i + 1);
}
}
void CalculateRSI(int x1)
{
rsi[x1] = iRSI(Symbol(),PERIOD_CURRENT,RSI_period,RSI_applied_price,x1);
}
void GetLongTrendVal(int shift)
{
double LongTLVal = ObjectGetValueByShift(RSITroughLine, shift);
//Print(shift);
//Print("Most recent Long TL Val is " + LongTLVal);
if(shift == 1)
{
LongTLRSI[shift] = LongTLVal;
if(LongTLRSI[shift] == 0 ) Comment("NOTHING");
Comment(Bars);
}
}
void GetShortTrendVal(int shift)
{
double ShortTLVal = ObjectGetValueByShift(RSIPeakLine, shift);
if(shift == 1) ShortTLRSI[shift] = ShortTLVal;
}
void DrawLongTrends(int shift)
{
int t4;
datetime h1,h2;
string s7;
if(IsIndicatorTrough(shift) == false)
return;
int currentTrough = shift;
int lastTrough = GetIndicatorLastTrough(shift);
//---Determine if most recent trough is higher than previous trough-----//
if(rsi[currentTrough] < rsi[lastTrough])
{
for(int i = 1; i < Bars; i++)
{
lastTrough = GetIndicatorLastTrough(shift + i);
if(rsi[currentTrough] > rsi[lastTrough]) break;
}
}
//---Delete previous long trendlines---///
ObjectDelete(0, RSITroughLine);
//--Draw Trendline through Troughs--//
h1=Time[currentTrough];
h2=Time[lastTrough];
s7=RSITroughLine;
t4=ChartWindowFind(0,indicatorName);
DrawLongTrendLine(s7,t4,h1,rsi[currentTrough],h2,rsi[lastTrough],LongColour,STYLE_SOLID,1);
}
void DrawShortTrends(int shift)
{
int t4;
datetime h1,h2;
string s7;
if(IsIndicatorPeak(shift) == false) return; //exit function if
int currentPeak = shift;
int lastPeak = GetIndicatorLastPeak(shift);
//---Determine if most recent peak is lower than previous peak-----//
if(rsi[currentPeak] > rsi[lastPeak])
{
for(int i = 1; i < Bars; i++)
{
lastPeak = GetIndicatorLastPeak(shift + i);
if(rsi[currentPeak] < rsi[lastPeak]) break;
}
}
//---Delete previous long trendlines---///
ObjectDelete(0, RSIPeakLine);
//--Draw Trendline through Peaks--//
h1=Time[currentPeak];
h2=Time[lastPeak];
s7=RSIPeakLine;
t4=ChartWindowFind(0,indicatorName);
DrawShortTrendLine(s7,t4,h1,rsi[currentPeak],h2,rsi[lastPeak],ShortColour,STYLE_SOLID,1);
}
bool IsIndicatorPeak(int shift)
{
if(rsi[shift] > rsi[shift+1] && rsi[shift] > rsi[shift-1])
return(true);
else
return(false);
}
bool IsIndicatorTrough(int shift)
{
if(rsi[shift] < rsi[shift+1] && rsi[shift] < rsi[shift-1])
return(true);
else
return(false);
}
int GetIndicatorLastPeak(int shift)
{
for(int j = shift + 2; j < Bars; j++)
{
if(rsi[j] > rsi[j+1] && rsi[j] > rsi[j-1])
return(j);
}
return(-1);
}
int GetIndicatorLastTrough(int shift)
{
for(int j = shift + 2; j < Bars; j++)
{
if(rsi[j] < rsi[j+1] && rsi[j] < rsi[j-1])
return(j);
}
return(-1);
}
void DisplayAlert(string message, int shift)
{
if(shift <= 2 && Time[shift] != lastAlertTime)
{
lastAlertTime = Time[shift];
Alert(message, Symbol(), " , ", Period(), " minutes chart");
}
}
void DrawShortTrendLine(string r6,int x1,datetime x6,double f6,datetime x7,double f7,color x3,int x4,int x5)
{
if (x6==0 && x7==0 && ObjectFind(0,r6)!=-1)
{
ObjectDelete(0,r6);
}
if (x6>0 || x7>0)
{
if (ObjectFind(0,r6)==-1)
{
ObjectCreate(0,r6,OBJ_TREND,x1,x7,f7,x6,f6);
ObjectSetInteger(0,r6,OBJPROP_RAY_RIGHT, true);
//ObjectSetInteger(0,r6,OBJPROP_RAY, false);
}
//ObjectSetInteger(0,r6,OBJPROP_TIME,x6);
//ObjectSetInteger(0,r6,OBJPROP_TIME,1,x7);
//ObjectSetDouble(0,r6,OBJPROP_PRICE,f6);
//ObjectSetDouble(0,r6,OBJPROP_PRICE,1,f7);
ObjectSetInteger(0,r6,OBJPROP_COLOR,x3);
ObjectSetInteger(0,r6,OBJPROP_STYLE,x4);
ObjectSetInteger(0,r6,OBJPROP_WIDTH,x5);
}
}
void DrawLongTrendLine(string r6,int x1,datetime x6,double f6,datetime x7,double f7,color x3,int x4,int x5)
{
if (x6==0 && x7==0 && ObjectFind(0,r6)!=-1)
{
ObjectDelete(0,r6);
}
if (x6>0 || x7>0)
{
if (ObjectFind(0,r6)==-1)
{
ObjectCreate(0,r6,OBJ_TREND,x1,x7,f7,x6,f6);
ObjectSetInteger(0,r6,OBJPROP_RAY_RIGHT, true);
//ObjectSetInteger(0,r6,OBJPROP_RAY, false);
}
//ObjectSetInteger(0,r6,OBJPROP_TIME,x6);
//ObjectSetInteger(0,r6,OBJPROP_TIME,1,x7);
//ObjectSetDouble(0,r6,OBJPROP_PRICE,f6);
//ObjectSetDouble(0,r6,OBJPROP_PRICE,1,f7);
ObjectSetInteger(0,r6,OBJPROP_COLOR,x3);
ObjectSetInteger(0,r6,OBJPROP_STYLE,x4);
ObjectSetInteger(0,r6,OBJPROP_WIDTH,x5);
}
}
void RemoveObjects(string r6)
{
int t1;
t1=ObjectsTotal()-3;
while(t1>=0)
{
if (StringFind(ObjectName(t1),r6,0)!=-1)
{
ObjectDelete(0,ObjectName(t1));
}
t1--;
}
}