Pine Script v5:
//credit to TV script thread #oG3G1T09 //@version=5 indicator(title="Volume Based Buy and Sell Momentum by 2tm", shorttitle="VBSM", overlay=false) // Inputs EMA_Len = input.int(25, title="Length", minval=1) // Calculations xROC = ta.roc(close, 1) // Initialize variables for self-referencing var float nRes1 = 0.0 var float nRes2 = 0.0 // Logic for nRes1 and nRes2 nRes1 := volume < volume[1] ? nRes1 + xROC : nRes1 nRes2 := volume > volume[1] ? nRes2 + xROC : nRes2 nRes3 = nRes1 + nRes2 nResEMA3 = ta.sma(nRes1, EMA_Len) + ta.sma(nRes2, EMA_Len) // Plotting PNVI = plot(nRes3, color=color.blue, title="PVI + NVI") PEMA = plot(nResEMA3, color=color.red, title="EMA") // Dynamic Color for Fill pCol = nRes3 > nResEMA3 ? color.new(color.blue, 70) : color.new(color.red, 70) fill(PNVI, PEMA, color=pCol, title="Momentum Fill")
Converted with MQL5 AI. Compiles with 0 errors and 0 warnings. Shows on a chart without drawing filling:
//+------------------------------------------------------------------+ //| VBSM.mq5 | //| Volume Based Buy and Sell Momentum by 2tm | //| (Pine Script Conversion) | //+------------------------------------------------------------------+ #property copyright "Converted from Pine Script by MetaTrader Assistant" #property link "" #property version "1.00" #property indicator_separate_window #property indicator_buffers 4 #property indicator_plots 2 //--- Plot 1: PVI + NVI (nRes3) #property indicator_label1 "PVI + NVI" #property indicator_type1 DRAW_LINE #property indicator_color1 clrBlue #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- Plot 2: SMA composite (nResEMA3) #property indicator_label2 "SMA" #property indicator_type2 DRAW_LINE #property indicator_color2 clrRed #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- Hidden fill buffers (use DRAW_FILLING on plot 2 via code) #property indicator_label3 "Momentum Fill" #property indicator_type3 DRAW_FILLING #property indicator_color3 clrBlue, clrRed //--- input parameters input int InpLength = 25; // Length //--- indicator buffers double BufferPviNvi[]; // nRes3 = nRes1 + nRes2 double BufferEma[]; // nResEMA3 = SMA(nRes1) + SMA(nRes2) double BufferFill1[]; // Same as nRes3 (for fill) double BufferFill2[]; // Same as nResEMA3 (for fill) //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Indicator buffers mapping SetIndexBuffer(0, BufferPviNvi, INDICATOR_DATA); SetIndexBuffer(1, BufferEma, INDICATOR_DATA); SetIndexBuffer(2, BufferFill1, INDICATOR_DATA); SetIndexBuffer(3, BufferFill2, INDICATOR_DATA); //--- Configure filling colors PlotIndexSetInteger(2, PLOT_DRAW_TYPE, DRAW_FILLING); PlotIndexSetInteger(2, PLOT_LINE_COLOR, 0, clrBlue); // when BufferPviNvi > BufferEma PlotIndexSetInteger(2, PLOT_LINE_COLOR, 1, clrRed); // when BufferPviNvi <= BufferEma //--- Set empty value PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0); PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0); PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0.0); PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, 0.0); //--- Short name IndicatorSetString(INDICATOR_SHORTNAME, "VBSM(" + (string)InpLength + ")"); 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[]) { if(rates_total < 2) return(0); int start = (prev_calculated == 0) ? 1 : prev_calculated - 1; //--- Local static arrays to persist nRes1 and nRes2 across bars (like Pine var) static double nRes1[]; static double nRes2[]; //--- Initialize or resize static arrays if(ArraySize(nRes1) != rates_total) { ArrayResize(nRes1, rates_total); ArrayResize(nRes2, rates_total); if(prev_calculated == 0) { ArrayInitialize(nRes1, 0.0); ArrayInitialize(nRes2, 0.0); } } //--- Temporary SMA accumulators double ma1 = 0.0, ma2 = 0.0; for(int i = start; i < rates_total; i++) { //--- Rate of Change (%): roc(close, 1) = (close / close[1] - 1) * 100 double xROC = (close[i - 1] > 0.0) ? ((close[i] / close[i - 1]) - 1.0) * 100.0 : 0.0; //--- Carry forward previous values (Pine var default: keep last value) nRes1[i] = nRes1[i - 1]; nRes2[i] = nRes2[i - 1]; //--- nRes1: accumulates xROC when volume decreases if(tick_volume[i] < tick_volume[i - 1]) nRes1[i] += xROC; //--- nRes2: accumulates xROC when volume increases if(tick_volume[i] > tick_volume[i - 1]) nRes2[i] += xROC; //--- Volume unchanged: neither accumulator changes (already carried forward) //--- nRes3 = nRes1 + nRes2 BufferPviNvi[i] = nRes1[i] + nRes2[i]; BufferFill1[i] = BufferPviNvi[i]; //--- Calculate SMAs on the fly using a simple sum over the window if(i >= InpLength - 1) { ma1 = 0.0; ma2 = 0.0; for(int k = 0; k < InpLength; k++) { ma1 += nRes1[i - k]; ma2 += nRes2[i - k]; } BufferEma[i] = (ma1 / InpLength) + (ma2 / InpLength); } else { BufferEma[i] = 0.0; } BufferFill2[i] = BufferEma[i]; } return(rates_total); } //+------------------------------------------------------------------+
The bug is trivial.
Can you fix it with AI help ? (I mean without checking the code yourself).
Fixed with MQL5 AI:
//+------------------------------------------------------------------+ //| VBSM.mq5 | //| Volume Based Buy and Sell Momentum by 2tm | //| (Pine Script Conversion) | //+------------------------------------------------------------------+ #property copyright "Converted from Pine Script by MetaTrader Assistant" #property link "" #property version "1.00" #property indicator_separate_window #property indicator_buffers 4 #property indicator_plots 3 //--- Plot 1: PVI + NVI (nRes3) #property indicator_label1 "PVI + NVI" #property indicator_type1 DRAW_LINE #property indicator_color1 clrBlue #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- Plot 2: SMA composite (nResEMA3) #property indicator_label2 "SMA" #property indicator_type2 DRAW_LINE #property indicator_color2 clrRed #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- Hidden fill buffers (use DRAW_FILLING on plot 2 via code) #property indicator_label3 "Momentum Fill" #property indicator_type3 DRAW_FILLING #property indicator_color3 clrBlue, clrRed //--- input parameters input int InpLength = 25; // Length //--- indicator buffers double BufferPviNvi[]; // nRes3 = nRes1 + nRes2 double BufferEma[]; // nResEMA3 = SMA(nRes1) + SMA(nRes2) double BufferFill1[]; // Same as nRes3 (for fill) double BufferFill2[]; // Same as nResEMA3 (for fill) //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Indicator buffers mapping SetIndexBuffer(0, BufferPviNvi, INDICATOR_DATA); SetIndexBuffer(1, BufferEma, INDICATOR_DATA); SetIndexBuffer(2, BufferFill1, INDICATOR_DATA); SetIndexBuffer(3, BufferFill2, INDICATOR_DATA); //--- Configure filling colors PlotIndexSetInteger(2, PLOT_DRAW_TYPE, DRAW_FILLING); PlotIndexSetInteger(2, PLOT_LINE_COLOR, 0, clrBlue); // when BufferPviNvi > BufferEma PlotIndexSetInteger(2, PLOT_LINE_COLOR, 1, clrRed); // when BufferPviNvi <= BufferEma //--- Set empty value PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0); PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0); PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0.0); PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, 0.0); //--- Short name IndicatorSetString(INDICATOR_SHORTNAME, "VBSM(" + (string)InpLength + ")"); 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[]) { if(rates_total < 2) return(0); int start = (prev_calculated == 0) ? 1 : prev_calculated - 1; //--- Local static arrays to persist nRes1 and nRes2 across bars (like Pine var) static double nRes1[]; static double nRes2[]; //--- Initialize or resize static arrays if(ArraySize(nRes1) != rates_total) { ArrayResize(nRes1, rates_total); ArrayResize(nRes2, rates_total); if(prev_calculated == 0) { ArrayInitialize(nRes1, 0.0); ArrayInitialize(nRes2, 0.0); } } //--- Temporary SMA accumulators double ma1 = 0.0, ma2 = 0.0; for(int i = start; i < rates_total; i++) { //--- Rate of Change (%): roc(close, 1) = (close / close[1] - 1) * 100 double xROC = (close[i - 1] > 0.0) ? ((close[i] / close[i - 1]) - 1.0) * 100.0 : 0.0; //--- Carry forward previous values (Pine var default: keep last value) nRes1[i] = nRes1[i - 1]; nRes2[i] = nRes2[i - 1]; //--- nRes1: accumulates xROC when volume decreases if(tick_volume[i] < tick_volume[i - 1]) nRes1[i] += xROC; //--- nRes2: accumulates xROC when volume increases if(tick_volume[i] > tick_volume[i - 1]) nRes2[i] += xROC; //--- Volume unchanged: neither accumulator changes (already carried forward) //--- nRes3 = nRes1 + nRes2 BufferPviNvi[i] = nRes1[i] + nRes2[i]; BufferFill1[i] = BufferPviNvi[i]; //--- Calculate SMAs on the fly using a simple sum over the window if(i >= InpLength - 1) { ma1 = 0.0; ma2 = 0.0; for(int k = 0; k < InpLength; k++) { ma1 += nRes1[i - k]; ma2 += nRes2[i - k]; } BufferEma[i] = (ma1 / InpLength) + (ma2 / InpLength); } else { BufferEma[i] = 0.0; } BufferFill2[i] = BufferEma[i]; } return(rates_total); } //+------------------------------------------------------------------+
One more (final) version here...
AI hardcoded the filling colors which could not be set by way of Inputs nor Colors tabs of the indicator window (despite having appeared on the Colors tab). I manually added color type Inputs for filling in this one:
You don't need to use PlotIndexSetInteger(x, PLOT_LINE_COLOR,...) if the color can only be changed by the user.
And if you need to know the color set by the user to use it elsewhere in your code, you can use :
color P2C1 = (color)PlotIndexGetInteger(2,PLOT_DRAW_TYPE,0); color P2C2 = (color)PlotIndexGetInteger(2,PLOT_DRAW_TYPE,1);
So for your indicator it could just be :
... //input color FillClrUp = clrMediumBlue; //input color FillClrDn = clrMaroon; //--- indicator buffers double BufferPviNvi[]; // nRes3 = nRes1 + nRes2 double BufferEma[]; // nResEMA3 = SMA(nRes1) + SMA(nRes2) double BufferFill1[]; // Same as nRes3 (for fill) double BufferFill2[]; // Same as nResEMA3 (for fill) //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Indicator buffers mapping SetIndexBuffer(0, BufferPviNvi, INDICATOR_DATA); SetIndexBuffer(1, BufferEma, INDICATOR_DATA); SetIndexBuffer(2, BufferFill1, INDICATOR_DATA); SetIndexBuffer(3, BufferFill2, INDICATOR_DATA); //--- Configure filling colors PlotIndexSetInteger(2, PLOT_DRAW_TYPE, DRAW_FILLING); //PlotIndexSetInteger(2, PLOT_LINE_COLOR, 0, FillClrUp); // when BufferPviNvi > BufferEma //PlotIndexSetInteger(2, PLOT_LINE_COLOR, 1, FillClrDn); // when BufferPviNvi <= BufferEma ...
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use

Hi
I am looking for a VBSM indicator (volume based buy and sell momentum) for MT5. Is there any equivalent here?
Screenshot of Trading view VBSM attached.
Thanks