MTF_Stochastic_v2.0hio

Download script
MTF_Stochastic_v2.0hio

This tool is designed to help traders visualize momentum on a single chart without having to constantly switch between different timeframes. Its core purpose is to take technical data from a higher (or lower) timeframe—such as a Daily or Weekly trend—and project it onto your current active chart.

Core Functionality

Multi-Timeframe Integration The script allows you to select any specific timeframe (e.g., moving from a 1-minute chart to viewing 4-hour data). It calculates the "Stochastic Oscillator," which is a standard technical indicator used to determine if an asset is overbought or oversold. By displaying this data from different timeframes simultaneously, it helps traders see the "big picture" while executing trades on smaller, faster scales.

Smooth Data Visualization (Linear Interpolation) One of the most sophisticated features of this script is how it handles the gap between timeframes. Normally, if you view Weekly data on a Daily chart, the price would look like a series of "steps" because the data only changes once a week.

This script solves that problem using linear interpolation. It mathematically calculates the points between the high and low timeframe values and fills in the gaps. This results in a smooth, continuous line rather than jagged jumps, making it much easier to see the gradual flow of the trend.

Dynamic Visual Updates The logic is built to automatically update as new price data arrives. It distinguishes between "closed" candles (historical data) and the "current" candle.

  • Historical Lines: These represent confirmed data from past periods.
  • Current Candle Tracking: The script provides a real-time look at the ongoing timeframe's movement, showing where the momentum is heading right now.

User Experience Features

Smart Coloring & Labeling The script includes an automatic styling system. Depending on which timeframe you choose to view, the indicator will change its colors (such as Lime, Red, or Gold) to ensure high visibility and clear distinction between different data sets. It also automatically labels itself so you can easily identify which specific timeframe you are currently observing.

Live Countdown Clock To help with timing, the script includes an optional visual clock. This shows a real-time countdown until the next candle closes on the selected higher timeframe. For example, if you are watching the Weekly trend, this clock tells you exactly how many minutes and seconds remain until the current weekly candle finishes, allowing for better synchronization of trades with market cycles.

Indicators Used
Stochastic oscillator
Miscellaneous
Implements a curve of type %1
15 Views
0 Downloads
0 Favorites
MTF_Stochastic_v2.0hio
//+------------------------------------------------------------------+
//|                                               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_level1		23.6
#property indicator_level2		38.2
#property indicator_level3    50
#property indicator_level4    61.8
#property indicator_level5    76.4
#property indicator_levelcolor  SlateGray
#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		= 14,
				DPeriod		= 3,
				Slowing		= 3,
				MAMethod		= 0,		// {0=SMA, 1=EMA, 2=SMMA, 3=LWMA}
				PriceField	= 0;		// {0=Hi/Low, 1=Close/Close}
extern bool	ShowClock	= true;	// display time to candle close countdown
extern color ClockColor	= Red;

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

//----
string	IndicatorName = "",
			TimeLabelName = "";
			
int color1 = Black;
int color2 = Black;
int color3 = Black;
int color4 = Black;


//+------------------------------------------------------------------+
//| 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);}
	}
	if (TimeFrame==15){
	
	   color1	=	DimGray;	// %K line
      color2	=	Blue;				// %D line
      color3	=	DimGray;	// %K line of the current candle
      color4	=	DodgerBlue;		// %D line of the current candle
      ClockColor	= Blue;
      }
   if (TimeFrame==30){
      color1	=	DimGray;	// %K line
      color2	=	Lime;				// %D line
      color3	=	DimGray;	// %K line of the current candle
      color4	=	LightGreen;		// %D line of the current candle
      ClockColor	= Lime;
      }
   if (TimeFrame==60){
      color1	=	DimGray;	// %K line
      color2	=	Red;				// %D line
      color3	=	DimGray;	// %K line of the current candle
      color4	=	OrangeRed;		// %D line of the current candle
      ClockColor	= Red;
      }
   if (TimeFrame==240){
      color1	=	DimGray;	// %K line
      color2	=	Yellow;				// %D line
      color3	=	DimGray;	// %K line of the current candle
      color4	=	Gold;		// %D line of the current candle
      ClockColor	= Yellow;
      }      
	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_NONE,EMPTY,2,color1);
	SetIndexStyle(1,DRAW_LINE,EMPTY,2,color2);
	SetIndexStyle(2,DRAW_NONE,EMPTY,1,color3);
	SetIndexStyle(3,DRAW_LINE,EMPTY,1,color4);
	//SetIndexStyle(
 	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!="")
		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