_i_FXGauge1

Download script
Author: Copyright � 2006, Doji Starr
_i_FXGauge1

This script functions as a multi-timeframe visual analysis tool designed to project a comprehensive "map" of market structure onto your trading chart. Instead of just showing you where the price is currently, it provides a visual framework of potential support and resistance zones based on data from four different timeframes simultaneously.

Core Logic Overview

The indicator operates by aggregating data from four specific timeframes (which can be customized by the user). It looks at these timeframes independently and performs the following logic for each:

1. Data Gathering and Momentum Mapping For every timeframe, the script retrieves a series of momentum levels (derived from an external moving average calculation). It identifies the highest and lowest values among these levels to establish a "boundary" for that specific timeframe's current price action.

2. Dynamic Zone Projection (The "Shades") Once the high and low boundaries are identified, the script calculates several "Blue Shade" levels. These act as a gradient of zones extending upward from the lowest momentum point and downward from the highest momentum point.

  • These zones visually represent "zones of interest."
  • The logic includes an automatic adjustment system: if different zones overlap (meaning the price action is compressed), the script intelligently hides the redundant layers to ensure the visual display remains clean and readable.

3. Visualizing Multi-Timeframe Synchronization The script organizes these results into a side-by-side grid on your chart. By spacing out the data from the four different timeframes, it allows you to see at a glance how various time periods (e.g., 1-minute, 5-minute, 15-minute, and 60-minute) align with one another. This helps traders identify "confluence"—points where multiple timeframes agree on a price level.

4. Identifying Significant Gaps (Vertical Lines) One of the script's primary roles is to detect significant "voids" or gaps in price action. It combines all calculated levels from the various timeframes and sorts them into a single master list. It then scans this list for any gaps larger than 10 pips.

  • When such a gap is found, it draws a solid vertical line.
  • Color Coding: These lines are color-coded based on their relation to the current price: one color indicates the gap is below the current price (potential support), while another indicates the gap is above (potential resistance).

Summary of Visual Elements

  • Blue Shades: Gradient rectangles representing momentum zones and price "stretch" across different timeframes.
  • Momentum Bars: Horizontal markers showing specific data points for each timeframe, color-coded to indicate their position relative to the current market price.
  • Vertical Lines: Dynamic indicators highlighting significant structural gaps in the market where price might react or move quickly.

In essence, the script transforms raw multi-timeframe data into a structured visual "gauge," allowing you to see the invisible boundaries of the market across different time scales simultaneously.

13 Views
0 Downloads
0 Favorites
_i_FXGauge1
//+------------------------------------------------------------------+
//|                                                   _i_FXGauge.mq4 |
//|                                     Copyright © 2006, Doji Starr |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Doji Starr"

#property indicator_chart_window

#define NBSL    8       // number of blue shade levels
#define NSVR    17      // number of solid vertical lines


// input params
extern int TF1 = 1;
extern int TF2 = 5;
extern int TF3 = 15;
extern int TF4 = 60;

int Shift = 2;
int Spacing = 7;
int Width = 6;

// vars
int counted_bars, startBar, bar, i;

int tf, c, offset, xUnit;
int shift, spacing, width;
int tfa[4];
double fml[4][7];                               // momentum lines
double bsl_up[4][NBSL];                         // blue shades levels to the up side
double bsl_down[4][NBSL];                       // blue shades levels to the down side
double _bsl[NBSL] = {8, 11, 16, 27, 43, 75, 100, 144};
                                                // blue shades distances
double bsl[NBSL];                               // blue shades distances ('Point' adjusted)
double tmpArray[7], lowestMA, highestMA;
double srl[24];                                 // support/resistance levels (total = 2*NBSL + 7 + 1(Bid) )
double price;
string objName;
datetime curTime;
//color blueShade[NBSL] = {LightBlue, LightSkyBlue, CornflowerBlue, RoyalBlue, Blue};
color blueShade[NBSL] = {C'216,239,255', C'167,224,254', C'96,215,255', C'1,191,223', C'16,137,218', C'0,0,255', C'0,0,255'};
color col;



