Hi,
in MQL4 I often grouped several indicators in one, filling the buffers with standard functions:
Now, iMA gives back a Handle instead of the values, so it is not working anymore like this in MQL5.
I only managed to call iMA from an EA with iCustom, but how can I use the standard indicator functions in my Indicator Code?
If you read the Documentation carefully you will see a clear example of what you need to do . . .
//+------------------------------------------------------------------+ //| Filling indicator buffers from the MA indicator | //+------------------------------------------------------------------+ bool FillArrayFromBuffer(double &values[], // indicator buffer of Moving Average values int shift, // shift int ind_handle, // handle of the iMA indicator int amount // number of copied values ) { //--- reset error code ResetLastError(); //--- fill a part of the iMABuffer array with values from the indicator buffer that has 0 index if(CopyBuffer(ind_handle,0,-shift,amount,values)<0) { //--- if the copying fails, tell the error code PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError()); //--- quit with zero result - it means that the indicator is considered as not calculated return(false); } //--- everything is fine return(true); }
If you read the Documentation carefully you will see a clear example of what you need to do . . .
:) thanks a lot...I actually read a lot but sometimes you get blind :(
This is why I post just simple code as a show case.
The code gives 4 lines in one indicator. 2 are calculated by simply writing PRICE_HIGH and PRICE_LOW into the buffers.
Another 2 are using the iMA function.
//+------------------------------------------------------------------+ //| Atest.mq5 | //| Claudio_arrau2 | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Claudio_arrau2" #property link "http://www.mql5.com" #property version "1.00" #property indicator_chart_window #property indicator_buffers 4 #property indicator_plots 4 #property indicator_label1 "GD" #property indicator_label2 "Short" #property indicator_label3 "Long" #property indicator_label4 "Large" #property indicator_type1 DRAW_LINE #property indicator_type2 DRAW_LINE #property indicator_type3 DRAW_LINE #property indicator_type4 DRAW_LINE #property indicator_color1 clrDeepSkyBlue #property indicator_color2 clrLimeGreen #property indicator_color3 clrRed #property indicator_color4 clrOrange #property indicator_style1 STYLE_SOLID #property indicator_style2 STYLE_SOLID #property indicator_style3 STYLE_SOLID #property indicator_style4 STYLE_SOLID #property indicator_width1 1 #property indicator_width2 1 #property indicator_width3 1 #property indicator_width3 1 double GDBuffer[],ShortBuffer[], LongBuffer[],LargeBuffer[]; int GDHandle,ShortHandle,LongHandle,LargeHandle; int FastEMA=20; int SlowEMA=1; int LargeEMA=70; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { SetIndexBuffer(0,GDBuffer,INDICATOR_DATA); SetIndexBuffer(1,ShortBuffer,INDICATOR_DATA); SetIndexBuffer(2,LongBuffer,INDICATOR_DATA); SetIndexBuffer(3,LargeBuffer,INDICATOR_DATA); GDHandle=iMA(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE); LargeHandle=iMA(NULL,0,LargeEMA,0,MODE_EMA,PRICE_CLOSE); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate (const int rates_total, // size of input time series const int prev_calculated, // bars handled in previous call const datetime& time[], // Time const double& open[], // Open const double& high[], // High const double& low[], // Low const double& close[], // Close const long& tick_volume[], // Tick Volume const long& volume[], // Real Volume const int& spread[] // Spread ) { //Method 1: Calculate Indicator with CopyBuffer, taking from the Handles in "OnInit" CopyBuffer(LargeHandle,0,0,rates_total,LargeBuffer); CopyBuffer(GDHandle,0,0,rates_total,GDBuffer); //Method 2: looping every Bar and writing directly to Buffer for line for(int i=0;i<rates_total;i++) { ShortBuffer[i]=low[i]; LongBuffer[i]=high[i]; } return(rates_total); }
Well, I was actually spending many hours in really understanding. Sometimes the examples are a little too complicated and giving good programming practices incl. error handling etc.
This is why I post just simple code as a show case.
The code gives 4 lines in one indicator. 2 are calculated by simply writing PRICE_HIGH and PRICE_LOW into the buffers.
Another 2 are using the iMA function.
Some suggestions :
- You have to check the returned value when using CopyBuffer
//Method 1: Calculate Indicator with CopyBuffer, taking from the Handles in "OnInit" if (CopyBuffer(LargeHandle,0,0,rates_total,LargeBuffer)<rates_total) return(0); if (CopyBuffer(GDHandle,0,0,rates_total,GDBuffer)<rates_total) return(0);
- There is no need to use a loop to copy low/high, you can use CopyLow/CopyHigh (if it's only for an example using a loop, then your example is poorly chosen).
//Method 2: looping every Bar and writing directly to Buffer for line if(CopyLow(_Symbol, _Period, 0, rates_total, ShortBuffer)<rates_total) return(0); if(CopyHigh(_Symbol, _Period, 0, rates_total, LongBuffer)<rates_total) return(0);
- Although functional, the indicator isn't effective because it recalculate all buffers on each tick.
//+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate (const int rates_total, // size of input time series const int prev_calculated, // bars handled in previous call const datetime& time[], // Time const double& open[], // Open const double& high[], // High const double& low[], // Low const double& close[], // Close const long& tick_volume[], // Tick Volume const long& volume[], // Real Volume const int& spread[] // Spread ) { //--- first calculation or number of bars was changed int start=(prev_calculated==0) ? 0 : prev_calculated-1; int to_copy=(prev_calculated==0) ? rates_total : rates_total-prev_calculated+1; //Method 1: Calculate Indicator with CopyBuffer, taking from the Handles in "OnInit" if(CopyBuffer(LargeHandle,0,start,to_copy,LargeBuffer)<to_copy) return(0); if(CopyBuffer(GDHandle,0,start,to_copy,GDBuffer)<to_copy) return(0); //Method 2: looping every Bar and writing directly to Buffer for line if(CopyLow(_Symbol,_Period,start,to_copy,ShortBuffer)<to_copy) return(0); if(CopyHigh(_Symbol,_Period,start,to_copy,LongBuffer)<to_copy) return(0); //--- return value of prev_calculated for next call return(rates_total); }
Not compiled, not tested.
- 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,
in MQL4 I often grouped several indicators in one, filling the buffers with standard functions:
Now, iMA gives back a Handle instead of the values, so it is not working anymore like this in MQL5.
I only managed to call iMA from an EA with iCustom, but how can I use the standard indicator functions in my Indicator Code?