#MTF Stochastic v2.0_002

Download script
#MTF Stochastic v2.0_002

This tool is a specialized technical analysis indicator designed for the MetaTrader trading platform. Its primary purpose is to allow traders to view "Stochastic" oscillator data from different timeframes simultaneously on a single chart.

Core Functionality

The main objective of this script is to solve a common visual problem in trading: it is often difficult to see how high-level market trends (like Daily or Weekly movements) align with the smaller price action you see on your immediate screen (like 15-minute or 1-hour charts). This script bridges that gap by pulling data from a higher timeframe and projecting it onto your current view.

Key Features and Logic

Multi-Timeframe Synchronization The script allows you to choose any specific time period (e.g., M1, H4, D1, etc.) to monitor. It automatically calculates the Stochastic values for that chosen timeframe and displays them on your current chart. This helps in identifying whether the market is overbought or oversold on a larger scale while you are looking at smaller price movements.

Visual Smoothing and Interpolation Because higher timeframe data usually consists of large "blocks" of time (for example, one Daily candle covers many 1-hour candles), simply displaying the data can result in jagged, blocky lines that are hard to read. To solve this, the script uses a logic called Linear Interpolation.

It calculates the difference between the starting and ending points of these larger blocks and "fills in" the gaps with smooth transitions. This ensures that the line moves fluidly across your chart, providing a more accurate visual representation of how the higher timeframe momentum is changing from one moment to the next.

Dual-Data Tracking The script distinguishes between two types of data:

  1. Historical Data: It plots the completed movements of past candles.
  2. Real-Time Data: It specifically tracks the current, active candle to show you what is happening "right now." By separating these, it ensures that the current live movement is highlighted accurately without being confused by historical data.

Optional Countdown Timer For users who want extra precision, the script includes an optional clock feature. This displays a countdown on the chart, showing exactly how much time remains until the next candle closes on the selected timeframe. This is useful for traders who need to know exactly when a new period of data will begin.

Summary for the User

Instead of having to switch between multiple windows to see different timeframes, this script combines them into one view. It takes complex high-level data, smooths it out so it looks natural on your current chart, and provides a clear visual path of market momentum across different scales.

Indicators Used
Stochastic oscillator
Miscellaneous
Implements a curve of type %1
14 Views
0 Downloads
0 Favorites
#MTF Stochastic v2.0_002
//+------------------------------------------------------------------+
//|                                               MTF Stochastic.mq4 |
//|													2007, Christof Risch (iya)	|
//| Stochastic indicator from any timeframe.									|
//+------------------------------------------------------------------+
#property link "http://www.forexfactory.com/showthread.php?t=30109"
#property indicator_separate_window
#property indicator_buffers	4
#property indicator_color1		LightSeaGreen	// %K line
#property indicator_color2		Red				// %D line
#property indicator_color3		LightGreen		// %K line of the current candle
#property indicator_color4		LightSalmon		// %D line of the current candle
#property indicator_level1		80
#property indicator_level2		20
#property indicator_maximum	100
#property indicator_minimum	0

//---- input parameters
extern int	TimeFrame	= 0,		// {1=M1, 5=M5, 15=M15, ..., 1440=D1, 10080=W1, 43200=MN1}
				KPeriod		= 8,
				DPeriod		= 3,
				Slowing		= 3,
				MAMethod		= 0,		// {0=SMA, 1=EMA, 2=SMMA, 3=LWMA}
				PriceField	= 0;		// {0=Hi/Low, 1=Close/Close}
 bool	ShowClock	= false;	// display time to candle close countdown
 color ClockColor	= Red;

//---- indicator buffers
double		BufferK[],
				BufferD[],
				BufferK_Curr[],
				BufferD_Curr[];

//----
string	IndicatorName = "",
			TimeLabelName = "";

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
//---- name for DataWindow and indicator subwindow label
	switch(TimeFrame)
	{
		case 1:		IndicatorName="Period M1";	break;
		case 5:		IndicatorName="Period M5"; break;
		case 15:		IndicatorName="Period M15"; break;
		case 30:		IndicatorName="Period M30"; break;
		case 60:		IndicatorName="Period H1"; break;
		case 240:	IndicatorName="Period H4"; break;
		case 1440:	IndicatorName="Period D1"; break;
		case 10080:	IndicatorName="Period W1"; break;
		case 43200:	IndicatorName="Period MN1"; break;
		default:	  {TimeFrame = Period(); init(); return(0);}
	}

	IndicatorName = IndicatorName+" Stoch("+KPeriod+","+DPeriod+","+Slowing+")";
	IndicatorShortName(IndicatorName);  
	IndicatorDigits(1);

//---- indicator lines
	SetIndexBuffer(0,BufferK);
	SetIndexBuffer(1,BufferD);
	SetIndexBuffer(2,BufferK_Curr);
	SetIndexBuffer(3,BufferD_Curr);
 	SetIndexStyle(0,DRAW_LINE);
	SetIndexStyle(1,DRAW_LINE);
	SetIndexStyle(2,DRAW_LINE);
	SetIndexStyle(3,DRAW_LINE);
 	SetIndexLabel(0,IndicatorName+" %K line");
	SetIndexLabel(1,IndicatorName+" %D Signal");
 	SetIndexLabel(2,IndicatorName+" %K current candle");
 	SetIndexLabel(3,IndicatorName+" %D current candle");
}

