MTF_BH_Ergodic_4TFBars_ADM

Download script
Author: Copyright � 2006, Eli hayun
MTF_BH_Ergodic_4TFBars_ADM

This script is designed to provide traders with a multi-timeframe visual analysis of market trends. It acts as a comprehensive trend indicator that simultaneously displays information from four different timeframes, allowing you to see the "big picture" and the "micro movements" at once on a single chart.

Core Functionality

The primary logic of this script revolves around Multi-Timeframe (MTF) synchronization. Instead of looking at just the current chart's data, the script automatically identifies the appropriate surrounding timeframes based on what you are currently viewing (for example, if you are on a 15-minute chart, it will select related intervals like 5, 30, and 60 minutes).

How the Analysis Works

  1. Dynamic Timeframe Detection: The script intelligently detects your current chart period and selects a specific set of four higher or lower timeframes to analyze. This ensures that the data shown is always contextually relevant to your current trading view.
  2. Trend Identification: It utilizes a specialized calculation (referenced as "BH-Ergodic") to determine whether the market is in an upward or downward trend for each of those four timeframes.
  3. Visual Representation: Rather than just providing numbers, the script renders visual markers (arrows) on a separate window at the bottom of your chart. Each timeframe is assigned its own distinct horizontal "lane" or level:
    • The data is stacked vertically so that you can see four different trend signals simultaneously.
    • It uses specific colors (typically Green for upward trends and Red/Brown for downward trends) to make it easy to identify market sentiment at a glance.
  4. Data Smoothing and Filtering: The logic includes several layers of moving averages and price type selections. This means the trend signal isn't just reacting to every tiny price tick; it is smoothed out to filter out "market noise," helping to highlight more significant, sustained movements.

Key Features for the User

  • Simultaneous Overview: You can see if the short-term trend agrees with the long-term trend without having to constantly switch between different tabs or charts.
  • Automatic Labeling: The script automatically labels the data lanes with their corresponding timeframes (e.g., M15, H1, H4) so you always know exactly what each row of information represents.
  • Customizable Aesthetics: Users can adjust the "Gap" between the lines to make the display cleaner, choose which price source to use (like Close, Open, or Median prices), and customize the colors to suit their visual preference.

Summary of Purpose

Essentially, this tool acts as a Trend Dashboard. It pulls complex data from multiple timeframes, processes it through a smoothing algorithm, and presents it as a simple "Up" or "Down" visual guide, helping you stay aligned with the dominant market direction across different scales.

Miscellaneous
Implements a curve of type %1
13 Views
0 Downloads
0 Favorites
MTF_BH_Ergodic_4TFBars_ADM
//+------------------------------------------------------------------+
//|MTF_BH_Ergodic_4TFBars_ASw |     lee_yan_cn  N4 4TF HASBar 2nd.mq4|
//|(TFswch autodisplay)| Modified by Matsu,from#MTF SupertrendBar.mq4|
//|2007, Bruce Hellstrom                  Copyright © 2006, Eli hayun|
//|4TFBars Forex-TSD.com ml ki                http://www.elihayun.com|
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Eli hayun"
#property link      "http://www.elihayun.com"

#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 5
#property indicator_buffers 8
#property indicator_color1 Red
#property indicator_color2 Green
#property indicator_color3 Red
#property indicator_color4 Green
#property indicator_color5 Red
#property indicator_color6 Green
#property indicator_color7 Red
#property indicator_color8 Green

//---- parameters
extern int BarDiff = 1;     // calculations are taken between current bar and current bar + BarDiff
extern int r = 2;           // First moving average on mean values
extern int s = 10;          // Second moving average applied to first
extern int u = 5;           // Third moving average applied to division
extern int trigger = 3;     // Final moving average or smoothing
extern int PriceType = 0;   // 0=Close, 1=Open, 2=High, 3=Low, 4=Median, 5=Typical, 6=Weighted
extern int BarWidth = 0;
extern color BarColorUp = LightSeaGreen;
extern color BarColorDown = SaddleBrown;
extern color TextColor = OliveDrab;
extern int MaxBars=500;

double Gap = 1; // Gap between the lines of bars
//---- buffers

