StepMA_3D_v3m
Download scriptThis script is a technical analysis tool designed to identify and visualize market trends using a unique "stepping" logic rather than the smooth, continuous curves typical of standard moving averages. Instead of following price perfectly, it moves in discrete increments based on current market volatility.
Core Logic and Functionality
1. Volatility-Based Step Calculation The script begins by analyzing the recent history of price fluctuations (Highs and Lows) to determine the market's "Average Range." It uses this data to establish three distinct sensitivity levels: Minimum, Mid, and Maximum. These levels act as the "step sizes" that dictate how far the indicator lines can move at any given moment.
2. Dynamic Trend Detection The tool monitors the relationship between current closing prices and the previous step boundaries. It essentially asks: "Has the price moved far enough to break the current trend step?"
- If the price breaks above a certain threshold, it triggers a trend shift in one direction.
- If the price breaks below a corresponding threshold, it shifts in the opposite direction.
3. The Three-Line System (3D Visualization) The script plots three separate lines on your chart, each representing a different level of trend sensitivity:
- Fast Line (Lawn Green): This is the most reactive line. It uses the smallest step sizes and responds quickly to minor price movements, helping to identify short-term momentum shifts.
- Mid Line (Aquamarine): This represents a balanced middle ground. It filters out some of the "noise" found in the fast line while remaining responsive enough to capture the primary trend.
- Slow Line (DeepSkyBlue): This is the most conservative line. It uses the largest step sizes, requiring significant price movement before it changes direction. It is designed to highlight the overarching long-term trend and ignore minor fluctuations.
4. Logic of Movement Unlike a standard moving average that recalculates every point based on a formula, these lines "lock" into place. Once a trend is established, the line stays flat until price action becomes strong enough to overcome the volatility-based step. This prevents the indicator from "waving" back and forth during choppy, sideways markets, providing a much clearer visual of when a true trend change is occurring.
Summary for the User
By combining these three lines—Fast, Mid, and Slow—you can observe the "agreement" between different timeframes. When all three lines are moving in the same direction, it signals a strong, confirmed trend. When they begin to diverge or "step" in opposite directions, it suggests market indecision or a potential trend reversal.
//+------------------------------------------------------------------+
//| StepMA_3D_v3m.mq4 |
//| Copyright © 2006, TrendLaboratory |
//| http://finance.groups.yahoo.com/group/TrendLaboratory |
//| E-mail: igorad2003@yahoo.co.uk |
//| Thanks to Nikolay Kositsin for good reversal tecnique |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, TrendLaboratory"
#property link "http://finance.groups.yahoo.com/group/TrendLaboratory"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 LawnGreen
#property indicator_color2 Aquamarine
#property indicator_color3 DeepSkyBlue
#property indicator_width1 1
#property indicator_width2 2
#property indicator_width3 2
//---- input parameters
extern int Length = 10; // Volty Length
extern double Kv = 1; // Sensivity Factor
extern int MA_Mode = 0; // Volty MA Mode : 0-SMA, 1-LWMA
extern int StepSizeMIN = 0; // Minimum Step Size (if need)
extern int StepSizeMAX = 0; // Maximum Step Size (if need)
extern int ShiftMIN = 0;
extern int ShiftMID = 0;
extern int ShiftMAX = 0;
//---- indicator buffers
double LineFstBuffer[];
double LineMidBuffer[];
double LineSlwBuffer[];
int time[2],TRENDMIN[2],TRENDMID[2],TRENDMAX[2];
double SMINMIN[2],SMAXMIN[2],SMINMAX[2],SMAXMAX[2],SMINMID[2],SMAXMID[2];
bool Expert=true;
double ATR0,ATRmax=0,ATRmin=100000;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
string short_name;
//---- indicator line
IndicatorBuffers(3);
SetIndexStyle(0,DRAW_LINE);
SetIndexStyle(1,DRAW_LINE);
SetIndexStyle(2,DRAW_LINE);
SetIndexBuffer(0,LineFstBuffer);
SetIndexBuffer(1,LineMidBuffer);
SetIndexBuffer(2,LineSlwBuffer);
//---- name for DataWindow and indicator subwindow label
short_name="StepMA 3D v3m("+Length+","+DoubleToStr(Kv,2)+")";
IndicatorShortName(short_name);
SetIndexLabel(0,"StepMA3Dfast");
SetIndexLabel(1,"StepMA3Dmid");
SetIndexLabel(2,"StepMA3Dslow");
SetIndexShift(0,ShiftMIN);
SetIndexShift(1,ShiftMID);
SetIndexShift(2,ShiftMAX);
//----
SetIndexDrawBegin(0,Length);
SetIndexDrawBegin(1,Length);
SetIndexDrawBegin(2,Length);
//----
return(0);
}
//+------------------------------------------------------------------+
//| StepMA_3D_v1 |
//+------------------------------------------------------------------+
int start()
{
int shift, TrendMin,TrendMax,TrendMid,MaxBar,limit,counted_bars=IndicatorCounted();
double StepSizeMin, StepSizeMax,StepSizeMid;
double SminMin[1],SmaxMin[1],SminMax[1],SmaxMax[1],SminMid[1],SmaxMid[1];
if (Bars-1<Length+1)return(0);
if (counted_bars<0)return(-1);
if (counted_bars>0) counted_bars--;
MaxBar=Bars-1-Length-1;
limit=Bars-counted_bars-1;
if (limit>MaxBar)
{
for (shift=limit;shift>=MaxBar;shift--)
{
LineFstBuffer[Bars-shift]=0;
LineSlwBuffer[Bars-shift]=0;
LineMidBuffer[Bars-shift]=0;
}
limit=MaxBar;
}
//----
if(ArrayResize(SminMin,limit+2)!=limit+2)return(-1);
if(ArrayResize(SmaxMin,limit+2)!=limit+2)return(-1);
if(ArrayResize(SminMax,limit+2)!=limit+2)return(-1);
if(ArrayResize(SmaxMax,limit+2)!=limit+2)return(-1);
if(ArrayResize(SminMid,limit+2)!=limit+2)return(-1);
if(ArrayResize(SmaxMid,limit+2)!=limit+2)return(-1);
//----
int Tnew=Time[limit+1];
if (limit<MaxBar)
if (Tnew==time[1])
{
TrendMin=TRENDMIN[1];
TrendMid=TRENDMID[1];
TrendMax=TRENDMAX[1];
SminMin[limit+1]=SMINMIN[1];
SmaxMin[limit+1]=SMAXMIN[1];
SminMax[limit+1]=SMINMAX[1];
SmaxMax[limit+1]=SMAXMAX[1];
SminMid[limit+1]=SMINMID[1];
SmaxMid[limit+1]=SMAXMID[1];
Expert=false;
}
else
if (Tnew==time[0])
{
TrendMin=TRENDMIN[0];
TrendMid=TRENDMID[0];
TrendMax=TRENDMAX[0];
SminMin[limit+1]=SMINMIN[0];
SmaxMin[limit+1]=SMAXMIN[0];
SminMax[limit+1]=SMINMAX[0];
SmaxMax[limit+1]=SMAXMAX[0];
SminMid[limit+1]=SMINMID[0];
SmaxMid[limit+1]=SMAXMID[0];
TRENDMIN[1]=TRENDMIN[0];
TRENDMID[1]=TRENDMID[0];
TRENDMAX[1]=TRENDMAX[0];
SMINMIN[1]=SMINMIN[0];
SMAXMIN[1]=SMAXMIN[0];
SMINMAX[1]=SMINMAX[0];
SMAXMAX[1]=SMAXMAX[0];
SMINMID[1]=SMINMID[0];
SMAXMID[1]=SMAXMID[0];
}
else
{
if (Tnew>time[1])Print("ERROR01");
else Print("ERROR02");
return(-1);
}
for(shift=limit;shift>=0;shift--)
{
double AvgRange=0;
double Weight = 0;
for (int i=Length-1;i>=0;i--)
{
if(MA_Mode==0) double alfa= 1.0; else alfa= 1.0*(Length-i)/Length;
AvgRange+= alfa*(High[shift+i]-Low[shift+i]);
Weight += alfa;
}
ATR0 = AvgRange/Weight;
if (ATR0>ATRmax) ATRmax=ATR0;
if (ATR0<ATRmin) ATRmin=ATR0;
if (StepSizeMIN > 0) ATRmin = StepSizeMIN*Point;
if (StepSizeMAX > 0) ATRmax = StepSizeMAX*Point;
StepSizeMin=MathRound(Kv*ATRmin/Point)*Point;
StepSizeMax=MathRound(Kv*ATRmax/Point)*Point;
StepSizeMid=MathRound(Kv*0.5*(ATRmax+ATRmin)/Point)*Point;
// Comment(" StepSize_min = ", StepSizeMin/Point,"\n",
// " StepSize_mid = ", StepSizeMid/Point,"\n",
// " StepSize_max = ", StepSizeMax/Point);
SmaxMin[shift]=Close[shift]+2.0*StepSizeMin;
SminMin[shift]=Close[shift]-2.0*StepSizeMin;
SmaxMax[shift]=Close[shift]+2.0*StepSizeMax;
SminMax[shift]=Close[shift]-2.0*StepSizeMax;
SmaxMid[shift]=Close[shift]+2.0*StepSizeMid;
SminMid[shift]=Close[shift]-2.0*StepSizeMid;
if(Close[shift]>SmaxMin[shift+1]) TrendMin=1;
if(Close[shift]<SminMin[shift+1]) TrendMin=-1;
if(Close[shift]>SmaxMax[shift+1]) TrendMax=1;
if(Close[shift]<SminMax[shift+1]) TrendMax=-1;
if(Close[shift]>SmaxMid[shift+1]) TrendMid=1;
if(Close[shift]<SminMid[shift+1]) TrendMid=-1;
if(TrendMin>0)
{
if(SminMin[shift]<SminMin[shift+1]) SminMin[shift]=SminMin[shift+1];
LineFstBuffer[shift]=SminMin[shift]+StepSizeMin;
}
if(TrendMin<0)
{
if(SmaxMin[shift]>SmaxMin[shift+1]) SmaxMin[shift]=SmaxMin[shift+1];
LineFstBuffer[shift]=SmaxMin[shift]-StepSizeMin;
}
if(TrendMax>0)
{
if(SminMax[shift]<SminMax[shift+1]) SminMax[shift]=SminMax[shift+1];
LineSlwBuffer[shift]=SminMax[shift]+StepSizeMax;
}
if(TrendMax<0)
{
if(SmaxMax[shift]>SmaxMax[shift+1]) SmaxMax[shift]=SmaxMax[shift+1];
LineSlwBuffer[shift]=SmaxMax[shift]-StepSizeMax;
}
if(TrendMid>0)
{
if(SminMid[shift]<SminMid[shift+1]) SminMid[shift]=SminMid[shift+1];
LineMidBuffer[shift]=SminMid[shift]+StepSizeMid;
}
if(TrendMid<0)
{
if(SmaxMid[shift]>SmaxMid[shift+1]) SmaxMid[shift]=SmaxMid[shift+1];
LineMidBuffer[shift]=SmaxMid[shift]-StepSizeMid;
}
if ((shift==2)||((shift==1)&&(Expert==true)))
{
time [shift-1]=Time [shift];
TRENDMIN[shift-1]=TrendMin;
TRENDMID[shift-1]=TrendMid;
TRENDMAX[shift-1]=TrendMax;
SMINMIN[shift-1]=SminMin[shift];
SMAXMIN[shift-1]=SmaxMin[shift];
SMINMAX[shift-1]=SminMax[shift];
SMAXMAX[shift-1]=SmaxMax[shift];
SMINMID[shift-1]=SminMid[shift];
SMAXMID[shift-1]=SmaxMid[shift];
}
}
return(0);
}
Comments