Plotting Pine Script indicators with MQL5 buffers
Turn plot() and hline() into indicator buffers and levels, using a real RSI example that draws correctly.
plot() becomes a buffer
Every plot() call in Pine needs an indicator buffer in MQL5. You declare how many buffers and plots exist with #property lines, connect each array with SetIndexBuffer, and fill it in OnCalculate. Buffers must be double arrays; int arrays do not compile with SetIndexBuffer.
Pine Script
//@version=5
indicator("RSI 14")
r = ta.rsi(close, 14)
plot(r, color=color.purple)
hline(70)
hline(30)MQL5
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrMediumPurple
#property indicator_level1 70
#property indicator_level2 30
#property indicator_minimum 0
#property indicator_maximum 100
input int Length = 14;
double RsiBuf[];
int hRsi;
int OnInit(){
SetIndexBuffer(0, RsiBuf, INDICATOR_DATA);
hRsi = iRSI(_Symbol, _Period, Length, PRICE_CLOSE);
return hRsi == INVALID_HANDLE ? INIT_FAILED : INIT_SUCCEEDED;
}
void OnDeinit(const int reason){ IndicatorRelease(hRsi); }
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(BarsCalculated(hRsi) < rates_total) return 0; // wait for data
int toCopy = (prev_calculated == 0) ? rates_total : rates_total - prev_calculated + 1;
if(CopyBuffer(hRsi, 0, 0, toCopy, RsiBuf) <= 0) return 0;
return rates_total;
}Why converted indicators show an empty window
The three usual causes: the buffer count in #property does not match the number of SetIndexBuffer calls, the code returns rates_total before the handle has data, or the loop wipes the whole buffer on every tick. Reset buffers only when prev_calculated is 0.