AMA_optimized_final_Slope
Download scriptThis script is a specialized technical analysis tool designed to identify and visualize market trends by analyzing price momentum and volatility. Rather than simply following the price, it uses an "Optimized Adaptive Moving Average" (AMA) logic to distinguish between meaningful market movement and random market noise.
Core Logic and Functionality
The indicator operates through several layers of calculation to provide a cleaner interpretation of price action:
1. Customizable Price Input The tool allows users to define which specific price data point should be used for calculations (e.g., the closing price, opening price, high, low, or a variety of averages). This flexibility ensures the script can be tailored to different trading styles and asset types.
2. Noise Filtering and Adaptation At its foundation, the script measures "noise"—the absolute change between consecutive price points. It calculates how much the current price deviates from its recent average relative to that noise level.
- If the market is moving significantly more than usual (high volatility), the indicator adjusts its responsiveness.
- If the market is behaving normally or staying flat, the indicator smooths out the data to prevent "whipsaws" (false signals caused by minor fluctuations).
3. Adaptive Smoothing (AMA) The script uses an adaptive smoothing coefficient. Unlike a standard moving average where the weight of new data is constant, this logic dynamically changes based on the market's behavior. It blends current data with historical data using a weighted formula that reacts more aggressively to strong trends and remains steady during consolidation.
4. Trend Slope and Signal Generation The primary purpose of this script is to calculate the "Slope" (the rate of change) of the smoothed AMA line. It looks for specific thresholds to trigger visual signals:
- Trend Detection: The tool identifies an upward or downward trend by checking if the slope exceeds a specific intensity threshold.
- Standard Deviation Integration: Depending on user settings, the tool can determine "significant" movement either by using a fixed point value (constant) or by using Standard Deviation (which measures how much the price typically fluctuates). If the current slope is stronger than this calculated "normal" volatility, it confirms a trend.
5. Visual Output The script provides three main layers of information on the chart:
- Trend Slope: A visual representation of the momentum of the adaptive average.
- Upward Signals: Visual markers (arrows) that appear when the price shows significant upward momentum that exceeds the noise threshold.
- Downward Signals: Visual markers (arrows) that appear when the price shows significant downward momentum that exceeds the noise threshold.
Summary for the User
Essentially, this tool acts as a sophisticated filter. It looks at the raw market data, strips away the "noise," calculates an adaptive average of the remaining price action, and then highlights specific moments where the trend's strength becomes high enough to be considered a valid movement rather than just random price fluctuation.
//+------------------------------------------------------------------+
//| AMA optimized.mq4 |
//| Copyright © 2006, MetaQuotes Software Corp. |
//|AMA optimized final Copyright © 2004, by konKop,wellx |
//+------------------------------------------------------------------+
//mod slope
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link "optimized by Rosh"
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 Gray
#property indicator_color2 Blue
#property indicator_color3 Red
#property indicator_width1 1
#property indicator_width2 1
#property indicator_width3 1
//---- input parameters
extern int periodAMA=10;
extern double nfast=2.0;
extern double nslow=30.0;
extern double G=2.0;
extern double dK=2.0;
extern int PriceType=0; // öåíà, îò êîòîðîé ñòðîèòñÿ
extern int AMA_Trend_Type=1; //deltaAMA 0:(dK*Point) 1:dK*StdAMA
//PRICE_CLOSE 0 Öåíà çàêðûòèÿ
//PRICE_OPEN 1 Öåíà îòêðûòèÿ
//PRICE_HIGH 2 Ìàêñèìàëüíàÿ öåíà
//PRICE_LOW 3 Ìèíèìàëüíàÿ öåíà
//PRICE_MEDIAN 4 Ñðåäíÿÿ öåíà, (high+low)/2
//PRICE_TYPICAL 5 Òèïè÷íàÿ öåíà, (high+low+close)/3
//PRICE_WEIGHTED 6 Âçâåøåííàÿ öåíà çàêðûòèÿ, (high+low+close+close)/4
extern string note_Price_ = "0C 1O 2H 3L 4Md 5Tp 6WghC: Md(HL/2)4,Tp(HLC/3)5,Wgh(HLCC/4)6";
extern string Trend_Type_ = "deltaAMA: dK*Point(0) dK*StdAM(1)";
//---- buffers
double AMAbuffer[];
double upAMA[];
double downAMA[];
double AbsBuffer[];
double AMA2Buffer[];
double SumAMABuffer[];
double StdAMA[];
double AMASlopeBuffer[];
double slowSC,fastSC,dFS;
//+------------------------------------------------------------------+
//| âîçâðàùàåò öåíó |
//+------------------------------------------------------------------+
double Price(int shift)
{
//----
double res;
//----
switch (PriceType)
{
case PRICE_OPEN: res=Open[shift]; break;
case PRICE_HIGH: res=High[shift]; break;
case PRICE_LOW: res=Low[shift]; break;
case PRICE_MEDIAN: res=(High[shift]+Low[shift])/2.0; break;
case PRICE_TYPICAL: res=(High[shift]+Low[shift]+Close[shift])/3.0; break;
case PRICE_WEIGHTED: res=(High[shift]+Low[shift]+2*Close[shift])/4.0; break;
default: res=Close[shift];break;
}
return(res);
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
IndicatorBuffers(8);
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,AMASlopeBuffer);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1,159);
SetIndexBuffer(1,upAMA);
SetIndexEmptyValue(1,0.0);
SetIndexStyle(2,DRAW_ARROW);
SetIndexArrow(2,159);
SetIndexBuffer(2,downAMA);
SetIndexEmptyValue(2,0.0);
SetIndexBuffer(3,AbsBuffer);
SetIndexBuffer(4,AMA2Buffer);
SetIndexBuffer(5,SumAMABuffer);
SetIndexBuffer(6,StdAMA);
SetIndexBuffer(7,AMAbuffer);
slowSC=(2.0 /(nslow+1));
fastSC=(2.0 /(nfast+1));
dFS=fastSC-slowSC;
IndicatorShortName("AMAopt Slope ("+periodAMA+")");
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
//----
int i,limit,limit2;
double Noise,ER,SSC;
double SredneeAMA,SumKvadratAMA;
double val1,val2;
double dipersion;
static bool debug=false;
if (debug) return;
if (counted_bars>0)
{
limit=Bars-counted_bars;
limit2=limit;
}
if (counted_bars==0)
{
ArrayInitialize(AMAbuffer,0);
ArrayInitialize(upAMA,0);
ArrayInitialize(downAMA,0);
ArrayInitialize(AbsBuffer,0);
ArrayInitialize(AMA2Buffer,0);
ArrayInitialize(SumAMABuffer,0);
ArrayInitialize(StdAMA,0);
limit=Bars-1;
limit2=Bars-periodAMA-1;
}
limit--;
limit2--;
for (i=limit;i>=0;i--)
{
AbsBuffer[i]=MathAbs(Price(i)-Price(i+1));
}
for (i=limit2;i>=0;i--)
{
Noise=iMAOnArray(AbsBuffer,0,periodAMA,0,MODE_SMA,i)*periodAMA;
if (Noise!=0) ER=MathAbs(Price(i)-Price(i+periodAMA))/Noise; else ER=0;
SSC=MathPow(ER*dFS+slowSC,G);
AMAbuffer[i]=Price(i)*SSC+AMAbuffer[i+1]*(1-SSC);
AMA2Buffer[i]=AMAbuffer[i]*AMAbuffer[i]+AMA2Buffer[i+1];// íàêàïëèâàåì ñóììó êâàäðàòîâ ÀÌû
SumAMABuffer[i]=SumAMABuffer[i+1]+AMAbuffer[i];
AMASlopeBuffer[i]=AMAbuffer[i]-AMAbuffer[i+1];
}
for (i=limit2;i>=0;i--)
{
val1=0;
val2=0;
SredneeAMA=(SumAMABuffer[i]-SumAMABuffer[i+periodAMA])/periodAMA;
SumKvadratAMA=AMA2Buffer[i]-AMA2Buffer[i+periodAMA];
dipersion=SumKvadratAMA/periodAMA-SredneeAMA*SredneeAMA;
if (dipersion<0)
{
StdAMA[i]=0;
if (IsTesting()&&false)
{
Print("Bar;Price;AbsBuffer;AMAbuffer;AMA2Buffer;SumAMABuffer;SredneeAMA");
for (int Z=Bars-1;Z>=i;Z--) Print(Z,";",Price(Z),";",AbsBuffer[Z],";",AMAbuffer[Z],";",AMA2Buffer[Z],";",SumAMABuffer[Z],";",(SumAMABuffer[Z]-SumAMABuffer[Z+periodAMA])/periodAMA);
}
}
else StdAMA[i]=MathSqrt(dipersion);
if (AMA_Trend_Type!=0)
{
if (MathAbs(AMAbuffer[i]-AMAbuffer[i+1])>dK*Point)
{
if (AMAbuffer[i]-AMAbuffer[i+1]>0) val1=AMASlopeBuffer[i];
else val2=AMASlopeBuffer[i];
}
}
else
{
if (MathAbs(AMAbuffer[i]-AMAbuffer[i+1])>dK*StdAMA[i])
{
if (AMAbuffer[i]-AMAbuffer[i+1]>0) val1=AMASlopeBuffer[i];
else val2=AMASlopeBuffer[i];
}
}
upAMA[i]=val1;
downAMA[i]=val2;
}
//----
return(0);
}
//+------------------------------------------------------------------+
Comments