This technical indicator, titled "The Heavy," is designed to provide traders with a visual representation of market momentum and price volatility by comparing recent price action against historical price swings. It operates in a separate window below your main chart, making it easier to analyze trends without cluttering the primary price candles.
Core Functionality
The tool functions by analyzing the "range" of the market—the distance between the highest price reached and the lowest price reached—over two distinct periods of time.
1. Volatility Comparison (Price Ranges) The script identifies two specific windows of historical data:
- Recent Range: It looks at the most recent bars on the chart (defined by a user-set period) to determine how much price movement occurred.
- Previous Range: It looks at an equal amount of time immediately preceding the recent period to see how much movement occurred back then.
By plotting these as lines, the indicator allows you to see if the current market "stretch" is larger or smaller than what happened recently in the past. This helps in identifying whether the market is expanding in volatility or cooling down.
2. Momentum Tracking (iAC) The script also utilizes a momentum calculation (Internal Accumulation Curve). It tracks the speed and direction of price movement to determine if the current flow is accelerating or decelerating.
Visual Representation
To make this data easy to read at a glance, the indicator uses four distinct visual elements:
- Last & Previous Lines: These represent the high-to-low ranges calculated above. They provide a steady baseline for comparing current market volatility against previous price behavior.
- Up & Down Histograms: These bars represent the momentum flow.
- If the current momentum is increasing compared to the previous step, a Blue Histogram appears, signaling upward strength.
- If the momentum is decreasing or shifting downward, a Red Histogram appears, signaling downward pressure.
Summary for the Trader
Essentially, this tool helps you distinguish between "noisy" price movements and significant structural shifts. By comparing current volatility ranges against historical ones while simultaneously tracking whether momentum is gaining or losing steam, it provides a clearer picture of where the market's energy is moving. It allows you to see if a move is gaining "weight" (momentum) relative to the price boundaries established in the recent past.
//+------------------------------------------------------------------+
//| The_Heavy.mq4 |
//| Copyright 2014, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
//| Written by Totom Sukopratomo - tomsuk001/MQL5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link "http://www.mql5.com"
#property version "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots 4
//--- plot Last
#property indicator_label1 "Last"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrLimeGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//--- plot Previous
#property indicator_label2 "Previous"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrDarkGreen
#property indicator_style2 STYLE_SOLID
#property indicator_width2 2
//--- plot Up
#property indicator_label3 "Up"
#property indicator_type3 DRAW_HISTOGRAM
#property indicator_color3 clrBlue
#property indicator_style3 STYLE_SOLID
#property indicator_width3 3
//--- plot Down
#property indicator_label4 "Down"
#property indicator_type4 DRAW_HISTOGRAM
#property indicator_color4 clrRed
#property indicator_style4 STYLE_SOLID
#property indicator_width4 3
//--- input parameters
/* Period for last x-bars range counted from current bar */
input int LastPeriod=35;
/* Period for previous x-bars range counted from LastPeriod bar */
input int PreviousPeriod=35;
//--- indicator buffers
double LastBuffer[];
double PreviousBuffer[];
double UpBuffer[];
double DownBuffer[];
double iACBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- count of buffers
IndicatorBuffers(5);
//--- indicator buffers mapping
SetIndexBuffer(0,LastBuffer);
SetIndexBuffer(1,PreviousBuffer);
SetIndexBuffer(2,UpBuffer);
SetIndexBuffer(3,DownBuffer);
SetIndexBuffer(4,iACBuffer);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- set arrays as timeseries
ArraySetAsSeries(high,true);
ArraySetAsSeries(low,true);
ArraySetAsSeries(open,true);
ArraySetAsSeries(close,true);
ArraySetAsSeries(LastBuffer,true);
ArraySetAsSeries(PreviousBuffer,true);
ArraySetAsSeries(UpBuffer,true);
ArraySetAsSeries(DownBuffer,true);
ArraySetAsSeries(iACBuffer,true);
//--- get limit's number of bars to calculate
int limit;
if(prev_calculated<=0)
{
//--- bars to calculate right after initialization of indicator succeded
limit=rates_total-LastPeriod-PreviousPeriod;
}
else
{
//--- last bar will be recounted
limit=rates_total-prev_calculated;
}
//--- main calculation
for(int i=0;i<limit;i++)
{
//--- save value of iAC into buffer
iACBuffer[i]=iAC(NULL,0,i);
//--- calculate last 'LastPeriod' bars range
LastBuffer[i]=high[ArrayMaximum(high,LastPeriod,i)]-low[ArrayMinimum(low,LastPeriod,i)];
//--- calculate previous 'PreviousPeriod' bars range
PreviousBuffer[i]=high[ArrayMaximum(high,PreviousPeriod,i+LastPeriod)]-low[ArrayMinimum(low,PreviousPeriod,i+LastPeriod)];
}
//--- set values of Up and Down buffer using values of iAC buffer
for(int i=0;i<limit;i++)
{
//--- if value of current iAC is greater then value of previous iAC set value of UpBuffer with value of current iAC
if(iACBuffer[i]>iACBuffer[i+1])
{
UpBuffer[i]=iACBuffer[i];
}
//--- else set value of DownBuffer with value of current iAC
else
{
DownBuffer[i]=iACBuffer[i];
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
Comments