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);
| |||
}
| |||
//+------------------------------------------------------------------+
|