double buf1_up[];
double buf1_down[];
double buf2_up[];
double buf2_down[];
double buf3_up[];
double buf3_down[];
double buf4_up[];
double buf4_down[];
double haOpen;
double haClose;

/*
extern int Period_1 = 15;
extern int Period_2 = 30;
extern int Period_3 = 60;
extern int Period_4 = 240;

extern bool AutoDisplay      = false;
*/
string shortname = "";
bool firstTime = true;

int ArrSize = 110;//159;
int UniqueNum = 2283;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
  
  
   //SetAutoDisplay();
   
  
   
   firstTime = true;
   
   //IndicatorShortName(shortname);
//---- indicators
   SetIndexStyle(0,DRAW_ARROW,0,BarWidth,BarColorDown);
   SetIndexArrow(0,ArrSize);
   SetIndexBuffer(0,buf4_up);
   SetIndexEmptyValue(0,0.0);
   SetIndexStyle(1,DRAW_ARROW,0,BarWidth,BarColorUp);
   SetIndexArrow(1,ArrSize);
   SetIndexBuffer(1,buf4_down);
   SetIndexEmptyValue(1,0.0);
   SetIndexStyle(2,DRAW_ARROW,0,BarWidth,BarColorDown);
   SetIndexArrow(2,ArrSize);
   SetIndexBuffer(2,buf3_up);
   SetIndexEmptyValue(2,0.0);
   SetIndexStyle(3,DRAW_ARROW,0,BarWidth,BarColorUp);
   SetIndexArrow(3,ArrSize);
   SetIndexBuffer(3,buf3_down);
   SetIndexEmptyValue(3,0.0);
   SetIndexStyle(4,DRAW_ARROW,0,BarWidth,BarColorDown);
   SetIndexArrow(4,ArrSize);
   SetIndexBuffer(4,buf2_up);
   SetIndexEmptyValue(4,0.0);
   SetIndexStyle(5,DRAW_ARROW,0,BarWidth,BarColorUp);
   SetIndexArrow(5,ArrSize);
   SetIndexBuffer(5,buf2_down);
   SetIndexEmptyValue(5,0.0);
   SetIndexStyle(6,DRAW_ARROW,0,BarWidth,BarColorDown);
   SetIndexArrow(6,ArrSize);
   SetIndexBuffer(6,buf1_up);
   SetIndexEmptyValue(6,0.0);
   SetIndexStyle(7,DRAW_ARROW,0,BarWidth,BarColorUp);
   SetIndexArrow(7,ArrSize);
   SetIndexBuffer(7,buf1_down);
   SetIndexEmptyValue(7,0.0);
   
/* SetIndexLabel(0,NULL);
   SetIndexLabel(1,NULL);
   SetIndexLabel(2,NULL);
   SetIndexLabel(3,NULL);
   SetIndexLabel(4,NULL);
   SetIndexLabel(5,NULL);
   SetIndexLabel(6,NULL);
   SetIndexLabel(7,NULL);
*/   
   IndicatorDigits(0);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   //SetAutoDisplay();
   
//   shortname = "# Forex Freedom("+Period_1+","+Period_2+","+Period_3+","+Period_4+")";
   firstTime = true;
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
   int i=0, y15m=0,y30m=0,y1h=0,y4h=0, yy;
  
    int Period_1, Period_2, Period_3, Period_4;
 
   int limit=Bars-counted_bars;
   limit=MathMax(limit,Period_1/Period());
   limit=MathMax(limit,Period_2/Period());
   limit=MathMax(limit,Period_3/Period());
   limit=MathMax(limit,Period_4/Period());
   limit=MathMin(limit,MaxBars);


   switch(Period()) 
      {
         case 1: 
            Period_1=1; Period_2=5; Period_3=15; Period_4=30;
            break;
         case 5: 
            Period_1=5; Period_2=15; Period_3=30; Period_4=60;
            break;
         case 15: 
            Period_1=15; Period_2=30; Period_3=60; Period_4=240;
            break;
         case 30: 
            Period_1=30; Period_2=60; Period_3=240; Period_4=1440;
            break;
         case 60: 
            Period_1=60; Period_2=240; Period_3=1440; Period_4=10080;
            break;
         case 240: 
            Period_1=240; Period_2=1440; Period_3=10080; Period_4=43200;
            break;
         case 1440: 
            Period_1=1440; Period_2=10080; Period_3=43200; Period_4=43200;
            break;
         case 10080: 
            Period_1=10080; Period_2=43200; Period_3=43200; Period_4=43200;
            break;
         case 43200: 
            Period_1=43200; Period_2=43200; Period_3=43200; Period_4=43200;
            break;
         
      }
      
      
   shortname = "BH_Ergodic ("+Period_1+","+Period_2+","+Period_3+","+Period_4+")";
   IndicatorShortName(shortname);

   datetime TimeArray_4H[], TimeArray_1H[], TimeArray_30M[], TimeArray_15M[];
