This script is designed to analyze historical price action on a trading chart and visually identify specific zones of market activity by mapping out "density levels." Instead of simply looking at where the price is now, it looks back at a set period of history to determine which price points were touched or passed through most frequently.
Core Logic Overview
The tool functions by scanning a specified number of past candles (defined by the user's history settings) and identifying the highest and lowest price points reached during that timeframe. Once this range is established, the script breaks that range into small, equal increments (steps).
It then "scans" every candle in that history to see which of these specific price steps were crossed. Every time a candle covers one of these steps, the script adds a count to that specific price level. Effectively, it creates a frequency map of the market's movement.
Visual Representation
Once the data collection is complete, the script draws horizontal lines across your chart to represent these levels:
- High Density Areas: These are price points where the history shows the market spent a significant amount of time or frequently returned to.
- Visual Style: The tool renders these as red trend lines, providing a clear visual representation of "support" and "resistance" based purely on historical frequency.
Key Features
- Dynamic History Scanning: You can choose how far back the script should look, allowing you to focus on recent volatility or long-term structural behavior.
- Adjustable Precision: The logic allows for a "step" configuration, which determines how granular the price levels are. A smaller step provides a more detailed map of the price action, while a larger step summarizes the broader movements.
- Automatic Cleanup: To keep your chart organized, the script is designed to automatically remove its previous drawings whenever it refreshes or is removed, ensuring you are only ever looking at the most current analysis of the data provided.
//+------------------------------------------------------------------+
//| Level Sensor.mq4 |
//| Copyright © 2005, Sfen. |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, Sfen"
#property indicator_chart_window
//---- input parameters
extern int MAX_HISTORY=500;
extern int STEP=1;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int init()
{
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double CSH(int shift)
{
return(MathMax(Open[shift],Close[shift]));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double CSL(int shift)
{
return(MathMin(Open[shift],Close[shift]));
}
string OBJECT_PREFIX="LEVELS";
int ObjectId=0;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
string IntToStr(int X)
{
return(DoubleToStr(X,0));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
string ObGetUniqueName(string Prefix)
{
ObjectId++;
return(Prefix+" "+IntToStr(ObjectId));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void ObDeleteObjectsByPrefix(string Prefix)
{
int L=StringLen(Prefix);
int i=0;
while(i<ObjectsTotal())
{
string ObjName=ObjectName(i);
if (StringSubstr(ObjName,0,L)!=Prefix) { i++; continue;}
ObjectDelete(ObjName);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int deinit()
{
ObDeleteObjectsByPrefix(OBJECT_PREFIX);
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start()
{
string S;
ObDeleteObjectsByPrefix(OBJECT_PREFIX);
double HH=0;
double LL=1000000;
int History=MathMin(Bars,MAX_HISTORY);
//----
int i, j, k;
for(i=1; i<History; i++)
{
HH=MathMax(HH,CSH(i));
LL=MathMin(LL,CSL(i));
}
int NumberOfPoints=(HH-LL)/(1.0*Point*STEP)+1;
int Count[];
ArrayResize(Count,NumberOfPoints);
//----
for(i=0; i<NumberOfPoints; i++) Count[i]=0;
for(i=1; i<History; i++)
{
double C=CSL(i);
while(C<CSH(i))
{
int Index=(C-LL)/(1.0*Point*STEP);
Count[Index]++;
C+=1.0*Point*STEP;
}
}
for(i=0; i<NumberOfPoints; i++)
{
double StartX=Time[5];
double StartY=LL + 1.0*Point*STEP*i;
double EndX =Time[5+Count[i]];
double EndY =StartY;
//----
string ObjName=ObGetUniqueName(OBJECT_PREFIX);
ObjectDelete(ObjName);
ObjectCreate(ObjName,OBJ_TREND,0,StartX,StartY,EndX,EndY);
ObjectSet(ObjName,OBJPROP_RAY,0);
ObjectSet(ObjName,OBJPROP_COLOR,Red);
}
return(0);
}
//+------------------------------------------------------------------+
Comments