Hi,
I’m in the process of trying to replicate a custom indicator from MT4 for the MT5 that is based off the turtle trading breakout strategy. The strategy in this example generates a trade signal at the breakout of the 20 day high for a long entry and 20 day low for a short entry. Furthermore, after taking a long position for example, it will exit the position after a 10 day low and the opposite for a short position.
...Hi angevoyageur,
Attached below is the MT4 indicator I am trying to replicate. It is essentially a free indicator I downloaded from pointzero-indicator.com.
When first trying to migrate the indicator from MT4 to MT5, I had only changed the syntax to the extent it was MT5 compatible but kept the logic the same. However, when I tried to compile in MT5, it kept on giving me an "Array out of range error" and pointed to the TrendDirection[i] = TrendDirection[i+1] as being the cause. It struck me as odd because I thought dynamic arrays would not experience such errors and thought it might have something to do with decrementing the loop from rates_total to 0 instead of the other way around. Changing the direction of the loop didn't fix the problem and the MT5 code you see above is how far I've progressed on the matter.
If you could help shed any light that would be much appreciated.
Thanks.
Peter
//+------------------------------------------------------------------+ //| TheTurtleTradingChannel.mq4 //| Copyright © Pointzero-indicator.com //+------------------------------------------------------------------+ #property copyright "Copyright © Pointzero-indicator.com" //---- indicator settings #property indicator_chart_window #property indicator_buffers 7 #property indicator_color1 DodgerBlue #property indicator_color2 Red #property indicator_color3 Yellow #property indicator_color4 Yellow #property indicator_color5 DodgerBlue #property indicator_color6 Red #property indicator_width1 3 #property indicator_width2 3 #property indicator_width3 1 #property indicator_width4 1 #property indicator_width5 1 #property indicator_width6 1 #property indicator_style3 STYLE_DOT #property indicator_style4 STYLE_DOT #property indicator_style5 STYLE_DOT #property indicator_style6 STYLE_DOT //---- indicator parameters extern int TradePeriod = 20; // Donchian channel period for trading signals extern int StopPeriod = 10; // Donchian channel period for exit signals extern bool Strict = false; // Apply strict entry parameters like the Turtles did extern bool DisplayAlerts = false; // You know... //---- indicator buffers double ExtMapBuffer1[]; double ExtMapBuffer2[]; double ExtMapBuffer3[]; double ExtMapBuffer4[]; double ExtMapBuffer5[]; double ExtMapBuffer6[]; double TrendDirection[]; //---- internal static datetime TimeStamp; static int AlertCount = 1; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { // One more invisible buffer to store trend direction IndicatorBuffers(7); // Drawing settings SetIndexStyle(0,DRAW_LINE); SetIndexStyle(1,DRAW_LINE); SetIndexStyle(2,DRAW_LINE); SetIndexStyle(3,DRAW_LINE); SetIndexStyle(4,DRAW_ARROW); SetIndexArrow(4,159); SetIndexStyle(5,DRAW_ARROW); SetIndexArrow(5,159); IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)); // Name and labels IndicatorShortName("Turtle Channel ("+ TradePeriod +"-"+ StopPeriod +")"); SetIndexLabel(0,"Upper line"); SetIndexLabel(1,"Lower line"); SetIndexLabel(2,"Longs Stop line"); SetIndexLabel(3,"Shorts Stop line"); SetIndexBuffer(4, "Bullish trend change"); SetIndexBuffer(5, "Bearish trend change"); // Buffers SetIndexBuffer(0,ExtMapBuffer1); SetIndexBuffer(1,ExtMapBuffer2); SetIndexBuffer(2,ExtMapBuffer3); // Stop level for longs SetIndexBuffer(3,ExtMapBuffer4); // Stop level for shorts SetIndexBuffer(4,ExtMapBuffer5); SetIndexBuffer(5,ExtMapBuffer6); SetIndexBuffer(6,TrendDirection); return(0); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { // More vars here too... int start = 0; int limit; int counted_bars = IndicatorCounted(); // check for possible errors if(counted_bars < 0) return(-1); // Only check these limit = Bars - 1 - counted_bars; // Check the signal foreach bar for(int i = limit; i >= start; i--) { // Highs and lows double rhigh = iHigh(Symbol(),Period(),iHighest(Symbol(), Period(), MODE_HIGH, TradePeriod,i+1)); double rlow = iLow(Symbol(),Period(),iLowest(Symbol(), Period(), MODE_LOW, TradePeriod, i+1)); double shigh = iHigh(Symbol(),Period(),iHighest(Symbol(), Period(), MODE_HIGH, StopPeriod,i+1)); double slow = iLow(Symbol(),Period(),iLowest(Symbol(), Period(), MODE_LOW, StopPeriod, i+1)); // Candle value double CLOSE = iClose(Symbol(),0, i); double HIGH = iHigh(Symbol(),0, i); double LOW = iLow(Symbol(),0, i); // Default behavior is to preserve the trend TrendDirection[i] = TrendDirection[i+1]; // It might be recalculating bar zero ExtMapBuffer1[i] = EMPTY_VALUE; ExtMapBuffer2[i] = EMPTY_VALUE; ExtMapBuffer3[i] = EMPTY_VALUE; ExtMapBuffer4[i] = EMPTY_VALUE; ExtMapBuffer5[i] = EMPTY_VALUE; ExtMapBuffer6[i] = EMPTY_VALUE; // Change to uptrend if((CLOSE > rhigh && i > 0)) { TrendDirection[i] = OP_BUY; ExtMapBuffer5[i] = rlow; // Change to downtrend } else if((CLOSE < rlow && i > 0)) { TrendDirection[i] = OP_SELL; ExtMapBuffer6[i] = rhigh; } // Draw lines if(TrendDirection[i] == OP_BUY) { ExtMapBuffer1[i] = rlow; ExtMapBuffer3[i] = slow; // Draw lines } else if(TrendDirection[i] == OP_SELL) { ExtMapBuffer2[i] = rhigh; ExtMapBuffer4[i] = shigh; } } // Alert if(TimeStamp != Time[0] && DisplayAlerts == true) { if(TrendDirection[1] == OP_SELL && TrendDirection[2] == OP_BUY && AlertCount == 0) { Alert("[Turtle Trading "+ TradePeriod +"-"+ StopPeriod +"]["+ Symbol() +"] SELL"); } else if (TrendDirection[1] == OP_BUY && TrendDirection[2] == OP_SELL && AlertCount == 0) { Alert("[Turtle Trading "+ TradePeriod +"-"+ StopPeriod +"]["+ Symbol() +"] BUY"); } TimeStamp = Time[0]; AlertCount = 0; } // Bye Bye return(0); }

