- OnCalculate Problem for Convert Candlestick Indicator to EA
- The Efficiency of MQL5 Indicators
- How to start with EA
I mean, for the rates_total and prev_calculated, is it just used as global variables?
I try to convert indi zigzag into EA, but we have different result with the actual indi.
can you help me please?
is it correct with the using of CopyLow, CopyHigh.. etc and with the rates_total and prev_calculated?
thank you
This is the source (indicator) :
//+------------------------------------------------------------------+ //| ZigZag.mq4 | //| Copyright 2006-2014, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "2006-2014, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property strict #property indicator_chart_window #property indicator_buffers 1 #property indicator_color1 Red //---- indicator parameters input int InpDepth=12; // Depth input int InpDeviation=5; // Deviation input int InpBackstep=3; // Backstep //---- indicator buffers double ExtZigzagBuffer[]; double ExtHighBuffer[]; double ExtLowBuffer[]; //--- globals int ExtLevel=3; // recounting's depth of extremums //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { if(InpBackstep>=InpDepth) { Print("Backstep cannot be greater or equal to Depth"); return(INIT_FAILED); } //--- 2 additional buffers IndicatorBuffers(3); //---- drawing settings SetIndexStyle(0,DRAW_SECTION); //---- indicator buffers SetIndexBuffer(0,ExtZigzagBuffer); SetIndexBuffer(1,ExtHighBuffer); SetIndexBuffer(2,ExtLowBuffer); SetIndexEmptyValue(0,0.0); //---- indicator short name IndicatorShortName("ZigZag("+string(InpDepth)+","+string(InpDeviation)+","+string(InpBackstep)+")"); //---- initialization done return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { int i,limit,counterZ,whatlookfor=0; int back,pos,lasthighpos=0,lastlowpos=0; double extremum; double curlow=0.0,curhigh=0.0,lasthigh=0.0,lastlow=0.0; //--- check for history and inputs if(rates_total<InpDepth || InpBackstep>=InpDepth) return(0); //--- first calculations if(prev_calculated==0) limit=InitializeAll(); else { //--- find first extremum in the depth ExtLevel or 100 last bars i=counterZ=0; while(counterZ<ExtLevel && i<100) { if(ExtZigzagBuffer[i]!=0.0) counterZ++; i++; } //--- no extremum found - recounting all from begin if(counterZ==0) limit=InitializeAll(); else { //--- set start position to found extremum position limit=i-1; //--- what kind of extremum? if(ExtLowBuffer[i]!=0.0) { //--- low extremum curlow=ExtLowBuffer[i]; //--- will look for the next high extremum whatlookfor=1; } else { //--- high extremum curhigh=ExtHighBuffer[i]; //--- will look for the next low extremum whatlookfor=-1; } //--- clear the rest data for(i=limit-1; i>=0; i--) { ExtZigzagBuffer[i]=0.0; ExtLowBuffer[i]=0.0; ExtHighBuffer[i]=0.0; } } } //--- main loop for(i=limit; i>=0; i--) { //--- find lowest low in depth of bars extremum=low[iLowest(NULL,0,MODE_LOW,InpDepth,i)]; //--- this lowest has been found previously if(extremum==lastlow) extremum=0.0; else { //--- new last low lastlow=extremum; //--- discard extremum if current low is too high if(low[i]-extremum>InpDeviation*Point) extremum=0.0; else { //--- clear previous extremums in backstep bars for(back=1; back<=InpBackstep; back++) { pos=i+back; if(ExtLowBuffer[pos]!=0 && ExtLowBuffer[pos]>extremum) ExtLowBuffer[pos]=0.0; } } } //--- found extremum is current low if(low[i]==extremum) ExtLowBuffer[i]=extremum; else ExtLowBuffer[i]=0.0; //--- find highest high in depth of bars extremum=high[iHighest(NULL,0,MODE_HIGH,InpDepth,i)]; //--- this highest has been found previously if(extremum==lasthigh) extremum=0.0; else { //--- new last high lasthigh=extremum; //--- discard extremum if current high is too low if(extremum-high[i]>InpDeviation*Point) extremum=0.0; else { //--- clear previous extremums in backstep bars for(back=1; back<=InpBackstep; back++) { pos=i+back; if(ExtHighBuffer[pos]!=0 && ExtHighBuffer[pos]<extremum) ExtHighBuffer[pos]=0.0; } } } //--- found extremum is current high if(high[i]==extremum) ExtHighBuffer[i]=extremum; else ExtHighBuffer[i]=0.0; } //--- final cutting if(whatlookfor==0) { lastlow=0.0; lasthigh=0.0; } else { lastlow=curlow; lasthigh=curhigh; } for(i=limit; i>=0; i--) { switch(whatlookfor) { case 0: // look for peak or lawn if(lastlow==0.0 && lasthigh==0.0) { if(ExtHighBuffer[i]!=0.0) { lasthigh=High[i]; lasthighpos=i; whatlookfor=-1; ExtZigzagBuffer[i]=lasthigh; } if(ExtLowBuffer[i]!=0.0) { lastlow=Low[i]; lastlowpos=i; whatlookfor=1; ExtZigzagBuffer[i]=lastlow; } } break; case 1: // look for peak if(ExtLowBuffer[i]!=0.0 && ExtLowBuffer[i]<lastlow && ExtHighBuffer[i]==0.0) { ExtZigzagBuffer[lastlowpos]=0.0; lastlowpos=i; lastlow=ExtLowBuffer[i]; ExtZigzagBuffer[i]=lastlow; } if(ExtHighBuffer[i]!=0.0 && ExtLowBuffer[i]==0.0) { lasthigh=ExtHighBuffer[i]; lasthighpos=i; ExtZigzagBuffer[i]=lasthigh; whatlookfor=-1; } break; case -1: // look for lawn if(ExtHighBuffer[i]!=0.0 && ExtHighBuffer[i]>lasthigh && ExtLowBuffer[i]==0.0) { ExtZigzagBuffer[lasthighpos]=0.0; lasthighpos=i; lasthigh=ExtHighBuffer[i]; ExtZigzagBuffer[i]=lasthigh; } if(ExtLowBuffer[i]!=0.0 && ExtHighBuffer[i]==0.0) { lastlow=ExtLowBuffer[i]; lastlowpos=i; ExtZigzagBuffer[i]=lastlow; whatlookfor=1; } break; } } //--- done return(rates_total); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int InitializeAll() { ArrayInitialize(ExtZigzagBuffer,0.0); ArrayInitialize(ExtHighBuffer,0.0); ArrayInitialize(ExtLowBuffer,0.0); //--- first counting position return(Bars-InpDepth); } //+------------------------------------------------------------------+
and this is my try of the conversion :
//----- Set Zigzag --------------// int InpDepth=12; // Depth int InpDeviation=5; // Deviation int InpBackstep=3; // Backstep double ExtZigzagBuffer[]; double ExtHighBuffer[]; double ExtLowBuffer[]; //--- globals int ExtLevel=3; // recounting's depth of extremums int rates_total = 0; int prev_calculated = 0; datetime time_array[]; double open_array[], high_array[], low_array[], close_array[]; long tick_volume_array[], volume_array[]; int spread_array[]; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- int nBarsTF; nBarsTF = iBars(Symbol(),0); rates_total = nBarsTF; if(ArraySize(ExtZigzagBuffer) < nBarsTF){ ArraySetAsSeries(ExtZigzagBuffer, false); ArraySetAsSeries(ExtHighBuffer, false); ArraySetAsSeries(ExtLowBuffer, false); //---- ArrayResize(ExtZigzagBuffer, nBarsTF); ArrayResize(ExtHighBuffer, nBarsTF); ArrayResize(ExtLowBuffer, nBarsTF); //---- ArraySetAsSeries(ExtZigzagBuffer, true); ArraySetAsSeries(ExtHighBuffer, true); ArraySetAsSeries(ExtLowBuffer, true); } //-------------- Indi_Zigzag -----------------------------------------------// CopyTime(Symbol(),0,0,nBarsTF,time_array); CopyOpen(Symbol(),0,0,nBarsTF,open_array); CopyHigh(Symbol(),0,0,nBarsTF,high_array); CopyLow(Symbol(),0,0,nBarsTF,low_array); CopyClose(Symbol(),0,0,nBarsTF,close_array); CopyTickVolume(Symbol(),0,0,nBarsTF,tick_volume_array); CopyRealVolume(Symbol(),0,0,nBarsTF,volume_array); CopySpread(Symbol(),0,0,nBarsTF,spread_array); int i,limit,counterZ,whatlookfor=0; int back,pos,lasthighpos=0,lastlowpos=0; double extremum; double curlow=0.0,curhigh=0.0,lasthigh=0.0,lastlow=0.0; if(rates_total<InpDepth || InpBackstep>=InpDepth) return; //--- check for history and inputs if(nBarsTF < 100) return; if(prev_calculated==0) { //--- first calculations Print("----"); for(int z = nBarsTF - 1; z >= 0; z--) { ExtZigzagBuffer[z] = 0.0; ExtHighBuffer[z] = 0.0; ExtLowBuffer[z] = 0.0; } limit = nBarsTF - InpDepth; } else { i = counterZ = 0; //--- find first extremum in the depth ExtLevel or 100 last bars while(counterZ<ExtLevel && i<100){ if(ExtZigzagBuffer[i]!=0.0) counterZ++; i++; } if(counterZ==0){ //--- no extremum found - recounting all from begin for(int z = nBarsTF - 1; z >= 0; z--) { ExtZigzagBuffer[z] = 0.0; ExtHighBuffer[z] = 0.0; ExtLowBuffer[z] = 0.0; } limit = nBarsTF - InpDepth; } else { limit = i-1; //--- set start position to found extremum position if(ExtLowBuffer[i]!=0.0){ //--- what kind of extremum? curlow = ExtLowBuffer[i]; //--- low extremum whatlookfor = 1; //--- will look for the next high extremum } else { curhigh=ExtHighBuffer[i]; //--- high extremum whatlookfor = -1; //--- will look for the next low extremum } for(i=limit-1; i>=0; i--){ //--- clear the rest data ExtZigzagBuffer[i]=0.0; ExtLowBuffer[i]=0.0; ExtHighBuffer[i]=0.0; } } } //--- main loop for(i=limit; i>=0; i--) { extremum = low_array[iLowest(Symbol(),0,MODE_LOW,InpDepth,i)]; //--- find lowest low in depth of bars if(extremum==lastlow) //--- this lowest has been found previously extremum = 0.0; else { lastlow = extremum; //--- new last low if(low_array[i]-extremum>InpDeviation*Point) //--- discard extremum if current low is too high extremum = 0.0; else { for(back=1; back<=InpBackstep; back++){ //--- clear previous extremums in backstep bars pos=i+back; if(ExtLowBuffer[pos]!=0 && ExtLowBuffer[pos]>extremum) ExtLowBuffer[pos]=0.0; } } } if(low_array[i]==extremum){ //--- found extremum is current low ExtLowBuffer[i]=extremum; } else ExtLowBuffer[i]=0.0; extremum=high_array[iHighest(Symbol(),0,MODE_HIGH,InpDepth,i)]; //--- find highest high in depth of bars if(extremum==lasthigh) //--- this highest has been found previously extremum = 0.0; else { lasthigh = extremum; //--- new last high if(extremum-high_array[i]>InpDeviation*Point) //--- discard extremum if current high is too low extremum = 0.0; else { for(back=1; back<=InpBackstep; back++) { //--- clear previous extremums in backstep bars pos=i+back; if(ExtHighBuffer[pos]!=0 && ExtHighBuffer[pos]<extremum) ExtHighBuffer[pos]=0.0; } } } if(high_array[i]==extremum) //--- found extremum is current high ExtHighBuffer[i] = extremum; else ExtHighBuffer[i]=0.0; } //--- final cutting if(whatlookfor==0) { lastlow = 0.0; lasthigh = 0.0; } else { lastlow = curlow; lasthigh = curhigh; } for(i=limit; i>=0; i--){ switch(whatlookfor){ case 0: // look for peak or lawn if(lastlow==0.0 && lasthigh==0.0) { if(ExtHighBuffer[i]!=0.0) { lasthigh=High[i]; lasthighpos=i; whatlookfor=-1; ExtZigzagBuffer[i]=lasthigh; } if(ExtLowBuffer[i]!=0.0) { lastlow=Low[i]; lastlowpos=i; whatlookfor=1; ExtZigzagBuffer[i]=lastlow; } } break; case 1: // look for peak if(ExtLowBuffer[i]!=0.0 && ExtLowBuffer[i]<lastlow && ExtHighBuffer[i]==0.0){ ExtZigzagBuffer[lastlowpos]=0.0; lastlowpos = i; lastlow = ExtLowBuffer[i]; ExtZigzagBuffer[i] = lastlow; } if(ExtHighBuffer[i]!=0.0 && ExtLowBuffer[i]==0.0) { lasthigh = ExtHighBuffer[i]; lasthighpos = i; ExtZigzagBuffer[i] = lasthigh; whatlookfor = -1; } break; case -1: // look for lawn if(ExtHighBuffer[i]!=0.0 && ExtHighBuffer[i]>lasthigh && ExtLowBuffer[i]==0.0){ ExtZigzagBuffer[lasthighpos]=0.0; lasthighpos = i; lasthigh = ExtHighBuffer[i]; ExtZigzagBuffer[i] = lasthigh; } if(ExtLowBuffer[i]!=0.0 && ExtHighBuffer[i]==0.0){ lastlow = ExtLowBuffer[i]; lastlowpos = i; ExtZigzagBuffer[i] = lastlow; whatlookfor = 1; } break; } } prev_calculated = rates_total; }
Forum on trading, automated trading systems and testing trading strategies
Hello,
Please EDIT your post and use the SRC button when you post code.
Okay. I'm sorry, my first time inserting some code..
Okay. I'm sorry, my first time inserting some code..
You don't need to use the ZigZag code inside your EA. You should use iCustom.
I am moving your topic to mql4 section, you will most probably receive more help there.
You don't need to use the ZigZag code inside your EA. You should use iCustom.
I am moving your topic to mql4 section, you will most probably receive more help there.
Thank you for your help.
Actually I'm on progress automatic validation for uploading my EA into market. Then the system found an error in my EA : array out of range in 'ZigZag.mq4' (77,28)
I used zigzag as one of my indicator in that ea. Then I think that I should include the zigzag into the ea..
But I still have problem with the conversion..
Just get the value of the indicator into the EA and do what you want with it. You should encapsulate your iCustom calls to make your code self-documenting.
Don't try do that. There are no buffers, no IndicatorCounted() or prev_calculated. No way to know if older bars have changed or been added (history update.)
Just get the value of the indicator into the EA and do what you want with it. You should encapsulate your iCustom calls to make your code self-documenting.
But I tried this to macd in my ea and it worked well. It is because the code is simple, no OnCalculate in it..
But in zigzag, it has OnCalculate, so I think that it need additional work by converting all the item/parameter in OnCalculate into ea code..
Thank you all friends..
We already get the code..! :)
I reset the array setting (aray size, set as series, array resize) of all the parameters copylow, copyhigh, etc just like the parameters of the buffers..
Just compile the indicator with the EA by including it as a resource.
Example:
#property strict #resource "ZigZag.ex4" //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { for(int i=0,cnt=0; i<Bars && cnt<10; i++) { double z = zigzag(i); if(z!=0.0 && z!=EMPTY_VALUE) Print("ZigZag value = ",z," cnt = ",++cnt); } } //+------------------------------------------------------------------+ double zigzag(const int i) { return iCustom(Symbol(),Period(),"::ZigZag.ex4",12,5,3,0,i); }
The attached script has the ZigZag indicator compiled with it, so as you can see there's no need for a separate indicator file.
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use