StepMA_3D_v1_v1
Download scriptThis script functions as a dynamic technical analysis tool designed to visualize market trends through three distinct "Step Moving Average" lines. Instead of creating smooth, curving lines like traditional moving averages, this logic creates a stepped appearance that reacts to price volatility while filtering out minor market noise.
Core Logic Overview
The primary objective of this script is to calculate and plot three different trend levels based on the historical volatility of the asset. It does this by performing several sequential steps:
1. Volatility Measurement (ATR Calculation) The script first calculates a custom version of an Average True Range (ATR). It looks back over a specific number of bars to determine how much price has been moving. By analyzing the highs and lows of recent price action, it establishes a baseline for the current market "environment."
2. Dynamic Step Scaling Rather than using a fixed point value for its steps, the script creates three different scale sizes (Min, Max, and Mid) based on the volatility calculated in the first step:
- Minimum Scale: Reacts quickly to smaller price movements.
- Maximum Scale: Reacts only to significant, large-scale price movements.
- Middle Scale: A balanced approach between the two.
3. Trend Identification and "Locking" The script determines the direction of the trend by checking if the current price has crossed a specific threshold relative to the previous bars' movement.
- If the price breaks above a certain level, it registers an upward trend.
- If the price falls below a certain level, it registers a downward trend.
One unique feature of this logic is its "memory." When a trend is active (moving up or down), the lines are designed to stay flat until the price movement is strong enough to overcome the current step size. This prevents the lines from jittering up and down constantly during minor fluctuations, ensuring that the "steps" only move when there is a significant shift in momentum.
4. Visual Output Finally, the script renders three separate lines on your chart:
- The Min Line: The most sensitive; it provides the fastest reaction to price changes.
- The Mid Line: Provides a moderate view of the trend.
- The Max Line: The most conservative; it stays flat for long periods and only moves when there is a major structural change in the market.
Summary for the User
In simple terms, this tool tells you where the "floors" and "ceilings" of the current trend are. By using three different scales, it allows you to see both the immediate micro-trends (via the Min line) and the broader macro-trends (via the Max line) simultaneously, helping you identify when a price move is significant enough to be considered a real change in direction.
//+------------------------------------------------------------------+
//| StepMA_v2.mq4 |
//| Copyright © 2005, TrendLaboratory Ltd. |
//| E-mail: igorad2004@list.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, TrendLaboratory Ltd."
#property link "E-mail: igorad2004@list.ru"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Yellow
#property indicator_color2 DeepSkyBlue
#property indicator_color3 Tomato
//---- input parameters
extern int PeriodWATR=10;
extern double Kwatr=1.0000;
extern int AdvanceMin=0;
extern int AdvanceMax=0;
extern int AdvanceMid=0;
extern int HighLow=0;
//---- indicator buffers
double LineMinBuffer[];
double LineMaxBuffer[];
double LineMidBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
string short_name;
//---- indicator line
SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,1);
SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,1);
SetIndexStyle(2,DRAW_LINE,STYLE_SOLID,1);
SetIndexShift(0,AdvanceMin);
SetIndexShift(1,AdvanceMax);
SetIndexShift(2,AdvanceMid);
SetIndexBuffer(0,LineMinBuffer);
SetIndexBuffer(1,LineMaxBuffer);
SetIndexBuffer(2,LineMidBuffer);
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
//---- name for DataWindow and indicator subwindow label
short_name="StepMA 3D("+PeriodWATR+")";
IndicatorShortName(short_name);
SetIndexLabel(0,"StepMA min");
SetIndexLabel(1,"StepMA max");
SetIndexLabel(2,"StepMA mid");
//----
SetIndexDrawBegin(0,PeriodWATR);
SetIndexDrawBegin(1,PeriodWATR);
SetIndexDrawBegin(2,PeriodWATR);
//----
return(0);
}
//+------------------------------------------------------------------+
//| StepMA_3D_v1 |
//+------------------------------------------------------------------+
int start()
{
int i,shift,TrendMin,TrendMax,TrendMid;
double SminMin0,SmaxMin0,SminMin1,SmaxMin1,SumRange,dK,WATR0,WATRmax,WATRmin,WATRmid;
double SminMax0,SmaxMax0,SminMax1,SmaxMax1,SminMid0,SmaxMid0,SminMid1,SmaxMid1;
for(shift=Bars-1;shift>=0;shift--)
{
SumRange=0;
for (i=PeriodWATR-1;i>=0;i--)
{
dK = 1.0+1.0*(PeriodWATR-i)/PeriodWATR;
SumRange+= dK*MathAbs(High[i+shift]-Low[i+shift]);
//Print(" dK= ",dK);
}
WATR0 = SumRange/PeriodWATR;
WATRmax=MathMax(WATR0,WATRmax);
if (shift==Bars-1-PeriodWATR) WATRmin=WATR0;
WATRmin=MathMin(WATR0,WATRmin);
int StepSizeMin=MathRound(Kwatr*WATRmin/Point);
int StepSizeMax=MathRound(Kwatr*WATRmax/Point);
int StepSizeMid=MathRound(Kwatr*0.5*(WATRmax+WATRmin)/Point);
Comment(" StepSize_min = ", StepSizeMin,"\n",
" StepSize_mid = ", StepSizeMid,"\n",
" StepSize_max = ", StepSizeMax);
if (HighLow>0)
{
SmaxMin0=Low[shift]+2*StepSizeMin*Point;
SminMin0=High[shift]-2*StepSizeMin*Point;
SmaxMax0=Low[shift]+2*StepSizeMax*Point;
SminMax0=High[shift]-2*StepSizeMax*Point;
SmaxMid0=Low[shift]+2*StepSizeMid*Point;
SminMid0=High[shift]-2*StepSizeMid*Point;
if(Close[shift]>SmaxMin1) TrendMin=1;
if(Close[shift]<SminMin1) TrendMin=-1;
if(Close[shift]>SmaxMax1) TrendMax=1;
if(Close[shift]<SminMax1) TrendMax=-1;
if(Close[shift]>SmaxMid1) TrendMid=1;
if(Close[shift]<SminMid1) TrendMid=-1;
}
if (HighLow == 0)
{
SmaxMin0=Close[shift]+2*StepSizeMin*Point;
SminMin0=Close[shift]-2*StepSizeMin*Point;
SmaxMax0=Close[shift]+2*StepSizeMax*Point;
SminMax0=Close[shift]-2*StepSizeMax*Point;
SmaxMid0=Close[shift]+2*StepSizeMid*Point;
SminMid0=Close[shift]-2*StepSizeMid*Point;
if(Close[shift]>SmaxMin1) TrendMin=1;
if(Close[shift]<SminMin1) TrendMin=-1;
if(Close[shift]>SmaxMax1) TrendMax=1;
if(Close[shift]<SminMax1) TrendMax=-1;
if(Close[shift]>SmaxMid1) TrendMid=1;
if(Close[shift]<SminMid1) TrendMid=-1;
}
if(TrendMin>0 && SminMin0<SminMin1) SminMin0=SminMin1;
if(TrendMin<0 && SmaxMin0>SmaxMin1) SmaxMin0=SmaxMin1;
if(TrendMax>0 && SminMax0<SminMax1) SminMax0=SminMax1;
if(TrendMax<0 && SmaxMax0>SmaxMax1) SmaxMax0=SmaxMax1;
if(TrendMid>0 && SminMid0<SminMid1) SminMid0=SminMid1;
if(TrendMid<0 && SmaxMid0>SmaxMid1) SmaxMid0=SmaxMid1;
if (TrendMin>0) LineMinBuffer[shift]=SminMin0+StepSizeMin*Point;
if (TrendMin<0) LineMinBuffer[shift]=SmaxMin0-StepSizeMin*Point;
if (TrendMax>0) LineMaxBuffer[shift]=SminMax0+StepSizeMax*Point;
if (TrendMax<0) LineMaxBuffer[shift]=SmaxMax0-StepSizeMax*Point;
if (TrendMid>0) LineMidBuffer[shift]=SminMid0+StepSizeMid*Point;
if (TrendMid<0) LineMidBuffer[shift]=SmaxMid0-StepSizeMid*Point;
SminMin1=SminMin0;
SmaxMin1=SmaxMin0;
SminMax1=SminMax0;
SmaxMax1=SmaxMax0;
SminMid1=SminMid0;
SmaxMid1=SmaxMid0;
}
return(0);
}
Comments