This script is a technical trading indicator designed to identify market trends by calculating an adaptive moving average. Unlike standard moving averages that apply a fixed smoothing rate to all price data, this logic dynamically adjusts its responsiveness based on current market conditions.
Core Logic and Mechanics
Adaptive Smoothing Mechanism The primary intelligence of the script lies in its ability to distinguish between "noisy" markets and trending markets. It performs two simultaneous calculations:
- Signal Strength: It measures the significant price movement over a specific period.
- Market Noise: It calculates the total cumulative volatility (micro-movements) within that same period.
By dividing the signal by the noise, the script determines an "Efficiency Ratio."
- In a trending market (high signal, low noise), the indicator becomes more responsive, allowing it to follow the price closely.
- In a choppy or ranging market (low signal, high noise), the indicator slows down to provide a smoother line and reduce "false" signals caused by market fluctuation.
The Main Line (AMkA) The script produces a main visual line on the chart. This line is calculated by taking the previous value of the adaptive average and adding a weighted portion of the current price difference. The weight is determined by the adaptive smoothing coefficients mentioned above.
Trend Identification and Filtering
Beyond just drawing a line, the script actively identifies directional shifts through specific trend points:
- Dynamic Filtering: The script evaluates how much the average has moved relative to the smallest price increment (Points).
- Standard Deviation Analysis: If enabled, the script tracks the history of these movements to calculate the Standard Deviation. This creates a "Filter" threshold. A trend is only confirmed if the movement exceeds this statistical threshold, which helps ignore minor ripples in the data.
- Visual Signals:
- UpTrend Points: The script identifies instances where the movement strongly exceeds the upward filter and marks them with a specific visual indicator (Green).
- DownTrend Points: Similarly, it identifies strong downward movements exceeding the downward filter and marks them with a different visual indicator (Red).
Summary of User Inputs
The logic relies on several key parameters that define its behavior:
- Periods: Define how far back the script looks to calculate both its adaptive response and its moving average.
- Fast/Slow Coefficients: These determine the extreme boundaries of how "fast" or "slow" the line can react during different market phases.
- Power Factor: Determines the intensity of the adaptive weight application.
- Filter Coefficient & Standard Deviation: These control the sensitivity of the trend arrows, helping users decide how aggressive or conservative they want the signal confirmations to be.
//+------------------------------------------------------------------+
//| AMkA.mq4 |
//| Copyright © 2006, D&S kiriyenko. |
//| http://groups.google.com/group/expert-developing |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, D&S Kiriyenko."
#property link "http://groups.google.com/group/expert-developing"
//----
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Green
#property indicator_width1 1
#property indicator_color2 Red
#property indicator_width2 2
#property indicator_color3 Blue
#property indicator_width3 2
//+------------------------------------------------------------------+
//| ìàêðîîïðåäåëåíèÿ |
//+------------------------------------------------------------------+
//---- ñòðîêîâûå êîíñòàíòû
#define INDICATOR_SHORT_NAME "AMkA"
#define MAIN "AMkA line"
#define UP "UpTrend point"
#define DOWN "DownTrend point"
//+------------------------------------------------------------------+
//| âíåøíèå ïåðåìåííûå |
//+------------------------------------------------------------------+
//---- ïåðèîäû
extern int periodAMA = 9; //ïåðèîä ðàñ÷¸òà ê-òà ýôôåêòèâíîñòè
extern double nfast = 2; //ïåðèîä EMA äëÿ ýôôåêòèâíîãî ðûíêà
extern double nslow = 30; //ïåðèîä EMA äëÿ íåýôôåêòèâíîãî ðûíêà
//---- ðàñ÷¸ò ñãëàæèâàþùåé êîíñòàíòû
extern double Pow = 2.0; //ñòåïåíü ýôôåêòèâíîñòè
//---- ôèëüòð ñèãíàëîâ
extern double dK = 1.0; //êîýôôèöèåíò äëÿ ôèëüòðà
extern bool use_stdev = true; //èñïîëüçîâàòü ñòàíäàðòíîå îòêëîíåíèå
//---- ïðèìåíÿòü ê öåíå
extern int app_price = 5; //ïî óìîë÷àíèþ - ê òèïè÷åñêîé
//+------------------------------------------------------------------+
//| ãëîáàëüíûå ïåðåìåííûå |
//+------------------------------------------------------------------+
//---- áóôåðû
double kAMAbuffer[];
double kAMAupsig[];
double kAMAdownsig[];
//---- ñãëàæèâàþùèå êîýôôèöèåíòû
double slowSC, fastSC;
//---- ïðèðàùåíèÿ èíäèêàòîðà
double ddAMA[];
//+------------------------------------------------------------------+
//| Âñòàâêà çíà÷åíèÿ â ìàññèâ ïðèðàùåíèé |
//+------------------------------------------------------------------+
bool InsertDif(double a)
{
//---- ïðîâåðêà, çàïîëíåí ëè ìàññèâ
for(int i = 0; i < periodAMA; i++) //äëÿ âñåõ ýëåìåíòîâ ìàññèâà
if(ddAMA[i] == 0) //åñëè ýëåìåíò ðàâåí íóëþ
{
ddAMA[i] = a; //ñîõðàíÿåì çíà÷åíèå â ýòîò ýëåìåíò
return (true); //è óäà÷íî çàâåðøàåìñÿ
}
//---- ìàññèâ óæå çàïîëíåí, íóæíî âñòàâëÿòü ýëåìåíò ñ êîíöà
for(i = 0; i < periodAMA-1; i++) //âñå ýëåìåíòû ìàññèâà, êðîìå ïîñëåäíåãî
ddAMA[i] = ddAMA[i+1]; //ñäâèãàåì âëåâî íà îäíó ïîçèöèþ
ddAMA[periodAMA-1] = a; //è çàïèñûâàåì çíà÷åíèå â ñàìóþ ïðàâóþ ïîçèöèþ
return (true); //ïîñëå ÷åãî óäà÷íî çàâåðøàåìñÿ
}
//+------------------------------------------------------------------+
//| Çàïðîñ öåíû áàðà |
//+------------------------------------------------------------------+
double Price(int i, int app = PRICE_TYPICAL)
{
switch(app)
{
case PRICE_CLOSE: return(Close[i]); break;
case PRICE_OPEN: return(Open[i]); break;
case PRICE_HIGH: return(High[i]); break;
case PRICE_LOW: return(Low[i]); break;
case PRICE_MEDIAN: return((High[i] + Low[i])/2); break;
case PRICE_TYPICAL: return((High[i] + Low[i] + Close[i])/3); break;
case PRICE_WEIGHTED: return((High[i] + Low[i] + Close[i]*2)/4); break;
}
}
//+------------------------------------------------------------------+
//| Èíèöèàëèçàöèÿ |
//+------------------------------------------------------------------+
int init()
{
//---- ãëàâíàÿ ëèíèÿ
SetIndexBuffer(0, kAMAbuffer);
SetIndexStyle(0, DRAW_LINE, 0, 2);
SetIndexLabel(0, MAIN);
SetIndexEmptyValue(0, 0.0);
//---- ïîäòâåðæäåíèå âîñõîäÿùåãî òðåíäà
SetIndexBuffer(1, kAMAupsig);
SetIndexStyle(1, DRAW_ARROW);
SetIndexArrow(1, 159);
SetIndexLabel(1, UP);
SetIndexEmptyValue(1, 0.0);
//---- ïîäòâåðæäåíèå íèñõîäÿùåãî òðåíäà
SetIndexBuffer(2, kAMAdownsig);
SetIndexStyle(2, DRAW_ARROW);
SetIndexArrow(2, 159);
SetIndexLabel(2, DOWN);
SetIndexEmptyValue(2, 0.0);
//---- íàñòðîéêè èíäèêàòîðà
IndicatorDigits(4);
string name = StringConcatenate(INDICATOR_SHORT_NAME,
" (", periodAMA, "/", nfast, "/", nslow, ")");
IndicatorShortName(name);
//---- ðàñ÷¸ò ê-òîâ
slowSC = (2.0 / (nslow + 1)); //ìåäëåííûé ê-ò ñãëàæèâàíèÿ
fastSC = (2.0 / (nfast + 1)); //áûñòðûé ê-ò ñãëàæèâàíèÿ
//---- ïîäãîòîâêà ìàññèâà
ArrayResize(ddAMA, periodAMA);
ArrayInitialize(ddAMA, 0.);
//---- ãîòîâî
return(0);
}
//+------------------------------------------------------------------+
//| Äåèíèöèàëèçàöèÿ |
//+------------------------------------------------------------------+
int deinit()
{
return(0);
}
//+------------------------------------------------------------------+
//| Èòåðàöèîííàÿ ôóíêöèÿ |
//+------------------------------------------------------------------+
int start()
{
//---- îïòèìèçàöèÿ ïðîèçâîäèòåëüíîñòè
if(Bars <= periodAMA + 2)
return (0); //åñëè áàðîâ íà ãðàôèêå ñëèøêîì ìàëî, âûõîäèì
//---- îïòèìèçàöèÿ êîäà èíäèêàòîðà
int counted_bars = IndicatorCounted(); //÷èñëî áàðîâ, íå èçìåí¸ííûõ ñ ïîñëåäíåãî âûçîâà
if(counted_bars < 0)
return (0); //çàùèùàåìñÿ îò îøèáîê
else
if(counted_bars > 0)
counted_bars--; //ïîñëåäíèé ïîñ÷èòàííûé áàð áóäåò ïåðåñ÷èòàí
int pos = Bars - periodAMA - 2; //ïîçèöèþ â íà÷àëî îòñ÷¸òà
if(counted_bars > 0)
pos = Bars - counted_bars; //èëè îïðåäåëÿåì ïîçèöèþ
//---- ïîäãîòîâêà ïåðåìåííûõ
double AMA0 = Price(pos+1, app_price); //ïðåäûäóùåå ÀÌÀ íå ðàñ÷èòûâàëîñü
if(kAMAbuffer[pos+1] > 0)
AMA0 = kAMAbuffer[pos+1]; //èëè ðàñ÷èòûâàëîñü
if(AMA0 == 0)
Print(Bars - pos);
//---- ðàñ÷¸ò èíäèêàòîðà
while(pos >= 0)
{
//---- ðàñ÷¸ò ñèãíàëà
double signal = MathAbs(Price(pos, app_price) - Price(pos + periodAMA, app_price));
//---- ðàñ÷¸ò øóìà
double noise = 0.000000001;
for(int i = 0; i < periodAMA; i++)
{
noise = noise + MathAbs(Price(pos+i, app_price) - Price(pos + i + 1, app_price));
}
//---- ðàñ÷¸ò êîýôôèöèåíòà ñãëàæèâàíèÿ
double ER = signal / noise; //êîýôôèöèåíò ýôôåêòèâíîñòè
double SSC = ER*(fastSC - slowSC) + slowSC; //êîýôôèöèåíò ñãëàæèâàíèÿ
//---- ðàñ÷¸ò ãëàâíîé ëèíèè
double AMA = AMA0 + (MathPow(SSC, Pow)*(Price(pos, app_price) - AMA0)); //ðàñ÷¸ò
AMA = NormalizeDouble(AMA, Digits);
kAMAbuffer[pos] = AMA; //âûâîä
//---- ðàñ÷¸ò ôèëüòðàöèè òðåíäà
double ddK = (AMA - AMA0) / Point; //ðàçíîñòü
if(use_stdev)
{
InsertDif(ddK); //íàêàïëèâàåì ïðèðàùåíèå
if(pos < Bars - 2*(periodAMA + 2)) //åñëè áàðîâ íàêîïèëîñü äîñòàòî÷íî
{
//---- ðàñ÷¸ò ñðåäíåãî àðèôìåòè÷åñêîãî
double SMAdif = 0; //âíà÷àëå ðàâíî íóëþ
for(i = 0; i < periodAMA; i++)
{
SMAdif += ddAMA[i]; //ïîñëåäîâàòåëüíî ñóììèðóåì
}
SMAdif /= periodAMA; //è äåëèì íà êîëè÷åñòâî
//---- ðàñ÷¸ò ñòàíäàðòíîãî îòêëîíåíèÿ
double StDev = 0; //âíà÷àëå ðàâíî íóëþ
for(i = 0; i < periodAMA; i++)
{
StDev += MathPow(ddAMA[i] - SMAdif, 2); //ñóììèðóåì êâàäðàòû îòêëîíåíèé
}
StDev = MathSqrt(StDev)/periodAMA; //èçâëåêàåì êîðåíü è äåëèì íà êîëè÷åñòâî
//---- ðàñ÷¸ò ôèëüòðà
double Filter = dK*StDev;
}
else
Filter = 100000;
}
else
Filter = dK;
//---- îáðàáîòêà çíà÷åíèé
double var1 = 0, var2 = 0;
if(ddK > Filter)
var1 = AMA; //åñòü âîñõîäÿùèé òðåíä
if(ddK < -Filter)
var2 = AMA; //åñòü íèñõîäÿùèé òðåíä
kAMAupsig[pos] = var1; //íåò âîñõîäÿùåãî òðåíäà
kAMAdownsig[pos] = var2; // íåò íèñõîäÿùåãî òðåíäà
//---- ïåðåõîä ê êîíöó öèêëà
AMA0 = AMA; //ñîõðàíÿåì ïðåäûäóùåå çíà÷åíèå AMA
pos--; //ïåðåõîäèì ê ñäåäóþùåìó áàðó
}
//---- çàâåðøåíèå ðàáîòû
return(0); //ãîòîâî
}
//+------------------------------------------------------------------+
Comments