This tool is a specialized market analysis indicator designed to help traders visualize the balance of power between buyers and sellers by analyzing "Tick Volume." Unlike standard volume, which can be abstract, this script breaks down the movement within each candle to determine the relative strength of upward versus downward pressure.
Core Logic and Data Processing
The indicator operates through a multi-layered smoothing process to filter out market noise and identify sustainable trends:
- Volume Decomposition: The logic first takes the total volume of a price bar and splits it into two components: "Up Ticks" (representing buying pressure) and "Down Ticks" (representing selling pressure). This is calculated by comparing the opening and closing prices against the total volume.
- Multi-Stage Smoothing: To prevent the indicator from reacting to erratic, one-off price spikes, the script applies three consecutive layers of Exponential Moving Averages (EMA). It smooths the individual up/down tick values first, then further refines them to create a more stable trend line.
- Relative Strength Calculation: The final data point is derived by calculating the percentage difference between the smoothed buying pressure and the smoothed selling pressure. This results in a "Ticks Volume Indicator" (TVI) value that oscillates to show who is currently dominating the market.
Signal Generation and Alerts
The script includes a sophisticated notification system that identifies specific turning points based on user-defined thresholds:
- Overextended Market Detection: The tool monitors if the market has pushed too far in one direction (crossing specific "Level Up" or "Level Down" boundaries). If the momentum starts to slow down while at these extremes, the script recognizes a potential reversal.
- Trend Break Identification: It can be configured to look for specific structural "breaks" in the graph—essentially identifying when the current price action deviates significantly from the established trend.
- Visual and Audio Feedback: When these conditions are met (e.g., a potential sell signal or a buy signal), the script is designed to provide immediate feedback through:
- On-Screen Arrows: Drawing visual markers directly on the chart to highlight entry or exit points.
- Audio Alerts: Playing a notification sound.
- Pop-up Notifications: Sending a text alert to the trading platform interface.
Customizable Behavior
The logic is highly flexible, allowing users to toggle specific behaviors:
- Timing Controls: You can choose to have signals only trigger at the start of a new candle or continuously.
- Sensitivity: Users can adjust the smoothing periods (the "r," "s," and "u" parameters) to make the indicator react faster to price changes or more slowly for a smoother, more reliable trend analysis.
//+------------------------------------------------------------------+
//| Ticks Volume Indicator |
//| Copyright © William Blau & Tor |
//| Coded/Verified by Profitrader |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Profitrader."
#property link "profitrader@inbox.ru"
//----
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- input parameters
extern int r=12;
extern int s=12;
extern int u=5;
extern bool alerts=false; // alert ïðåäïîëàãàåìûõ ñäåëîê
extern bool play=false; // çâóêîâîå îïîâåùåíèå
extern bool strelka=true; // ðèñîâàòü ñòðåëêè ?
extern bool searchHight=true; // èñêàòü ïåðåëîìû ãðàôèêà
extern bool NaOtkrytieSvechi=true; // òîëüêî íà îòêðûòèè ñâå÷è
extern bool AllHights=false; // âñå ïåðåëîìû èëè òîëüêî âûïàäàþùèå çà óðîâíè â íàñòðîéêàõ levelUP è levelDOWN
extern int barp=0; // íà êàêîé ñâå÷å ñìîòðèì 0 èëè 1
extern int levelUP=4; // äëÿ çîëîòà *10
extern int levelDOWN=-4; // äëÿ çîëîòà *10
//---- buffers
double TVI[];
double UpTicks[];
double DownTicks[];
double EMA_UpTicks[];
double EMA_DownTicks[];
double DEMA_UpTicks[];
double DEMA_DownTicks[];
double TVI_calculate[];
int tick=0;
datetime lastobject;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
lastobject=Time[0];
IndicatorShortName("TVI("+r+","+s+","+u+")");
IndicatorBuffers(8);
SetIndexBuffer(0,TVI);
SetIndexBuffer(1,UpTicks);
SetIndexBuffer(2,DownTicks);
SetIndexBuffer(3,EMA_UpTicks);
SetIndexBuffer(4,EMA_DownTicks);
SetIndexBuffer(5,DEMA_UpTicks);
SetIndexBuffer(6,DEMA_DownTicks);
SetIndexBuffer(7,TVI_calculate);
SetLevelValue(1,levelDOWN);
SetLevelValue(2,levelUP);
/* SetLevelValue(3,levelDOWN-1);
SetLevelValue(4,levelUP+1);
SetLevelValue(5,levelDOWN-2);
SetLevelValue(6,levelUP+2);
SetLevelValue(7,levelDOWN-3);
SetLevelValue(8,levelUP+3);
SetLevelValue(9,levelDOWN-4);
SetLevelValue(10,levelUP+4);*/
SetIndexStyle(0,DRAW_LINE);
SetIndexLabel(0,"TVI");
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
return(0);
}
//+------------------------------------------------------------------+
//| Ticks Volume Indicator |
//+------------------------------------------------------------------+
int start()
{
tick++; static datetime nt=0;
int i,counted_bars=IndicatorCounted();
//---- check for possible errors
if(counted_bars<0) return(-1);
//---- last counted bar will be recounted
if(counted_bars>0) counted_bars--;
int limit=Bars-counted_bars;
//----
for(i=0; i<limit; i++)
{
UpTicks[i]=(Volume[i]+(Close[i]-Open[i])/Point)/2;
DownTicks[i]=Volume[i]-UpTicks[i];
}
for(i=limit-1; i>=0; i--)
{
EMA_UpTicks[i]=iMAOnArray(UpTicks,0,r,0,MODE_EMA,i);
EMA_DownTicks[i]=iMAOnArray(DownTicks,0,r,0,MODE_EMA,i);
}
for(i=limit-1; i>=0; i--)
{
DEMA_UpTicks[i]=iMAOnArray(EMA_UpTicks,0,s,0,MODE_EMA,i);
DEMA_DownTicks[i]=iMAOnArray(EMA_DownTicks,0,s,0,MODE_EMA,i);
}
for(i=0; i<limit; i++)
{
TVI_calculate[i]=100.0*(DEMA_UpTicks[i]-DEMA_DownTicks[i])/(DEMA_UpTicks[i]+DEMA_DownTicks[i]);
}
for(i=limit-1; i>=0; i--)
TVI[i]=iMAOnArray(TVI_calculate,0,u,0,MODE_EMA,i);
if(!searchHight && TVI[0+barp]<TVI[1+barp] && TVI[0+barp]>levelUP)
{
if(alerts) Alert("ìîæíî ïðîáîâàòü ÏÐÎÄÀÒÜ "+Symbol()+" indicator TVI");
if(play) PlaySound("expert.wav");
if(strelka)
{
if(Time[0]==nt){ return(0); }
nt=Time[0];
if((Time[0]-lastobject)>=Period()*60*1){ StrelkaVniz(); lastobject=Time[0]; }
}
}
if(!searchHight && TVI[0+barp]>TVI[1+barp] && TVI[0+barp]<levelDOWN)
{
if(alerts) Alert("ìîæíî ïðîáîâàòü ÊÓÏÈÒÜ "+Symbol()+" indicator TVI");
if(play) PlaySound("expert.wav");
if(strelka)
{
if(Time[0]==nt){ return(0); }
nt=Time[0];
if((Time[0]-lastobject)>=Period()*60*1){ StrelkaVverh(); lastobject=Time[0]; }
}
}
if(AllHights && searchHight && TVI[0+barp]>TVI[1+barp] && TVI[2+barp]>=TVI[1+barp])
{// && TVI[0]<0 && TVI[1]<0 && TVI[2]<0
if(alerts) Alert("ìîæíî ïðîáîâàòü ÊÓÏÈÒÜ "+Symbol()+" indicator TVI");
if(play) PlaySound("expert.wav");
if(strelka)
{
if(NaOtkrytieSvechi){ if(Time[0]==nt){ return(0); } }
nt=Time[0];
if((Time[0]-lastobject)>=Period()*60*1){ StrelkaVverh(); lastobject=Time[0]; }
}
}
if(AllHights && searchHight && TVI[0+barp]<TVI[1+barp] && TVI[2+barp]<=TVI[1+barp])
{ //&& TVI[0]>0 && TVI[1]>0 && TVI[2]>0
if(alerts) Alert("ìîæíî ïðîáîâàòü ÏÐÎÄÀÒÜ "+Symbol()+" indicator TVI");
if(play) PlaySound("expert.wav");
if(strelka)
{
if(NaOtkrytieSvechi){ if(Time[0]==nt){ return(0); } }
nt=Time[0];
if((Time[0]-lastobject)>=Period()*60*1){ StrelkaVniz(); lastobject=Time[0]; }
}
}
if(!AllHights && searchHight && TVI[0+barp]>TVI[1+barp] && TVI[2+barp]>=TVI[1+barp] && TVI[0+barp]<levelDOWN)
{// && TVI[0]<0 && TVI[1]<0 && TVI[2]<0
if(alerts) Alert("ìîæíî ïðîáîâàòü ÊÓÏÈÒÜ "+Symbol()+" indicator TVI");
if(play) PlaySound("expert.wav");
if(strelka)
{
if(NaOtkrytieSvechi){ if(Time[0]==nt){ return(0); } }
nt=Time[0];
if((Time[0]-lastobject)>=Period()*60*1){ StrelkaVverh(); lastobject=Time[0]; }
}
}
if(!AllHights && searchHight && TVI[0+barp]<TVI[1+barp] && TVI[2+barp]<=TVI[1+barp] && TVI[0+barp]>levelUP)
{ //&& TVI[0]>0 && TVI[1]>0 && TVI[2]>0
if(alerts) Alert("ìîæíî ïðîáîâàòü ÏÐÎÄÀÒÜ "+Symbol()+" indicator TVI");
if(play) PlaySound("expert.wav");
if(strelka)
{
if(NaOtkrytieSvechi){ if(Time[0]==nt){ return(0); } }
nt=Time[0];
if((Time[0]-lastobject)>=Period()*60*1){ StrelkaVniz(); lastobject=Time[0]; }
}
}
//----
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void StrelkaVverh()
{
ObjectCreate("TVIup"+tick,OBJ_ARROW,0,Time[0],Ask);
ObjectSet("TVIup"+tick,OBJPROP_COLOR,Blue);
ObjectSet("TVIup"+tick,OBJPROP_ARROWCODE,SYMBOL_ARROWUP);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void StrelkaVniz()
{
ObjectCreate("TVIdown"+tick,OBJ_ARROW,0,Time[0],Bid);
ObjectSet("TVIdown"+tick,OBJPROP_COLOR,Red);
ObjectSet("TVIdown"+tick,OBJPROP_ARROWCODE,SYMBOL_ARROWDOWN);
}
//+------------------------------------------------------------------+
Comments