//----

   if (firstTime || NewBar())
   {
      firstTime = false;
      int win = UniqueNum; // WindowFind(shortname);
      double dif = Time[0] - Time[1];
      for (int ii=ObjectsTotal()-1; ii>-1; ii--)
      {
         if (StringFind(ObjectName(ii),"FF2_"+win+"_") >= 0)
            ObjectDelete(ObjectName(ii));
         else 
            ii=-1;
      }
      
      double shift = 0.5;
      for (ii=0; ii<4; ii++)
      {  
         string txt = "??";
         double gp;
         switch (ii)
         {
            case 0: txt = tf2txt(Period_4);  gp = 1 + shift;         
break;
            case 1: txt = tf2txt(Period_3);  gp = 1 + Gap + shift;   
break;
            case 2: txt = tf2txt(Period_2);  gp = 1 + Gap*2 + shift; 
break;
            case 3: txt = tf2txt(Period_1);  gp = 1 + Gap*3 + shift; 
break;
         }
         string name = "FF2_"+win+"_"+ii+"_"+txt;
         ObjectCreate(name, OBJ_TEXT, WindowFind(shortname), iTime(NULL,0,0)+dif*8, gp);
         ObjectSetText(name, txt,6,"Arial", TextColor);
      }
   }
 
   ArrayCopySeries(TimeArray_15M,MODE_TIME,Symbol(),Period_1); 
   ArrayCopySeries(TimeArray_30M,MODE_TIME,Symbol(),Period_2);
   ArrayCopySeries(TimeArray_1H,MODE_TIME,Symbol(),Period_3); 
   ArrayCopySeries(TimeArray_4H,MODE_TIME,Symbol(),Period_4); 
   
   
   for(i=0, y15m=0,  y4h=0,  y1h=0,  y30m=0;i<limit;i++)
 //  for(i=0, y15m=0,  y4h=0,  y1h=0,  y30m=0;i<MaxBars;i++)
   {
      if (Time[i]<TimeArray_15M [y15m])  y15m++;
      if (Time[i]<TimeArray_30M [y30m])  y30m++;
      if (Time[i]<TimeArray_1H  [y1h])   y1h++;
      if (Time[i]<TimeArray_4H  [y4h])   y4h++;

      for (int tf = 0; tf < 4; tf++)
      {
         int prd;
         switch (tf)
         {
            case 3: prd = Period_1; yy = y15m;  break;
            case 2: prd = Period_2; yy = y30m;  break;
            case 1: prd = Period_3;  yy = y1h;   break;
            case 0: prd = Period_4;  yy = y4h;   break;
         }
         
        
         haOpen = iCustom(NULL,prd,"BH-Ergodic",BarDiff,r,s,u,trigger,PriceType,0,yy) ;
         haClose = iCustom(NULL,prd,"BH-Ergodic",BarDiff,r,s,u,trigger,PriceType,1,yy) ;
     
         double dUp = EMPTY_VALUE; //   iCustom(NULL, prd, "SuperTrend", false, 1, yy);
         double dDn = EMPTY_VALUE; //iCustom(NULL, prd, "SuperTrend", false, 0, yy);
         
         if (haOpen<haClose) dDn = 1; else dUp = 1;
         
         switch (tf)
         {
            case 0: if (dUp == EMPTY_VALUE)  buf1_down[i] = 1;           
else buf1_up[i] = 1; break;
            case 1: if (dUp == EMPTY_VALUE)  buf2_down[i] = 1 + Gap * 
1; else buf2_up[i] = 1 + Gap * 1; break;
            case 2: if (dUp == EMPTY_VALUE)  buf3_down[i]  = 1 + Gap * 
2; else buf3_up[i]  = 1 + Gap * 2; break;
            case 3: if (dUp == EMPTY_VALUE)  buf4_down[i]  = 1  + Gap * 
3; else buf4_up[i]  = 1 + Gap * 3; break;
         }
         
         
      }


   }

   return(0);
  }
