//+------------------------------------------------------------------+ //| FinVolEleLinRegSl.mq5 | //| Copyright 2026, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2026, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property indicator_separate_window #property description "Finite Volume Elements + Linear Regression Slope" #property indicator_buffers 5 #property indicator_plots 2 //--- plot FVESlope #property indicator_label1 "FVESlope" #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- plot PriceSlope #property indicator_label2 "PriceSlope" #property indicator_type2 DRAW_LINE #property indicator_color2 clrBlue #property indicator_style2 STYLE_SOLID #property indicator_width2 1 enum ENUM_USED_VOLUME // Перечисление используемых объёмов { USED_VOLUME_REAL, // Real Volume USED_VOLUME_TICK, // Tick Volume }; //--- input parameters input(name="Samples") int InpSamples = 22; // Период расчёта input(name="Threshold") double InpCutOff = 0.3; // Порог чувствительности input(name="SlopePeriod") int InpSlopePeriod = 35; // Период линейной регрессии input(name="PriceSlopeFactor")double InpPriceSlopeFactor = 2500; // Масштаб цены (индивидуально под инструмент) input(name="Used Volume") ENUM_USED_VOLUME InpUsedVolume = USED_VOLUME_TICK; // Используемый объём //--- indicator buffers double BufferFVESlope[]; double BufferPriceSlope[]; double BufferFVE[]; double BufferVolumePlusMinus[]; double BufferVolumes[]; //--- global variables int samples; double cutoff; int slope_period; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- отображаемые буферы SetIndexBuffer(0,BufferFVESlope,INDICATOR_DATA); SetIndexBuffer(1,BufferPriceSlope,INDICATOR_DATA); //--- расчётные буферы SetIndexBuffer(2,BufferFVE,INDICATOR_CALCULATIONS); SetIndexBuffer(3,BufferVolumePlusMinus,INDICATOR_CALCULATIONS); SetIndexBuffer(4,BufferVolumes,INDICATOR_CALCULATIONS); PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE); PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,EMPTY_VALUE); samples=(InpSamples<1? 22 : InpSamples); cutoff=InpCutOff/100.0; slope_period=(InpSlopePeriod<2? 35 : InpSlopePeriod); //--- Короткое имя индикатора IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("FVELinReg(%d,%.3f,%d,%.1f)",samples,InpCutOff,slope_period,InpPriceSlopeFactor)); //--- Уровень 0 индикатора IndicatorSetInteger(INDICATOR_LEVELS,1); IndicatorSetDouble(INDICATOR_LEVELVALUE,0,0.0); ArraySetAsSeries(BufferFVE,true); ArraySetAsSeries(BufferVolumePlusMinus,true); ArraySetAsSeries(BufferVolumes,true); ArraySetAsSeries(BufferFVESlope,true); ArraySetAsSeries(BufferPriceSlope,true); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int32_t rates_total, const int32_t 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 int32_t &spread[]) { //--- Проверка количества доступных баров if(rates_total1) { limit=rates_total-samples-slope_period-1; ArrayInitialize(BufferFVE,0); ArrayInitialize(BufferVolumePlusMinus,0); ArrayInitialize(BufferVolumes,0); ArrayInitialize(BufferFVESlope,0); ArrayInitialize(BufferPriceSlope,0); } //--- Расчёт индикатора for(int i=limit; i>=0; i--) { //--- Типичные цены для текущего и предыдущего баров (FVE) double TP_curr=(high[i]+low[i]+close[i])/3.0; double TP_prev=(high[i+1]+low[i+1]+close[i+1])/3.0; //--- Рассчитываем текущие метрику и направление движения цены (FVE) double MF=(close[i]-(high[i]+low[i])/2.0)+TP_curr-TP_prev; int FveFactor=(MF>cutoff*close[i]) ? 1 : (MF< -cutoff*close[i]) ? -1 : 0; //--- Записываем текущие скорректированный и общий объёмы в буферы (FVE) long vol=Volume(i,volume,tick_volume); BufferVolumePlusMinus[i]=double(vol*FveFactor); BufferVolumes[i]=(double)vol; //--- Суммируем скорректированный и общий объём за samples баров (FVE) double FVEsum=0, VolSum=0; for(int j=0;j