This tool is designed to analyze market volatility and price positioning by measuring the relative movement of a currency or asset over a specific timeframe. Instead of looking at raw prices, it transforms price action into a standardized "change" format, making it easier to visualize how far the current price has moved compared to its historical highs and lows within a set window.
Core Logic and Methodology
The indicator operates based on several key steps performed automatically for every candle on your chart:
1. Establishing the Reference Window The tool looks back at a specific number of previous candles (defined by the user). For example, if the period is set to 77, it examines the last 77 bars of data to establish the "boundaries" of recent market activity.
2. Identifying Extremes and Movement Within that chosen window, the script identifies:
- The highest price reached.
- The lowest price reached.
- The current closing price.
- The opening price of the start of that specific window.
3. Calculating Price Variance The tool then calculates the distance moved from the starting point to these extremes (High, Low, and Close). By dividing these values by the smallest possible price move (the "Point"), it converts the data into a unit of measurement that represents the magnitude of the price swing.
4. Finding the Equilibrium (The Midpoint) One of the most important steps in this logic is determining the "Middle" point. The script calculates the average between the highest and lowest swings. This acts as a baseline or an equilibrium point for the market's recent volatility.
5. Normalizing the Visual Output To provide a clear picture of where the price sits relative to its range, the final step subtracts this "Middle" value from the High, Low, and Close values.
What this means for the user
By subtracting the midpoint, the indicator essentially "centers" the data. This allows you to see exactly how far the current price is stretching above or below the average volatility of the period. It filters out the absolute price levels to focus purely on the relative momentum—showing you whether the market is leaning toward a high, a low, or sitting comfortably in the middle of its recent trading range.
//+------------------------------------------------------------------+
//| Price Range Mod.mq4 |
//| copyright Grigori Minassian |
//| Rustem Bigeev modyfied |
//| www.parch.ru |
//+------------------------------------------------------------------+
//mod hlcl md
#property copyright "Grigori Minassian"
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 Blue
#property indicator_color2 Red
#property indicator_color3 Green
//#property indicator_level1 0
#property indicator_width3 1
#property indicator_width4 1
double ChangeHigh[];
double ChangeClose[];
double ChangeLow[];
extern int PR_Period = 77;
extern bool showHL = true;
int init()
{
int draw = DRAW_NONE; if (showHL) draw = DRAW_LINE;
SetIndexStyle(0, draw);
SetIndexStyle(1, draw);
SetIndexStyle(2, DRAW_LINE);
SetIndexBuffer(0, ChangeHigh);
SetIndexBuffer(1, ChangeLow);
SetIndexBuffer(2, ChangeClose);
IndicatorDigits(Digits + 1);
IndicatorShortName("Price Range HLClMid (" + PR_Period + ") ");
SetIndexLabel(0, "High");
SetIndexLabel(1, "Low");
SetIndexLabel(2, "Middle");
SetIndexLabel(3, "Close");
return(0);
}
double price_change_high = 0;
double price_change_low = 0;
double price_change_close = 0;
double price_change_mid = 0;
void ComputePriceRange(int period, int shift)
{
int high_shift = iHighest(Symbol(), 0, MODE_HIGH, period, shift);
int low_shift = iLowest (Symbol(), 0, MODE_LOW, period, shift);
double price_open = iClose(Symbol(), 0, period + shift);
double price_high = iClose(Symbol(), 0, high_shift);
double price_low = iClose(Symbol(), 0, low_shift);
double price_close = iClose(Symbol(), 0, shift);
price_change_high = (price_high - price_open) / Point;
price_change_low = (price_low - price_open) / Point;
price_change_close = (price_close - price_open) / Point;
price_change_mid = (price_change_high+price_change_low)/2;
}
int start()
{
int i, limit;
int counted_bars=IndicatorCounted();
if(counted_bars<0) return(-1);
if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
for(i = 0; i < limit; i++)
{
ComputePriceRange(PR_Period, i);
ChangeClose[i] = price_change_close-price_change_mid;
ChangeHigh[i] = price_change_high-price_change_mid;
ChangeLow[i] = price_change_low-price_change_mid;
}
return(0);
}
Comments