▶ Full Post Text
Hey everyone,
Following up on my previous post where I shared the **Volatility Expansion Index (VEI)** for TradingView, I’ve had a few requests for the MetaTrader 5 (MT5) version.
I you want to know more about VEI and Tradingview Script :
[https://www.reddit.com/r/algotrading/comments/1phv4zz/the\_signal\_i\_use\_to\_detect\_hidden\_instability\_in/](https://www.reddit.com/r/algotrading/comments/1phv4zz/the_signal_i_use_to_detect_hidden_instability_in/)
The VEI is a simple ratio to spot when volatility is expanding relative to its long-term average:
VEI = ATR(Short) / ATR(Long)
**The Logic:**
* **Benchmark:** 1.2 (Default). When the ratio climbs above this, it indicates a significant "expansion" phase.
* **Visuals:** The line plots in a separate window. I’ve coded it to automatically change color to **Red** when it breaks the benchmark, making it easy to spot breakouts or high-momentum moves.
MQL5 Code:
You can find the full source code below. Just open your MetaEditor (F4), create a New Indicator, and paste this in.
`//+------------------------------------------------------------------+`
`//| VEI.mq5 |`
`//| Volatility Expansion Index |`
`//| Created for by Prabuddha Peramuna|`
`//+------------------------------------------------------------------+`
`#property copyright "Created by Prabuddha Peramuna"`
`#property version "1.00"`
`#property description "VEI - Volatility Expansion Index"`
`#property indicator_separate_window`
`#property indicator_buffers 2`
`#property indicator_plots 1`
`//--- Plot VEI`
`#property indicator_label1 "VEI"`
`#property indicator_type1 DRAW_COLOR_LINE`
`#property indicator_color1 clrSilver, clrRed // Color 0: Normal, Color 1: Alert`
`#property indicator_style1 STYLE_SOLID`
`#property indicator_width1 2`
`//--- Input parameters`
`input int InpFastATR = 10; // Fast ATR Period`
`input int InpSlowATR = 50; // Slow ATR Period`
`input double InpBenchmark = 1.2; // Benchmark Level (Trigger Color)`
`//--- Indicator Buffers`
`double VEIBuffer[];`
`double ColorBuffer[];`
`//--- Indicator Handles`
`int hFastATR;`
`int hSlowATR;`
`//+------------------------------------------------------------------+`
`//| Custom indicator initialization function |`
`//+------------------------------------------------------------------+`
`int OnInit()`
`{`
`//--- Mapping indicator buffers`
`SetIndexBuffer(0,VEIBuffer,INDICATOR_DATA);`
`SetIndexBuffer(1,ColorBuffer,INDICATOR_COLOR_INDEX);`
`//--- Get handles for the built-in ATR indicators`
`hFastATR = iATR(_Symbol, _Period, InpFastATR);`
`hSlowATR = iATR(_Symbol, _Period, InpSlowATR);`
`//--- Check if handles were created successfully`
`if(hFastATR == INVALID_HANDLE || hSlowATR == INVALID_HANDLE)`
`{`
`Print("Failed to create ATR handles.");`
`return(INIT_FAILED);`
`}`
`//--- Set the indicator name and digits`
`string short_name = "VEI(" + IntegerToString(InpFastATR) + "/" + IntegerToString(InpSlowATR) + ")";`
`IndicatorSetString(INDICATOR_SHORTNAME, short_name);`
`IndicatorSetInteger(INDICATOR_DIGITS, 2);`
`//--- Add a visual horizontal line at the benchmark level`
`IndicatorSetInteger(INDICATOR_LEVELS, 1);`
`IndicatorSetDouble(INDICATOR_LEVELVALUE, 0, InpBenchmark);`
`IndicatorSetInteger(INDICATOR_LEVELCOLOR, 0, clrGray);`
`IndicatorSetInteger(INDICATOR_LEVELSTYLE, 0, STYLE_DOT);`
`return(INIT_SUCCEEDED);`
`}`
`//+------------------------------------------------------------------+`
`//| Custom indicator iteration function |`
`//+------------------------------------------------------------------+`
`int OnCalculate(const int rates_total,`
`const int prev_calculated,`
`const datetime &time[],`
`const double &open[],`
`const double &high[],`
`const double &low[],`
`const double &close[],`
`const long &tick_volume[],`
`const long &volume[],`
`const int &spread[])`
`{`
`//--- Check if we have enough data to calculate the Slow ATR`
`if(rates_total < InpSlowATR)`
`return(0);`
`//--- Define the start index for calculation`
`int start;`
`if(prev_calculated == 0)`
`start = 0;`
`else`
`start = prev_calculated - 1;`
`//--- Arrays to store ATR values`
`double FastATRVal[];`
`double SlowATRVal[];`
`//--- Copy values from the ATR handles`
`int copied1 = CopyBuffer(hFastATR, 0, 0, rates_total, FastATRVal);`
`int copied2 = CopyBuffer(hSlowATR, 0, 0, rates_total, SlowATRVal);`
`if(copied1 <= 0 || copied2 <= 0)`
`return(0);`
`//--- Main calculation loop`
`for(int i = start; i < rates_total; i++)`
`{`
`double fast = FastATRVal[i];`
`double slow = SlowATRVal[i];`
`// Prevent division by zero`
`if(slow != 0)`
`{`
`double vei = fast / slow;`
`VEIBuffer[i] = vei;`
`//--- Logic: Change color if above benchmark`
`if(vei > InpBenchmark)`
`ColorBuffer[i] = 1; // Index 1 is Red (as defined in properties)`
`else`
`ColorBuffer[i] = 0; // Index 0 is Silver`
`}`
`else`
`{`
`VEIBuffer[i] = 0.0;`
`ColorBuffer[i] = 0;`
`}`
`}`
`//--- Return value of prev_calculated for next call`
`return(rates_total);`
`}`
`//+`