200 lines
15 KiB
MQL5
200 lines
15 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Ticks Volume Indicator |
|
|
//| Copyright © William Blau & Tor |
|
|
//| Coded/Verified by Profitrader |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright ""
|
|
#property link ""
|
|
//---- indicator properties
|
|
#property indicator_separate_window
|
|
#property indicator_buffers 1
|
|
#property indicator_color1 Red
|
|
//---- input parameters
|
|
input int r = 12;
|
|
input int s = 12;
|
|
input int u = 5;
|
|
input bool alerts = false; // alerts for crossing levels
|
|
input bool play = false; // play sound alerts
|
|
input bool strelka = false; // draw arrows?
|
|
input bool searchHight = false; // search for previous extremes
|
|
input bool NaOtkrytieSvechi = false; // not to open candles
|
|
input bool AllHights = false; // all previous highs/levelUP and levelDOWN
|
|
input int barp = 0; // at what candle to look 0 or 1
|
|
|
|
int levelUP = 10; // for upper level
|
|
int levelDOWN = -10; // for lower level
|
|
//---- 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 OnInit()
|
|
{
|
|
lastobject = TimeCurrent();
|
|
IndicatorShortName("TVI(" + IntegerToString(r) + "," + IntegerToString(s) + "," + IntegerToString(u) + ")");
|
|
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);
|
|
SetIndexStyle(0, DRAW_LINE);
|
|
SetIndexLabel(0, "TVI");
|
|
|
|
return (INIT_SUCCEEDED);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Custom indicator deinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
ObjectsDeleteAll(); // Remove all drawn objects on deinitialization
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Ticks Volume Indicator calculation |
|
|
//+------------------------------------------------------------------+
|
|
int OnCalculate(const int rates_total, // size of the price array
|
|
const int prev_calculated, // number of calculated bars
|
|
const datetime &time[], // Time array
|
|
const double &open[], // Open prices
|
|
const double &high[], // High prices
|
|
const double &low[], // Low prices
|
|
const double &close[], // Close prices
|
|
const long &tick_volume[], // Tick volume
|
|
const long &volume[], // Real volume
|
|
const double &spread[]) // Spread
|
|
{
|
|
tick++;
|
|
static datetime nt = 0;
|
|
|
|
int counted_bars = prev_calculated;
|
|
|
|
if (counted_bars < 0) return 0;
|
|
|
|
if (counted_bars > 0) counted_bars--;
|
|
|
|
int limit = rates_total - counted_bars;
|
|
|
|
// Calculate UpTicks and DownTicks
|
|
for (int i = 0; i < limit; i++)
|
|
{
|
|
UpTicks[i] = (tick_volume[i] + (close[i] - open[i]) / _Point) / 2;
|
|
DownTicks[i] = tick_volume[i] - UpTicks[i];
|
|
}
|
|
|
|
// Calculate EMA values
|
|
for (int 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);
|
|
}
|
|
|
|
// Calculate DEMA values
|
|
for (int 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);
|
|
}
|
|
|
|
// Calculate TVI
|
|
for (int i = 0; i < limit; i++)
|
|
{
|
|
TVI_calculate[i] = 100.0 * (DEMA_UpTicks[i] - DEMA_DownTicks[i]) / (DEMA_UpTicks[i] + DEMA_DownTicks[i]);
|
|
}
|
|
|
|
for (int i = limit - 1; i >= 0; i--)
|
|
TVI[i] = iMAOnArray(TVI_calculate, 0, u, 0, MODE_EMA, i);
|
|
|
|
// Alerts and drawing arrows
|
|
if (!searchHight && TVI[barp] < TVI[barp + 1] && TVI[barp] > levelUP)
|
|
{
|
|
TriggerAlert("BREAKOUT UP " + Symbol() + " indicator TVI");
|
|
}
|
|
|
|
if (!searchHight && TVI[barp] > TVI[barp + 1] && TVI[barp] < levelDOWN)
|
|
{
|
|
TriggerAlert("BREAKOUT DOWN " + Symbol() + " indicator TVI");
|
|
}
|
|
|
|
if (AllHights && searchHight && TVI[barp] > TVI[barp + 1] && TVI[barp + 2] >= TVI[barp + 1])
|
|
{
|
|
TriggerAlert("BREAKOUT UP " + Symbol() + " indicator TVI");
|
|
}
|
|
|
|
if (AllHights && searchHight && TVI[barp] < TVI[barp + 1] && TVI[barp + 2] <= TVI[barp + 1])
|
|
{
|
|
TriggerAlert("BREAKOUT DOWN " + Symbol() + " indicator TVI");
|
|
}
|
|
|
|
if (!AllHights && searchHight && TVI[barp] > TVI[barp + 1] && TVI[barp + 2] >= TVI[barp + 1] && TVI[barp] < levelDOWN)
|
|
{
|
|
TriggerAlert("BREAKOUT UP " + Symbol() + " indicator TVI");
|
|
}
|
|
|
|
if (!AllHights && searchHight && TVI[barp] < TVI[barp + 1] && TVI[barp + 2] <= TVI[barp + 1] && TVI[barp] > levelUP)
|
|
{
|
|
TriggerAlert("BREAKOUT DOWN " + Symbol() + " indicator TVI");
|
|
}
|
|
|
|
return rates_total;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Trigger alert and sound |
|
|
//+------------------------------------------------------------------+
|
|
void TriggerAlert(string message)
|
|
{
|
|
if (alerts) Alert(message);
|
|
if (play) PlaySound("expert.wav");
|
|
|
|
if (strelka)
|
|
{
|
|
if (TimeCurrent() == lastobject) { return; }
|
|
lastobject = TimeCurrent();
|
|
|
|
if ((TimeCurrent() - lastobject) >= Period() * 60 * 1)
|
|
{
|
|
StrelkaVverh(); // You can modify which arrow to call based on condition
|
|
lastobject = TimeCurrent();
|
|
}
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Draw upward arrow |
|
|
//+------------------------------------------------------------------+
|
|
void StrelkaVverh()
|
|
{
|
|
ObjectCreate(0, "TVIup" + IntegerToString(tick), OBJ_ARROW, 0, Time[0], SymbolInfoDouble(_Symbol, SYMBOL_ASK));
|
|
ObjectSetInteger(0, "TVIup" + IntegerToString(tick), OBJPROP_COLOR, clrBlue);
|
|
ObjectSetInteger(0, "TVIup" + IntegerToString(tick), OBJPROP_ARROWCODE, SYMBOL_ARROWUP);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Draw downward arrow |
|
|
//+------------------------------------------------------------------+
|
|
void StrelkaVniz()
|
|
{
|
|
ObjectCreate(0, "TVIdown" + IntegerToString(tick), OBJ_ARROW, 0, Time[0], SymbolInfoDouble(_Symbol, SYMBOL_BID));
|
|
ObjectSetInteger(0, "TVIdown" + IntegerToString(tick), OBJPROP_COLOR, clrRed);
|
|
ObjectSetInteger(0, "TVIdown" + IntegerToString(tick), OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|