_i_FXGaugeT

Download script
Author: Copyright � 2006, Doji Starr
_i_FXGaugeT

The FXGauge script is a sophisticated visual analysis tool designed for the MetaTrader 4 platform. Its primary purpose is to provide traders with a multi-layered "dashboard" view of market dynamics by synthesizing data across four different timeframes simultaneously on a single chart.

Core Functionality

The logic operates by scanning several timeframes (configured by the user, such as 1, 5, 15, and 60 minutes) to identify key price zones and momentum levels. Instead of simply showing a single line or a standard moving average, it creates a structured "gauge" of information using three distinct visual components:

1. Momentum Level Mapping The script retrieves data from seven different moving average points for each timeframe. It identifies the highest and lowest values among these points to establish a range of market momentum. These levels are then displayed as text labels on the chart, allowing the trader to see exactly where the "momentum" sits relative to the current price.

2. Dynamic Shade Zones (The Grid) To help visualize price "density," the script generates a series of shaded rectangles (blue shades) above and below the momentum range.

  • Upper/Lower Bounds: These represent potential zones of interest based on specific distance calculations from the highest and lowest moving averages.
  • Dynamic Overlap Handling: A key logical feature is its ability to detect when these zones overlap. If a zone is compressed or overlapping, the script intelligently hides redundant objects to ensure the visual display remains clean and readable rather than cluttered with "ghost" images.

3. Support and Resistance Detection (Vertical Lines) The indicator performs an automated "gap analysis" to identify significant price levels:

  • It compiles every identified momentum level, the upper/lower shaded boundaries, and the current market price into a single sorted list for each timeframe.
  • It then calculates the distance between every consecutive level in that list.
  • If it detects a gap of 10 pips (or more) between two levels, it draws a solid vertical line.
  • Color Coding: These lines are automatically colored—typically red for bearish resistance zones and green for bullish support zones—depending on their position relative to the current price.

User Experience Summary

For a trader, this means that instead of looking at four different charts to understand different timeframes, they can view one unified "gauge." The script does the heavy lifting of calculating momentum, identifying price gaps, and organizing the visual layout, highlighting where the market is currently "squeezed" or where significant price voids exist.

8 Views
0 Downloads
0 Favorites
_i_FXGaugeT
//+------------------------------------------------------------------+
//|                                                   _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;
int TxtScale = 8;

// 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] = {9, 16, 26, 42, 68, 110, 178, 244};
                                                // 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_txt_"+tf+"_"+i;
            ObjectCreate(objName, OBJ_TEXT, 0, 0, 0, 0, 0);
            ObjectSet(objName, OBJPROP_COLOR, Black);
            ObjectSet(objName, OBJPROP_RAY, false);
            ObjectSet(objName, OBJPROP_WIDTH, 2);
            
            objName = "bsl_down_txt_"+tf+"_"+i;
            ObjectCreate(objName, OBJ_TEXT, 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_txt_"+tf+"_"+i;
            ObjectCreate(objName, OBJ_TEXT, 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_txt_"+tf+"_"+i);
            ObjectDelete("bsl_down_txt_"+tf+"_"+i);
        }
        ObjectDelete("MidShade_"+tf);
        
        ObjectDelete("Box1_"+tf);
        ObjectDelete("Box2_"+tf);
        
        for (i=0; i<7; i++)
            ObjectDelete("fml_txt_"+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_txt_"+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_txt_"+tf+"_"+(i-offset);
            ObjectSet(objName, OBJPROP_TIME1, curTime+shift+tf*spacing+3*xUnit);
            ObjectSet(objName, OBJPROP_PRICE1, bsl_up[tf][i]+(TxtScale*Point)/4);
            ObjectSetText(objName, DoubleToStr(bsl_up[tf][i], Digits), TxtScale);
        }
        
        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_txt_"+tf+"_"+(NBSL-2-offset+1);
            //ObjectSet(objName, OBJPROP_TIME1, 0);
            //ObjectSet(objName, OBJPROP_PRICE1, 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_txt_"+tf+"_"+(i-offset);
            ObjectSet(objName, OBJPROP_TIME1, curTime+shift+tf*spacing+3*xUnit);
            ObjectSet(objName, OBJPROP_PRICE1, bsl_down[tf][i]+(TxtScale*Point)/4);
            ObjectSetText(objName, DoubleToStr(bsl_down[tf][i], Digits), TxtScale);
        }
/*        
        // 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_txt_"+tf+"_"+i;
            ObjectSet(objName, OBJPROP_TIME1, curTime+shift+tf*spacing+3*xUnit);
            ObjectSet(objName, OBJPROP_PRICE1, fml[tf][i]+(TxtScale*Point)/4);
            ObjectSetText(objName, DoubleToStr(fml[tf][i], Digits), TxtScale);
/*
            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