- www.mql5.com
Hi angevoyageur,
Attached below is the MT4 indicator I am trying to replicate. It is essentially a free indicator I downloaded from pointzero-indicator.com.
When first trying to migrate the indicator from MT4 to MT5, I had only changed the syntax to the extent it was MT5 compatible but kept the logic the same. However, when I tried to compile in MT5, it kept on giving me an "Array out of range error" and pointed to the TrendDirection[i] = TrendDirection[i+1] as being the cause. It struck me as odd because I thought dynamic arrays would not experience such errors and thought it might have something to do with decrementing the loop from rates_total to 0 instead of the other way around. Changing the direction of the loop didn't fix the problem and the MT5 code you see above is how far I've progressed on the matter.
If you could help shed any light that would be much appreciated.
Thanks.
Peter
I will check that. As a remark, when you post complete code of an indicator (or EA/script), it's more useful to use the Attach file link, so we only have to download it.
Ok no problem, thanks for the heads up.
PV
The more obvious way to convert from mql4 if you are not accustomed with mql5 is by using ArraySetAsSeries() to have the indexing of arrays working like in mt4.
ArraySetAsSeries(ExtMapBuffer1,true); ... ...
You also have to take into account TradePeriod & StopPeriod to calculate "first" and then avoid out of range error.
if(prev_calculated==0) { first=rates_total-1-MathMax(TradePeriod,StopPeriod); TrendDirection[first+1]=0; } else first=rates_total-1-prev_calculated;
Finally you make a little on error low calculation, you have to use ArrayMinimum instead of ArrayMaximum :
double rlow = low[ArrayMinimum(low,i+1,TradePeriod)];
See working full code attached.
The more obvious way to convert from mql4 if you are not accustomed with mql5 is by using ArraySetAsSeries() to have the indexing of arrays working like in mt4.
You also have to take into account TradePeriod & StopPeriod to calculate "first" and then avoid out of range error.
Finally you make a little on low calculation, you have to use ArrayMinimum instead of ArrayMaximum :
See working full code attached.
Hi Alain,
Wow you make it look very easy. I did initially put in ArraySetAsSeries but maybe because I had parts of the code grabbing the array elements in one direction and other parts of the code grabbing elements in the opposite direction that it never worked. Definitely a thing to store in the knowledge bank.
Once again, thanks for your help with this.
Peter
Hi Alain,
Wow you make it look very easy. I did initially put in ArraySetAsSeries but maybe because I had parts of the code grabbing the array elements in one direction and other parts of the code grabbing elements in the opposite direction that it never worked. Definitely a thing to store in the knowledge bank.
Once again, thanks for your help with this.
Peter
You are welcome. I attach also here the same indicator but with default indexing of mql5. So you can compare both versions.
Hi Alain,
Thanks again. Its especially helpful seeing the two versions of indicator arrays - now I definitely understand how they work!
Cheers.
PV
hello. i have a similar question, cannot understand what is going wrong with robot - it does not load data from indicator so doesnt work.
here is indicator(attached full code, left here most important for convenience:)
#property indicator_buffers 2 extern int InpQual=5; extern int InpLen=5; extern int InpCountbars=1000; double Up[]; double Dn[]; int OnInit(){ SetIndexBuffer(0, Up, INDICATOR_DATA); SetIndexBuffer(1, Dn, INDICATOR_DATA); } int OnCalculate(....){ if (rates_total - prev_calculated == 0) return(rates_total);//no need to calculate current bar int limit; if (prev_calculated < 1){ ArrayInitialize(Up, EMPTY_VALUE); ArrayInitialize(Dn, EMPTY_VALUE); ArraySetAsSeries(Up, 0); ArraySetAsSeries(Dn, 0); limit = InpCountbars-5; //limit = MathMin(Countbars - 5, Bars(_Symbol,_Period)); } else limit = prev_calculated; for (int i = limit; i < rates_total && !IsStopped(); i++){ //simple arithmetical calculations return(rates_total);}
and also here is robot, looked how macd sample.mq5 is written. previously i wrote in mq4 but experience with mq5 is new for me. indicator works ok
int OnInit() { if(!ResultExpert.Init()) return(INIT_FAILED); return(INIT_SUCCEEDED); } bool CExpert::Init(void) { // *** symbol name and other common information if(!InitIndicators()) return(false); return(true); } bool CExpert::InitIndicators(void) { if(m_handle_lelExt==INVALID_HANDLE) if((m_handle_lelExt=iCustom(_Symbol,0,ind, ind_qual,ind_len,ind_countbars))==INVALID_HANDLE){ printf("Error creating Leledc_ExhaustionBar3_upd_mq5 - 0 indicator"); return false; } return(true); } void OnTick() { static int perSec = PeriodSeconds(PERIOD_CURRENT); static datetime last_bar=0; // last bar datetime if (TimeCurrent()/perSec*perSec > last_bar){ ResultExpert.Processing(); last_bar = TimeCurrent()/perSec*perSec; } } bool CExpert::Processing(void) { if(BarsCalculated(m_handle_lelExt)<2) return(false); if(CopyBuffer(m_handle_lelExt,0,0,2,m_buff_lelExt0) !=2 || CopyBuffer(m_handle_lelExt,1,0,2,m_buff_lelExt1) !=2) return(false); ArraySetAsSeries(m_buff_lelExt0,0); ArraySetAsSeries(m_buff_lelExt1,0); m_lelExt0 = m_buff_lelExt0[1]; m_lelExt1 = m_buff_lelExt1[1]; Print("new bar:",TimeCurrent()," ",DoubleToString(m_lelExt0,5),"/",DoubleToString(m_lelExt1,5)); /// further code, but by now buffer is loaded with error, as sometimes indicator on chart has values, but robot fails to load it return(true); }
run in tester, obtained info (time current at start of bar and 0.0000000/0.0000000000 for both values) which is not correct, so no need in further calculations.
please help with loading indicator in mt5. thank you!
edit: attached picture from tester: both 9:00 and 17:00 candles have values of indicator, as can be seen, but tester failed to get that values.

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hi,
I’m in the process of trying to replicate a custom indicator from MT4 for the MT5 that is based off the turtle trading breakout strategy. The strategy in this example generates a trade signal at the breakout of the 20 day high for a long entry and 20 day low for a short entry. Furthermore, after taking a long position for example, it will exit the position after a 10 day low and the opposite for a short position.
Specifically, the custom indicator I’m trying to replicate is intended to do the following:
1. Identify the trend by comparing the current bar’s close against the 20 day high/low (i.e. refer to rhigh and rlow below). If the close > 20 day high then it is an uptrend (i.e. TrendDirection[i] = OP_BUY) therefore plot:
a. an arrow indicating the point of change in trend, the new 20 day breakout line and also the 10 day low exit line (i.e. against ExtMapBuffer5[i], ExtMapBuffer1[i] and ExtMapBuffer3[i] respectively;
2. The opposite would apply if the close < 20 day low then it is a downtrend. In both cases, the direction of the trend would be recorded in the TrendDirection[] array for comparison purposes for when a new bar appears;
3. Should there be a change in the trend in the form of a 20 day breakout in the opposite direction then change the plotting of the line.
I have attached a screenshot of what it currently looks like in MT4 and also what I am getting in MT5.
Also attached below is the work in progress code for the MT5.
Comparing the two screenshots it is clear that my MT5 indicator is not getting the desired results. I suspect it has something to do with how the TrendDirection[i] array is recording the information. When I run an Alert function in the loop to output the TrendDirection array I get a stack of zeroes. I have been trawling through this forum and reading up on indicator buffers and arrays but am truly stuck.
Could someone kindly guide me as to why this is the case?
Thanks in advance for your help.
PV