Hi all,
I have been trying, without success, to create a moving median indicator using MathMedian(), such as MathMedian(prices).
Can anyone give me a clue on how to fetch the prices, put into an array, calculate using MathMedian()?
Many thanks,
Arthur.Just replace the calculation in a simple indicator.
For example, the Indicators\Examples\ROC.mq5 indicator (ships with MT5) is very simple.
Just replace the calculation in a simple indicator.
For example, the Indicators\Examples\ROC.mq5 indicator (ships with MT5) is very simple.
Used ROC, but with this line:
#include <Math\Stat\Normal.mqh>
And changed the follinw code:
for(int i=pos;i<rates_total && !IsStopped();i++)
{
if(price[i]==0.0)
ExtRocBuffer[i]=0.0;
else
ExtRocBuffer[i]=MathMedian(price); //--- changed line
}
But I got an error:
'price' - constant variable cannot be passed as reference
Try something like this:
double medianArray[]; ArrayCopy(medianArray, price, 0, 0, InpRocPeriod); ExtRocBuffer[i]=MathMedian(medianArray);
I haven't tested this.
Try something like this:
I haven't tested this.
Have to add:
Try something like this:
I haven't tested this.
The original line of code is:
ExtRocBuffer[i]=(price[i]-price[i-ExtRocPeriod])/price[i]*100;
I have tried this:
ArrayCopy(medianarray,price,0,i,ExtRocPeriod);
But I am always getting the errorarray out of range in 'MovingMd.mq5' (69,22)
ExtRocBuffer[i]=MathMedian(medianArray);
//--- the main loop of calculations
for(int i=pos;i<rates_total && !IsStopped();i++)
{
if(price[i]==0.0) {
ExtRocBuffer[i]=0.0;
medianArray[i]=0.0;
}
else {
//-- ExtRocBuffer[i]=(price[i]-price[i-ExtRocPeriod])/price[i]*100;
ArrayCopy(medianArray, price, 0, 0, ExtRocPeriod);
ExtRocBuffer[i]=MathMedian(medianArray);
}
}
//--- OnCalculate done. Return new prev_calculated.
You probably want a lookback of, say, 12 starting with the rightmost bar.
Thus, you want to loop backwards.
Which means you want to use ArraySetAsSeries().
Perhaps something like this:
#property description "Median" //--- indicator settings #property indicator_separate_window #property indicator_buffers 1 #property indicator_plots 1 #property indicator_type1 DRAW_LINE #property indicator_color1 LightSeaGreen #include <Math\Stat\Normal.mqh> //--- input parameters input int InpLookbackPeriod=12; // Period //--- indicator buffers double ExtMedianBuffer[]; void OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,ExtMedianBuffer,INDICATOR_DATA); //--- set accuracy IndicatorSetInteger(INDICATOR_DIGITS,6); //--- name for DataWindow and indicator subwindow label IndicatorSetString(INDICATOR_SHORTNAME,"MED("+string(InpLookbackPeriod)+")"); //--- sets first bar from what index will be drawn PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpLookbackPeriod); ArraySetAsSeries(ExtMedianBuffer,true); //--- initialization done } int OnCalculate(const int rates_total,const int prev_calculated,const int begin,const double &price[]) { //--- check for rates count if(rates_total<InpLookbackPeriod) return(0); //--- Checking and calculating the number of countable bars int limit=rates_total-prev_calculated; if(limit>1) { limit=rates_total-InpLookbackPeriod; } //--- the main loop of calculations for(int i=limit; i>=0 && !IsStopped(); i--) { double medianArray[]; ArrayCopy(medianArray, price, 0, i, InpLookbackPeriod); ExtMedianBuffer[i]=MathMedian(medianArray); } //--- OnCalculate done. Return new prev_calculated. return(rates_total); } //+------------------------------------------------------------------+
You probably want a lookback of, say, 12 starting with the rightmost bar.
Thus, you want to loop backwards.
Which means you want to use ArraySetAsSeries().
Perhaps something like this:
int OnCalculate(const int rates_total,const int prev_calculated,const int begin,const double &price[]) { ArrayCopy(PricesCopy,price,0,0,WHOLE_ARRAY); ArraySetAsSeries(PricesCopy,true); //--- check for rates count if(rates_total<InpLookbackPeriod) return(0); //--- Checking and calculating the number of countable bars int limit=rates_total-prev_calculated; if(limit>1) { limit=rates_total-InpLookbackPeriod; } //--- the main loop of calculations for(int i=limit; i>=0 && !IsStopped(); i--) { ArrayCopy(PricesCopy, price, 0, i, InpLookbackPeriod); ArraySetAsSeries(PricesCopy,true); ExtMedianBuffer[i]=MathMedian(PricesCopy); } //--- OnCalculate done. Return new prev_calculated. return(rates_total); }
The problem is: the results are wrong. I attached it to a chart and results are just a fraction of price. That doesn't make sense. Results are like this: MathMedian(2,3,4,5,6) = 2. Result should be 4. I am trying to calculate median value of a price that's between 40 and 50, but the results are close to 20, lower than minimum value...
The problem is: the results are wrong. I attached it to a chart and results are just a fraction of price. That doesn't make sense. Results are like this: MathMedian(2,3,4,5,6) = 2. Result should be 4. I am trying to calculate median value of a price that's between 40 and 50, but the results are close to 20, lower than minimum value...
Oh, you actually want the numbers to be correct?
:-D
Here's a complete solution. I put it on the main chart. The few test points I tried appear correct. Caveat emptor.
#property description "Simple Moving Median" #property description " " #property description "Created for https://www.mql5.com/en/forum/273812" #property description " " #property description "MQL5 Profile: https://www.mql5.com/en/users/tonegarot" #property description "My Website: http://www.garot.com/trading/" #property strict //--- indicator settings #property indicator_chart_window #property indicator_buffers 1 #property indicator_plots 1 #property indicator_type1 DRAW_LINE #property indicator_color1 LightSeaGreen #property indicator_width1 3 #include <Math\Stat\Normal.mqh> //--- input parameters input int InpLookbackPeriod=12; // Period //--- indicator buffers double ExtMedianBuffer[]; void OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,ExtMedianBuffer,INDICATOR_DATA); //--- set accuracy IndicatorSetInteger(INDICATOR_DIGITS,5); //--- name for DataWindow and indicator subwindow label IndicatorSetString(INDICATOR_SHORTNAME,"SMM("+string(InpLookbackPeriod)+")"); //--- sets first bar from what index will be drawn PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpLookbackPeriod); ArraySetAsSeries(ExtMedianBuffer,false); //--- initialization done } int OnCalculate(const int rates_total,const int prev_calculated,const int begin,const double &price[]) { //--- check for rates count if(rates_total<InpLookbackPeriod) return(0); //--- Checking and calculating the number of countable bars int limit=rates_total-prev_calculated; if(limit>1) { limit=rates_total-1; } //--- the main loop of calculations for(int i=limit; i>=0 && !IsStopped(); i--) { double medianArray[]; ArrayCopy(medianArray, price, 0, i-InpLookbackPeriod+1, InpLookbackPeriod); ExtMedianBuffer[i]=MathMedian(medianArray); } //--- OnCalculate done. Return new prev_calculated. return(rates_total); } //+------------------------------------------------------------------+
Oh, you actually want the numbers to be correct?
:-D
Here's a complete solution. I put it on the main chart. The few test points I tried appear correct. Caveat emptor.
#include <Math\Stat\Math.mqh>
Is enough. Values seem right now. But as Romans said: "caveat emptor" :D
I really forgot the +1 and -1 ones... Result? Array out index :P
#include <Math\Stat\Math.mqh>
Is enough. Values seem right now. But as Romans said: "caveat emptor" :D
I really forgot the +1 and -1 ones... Result? Array out index :P
The strategy tester failed.

- 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 all,
I have been trying, without success, to create a moving median indicator using MathMedian(), such as MathMedian(prices).
Can anyone give me a clue on how to fetch the prices, put into an array, calculate using MathMedian()?
Many thanks,
Arthur.