130 lines
4.8 KiB
MQL5
130 lines
4.8 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| AMA.mq5 |
|
|
//| Copyright 2000-2025, MetaQuotes Ltd. |
|
|
//| https://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2000-2025, MetaQuotes Ltd."
|
|
#property link "https://www.mql5.com"
|
|
#property version "1.00"
|
|
#property description "Adaptive Moving Average"
|
|
|
|
#property indicator_chart_window
|
|
#property indicator_buffers 1
|
|
#property indicator_plots 1
|
|
//--- plot ExtAMABuffer
|
|
#property indicator_label1 "AMA"
|
|
#property indicator_type1 DRAW_LINE
|
|
#property indicator_color1 clrRed
|
|
#property indicator_style1 STYLE_SOLID
|
|
#property indicator_width1 1
|
|
//--- default applied price
|
|
#property indicator_applied_price PRICE_OPEN
|
|
//--- input parameters
|
|
input int InpPeriodAMA=10; // AMA period
|
|
input int InpFastPeriodEMA=2; // Fast EMA period
|
|
input int InpSlowPeriodEMA=30; // Slow EMA period
|
|
input int InpShiftAMA=0; // AMA shift
|
|
//--- indicator buffer
|
|
double ExtAMABuffer[];
|
|
|
|
double ExtFastSC;
|
|
double ExtSlowSC;
|
|
int ExtPeriodAMA;
|
|
int ExtSlowPeriodEMA;
|
|
int ExtFastPeriodEMA;
|
|
//+------------------------------------------------------------------+
|
|
//| AMA initialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnInit()
|
|
{
|
|
//--- check for input values
|
|
if(InpPeriodAMA<=0)
|
|
{
|
|
ExtPeriodAMA=10;
|
|
PrintFormat("Input parameter InpPeriodAMA has incorrect value (%d). Indicator will use value %d for calculations.",
|
|
InpPeriodAMA,ExtPeriodAMA);
|
|
}
|
|
else
|
|
ExtPeriodAMA=InpPeriodAMA;
|
|
if(InpSlowPeriodEMA<=0)
|
|
{
|
|
ExtSlowPeriodEMA=30;
|
|
PrintFormat("Input parameter InpSlowPeriodEMA has incorrect value (%d). Indicator will use value %d for calculations.",
|
|
InpSlowPeriodEMA,ExtSlowPeriodEMA);
|
|
}
|
|
else
|
|
ExtSlowPeriodEMA=InpSlowPeriodEMA;
|
|
if(InpFastPeriodEMA<=0)
|
|
{
|
|
ExtFastPeriodEMA=2;
|
|
PrintFormat("Input parameter InpFastPeriodEMA has incorrect value (%d). Indicator will use value %d for calculations.",
|
|
InpFastPeriodEMA,ExtFastPeriodEMA);
|
|
}
|
|
else
|
|
ExtFastPeriodEMA=InpFastPeriodEMA;
|
|
//--- indicator buffers mapping
|
|
SetIndexBuffer(0,ExtAMABuffer,INDICATOR_DATA);
|
|
//--- set accuracy
|
|
IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
|
|
//--- sets first bar from what index will be drawn
|
|
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtPeriodAMA);
|
|
//--- set index shift
|
|
PlotIndexSetInteger(0,PLOT_SHIFT,InpShiftAMA);
|
|
//--- set shortname and change label
|
|
string short_name=StringFormat("AMA(%d,%d,%d)",ExtPeriodAMA,ExtFastPeriodEMA,ExtSlowPeriodEMA);
|
|
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
|
|
PlotIndexSetString(0,PLOT_LABEL,short_name);
|
|
//--- calculate ExtFastSC & ExtSlowSC
|
|
ExtFastSC=2.0/(ExtFastPeriodEMA+1.0);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| AMA iteration function |
|
|
//+------------------------------------------------------------------+
|
|
int OnCalculate(const int rates_total,
|
|
const int prev_calculated,
|
|
const int begin,
|
|
const double &price[])
|
|
{
|
|
int i;
|
|
//--- check for rates count
|
|
if(rates_total<ExtPeriodAMA+begin)
|
|
return(0);
|
|
//--- draw begin may be corrected
|
|
if(begin!=0)
|
|
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtPeriodAMA+begin);
|
|
//--- detect position
|
|
int pos=prev_calculated-1;
|
|
//--- first calculations
|
|
if(pos<ExtPeriodAMA+begin)
|
|
{
|
|
pos=ExtPeriodAMA+begin;
|
|
for(i=0; i<pos-1; i++)
|
|
ExtAMABuffer[i]=0.0;
|
|
ExtAMABuffer[pos-1]=price[pos-1];
|
|
}
|
|
//--- main cycle
|
|
for(i=pos; i<rates_total && !IsStopped(); i++)
|
|
{
|
|
//--- calculate SSC
|
|
double currentSSC=(CalculateER(i,price)*(ExtFastSC-ExtSlowSC))+ExtSlowSC;
|
|
//--- calculate AMA
|
|
double prevAMA=ExtAMABuffer[i-1];
|
|
ExtAMABuffer[i]=MathPow(currentSSC,2)*(price[i]-prevAMA)+prevAMA;
|
|
}
|
|
//--- return value of prev_calculated for next call
|
|
return(rates_total);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Calculate ER value |
|
|
//+------------------------------------------------------------------+
|
|
double CalculateER(const int pos,const double& price[])
|
|
{
|
|
double signal=MathAbs(price[pos]-price[pos-ExtPeriodAMA]);
|
|
double noise=0.0;
|
|
for(int delta=0; delta<ExtPeriodAMA; delta++)
|
|
noise+=MathAbs(price[pos-delta]-price[pos-delta-1]);
|
|
if(noise!=0.0)
|
|
return(signal/noise);
|
|
return(0.0);
|
|
}
|
|
//+------------------------------------------------------------------+
|