StepMA_3D_v1
Download scriptThis script is a technical analysis tool designed to identify and visualize market trends by creating three distinct "stepping" lines on a price chart. Unlike standard moving averages that provide a smooth, continuous curve, this tool creates a階段 (stepped) appearance to better highlight specific trend directions and volatility levels.
Core Logic Overview
The indicator functions by analyzing price movement through three primary layers of logic: Volatility Measurement, Step Calculation, and Trend Determination.
1. Dynamic Volatility Analysis
The script begins by calculating the "Average True Range" or general market volatility over a user-defined period. It looks at the distance between the high and low prices of recent candles. This ensures that the size of the "steps" on your chart adjusts automatically: in a volatile market, the steps will be larger; in a quiet market, the steps will become smaller.
2. Three-Dimensional Step Calculation
Instead of providing just one trend line, the logic calculates three different versions based on the volatility found in step one:
- Minimum Step: Based on the lowest recent volatility levels.
- Maximum Step: Based on the highest recent volatility levels.
- Mid Step: A balanced average of the minimum and maximum levels.
Each of these three lines represents a different "sensitivity" to market movement, allowing a user to see a spectrum of possible trend paths simultaneously.
3. Trend Direction & Locking
The script determines whether the market is moving up or down by comparing the current closing price against the calculated boundaries of the previous period's steps.
- Upward Momentum: If the price breaks above a specific threshold, the line "steps up."
- Downward Momentum: If the price falls below a specific threshold, the line "steps down."
A key feature of this logic is its "memory." The lines are designed to stay flat (horizontal) until a significant price movement occurs that is strong enough to overcome the calculated step size. This prevents the indicator from reacting to minor market "noise" and helps filter out insignificant fluctuations, ensuring that the lines only move when a meaningful trend shift is confirmed.
Summary for the User
In practical terms, this tool provides three distinct visual paths on your chart. By observing where these lines shift upward or downward, you can identify the strength of a trend. The "Maximum" line represents a more aggressive, high-volatility trend view, while the "Minimum" line offers a more conservative, low-volatility perspective. The "Mid" line acts as a balanced middle ground between the two.
//+------------------------------------------------------------------+
//| 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=0;
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