//+------------------------------------------------------------------+
int deinit()
{
	if(TimeLabelName!="")
	if(ObjectFind	(TimeLabelName) != -1)
		ObjectDelete(TimeLabelName);
}

//+------------------------------------------------------------------+
//| MTF Stochastic                                                   |
//+------------------------------------------------------------------+
int start()
{
//----
//	counted bars from indicator time frame
	static int countedBars1 = 0;

//----
//	counted bars from display time frame
	if(Bars-1-IndicatorCounted() > 1 && countedBars1!=0)
		countedBars1 = 0;

	int bars1 = iBars(NULL,TimeFrame),
		 start1 = bars1-1-countedBars1,
		 limit1 = iBarShift(NULL,TimeFrame,Time[Bars-1]);

	if(countedBars1 != bars1-1)
	{
		countedBars1  = bars1-1;
		ArrayInitialize(BufferK_Curr,EMPTY_VALUE);
		ArrayInitialize(BufferD_Curr,EMPTY_VALUE);
		if(TimeLabelName!=TimeFrame+"")
		if(ObjectFind	(TimeLabelName) != -1)
			ObjectDelete(TimeLabelName);
	}

	if(start1 > limit1 && limit1 != -1)
		start1 = limit1;

//----
//	3... 2... 1... GO!
	for(int i = start1; i >= 0; i--)
	{
		int shift1 = i;

		if(TimeFrame < Period())
			shift1 = iBarShift(NULL,TimeFrame,Time[i]);

		int time1  = iTime    (NULL,TimeFrame,shift1),
			 shift2 = iBarShift(NULL,0,time1);

		double stochK = iStochastic(NULL,TimeFrame,KPeriod,DPeriod,Slowing,MAMethod,PriceField,0,shift1),
				 stochD = iStochastic(NULL,TimeFrame,KPeriod,DPeriod,Slowing,MAMethod,PriceField,1,shift1);

	//----
	//	old (closed) candles
		if(shift1>=1)
		{
			BufferK[shift2] = stochK;
			BufferD[shift2] = stochD;
		}

	//----
	//	current candle
		if((TimeFrame >=Period() && shift1<=1)
		|| (TimeFrame < Period() &&(shift1==0||shift2==1)))
		{
			BufferK_Curr[shift2] = stochK;
			BufferD_Curr[shift2] = stochD;
		}

	//----
	//	linear interpolatior for the number of intermediate bars, between two higher timeframe candles.
		int n = 1;
		if(TimeFrame > Period())
		{
			int shift2prev = iBarShift(NULL,0,iTime(NULL,TimeFrame,shift1+1));

			if(shift2prev!=-1 && shift2prev!=shift2)
				n = shift2prev - shift2;
		}

	//----
	//	apply interpolation
		double factor = 1.0 / n;
		if(shift1>=1)
		if(BufferK[shift2+n]!=EMPTY_VALUE && BufferK[shift2]!=EMPTY_VALUE)
		{
			for(int k = 1; k < n; k++)
			{
				BufferK[shift2+k] = k*factor*BufferK[shift2+n] + (1.0-k*factor)*BufferK[shift2];
				BufferD[shift2+k] = k*factor*BufferD[shift2+n] + (1.0-k*factor)*BufferD[shift2];
			}
		}

	//----
	//	current candle
		if(shift1==0)
		if(BufferK_Curr[shift2+n]!=EMPTY_VALUE && BufferK_Curr[shift2]!=EMPTY_VALUE)
		{
			for(k = 1; k < n; k++)
			{
				BufferK_Curr[shift2+k] = k*factor*BufferK_Curr[shift2+n] + (1.0-k*factor)*BufferK_Curr[shift2];
				BufferD_Curr[shift2+k] = k*factor*BufferD_Curr[shift2+n] + (1.0-k*factor)*BufferD_Curr[shift2];
			}

		//----
		//	candle time countdown
			if(ShowClock)
			{
				int m,s;

				s = iTime(NULL,TimeFrame,0)+TimeFrame*60 - TimeCurrent();
				m = (s-s%60)/60;
				s = s%60;

				string text;
				if(s<10)	text = "0"+s;
				else		text = ""+s;
				text = "            "+m+":"+text;

				int window = WindowFind(IndicatorName);
				if(window==-1)
					window = WindowOnDropped() ;

				TimeLabelName = IndicatorName+" Time Counter "+window;

				if(ObjectFind	(TimeLabelName) == -1)
					ObjectCreate(TimeLabelName, OBJ_TEXT, window, Time[shift2], BufferK_Curr[shift2]+3);
				else
					ObjectMove	(TimeLabelName, 0, Time[shift2], BufferK_Curr[shift2]+3);

				ObjectSetText	(TimeLabelName, text, 8, "Verdana", ClockColor);
			}
		}
	}

	return(0);
}


Comments