Author: Adapted by Lakshmi Inc.
4TF_RSI

Overview

The "Forex Freedom Bars" is a multi-timeframe technical analysis tool designed to identify market momentum by monitoring four different timeframes simultaneously. Instead of looking at a single chart, this script analyzes data from four distinct periods (such as 5-minute, 15-minute, 30-minute, and 1-hour charts) to provide a synchronized view of the market's direction.

Core Logic and Functionality

Multi-Timeframe Synchronization The primary strength of this script is its ability to "look ahead" across various time horizons. It automatically calculates data for four different periods at once. Depending on which chart you are currently viewing, the script intelligently selects the most relevant sequence of timeframes to monitor, ensuring that the analysis is always relevant to your current trading perspective.

The RSI Divergence Mechanism Inside each of those four timeframes, the script employs a specific calculation involving two different versions of a momentum oscillator (RSI):

  • Fast Component: A quicker-reacting indicator that tracks immediate price fluctuations.
  • Slow Component: A smoother, slower-moving indicator that filters out "noise" to show the broader trend.

By comparing these two components against each other, the script determines if the momentum is currently tilting upwards or downwards for each specific timeframe.

Visual Representation The tool translates this complex data into a simplified visual format:

  • Directional Bars: It creates a series of visual markers (bars/arrows) in a separate window.
  • Spacing: To keep the display organized and readable, it uses a "Gap" system to stack these bars vertically. This prevents the data from overlapping, allowing you to see the status of all four timeframes clearly at a glance.
  • Labels: The script dynamically labels these bars so you know exactly which timeframe is being represented by which row.

Signal Confirmation and Alerts The logic follows a strict "consensus" rule for generating alerts. Rather than alerting on just one timeframe, it looks for a unanimous agreement:

  1. It checks if the momentum on all four timeframes is pointing Up.
  2. It checks if the momentum on all four timeframes is pointing Down.

If, and only if, all four timeframes align in the same direction at the start of a new candle, the script triggers an audible alert sound and prints a notification message. This "confluence" logic is designed to help traders identify high-probability moves where short-term momentum aligns with long-term trends.

Summary for the User

Think of this tool as a "consensus meter." It monitors four different "opinions" from different timeframes. When all four opinions agree on the direction of the market, it gives you a definitive signal. This helps filter out minor price wiggles and focuses your attention on significant moves supported by multiple levels of market analysis.

Indicators Used
Relative strength index
Miscellaneous
Implements a curve of type %1It plays sound alerts
4 Views
0 Downloads
0 Favorites
4TF_RSI
//+------------------------------------------------------------------+
//|                                           #The Forex Freedom Bars
//|                                           
//+------------------------------------------------------------------+
#property copyright "Programmed by Eli hayun"
#property copyright "Adapted by Lakshmi Inc."
#property indicator_separate_window
#property indicator_minimum -0.5
//#property indicator_maximum 5
#property indicator_buffers 8
#property indicator_color1 Red
#property indicator_color2 DodgerBlue
#property indicator_color3 Red
#property indicator_color4 DodgerBlue
#property indicator_color5 Red
#property indicator_color6 DodgerBlue
#property indicator_color7 Red
#property indicator_color8 DodgerBlue
//---- buffers
double buf4_up[];
double buf4_down[];
double buf3_up[];
double buf3_down[];
double buf2_up[];
double buf2_down[];
double buf1_up[];
double buf1_down[];

extern double Gap = 1; // Gap between the lines of bars

extern int Period_1 = PERIOD_M5;//M15
extern int Period_2 = PERIOD_M15;//M30
extern int Period_3 = PERIOD_M30;//H1
extern int Period_4 = PERIOD_H1;//H4
extern int RSI1_Period=5;
extern int RSI2_Period=21;
extern int EMA1_Period=5;
extern int EMA2_Period=5;
extern int BarsCount=300;

double emaFactor1;
double emaFactor2;

double oldRSI1, oldRSI2;



bool AutoDisplay      = false;

string shortname = "";
bool firstTime = true;

int UniqueNum = 228;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
  
  
   SetAutoDisplay();
   if(EMA1_Period>0)
      {
      emaFactor1 = 2.0 / (EMA1_Period + 1);
      }
   else
      {
      emaFactor1 = 2.0 / (RSI1_Period + 1);
      }
   if(EMA2_Period>0)
      {
      emaFactor2 = 2.0 / (EMA2_Period + 1);
      }
   else
      {
      emaFactor2 = 2.0 / (RSI2_Period + 1);
      }
   
  
   shortname = "#4TF RSI Div("+Period_1+","+Period_2+","+Period_3+","+Period_4+")";
   firstTime = true;
   
   IndicatorShortName(shortname);
