-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathAMA.mq5
130 lines (128 loc) · 4.91 KB
/
AMA.mq5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//+------------------------------------------------------------------+
//| AMA.mq5 |
//| Copyright 2000-2024, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, 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 Red
#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);
}
//+------------------------------------------------------------------+