SlowKD
Download scriptThis script functions as a specialized technical analysis tool designed to help traders identify momentum and potential reversals in market price trends. By analyzing the relationship between recent highs and lows, it translates complex price movements into a simplified visual format ranging from 0 to 100.
Core Logic Overview
The indicator operates by measuring where the current market price sits relative to its recent price range. It doesn't just look at the latest price; instead, it scans back through a specific window of time (defined by your settings) to determine the "ceiling" (the highest price reached) and the "floor" (the lowest price reached).
How the Calculations Work
The logic follows a multi-step sequence to ensure the data is smooth and readable:
- High and Low Identification: The script first scans the historical bars to identify the absolute highest and lowest points for every period. This establishes the boundaries of the market's recent volatility.
- Momentum Calculation (%K): It then calculates the "distance" between the closing price and these boundaries. By comparing how close the price is to the top versus the bottom, it produces a percentage value. A high value suggests strong upward momentum, while a low value suggests downward pressure.
- Smoothing (The "Slow" Element): To prevent the indicator from reacting too violently to every minor price flicker, the script applies a smoothing process. It averages out these percentages over a set period, creating a more stable trend line.
- Signal Generation: Finally, the script takes that smoothed data and performs a secondary calculation to create a "Signal Line." This acts as a moving average of the primary indicator.
Visual Interpretation
On your chart, this results in two distinct lines:
- The Main Line: Represents the core momentum of the asset.
- The Signal Line: Acts as a secondary guide that follows the main line.
By observing how these two lines interact—specifically when they cross one another or reach extreme ends of the 0-100 scale—traders can better visualize whether the market is becoming overbought, oversold, or shifting its primary direction.
//+------------------------------------------------------------------+
//| SlowKD.mq4 |
//| Copyright ?2004, MetaQuotes Software Corp. |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright ?2004, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net"
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_buffers 2
#property indicator_color1 LightSeaGreen
#property indicator_color2 Red
//---- input parameters
extern int KPeriod=5;
extern int DPeriod=3;
extern int Slowing=3;
//---- buffers
double KBuffer[];
double DBuffer[];
double MainBuffer[];
double SignalBuffer[];
double HighesBuffer[];
double LowesBuffer[];
//----
int draw_begin1=0;
int draw_begin2=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
string short_name;
//---- 2 additional buffers are used for counting.
IndicatorBuffers(6);
SetIndexBuffer(2, HighesBuffer);
SetIndexBuffer(3, LowesBuffer);
SetIndexBuffer(4, MainBuffer);
SetIndexBuffer(5, SignalBuffer);
//---- indicator lines
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0, KBuffer);
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1, DBuffer);
//---- name for DataWindow and indicator subwindow label
short_name="SlowKD("+KPeriod+","+DPeriod+","+Slowing+")";
IndicatorShortName(short_name);
SetIndexLabel(4,short_name);
SetIndexLabel(5,"Signal");
//----
draw_begin1=KPeriod+Slowing;
draw_begin2=draw_begin1+DPeriod;
SetIndexDrawBegin(0,draw_begin1);
SetIndexDrawBegin(1,draw_begin2);
//----
return(0);
}
//+------------------------------------------------------------------+
//| Stochastic oscillator |
//+------------------------------------------------------------------+
int start()
{
int i,k;
int counted_bars=IndicatorCounted();
double price;
//----
if(Bars<=draw_begin2) return(0);
//---- initial zero
if(counted_bars<1)
{
for(i=1;i<=draw_begin1;i++) MainBuffer[Bars-i]=0;
for(i=1;i<=draw_begin2;i++) SignalBuffer[Bars-i]=0;
}
//---- minimums counting
i=Bars-KPeriod;
if(counted_bars>KPeriod) i=Bars-counted_bars-1;
while(i>=0)
{
double min=1000000;
k=i+KPeriod-1;
while(k>=i)
{
price=Low[k];
if(min>price) min=price;
k--;
}
LowesBuffer[i]=min;
i--;
}
//---- maximums counting
i=Bars-KPeriod;
if(counted_bars>KPeriod) i=Bars-counted_bars-1;
while(i>=0)
{
double max=-1000000;
k=i+KPeriod-1;
while(k>=i)
{
price=High[k];
if(max<price) max=price;
k--;
}
HighesBuffer[i]=max;
i--;
}
//---- %K line
i=Bars-draw_begin1;
if(counted_bars>draw_begin1) i=Bars-counted_bars-1;
while(i>=0)
{
double sumlow=0.0;
double sumhigh=0.0;
for(k=(i+Slowing-1);k>=i;k--)
{
sumlow+=Close[k]-LowesBuffer[k];
sumhigh+=HighesBuffer[k]-LowesBuffer[k];
}
if(sumhigh==0.0) MainBuffer[i]=100.0;
else MainBuffer[i]=sumlow/sumhigh*100;
i--;
}
//---- last counted bar will be recounted
if(counted_bars>0) counted_bars--;
int limit=Bars-counted_bars;
//---- signal line is simple movimg average
for(i=0; i<limit; i++)
KBuffer[i]=iMAOnArray(MainBuffer,Bars,Slowing,0,MODE_SMA,i);
for(i=0; i<limit; i++)
DBuffer[i]=iMAOnArray(KBuffer,Bars,DPeriod,0,MODE_SMA,i);
//----
return(0);
}
//+------------------------------------------------------------------+
Comments