//+------------------------------------------------------------------+

string tf2txt(int tf)
{
   if (tf == PERIOD_M1)    return("M1");
   if (tf == PERIOD_M5)    return("M5");
   if (tf == PERIOD_M15)    return("M15");
   if (tf == PERIOD_M30)    return("M30");
   if (tf == PERIOD_H1)    return("H1");
   if (tf == PERIOD_H4)    return("H4");
   if (tf == PERIOD_D1)    return("D1");
   if (tf == PERIOD_W1)    return("W1");
   if (tf == PERIOD_MN1)    return("MN1");
  //----  Refresh buffers ++++++++++++++++++++ upgrade by Raff  
   int TimeFrame,TimeArray[],i;
   if (TimeFrame>Period()) {
     int PerINT=TimeFrame/Period()+1;
     datetime TimeArr[]; ArrayResize(TimeArr,PerINT);
     ArrayCopySeries(TimeArr,MODE_TIME,Symbol(),Period()); 
     for(i=0;i<PerINT+1;i++) {if (TimeArr[i]>=TimeArray[0]) {
//----
 /********************************************************  
    Refresh buffers:         buffer[i] = buffer[0];
 ********************************************************/  

buf4_up[i]=buf4_up[0];
buf4_down[i]=buf4_down[0];
buf3_up[i]=buf3_up[0];
buf3_down[i]=buf3_down[0];
 buf2_up[i]= buf2_up[0];
 buf2_down[i]= buf2_down[0];
 buf1_up[i]=buf1_up[0];
 buf1_down[i]= buf1_down[0];

//----
   } } }
//+++++++++++++++++++++++++++++++++++++++++++++++ Raff  
   
   return("??");
}

/*void SetValues(int p1, int p2, int p3, int p4)
{
   Period_1 = p1;   Period_2 = p2; Period_3 = p3; Period_4 = p4; 
}


void SetAutoDisplay()
{
   if (AutoDisplay)
   {
      switch (Period())
      {
         case PERIOD_M1  :  SetValues(PERIOD_M1,  PERIOD_M5, 
PERIOD_M15,PERIOD_M30); break;
         case PERIOD_M5  :  SetValues(PERIOD_M5,  
PERIOD_M15,PERIOD_M30,PERIOD_H1); break;
         case PERIOD_M15 :  SetValues(PERIOD_M5,  
PERIOD_M15,PERIOD_M30,PERIOD_H1); break;
         case PERIOD_M30 :  SetValues(PERIOD_M5, PERIOD_M15,PERIOD_M30, 
PERIOD_H1); break;
         case PERIOD_H1  :  SetValues(PERIOD_M15, PERIOD_M30,PERIOD_H1, 
PERIOD_H4);  break;
         case PERIOD_H4  :  SetValues(PERIOD_M30, PERIOD_H1, PERIOD_H4, 
PERIOD_D1);  break;
         case PERIOD_D1  :  SetValues(PERIOD_H1,  PERIOD_H4, PERIOD_D1, 
PERIOD_W1); break;
         case PERIOD_W1  :  SetValues(PERIOD_H4,  PERIOD_D1, 
PERIOD_W1,PERIOD_MN1); break;
         case PERIOD_MN1 :  SetValues(PERIOD_H4,  PERIOD_D1, 
PERIOD_W1,PERIOD_MN1);  break;
      }
   }
   
}
*/
bool NewBar()
{
   static datetime dt = 0;
   
   if (Time[0] != dt)
   {
      dt = Time[0];
      return(true);
   }
   return(false);
}

Comments