//---- indicators
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexArrow(0,110);
   SetIndexBuffer(0,buf4_up);
   SetIndexEmptyValue(0,0.0);
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexArrow(1,110);
   SetIndexBuffer(1,buf4_down);
   SetIndexEmptyValue(1,0.0);
   SetIndexStyle(2,DRAW_ARROW);
   SetIndexArrow(2,110);
   SetIndexBuffer(2,buf3_up);
   SetIndexEmptyValue(2,0.0);
   SetIndexStyle(3,DRAW_ARROW);
   SetIndexArrow(3,110);
   SetIndexBuffer(3,buf3_down);
   SetIndexEmptyValue(3,0.0);
   SetIndexStyle(4,DRAW_ARROW);
   SetIndexArrow(4,110);
   SetIndexBuffer(4,buf2_up);
   SetIndexEmptyValue(4,0.0);
   SetIndexStyle(5,DRAW_ARROW);
   SetIndexArrow(5,110);
   SetIndexBuffer(5,buf2_down);
   SetIndexEmptyValue(5,0.0);
   SetIndexStyle(6,DRAW_ARROW);
   SetIndexArrow(6,110);
   SetIndexBuffer(6,buf1_up);
   SetIndexEmptyValue(6,0.0);
   SetIndexStyle(7,DRAW_ARROW);
   SetIndexArrow(7,110);
   SetIndexBuffer(7,buf1_down);
   SetIndexEmptyValue(7,0.0);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   SetAutoDisplay();
   
   shortname = "# 4TF RSI Divergence("+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, y5m=0, y1h=0, y30m=0, y15m=0, yy;
   int limit=BarsCount;

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

   
   
   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),"FF_"+win+"_") >= 0)
            ObjectDelete(ObjectName(ii));
         else 
            ii=-1;
      }
      
      double shift = 0.2;
      for (ii=0; ii<4; ii++)
      {  
         string txt = "??";
         double gp;
         switch (ii)
         {
            case 0: txt = tf2txt(Period_1);  gp = 1 + shift;         break;
            case 1: txt = tf2txt(Period_2);  gp = 1 + Gap + shift;   break;
            case 2: txt = tf2txt(Period_3);  gp = 1 + Gap*2 + shift; break;
            case 3: txt = tf2txt(Period_4);  gp = 1 + Gap*3 + shift; break;
         }
         string name = "FF_"+win+"_"+ii+"_"+txt;
         ObjectCreate(name, OBJ_TEXT, WindowFind(shortname), iTime(NULL,0,0)+dif*3, gp);
         ObjectSetText(name, txt,8,"Arial", Silver);
      }
   }
   
   ArrayCopySeries(TimeArray_1H,MODE_TIME,Symbol(),Period_4); 
   ArrayCopySeries(TimeArray_30M,MODE_TIME,Symbol(),Period_3); 
   ArrayCopySeries(TimeArray_15M,MODE_TIME,Symbol(),Period_2);
   ArrayCopySeries(TimeArray_5M,MODE_TIME,Symbol(),Period_1); 
      
   for(i=0, y5m=0,  y1h=0,  y30m=0,  y15m=0;i<limit;i++)
   {
      if (Time[i]<TimeArray_5M[y5m]) y5m++;
      if (Time[i]<TimeArray_1H[y1h])   y1h++;
      if (Time[i]<TimeArray_30M[y30m])   y30m++;
      if (Time[i]<TimeArray_15M[y15m]) y15m++;
      
      
      for (int tf = 0; tf < 4; tf++)
      {
         int prd;
         switch (tf)
         {
            case 0: prd = Period_1; yy = y5m;    break;
            case 1: prd = Period_2; yy = y15m;   break;
            case 2: prd = Period_3; yy = y30m;   break;
            case 3: prd = Period_4; yy = y1h;   break;
         }
         
         double Fast_RSI = RSI_EMA1(yy, RSI1_Period, emaFactor1, oldRSI1, prd);
         double Slow_RSI = RSI_EMA1(yy, RSI2_Period, emaFactor2, oldRSI2, prd);
                  
         switch (tf)
         {
            case 0: if (Fast_RSI>Slow_RSI)  buf1_down[i] = 1;           if (Fast_RSI<Slow_RSI) buf1_up[i] = 1; break;
            case 1: if (Fast_RSI>Slow_RSI)  buf2_down[i] = 1 + Gap * 1; if (Fast_RSI<Slow_RSI) buf2_up[i] = 1 + Gap * 1; break;
            case 2: if (Fast_RSI>Slow_RSI)  buf3_down[i]  = 1 + Gap * 2; if (Fast_RSI<Slow_RSI) buf3_up[i]  = 1 + Gap * 2; break;
            case 3: if (Fast_RSI>Slow_RSI)  buf4_down[i]  = 1  + Gap * 3; if (Fast_RSI<Slow_RSI) buf4_up[i]  = 1 + Gap * 3; break;
         }
         if (NewBar())
         {
            string sDir = "";
            if (buf1_up[0] + buf2_up[0] + buf3_up[0] + buf4_up[0] == 4)
               sDir = "Up";
            if (buf1_down[0] + buf2_down[0] + buf3_down[0] + buf4_down[0] == 4)
               sDir = "Down";
            if (sDir != "")
            {
               PlaySound("alert1.wav");
               Print("RSI Signal - Direction ",sDir);
            }
         }         
         
      }


   }

   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");
   
   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);
}

//+------------------------------------------------------------------+

double RSI_EMA1(int pos, int RSI_Period, double emaFactor, double& oldRSI, int TF)
{
double curRSI;
   if(pos==Bars-2) 
      curRSI = iRSI(Symbol(),TF,RSI_Period,PRICE_CLOSE,pos+1);
   else   
      curRSI = iRSI(Symbol(),TF,RSI_Period,PRICE_CLOSE,pos)*emaFactor + oldRSI*(1-emaFactor);
      
      
   oldRSI = curRSI;   
   return(curRSI);
}

Comments