//+------------------------------------------------------------------+ //| 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); } //+------------------------------------------------------------------+