_i_FXGauge_lite

Download script
Author: Copyright � 2006, Doji Starr
_i_FXGauge_lite

The following description outlines the logic and functionality of the FXGauge_lite script. It is designed to provide a visual representation of market structure and momentum by analyzing multiple timeframes simultaneously.

Core Concept: Multi-Timeframe Market Mapping

The script functions as a comprehensive visual "gauge" for price action. Instead of looking at just one chart, it processes data from four different timeframes (defined by the user) to create a synchronized grid of support, resistance, and momentum zones on your current screen.

Key Logic Components

1. Momentum Analysis

The script identifies specific price levels based on an external Moving Average indicator. It pulls seven different moving average values for each of the four timeframes. These are used to determine:

  • Highs and Lows: The logic finds the highest and lowest moving average values for every timeframe.
  • Momentum Bars: It draws horizontal bars representing these specific price levels. Depending on whether the current market price is above or below these levels, the bars change color (e.g., Green or Red) to indicate relative strength or weakness.

2. The "Blue Shade" Grid (Zones of Interest)

The script generates a series of "shades" (rectangles and bars) extending both upward and downward from the calculated momentum boundaries.

  • Dynamic Scaling: These shades are not fixed; they are calculated as specific distances from the highest and lowest moving averages identified in the previous step.
  • Overlapping Logic: To ensure the chart remains clean, the script includes logic to detect where these zones overlap. If the upward and downward "shades" meet or cross, it intelligently hides the redundant objects to prevent visual clutter.
  • Visual Weight: The center of this grid is highlighted as a "MidShade," representing the primary area of interest where various price actions converge.

3. Support and Resistance (S&R) Detection

One of the script's most sophisticated features is its ability to automatically identify significant price gaps.

  • Price Gap Analysis: The script gathers all relevant price levels—including momentum lines, boundary shades, and the current market price—and sorts them into a single chronological list.
  • Significant Volatility Identification: It calculates the distance between these sorted levels. If it finds a gap of 10 pips or more, it identifies this as a significant zone.
  • Visual Signaling: These gaps are marked with vertical lines. The color of these lines shifts based on whether the price is currently trading above or below that specific gap, helping traders identify "voids" in liquidity or potential areas of price rejection.

User Experience Summary

For a trader, this script transforms a standard chart into a multi-dimensional map. It visualizes:

  • Timeframe Harmony: By showing four timeframes at once, it helps you see if short-term and long-term trends are aligned.
  • Price Boundaries: The blue shades provide a "heat map" of where price might interact with established historical momentum.
  • Structural Gaps: The vertical lines highlight empty spaces in the market that often lead to rapid price movements or significant reactions.
Price Data Components
Series array that contains close prices for each bar
12 Views
0 Downloads
0 Favorites
_i_FXGauge_lite
//+------------------------------------------------------------------+
//|                                              _i_FXGauge_lite.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, 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_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 = iClose(Symbol(),0,0);
    
    for (tf=0; tf<4; tf++)
    {
//        bar = 0;
        bar = iBarShift(Symbol(), tfa[tf], curTime, false);

        // populating the fml array...
        for (i=0; i<7; i++)
            fml[tf][i] = iCustom(Symbol(), tfa[tf], "_i_FXGaugeMAs_lite", 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