Author: Copyright � 2006, D&S Kiriyenko.
AMkA

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:

  1. Signal Strength: It measures the significant price movement over a specific period.
  2. 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.
Miscellaneous
Implements a curve of type %1
11 Views
0 Downloads
0 Favorites
AMkA
//+------------------------------------------------------------------+
//|                                                         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