//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
    tfa[0] = TF1;
    tfa[1] = TF2;
    tfa[2] = TF3;
    tfa[3] = TF4;

    xUnit = Period() * 60;
    shift = Shift * xUnit;
    spacing = Spacing * xUnit;
    width = Width * xUnit;
    
    for (i=0; i<NBSL; i++)
        bsl[i] = _bsl[i]*Point;

    // creating the objects for drawing the grid    
    for (tf=0; tf<4; tf++)
    {
        // blue shade rectangles and bars
        for (i=0; i<NBSL; i++)
        {
            objName = "bsl_up_rect_"+tf+"_"+i;
            ObjectCreate(objName, OBJ_RECTANGLE, 0, 0, 0, 0, 0);
            ObjectSet(objName, OBJPROP_COLOR, blueShade[i]);
            
            objName = "bsl_down_rect_"+tf+"_"+i;
            ObjectCreate(objName, OBJ_RECTANGLE, 0, 0, 0, 0, 0);
            ObjectSet(objName, OBJPROP_COLOR, blueShade[i]);
            
            objName = "bsl_up_bar_"+tf+"_"+i;
            ObjectCreate(objName, OBJ_TREND, 0, 0, 0, 0, 0);
            ObjectSet(objName, OBJPROP_COLOR, Black);
            ObjectSet(objName, OBJPROP_RAY, false);
            ObjectSet(objName, OBJPROP_WIDTH, 2);
            
            objName = "bsl_down_bar_"+tf+"_"+i;
            ObjectCreate(objName, OBJ_TREND, 0, 0, 0, 0, 0);
            ObjectSet(objName, OBJPROP_COLOR, Black);
            ObjectSet(objName, OBJPROP_RAY, false);
            ObjectSet(objName, OBJPROP_WIDTH, 2);
        }
        objName = "MidShade_"+tf;
        ObjectCreate(objName, OBJ_RECTANGLE, 0, 0, 0, 0, 0);
        ObjectSet(objName, OBJPROP_COLOR, White);
        
        // S&R boxes
        objName = "Box1_"+tf;
        ObjectCreate(objName, OBJ_ARROW, 0, 0, 0);
        ObjectSet(objName, OBJPROP_ARROWCODE, 1);
        objName = "Box2_"+tf;
        ObjectCreate(objName, OBJ_ARROW, 0, 0, 0);
        ObjectSet(objName, OBJPROP_ARROWCODE, 1);
        
        // momentum lines bars
        for (i=0; i<7; i++)
        {
            objName = "fml_bar_"+tf+"_"+i;
            ObjectCreate(objName, OBJ_TREND, 0, 0, 0, 0, 0);
            ObjectSet(objName, OBJPROP_COLOR, Black);
            ObjectSet(objName, OBJPROP_RAY, false);
            if (i<2)
                ObjectSet(objName, OBJPROP_WIDTH, 5);
            else
                ObjectSet(objName, OBJPROP_WIDTH, 2);
        }
        
        // solid vertical lines (of 10 pips or more)
        for (i=1; i<=NSVR; i++)
        {
            objName = "svr_"+tf+"_"+i;
            ObjectCreate(objName, OBJ_TREND, 0, 0, 0, 0, 0);
            ObjectSet(objName, OBJPROP_RAY, false);
            ObjectSet(objName, OBJPROP_WIDTH, 3);
        }

    }
        
    return(0);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
{
    // deleting the drawing objects
    for (tf=0; tf<4; tf++)
    {
        for (i=0; i<NBSL; i++)
        {
            ObjectDelete("bsl_up_rect_"+tf+"_"+i);
            ObjectDelete("bsl_down_rect_"+tf+"_"+i);
            ObjectDelete("bsl_up_bar_"+tf+"_"+i);
            ObjectDelete("bsl_down_bar_"+tf+"_"+i);
        }
        ObjectDelete("MidShade_"+tf);
        
        ObjectDelete("Box1_"+tf);
        ObjectDelete("Box2_"+tf);
        
        for (i=0; i<7; i++)
            ObjectDelete("fml_bar_"+tf+"_"+i);
            
        for (i=1; i<=NSVR; i++)
            ObjectDelete("svr_"+tf+"_"+i);
    }

    return(0);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{
/*
    if (Bars-IndicatorCounted() > 2)
        return;
*/

//    curTime = TimeCurrent();
    curTime = Time[0];
//    price = Bid;
    price = Close[0];
    
    for (tf=0; tf<4; tf++)
    {
//        bar = 0;
        bar = iBarShift(NULL, tfa[tf], curTime, false);

        // populating the fml array...
        for (i=0; i<7; i++)
            fml[tf][i] = iCustom(NULL, tfa[tf], "_i_FXGaugeMAs", i, bar);
         
        // finding the highest and lowest MAs from the 7 fml's
        for (i=0; i<7; i++)
            tmpArray[i] = fml[tf][i];     // copying the MAs levels of this TF to one dim array to feed ArrayBsearch
        ArraySort(tmpArray);
        lowestMA = tmpArray[0];
        highestMA = tmpArray[6];

        // populating the bsl arrays...
        for (i=0; i<NBSL; i++)
        {
            bsl_up[tf][i] = lowestMA + bsl[i];
            bsl_down[tf][i] = highestMA - bsl[i];
        }
    }
    
    // OK... now drawing
    for (tf=0; tf<4; tf++)
    {
        // drawing the blue shades of the grid from top to bottom
        
        // find the number of overlapping shades
        offset = 0;
        for (i=offset; i<NBSL-1; i++)
            if (bsl_up[tf][i] <= bsl_down[tf][i])
                offset++;
//Print(offset);
        // hide the objects of the first level of overlapping so they wont be left as 'ghosts'
        if (offset > 0)
        {
            objName = "bsl_up_rect_"+tf+"_"+(NBSL-2-offset+1);
            ObjectSet(objName, OBJPROP_TIME1, 0);
            ObjectSet(objName, OBJPROP_TIME2, 0);
            ObjectSet(objName, OBJPROP_PRICE1, 0);
            ObjectSet(objName, OBJPROP_PRICE2, 0);

            objName = "bsl_up_bar_"+tf+"_"+(NBSL-2-offset+1);
            ObjectSet(objName, OBJPROP_TIME1, 0);
            ObjectSet(objName, OBJPROP_TIME2, 0);
            ObjectSet(objName, OBJPROP_PRICE1, 0);
            ObjectSet(objName, OBJPROP_PRICE2, 0);
        }
        for (i=NBSL-2; i>=offset; i--)
        {
            objName = "bsl_up_rect_"+tf+"_"+(i-offset);
            ObjectSet(objName, OBJPROP_TIME1, curTime+shift+tf*spacing);
            ObjectSet(objName, OBJPROP_TIME2, curTime+shift+tf*spacing+width);
            ObjectSet(objName, OBJPROP_PRICE1, bsl_up[tf][i]);
            ObjectSet(objName, OBJPROP_PRICE2, bsl_up[tf][i+1]);
            
            objName = "bsl_up_bar_"+tf+"_"+(i-offset);
            ObjectSet(objName, OBJPROP_TIME1, curTime+shift+tf*spacing+xUnit);
            ObjectSet(objName, OBJPROP_TIME2, curTime+shift+tf*spacing+width-xUnit);
            ObjectSet(objName, OBJPROP_PRICE1, bsl_up[tf][i]);
            ObjectSet(objName, OBJPROP_PRICE2, bsl_up[tf][i]);
        }
        
        objName = "MidShade_"+tf;
        ObjectSet(objName, OBJPROP_TIME1, curTime+shift+tf*spacing);
        ObjectSet(objName, OBJPROP_TIME2, curTime+shift+tf*spacing+width);
        ObjectSet(objName, OBJPROP_PRICE1, bsl_up[tf][offset]);
        ObjectSet(objName, OBJPROP_PRICE2, bsl_down[tf][offset]);

        // hide the objects of the first level of overlapping so they wont be left as 'ghosts'
        if (offset > 0)
        {
            objName = "bsl_down_rect_"+tf+"_"+(NBSL-2-offset+1);
            ObjectSet(objName, OBJPROP_TIME1, 0);
            ObjectSet(objName, OBJPROP_TIME2, 0);
            ObjectSet(objName, OBJPROP_PRICE1, 0);
            ObjectSet(objName, OBJPROP_PRICE2, 0);

            objName = "bsl_down_bar_"+tf+"_"+(NBSL-2-offset+1);
            ObjectSet(objName, OBJPROP_TIME1, 0);
            ObjectSet(objName, OBJPROP_TIME2, 0);
            ObjectSet(objName, OBJPROP_PRICE1, 0);
            ObjectSet(objName, OBJPROP_PRICE2, 0);
        }
        for (i=0; i<NBSL-1; i++)
        {
            objName = "bsl_down_rect_"+tf+"_"+(i-offset);
            ObjectSet(objName, OBJPROP_TIME1, curTime+shift+tf*spacing);
            ObjectSet(objName, OBJPROP_TIME2, curTime+shift+tf*spacing+width);
            ObjectSet(objName, OBJPROP_PRICE1, bsl_down[tf][i]);
            ObjectSet(objName, OBJPROP_PRICE2, bsl_down[tf][i+1]);
            
            objName = "bsl_down_bar_"+tf+"_"+(i-offset);
            ObjectSet(objName, OBJPROP_TIME1, curTime+shift+tf*spacing+xUnit);
            ObjectSet(objName, OBJPROP_TIME2, curTime+shift+tf*spacing+width-xUnit);
            ObjectSet(objName, OBJPROP_PRICE1, bsl_down[tf][i]);
            ObjectSet(objName, OBJPROP_PRICE2, bsl_down[tf][i]);
        }
/*        
        // drawing the boxes
        objName = "Box1_"+tf;
        ObjectSet(objName, OBJPROP_TIME1, curTime+shift+tf*spacing+xUnit);
        ObjectSet(objName, OBJPROP_PRICE1, fml[tf][0]);
        if (fml[tf][0] > price+Point/2)       col = FireBrick;
        else if (fml[tf][0] < price-Point/2)  col = Green;
        else                                col = Orange;
        ObjectSet(objName, OBJPROP_COLOR, col);
        objName = "Box2_"+tf;
        ObjectSet(objName, OBJPROP_TIME1, curTime+shift+tf*spacing+xUnit);
        ObjectSet(objName, OBJPROP_PRICE1, fml[tf][1]);
        if (fml[tf][1] > price+Point/2)       col = FireBrick;
        else if (fml[tf][1] < price-Point/2)  col = Green;
        else                                col = Orange;
        ObjectSet(objName, OBJPROP_COLOR, col);
*/        
        // drawing the momentum lines bars
        for (i=0; i<7; i++)
        {
            objName = "fml_bar_"+tf+"_"+i;
            ObjectSet(objName, OBJPROP_TIME1, curTime+shift+tf*spacing+xUnit);
            ObjectSet(objName, OBJPROP_TIME2, curTime+shift+tf*spacing+width-xUnit);
            ObjectSet(objName, OBJPROP_PRICE1, fml[tf][i]);
            ObjectSet(objName, OBJPROP_PRICE2, fml[tf][i]);
/*
            if (i<2)
            {
                if (fml[tf][i] > price+Point/2)      col = FireBrick;
                else if (fml[tf][i] < price-Point/2) col = Green;
                else                                col = Orange;
                ObjectSet(objName, OBJPROP_COLOR, col);
            }
*/            
            if (i==1)
            {
                if (fml[tf][i] >= price)        col = IndianRed;
                else if (fml[tf][i] < price)    col = LimeGreen;
                ObjectSet(objName, OBJPROP_COLOR, col);
            }
            else if (i==0)
            {
                if (fml[tf][i] >= price)        col = FireBrick;
                else if (fml[tf][i] < price)    col = Green;
                ObjectSet(objName, OBJPROP_COLOR, col);
            }
        }

        // drawing the solid vertical lines:
        // arranging all the bars levels in a single sorted array
        ArrayInitialize(srl, -1) ;
        for (i=0; i<7; i++)
            srl[i] = fml[tf][i];
        for (i=offset; i<NBSL; i++)
        {
            srl[7+i] = bsl_down[tf][i];
            srl[7+NBSL+i] = bsl_up[tf][i];
        }
        srl[7+2*NBSL] = price;
        ArraySort(srl);
        // looking for a gap of 10 pips or more
        c = 0;
        for (i=0; i<7+2*NBSL+2; i++)
        {
            if (-1 == srl[i])
                continue;
            if (srl[i+1]-srl[i] >= 10*Point)
            {
                c++;
                objName = "svr_"+tf+"_"+c;
                ObjectSet(objName, OBJPROP_TIME1, curTime+shift+tf*spacing+3*xUnit);
                ObjectSet(objName, OBJPROP_TIME2, curTime+shift+tf*spacing+3*xUnit);
                ObjectSet(objName, OBJPROP_PRICE1, srl[i]+Point);
                ObjectSet(objName, OBJPROP_PRICE2, srl[i+1]-Point);
                if (srl[i+1] <= price)
                    ObjectSet(objName, OBJPROP_COLOR, FireBrick);
                else
                    ObjectSet(objName, OBJPROP_COLOR, Green);
            }
        }
        if (c >= NSVR)
            Print("Warning: NSVR exceeded");
        else
        {
            // hide the (only the first) unused vertical lines objects so they wont be left as 'ghosts'
//            for (sr=c; sr<NSVR; sr++)
            {
                objName = "svr_"+tf+"_"+(c+1);
                ObjectSet(objName, OBJPROP_TIME1, 0);
                ObjectSet(objName, OBJPROP_TIME2, 0);
                ObjectSet(objName, OBJPROP_PRICE1, 0);
                ObjectSet(objName, OBJPROP_PRICE2, 0);
            }
        }
    }

    return(0);
}

Comments