Stochastic 21,9,9
Download scriptThis script functions as a technical analysis tool designed to help traders identify potential overbought and oversold conditions in a financial market. It translates complex price movements into a visual oscillator that moves between 0 and 100, making it easier to gauge the momentum of an asset.
Core Logic Overview
The indicator operates by analyzing the relationship between recent high and low prices over specific timeframes. Instead of looking at the raw price alone, it calculates where the current price sits relative to the boundaries established during a past period.
How the Calculation Works
To generate the visual data, the script follows a four-step logical process:
- Identifying Extremes: The tool first looks back at a defined number of candles (the "K Period") to identify the highest price reached and the lowest price hit during that window. This establishes the "trading range" for that specific duration.
- Smoothing the Data: To prevent the indicator from reacting too erratically to minor price fluctuations, it applies a "Slowing" factor. This takes the current price's position within its range and averages it over a set period, resulting in a smoother flow of data.
- Generating the Main Line (%K): The primary visual line represents the percentage of the trading range that has been covered. For example, if the price is near the top of the established high/low range, the value will climb toward 100; if it is near the bottom, it will drop toward 0.
- Creating the Signal Line: Finally, the script calculates a secondary line based on a Simple Moving Average (SMA) of the Main Line. This "Signal" line acts as a trend indicator for the oscillator itself, helping users see if the momentum is accelerating or decelerating.
Summary for the User
By observing these two lines together, traders can look for moments where the price moves significantly outside of its normal range (oversold or overbought) and use the intersection or divergence between the Main Line and the Signal Line to gauge potential changes in market direction.
//+------------------------------------------------------------------+
//| Stochastic.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=21;
extern int DPeriod=9;
extern int Slowing=9;
//---- buffers
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(4);
SetIndexBuffer(2, HighesBuffer);
SetIndexBuffer(3, LowesBuffer);
//---- indicator lines
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0, MainBuffer);
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1, SignalBuffer);
//---- name for DataWindow and indicator subwindow label
short_name="Sto("+KPeriod+","+DPeriod+","+Slowing+")";
IndicatorShortName(short_name);
SetIndexLabel(0,short_name);
SetIndexLabel(1,"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++)
SignalBuffer[i]=iMAOnArray(MainBuffer,Bars,DPeriod,0,MODE_SMA,i);
//----
return(0);
}
//+------------------------------------------------------------------+
Comments