L1Trend/Indicators/L1VolatilitySmoothed.mq5

88 lines
6.5 KiB
MQL5
Raw Permalink Normal View History

<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| L1VolatilitySmoothed.mq5 |
//| Copyright 2000-2026, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2026, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
#property indicator_label1 "L1VolatilitySmoothed"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrMediumVioletRed
#property indicator_width1 2
//---
input int BarsToShow = 1000; // Number of bars to calculate L1
input double CoefLambda = 0.015; // Lambda in lambda_max units
input int SmoothPeriod = 10; // Smooth period
//---
double VolSmoothed[];
//+------------------------------------------------------------------+
//| Indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, VolSmoothed, INDICATOR_DATA);
ArrayInitialize(VolSmoothed, EMPTY_VALUE);
PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
//---
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
//| 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[])
{
if(rates_total < BarsToShow)
{
ArrayInitialize(VolSmoothed, EMPTY_VALUE);
return 0;
}
//--- recalc only on new bar
static datetime last_bar_time = 0;
if(time[0] == last_bar_time && prev_calculated > 0)
return prev_calculated;
last_bar_time = time[0];
//---
int start = rates_total - BarsToShow;
for(int i = 0; i < start; i++)
VolSmoothed[i] = EMPTY_VALUE;
//--- copy close prices
vector<double> price(BarsToShow);
for(int i = 0; i < BarsToShow; i++)
price[i] = close[start + i];
vector<double> l1(BarsToShow);
price.L1TrendFilter(l1, CoefLambda, true);
//--- calculate raw volatility
vector<double> rawVol(BarsToShow);
for(int i = 0; i < BarsToShow; i++)
rawVol[i] = close[start + i] - l1[i];
//--- apply simple moving average smoothing
for(int i = 0; i < BarsToShow; i++)
{
double sum = 0;
int count = 0;
for(int j = MathMax(0, i - SmoothPeriod + 1); j <= i; j++)
{
sum += rawVol[j];
count++;
}
VolSmoothed[start + i] = sum / count;
}
//---
return rates_total;
}
//+------------------------------------------------------------------+