GANN_rvm_v4
Download scriptThis script is a sophisticated technical analysis tool designed to provide traders with multi-layered perspective on market price action. It functions by analyzing price data across different timeframes and calculating several distinct mathematical values to help identify potential balance levels, trends, and volatility boundaries.
Core Logic and Functionality
The logic of the script can be broken down into four primary components:
1. Multi-Timeframe Synchronization Instead of looking only at the current chart's price movement, the script is designed to "look ahead" or "look back" at specific time intervals (defined by the user). It calculates how many smaller price bars fit into a larger timeframe. This allows the tool to maintain a cohesive view of the market even when the user is zoomed in on a very short period, ensuring that the data shown remains consistent with higher-level market structures.
2. Dynamic Equilibrium Calculation (Balance Levels) The script continuously monitors the relationship between the highest price reached (High), the lowest price reached (Low), and the current closing price. It calculates a "Balance Level" by averaging these three values. By tracking these averages over a specific range of bars, it creates a smoother representation of where the market is currently finding equilibrium.
3. Support and Resistance Mapping (HLN Logic) The script identifies specific boundaries for the market using what are referred to as "High-Low Next" levels. It calculates:
- Upper Boundaries: Based on the average of historical highs over a specific range.
- Lower Boundaries: Based on the average of historical lows over a specific range. These values act as dynamic visual guides, showing where price may face resistance or find support based on recent historical extremes.
4. Real-Time Updates and Memory Management To ensure the chart remains smooth and responsive, the script uses an internal "memory" system (arrays). It stores historical calculations so that it doesn't have to recalculate every single piece of data every time the price moves by a fraction of a cent. It updates these values under three specific conditions:
- Tick Updates: Small movements in price are processed instantly.
- New Bar Formation: When a standard candle closes and a new one begins, the script recalibrates its baseline.
- Higher Timeframe Shifts: When the larger timeframe being monitored rolls over to a new period, the script shifts its internal memory to accommodate the new data set without losing the sequence of previous movements.
Visual Output
For the user, this logic translates into several visual lines on the trading platform:
- Balance Levels and Steps: These show the current "center" of the market and the rate at which that center is moving.
- Boundary Lines: These provide visual "ceilings" and "floors" based on recent high and low price averages, helping traders visualize potential zones where the price might react or reverse.
//+------------------------------------------------------------------+
//| GANN_rvm_v4.mq4 |
//| Copyright © 2005, MetaQuotes Software Corp. |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net"
#property indicator_chart_window
#property indicator_buffers 8
#property indicator_color1 DeepSkyBlue
#property indicator_color2 Black
#property indicator_color3 DeepSkyBlue
#property indicator_color4 Black
#property indicator_color5 Yellow
#property indicator_color6 Green
#property indicator_color7 Red
#property indicator_color8 Red
//---- input parameters
extern int NextTF=15;
extern int BL_Range=5;
extern int HLN_Range=3;
extern bool HLN_UseFullTF=false;
//---- buffers
double HLNUp_sl[];
double HLNDn_sl[];
double HLNUp[];
double HLNDn[];
double BLLev[];
double BLStep[];
double ExtMapBuffer7[];
double ExtMapBuffer8[];
//----
int NextTFs;
int initfl;
int Displacement;
int dig;
int ArrSize;
int ArrIdx;
int lb;
double MyArr[][10];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0,DRAW_LINE);
SetIndexStyle(1,DRAW_LINE);
SetIndexStyle(2,DRAW_LINE);
SetIndexStyle(3,DRAW_LINE);
SetIndexStyle(4,DRAW_LINE);
SetIndexStyle(5,DRAW_LINE);
SetIndexStyle(6,DRAW_LINE);
SetIndexStyle(7,DRAW_LINE);
SetIndexBuffer(0,HLNUp_sl);
SetIndexBuffer(1,HLNDn_sl);
SetIndexBuffer(2,HLNUp);
SetIndexBuffer(3,HLNDn);
SetIndexBuffer(4,BLLev);
SetIndexBuffer(5,BLStep);
SetIndexBuffer(6,ExtMapBuffer7);
SetIndexBuffer(7,ExtMapBuffer8);
SetIndexLabel(0,"HLNextUp_sec (M"+NextTF+","+BL_Range+","+HLN_Range+","+HLN_UseFullTF+")");
SetIndexLabel(1,"HLNextDn_sec (M"+NextTF+","+BL_Range+","+HLN_Range+","+HLN_UseFullTF+")");
SetIndexLabel(2,"HLNextUp (M"+NextTF+","+BL_Range+","+HLN_Range+","+HLN_UseFullTF+")");
SetIndexLabel(3,"HLNextDn (M"+NextTF+","+BL_Range+","+HLN_Range+","+HLN_UseFullTF+")");
SetIndexLabel(4,"BalansLevel (M"+NextTF+","+BL_Range+","+HLN_Range+","+HLN_UseFullTF+")");
SetIndexLabel(5,"BalansStep (M"+NextTF+","+BL_Range+","+HLN_Range+","+HLN_UseFullTF+")");
SetIndexLabel(6,"1");
SetIndexLabel(7,"2");
SetIndexEmptyValue(0,0.0);
SetIndexEmptyValue(1,0.0);
SetIndexEmptyValue(2,0.0);
SetIndexEmptyValue(3,0.0);
SetIndexEmptyValue(4,0.0);
SetIndexEmptyValue(5,0.0);
SetIndexEmptyValue(6,0.0);
SetIndexEmptyValue(7,0.0);
//----
NextTFs=NextTF*60;
//----
return(0);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
int cb,i,limit,index,ai;
//----
if( initfl!=1 )
{
myInit();
if( initfl!=1 )
{
Alert("Èíäèêàòîð íå èíèöèàëèçèðîâàí!");
return(-1);
}
}
index=Bars-1;
if( counted_bars>=0 )
{
if( index-counted_bars<=0 )
{
limit=0;
}
else
{
limit=index-counted_bars;
}
}
else
{
Alert("Ñáîé! /n counted_bars < 0");
return(-1);
}
//öèêë ïî áàðàì
for( cb=limit;cb>=0;cb-- )
{
ai=index-cb;
//åñëè ýòî ïåðâûé áàð
if( cb==Bars-1 )
{
if( FBar(cb)<0 )
{
return(-1);
}
continue;
}
else
{
//åñëè ýòî íîâûé áàð
if( lb!=ai )
{
lb=ai;
//åñëè îí íå ÿâëÿåòñÿ íà÷àëîì íîâîãî áàðà íà ñòàðøåì ò-ô
if( BBarBegin(cb,NextTF)!=1 )
{
if( NewBar(cb)<0 )
{
return(-1);
}
}
else
{
if( NBBar(cb)<0 )
{
return(-1);
}
}
//îòðèñîâêà õàé ëîó àêòèâàòîð
if( HLN_UseFullTF!=1 )
{
if( Close[cb]>MyArr[ArrIdx-1][8] )
{
HLNUp[cb]=0;
HLNDn[cb]=MyArr[ArrIdx-1][9];
}
else
{
if( Close[cb]<MyArr[ArrIdx-1][9] )
{
HLNUp[cb]=MyArr[ArrIdx-1][8];
HLNDn[cb]=0;
}
else
{
if( HLNUp[cb+1]>0 )
{
HLNUp[cb]=MyArr[ArrIdx-1][8];
HLNDn[cb]=0;
}
else
{
HLNUp[cb]=0;
HLNDn[cb]=MyArr[ArrIdx-1][9];
}
}
}
}
else
{
if( MyArr[ArrIdx-1][5]>MyArr[ArrIdx-2][8] )
{
HLNUp[cb]=0;
HLNDn[cb]=MyArr[ArrIdx-1][9];
}
else
{
if( MyArr[ArrIdx-1][5]<MyArr[ArrIdx-2][9] )
{
HLNUp[cb]=MyArr[ArrIdx-1][8];
HLNDn[cb]=0;
}
else
{
if( HLNUp[cb+1]>0 )
{
HLNUp[cb]=MyArr[ArrIdx-1][8];
HLNDn[cb]=0;
}
else
{
HLNUp[cb]=0;
HLNDn[cb]=MyArr[ArrIdx-1][9];
}
}
}
}
}
else
{
if( NewTic(cb)<0 )
{
return(-1);
}
}
}
}
//----
return(0);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//+--------------------------------------------------------------------+
//| Ôóíêöèÿ âîçâðàùàåò èñòèíó, åñëè áàð ÿâëÿåòñÿ íà÷àëîì áàðà ñòàðøåãî |
//| ò-ô |
//+--------------------------------------------------------------------+
bool BBarBegin(int bar, int TF)
{
//----
bool bbegin=0;
if(TF!=10080)
{
if( MathFloor(Time[bar]/NextTFs)*NextTFs>Time[bar+1] )
{
bbegin=1;
}
}
else
{
if( (MathFloor((Time[bar]+259200)/NextTFs)*NextTFs-259200)>Time[bar+1] )
{
bbegin=1;
}
}
//----
return(bbegin);
}
//+--------------------------------------------------------------------+
//+------------------------------------------------------------------+
// Ôóíêöèÿ íà÷àëüíîé èíèöèàëèçàöèè èíäèêàòîðà |
//+------------------------------------------------------------------+
void myInit()
{
int ArrSize,Displacement,arcount,i,BR;
//----
//îïðåäåëÿåì êîëè÷åñòâî áàðîâ ìëàäøåãî ò-ô ñîäåðæàùèõñÿ â áàðå ñòàðøåãî ò-ô
if( NextTF<10080)
{
Displacement=NextTF/Period();
}
else
{
if( NextTF==10080 )
{
Displacement=7200/Period();
}
else
{
if( NextTF==43200 )
{
Displacement=31680/Period();
}
}
}
//---------
SetIndexShift(0,Displacement);
SetIndexShift(1,Displacement);
SetIndexShift(4,Displacement);
SetIndexShift(5,Displacement);
SetIndexDrawBegin(0,Displacement*HLN_Range);
SetIndexDrawBegin(1,Displacement*HLN_Range);
SetIndexDrawBegin(2,Displacement*HLN_Range);
SetIndexDrawBegin(3,Displacement*HLN_Range);
SetIndexDrawBegin(4,0);
SetIndexDrawBegin(5,Displacement*BL_Range);
//---------
//åñëè íåâåðíî óêàçàíû ïàðàìåòðû BL_Range,HLN_Range
if( BL_Range<1 || HLN_Range<1 )
{
Alert("Íåâåðíî óêàçàíû ïàðàìåòðû èíèêàòîðà!");
return(-1);
}
BR=MathMax(BL_Range,HLN_Range);
//åñëè íà ãðàôèêå íåäîñòàòî÷íî äàííûõ
if( Bars<BR*Displacement )
{
Alert("Íà ãðàôèêå íåäîñòàòî÷íî äàííûõ");
return(-1);
}
//åñëè íåâåðíî óêàçàí ïàðàìåòð NextTF
if( NextTF<=Period() )
{
Alert("Íåâåðíî óêàçàí ïàðàìåòð NextTF !/n Çíà÷åíèå äîëæíî áûòü áîëüøå /n òåêóùåãî ò-ô â ìèíóòàõ");
return(-1);
}
//êîëè÷åñòâî çíàêîâ äî êîòîðûõ áóäóò îêðóãëÿòüñÿ ðàñ÷åòû
dig=Digits;
//îïðåäåëÿåì íåîáõîäèìûé ðàçìåð ìàññèâà è åãî ïîñëåäíèé èíäåêñ
ArrSize=BR;
ArrIdx=BR-1;
//100 ïîïûòîê íà èçìåíåíèå ðàçìåðà ìàññèâà
for( i=0;i<100;i++)
{
arcount=ArrayResize(MyArr,ArrSize);
if( arcount>0 )
{
break;
}
}
//100 ïîïûòîê íà èíèöèàëèçàöèþ ìàññèâà
for( i=0;i<100;i++)
{
arcount=0;
arcount=ArrayInitialize(MyArr,0.0);
if( arcount>0 )
{
break;
}
}
initfl=1;
//----
return(0);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Ôóíêöèÿ îòðàáàòûâàþùàÿ íà êàæäûé òèê åñëè ýòî íå íîâûé áàð |
//+------------------------------------------------------------------+
int NewTic( int Bar )
{
//----
int i;
double sH,sL,sBL;
if( High[Bar]>MyArr[ArrIdx][3] ) MyArr[ArrIdx][3]=High[Bar];
if( Low[Bar] <MyArr[ArrIdx][4] ) MyArr[ArrIdx][4]=Low[Bar];
MyArr[ArrIdx][5]=Close[Bar];
MyArr[ArrIdx][6]=NormalizeDouble((MyArr[ArrIdx][3]+MyArr[ArrIdx][4]+MyArr[ArrIdx][5])/3,dig);
//öèêë ïî ìàññèâó
for( i=ArrIdx;i>=ArrIdx+1-BL_Range;i-- )
{
sBL+=MyArr[i][6];
}
MyArr[ArrIdx][7]=NormalizeDouble(sBL/BL_Range,dig);
for( i=ArrIdx;i>=ArrIdx+1-HLN_Range;i-- )
{
sH+=MyArr[i][3];
sL+=MyArr[i][4];
}
MyArr[ArrIdx][8]=NormalizeDouble(sH/HLN_Range,dig);
MyArr[ArrIdx][9]=NormalizeDouble(sL/HLN_Range,dig);
//îòðèñîâûâàåì íà ãðàôèêå
for( i=Bars-1-MyArr[ArrIdx][0];i>=Bars-1-MyArr[ArrIdx][1];i-- )
{
BLLev[i]=MyArr[ArrIdx][6];
BLStep[i]=MyArr[ArrIdx][7];
HLNUp_sl[i]=MyArr[ArrIdx][8];
HLNDn_sl[i]=MyArr[ArrIdx][9];
}
if( MyArr[ArrIdx][2]<=0 || MyArr[ArrIdx][3]<=0 || MyArr[ArrIdx][4]<=0 || MyArr[ArrIdx][5]<=0 || MyArr[ArrIdx][6]<=0 || BLLev[Bar]<=0 )
{
Alert("Ñáîé ðàñ÷åòà èíäèêàòîðà íà íîâîì òèêå!");
return(-1);
}
//----
return(0);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Ôóíêöèÿ îòðàáàòûâàþùàÿ íà ïåðâûé áàð íà ãðàôèêå |
//+------------------------------------------------------------------+
int FBar( int Bar )
{
//----
//íà÷èíàåì çàïèñûâàòü â ìàññèâ
MyArr[ArrIdx][0]=Bars-1-Bar;
MyArr[ArrIdx][1]=Bars-1-Bar;
MyArr[ArrIdx][2]=Open[Bar];
MyArr[ArrIdx][3]=High[Bar];
MyArr[ArrIdx][4]=Low[Bar];
MyArr[ArrIdx][5]=Close[Bar];
MyArr[ArrIdx][6]=NormalizeDouble((MyArr[ArrIdx][3]+MyArr[ArrIdx][4]+MyArr[ArrIdx][5])/3,dig);
BLLev[Bar]=MyArr[ArrIdx][6];
if( MyArr[ArrIdx][2]<=0 || MyArr[ArrIdx][3]<=0 || MyArr[ArrIdx][4]<=0 || MyArr[ArrIdx][5]<=0 || MyArr[ArrIdx][6]<=0 || BLLev[Bar]<=0 )
{
Alert("Îøèáêà ïðîñ÷åòà 1 áàðà!");
return(-1);
}
//----
return(0);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Ôóíêöèÿ îòðàáàòûâàþùàÿ ïðè ïîÿâëåíèè íîâîãî áàðà 1 ðàç |
//+------------------------------------------------------------------+
int NewBar( int Bar )
{
//----
int i;
double sH,sL,sBL;
MyArr[ArrIdx][1]=Bars-1-Bar;
if( High[Bar]>MyArr[ArrIdx][3] ) MyArr[ArrIdx][3]=High[Bar];
if( Low[Bar] <MyArr[ArrIdx][4] ) MyArr[ArrIdx][4]=Low[Bar];
MyArr[ArrIdx][5]=Close[Bar];
MyArr[ArrIdx][6]=NormalizeDouble((MyArr[ArrIdx][3]+MyArr[ArrIdx][4]+MyArr[ArrIdx][5])/3,dig);
//öèêë ïî ìàññèâó
for( i=ArrIdx;i>=ArrIdx+1-BL_Range;i-- )
{
sBL+=MyArr[i][6];
}
MyArr[ArrIdx][7]=NormalizeDouble(sBL/BL_Range,dig);
for( i=ArrIdx;i>=ArrIdx+1-HLN_Range;i-- )
{
sH+=MyArr[i][3];
sL+=MyArr[i][4];
}
MyArr[ArrIdx][8]=NormalizeDouble(sH/HLN_Range,dig);
MyArr[ArrIdx][9]=NormalizeDouble(sL/HLN_Range,dig);
//îòðèñîâûâàåì íà ãðàôèêå
for( i=Bars-1-MyArr[ArrIdx][0];i>=Bars-1-MyArr[ArrIdx][1];i-- )
{
BLLev[i]=MyArr[ArrIdx][6];
BLStep[i]=MyArr[ArrIdx][7];
HLNUp_sl[i]=MyArr[ArrIdx][8];
HLNDn_sl[i]=MyArr[ArrIdx][9];
}
if( MyArr[ArrIdx][2]<=0 || MyArr[ArrIdx][3]<=0 || MyArr[ArrIdx][4]<=0 || MyArr[ArrIdx][5]<=0 || MyArr[ArrIdx][6]<=0 || BLLev[Bar]<=0 )
{
Alert("Îøèáêà ïðîñ÷åòà íîâîãî áàðà!");
return(-1);
}
//----
return(0);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Ôóíêöèÿ îòðàáàòûâàþùàÿ ïðè ïîÿâëåíèè íîâîãî áàðà ñòàðøåãî ò-ô |
//+------------------------------------------------------------------+
int NBBar( int Bar )
{
//----
int i;
double sH,sL,sBL;
//ñäèã ïî ñòåêó â ìàññèâå
for( i=0;i<ArrIdx;i++)
{
MyArr[i][0]=MyArr[i+1][0];
MyArr[i][1]=MyArr[i+1][1];
MyArr[i][2]=MyArr[i+1][2];
MyArr[i][3]=MyArr[i+1][3];
MyArr[i][4]=MyArr[i+1][4];
MyArr[i][5]=MyArr[i+1][5];
MyArr[i][6]=MyArr[i+1][6];
MyArr[i][7]=MyArr[i+1][7];
MyArr[i][8]=MyArr[i+1][8];
MyArr[i][9]=MyArr[i+1][9];
}
MyArr[ArrIdx][0]=Bars-1-Bar;
MyArr[ArrIdx][1]=Bars-1-Bar;
MyArr[ArrIdx][2]=Open[Bar];
MyArr[ArrIdx][3]=High[Bar];
MyArr[ArrIdx][4]=Low[Bar];
MyArr[ArrIdx][5]=Close[Bar];
MyArr[ArrIdx][6]=NormalizeDouble((MyArr[ArrIdx][3]+MyArr[ArrIdx][4]+MyArr[ArrIdx][5])/3,dig);
//öèêë ïî ìàññèâó
for( i=ArrIdx;i>=ArrIdx+1-BL_Range;i-- )
{
sBL+=MyArr[i][6];
}
MyArr[ArrIdx][7]=NormalizeDouble(sBL/BL_Range,dig);
for( i=ArrIdx;i>=ArrIdx+1-HLN_Range;i-- )
{
sH+=MyArr[i][3];
sL+=MyArr[i][4];
}
MyArr[ArrIdx][8]=NormalizeDouble(sH/HLN_Range,dig);
MyArr[ArrIdx][9]=NormalizeDouble(sL/HLN_Range,dig);
//îòðèñîâûâàåì íà ãðàôèêå
BLLev[Bar]=MyArr[ArrIdx][6];
BLStep[Bar]=MyArr[ArrIdx][7];
HLNUp_sl[Bar]=MyArr[ArrIdx][8];
HLNDn_sl[Bar]=MyArr[ArrIdx][9];
if( MyArr[ArrIdx][2]<=0 || MyArr[ArrIdx][3]<=0 || MyArr[ArrIdx][4]<=0 || MyArr[ArrIdx][5]<=0 || MyArr[ArrIdx][6]<=0 || BLLev[Bar]<=0 )
{
Alert("Îøèáêà ïðîñ÷åòà íîâîãî áàðà ñòàðøåãî ò-ô!");
return(-1);
}
//----
return(0);
}
//+------------------------------------------------------------------+
Comments