Pine Script实现RSI策略调用request.security_lower_tf编译报错
问题概述
需要在TradingView实现5分钟周期交易策略,规则如下:
- 开多仓条件:5周期RSI低于30,价格位于200周期EMA上方,且1分钟周期MACD出现上穿金叉
- 平仓条件:5周期RSI进入超买区间后下穿70,或价格较开仓价下跌幅度超过1%时,平掉全部持仓
策略逻辑参考:策略逻辑截图
基于Pine Script v5编写代码时,request.security_lower_tf相关代码触发编译错误,无法运行,原始代码如下:
//@version=5 strategy("RSI strategy", overlay = true, commission_type = strategy.commission.percent, currency = currency.USD, commission_value = 0.075, slippage = 2, initial_capital = 1000) // RSI rsi = ta.rsi(close, 5) // MACD [macdLine, signalLine, histLine] = ta.macd(close, 12, 26, 9) macd = request.security_lower_tf(syminfo.tickerid, "1", macdLine) signal = request.security_lower_tf(syminfo.tickerid, "1", signalLine) hist = request.security_lower_tf(syminfo.tickerid, "1", histLine) // EMA ema = ta.ema(close, 200) // Inputs and variables orderStake = input.int(90, 'Order Stake (%)', minval=0, step=1) / 100 var float entryPrice = na rsiRising = input.int(5, minval=1, title="RSI's Moving Average is rising for x candles") myRSI = ta.ema(ta.rsi(close,14),14) cond1 = ta.rising(myRSI,rsiRising) rsiLessThan = input.int(80,step=1,title="RSI Must be lower than x") cond2 = ta.rsi(close,14) < rsiLessThan //enterLong = cond1 and cond2 if bar_index == last_bar_index - 1 label.new(bar_index, high, str.tostring(macd)) enterLong = rsi < 30 and close > ema //and macd > signal orderSize = strategy.equity * orderStake / close if orderSize > 1000000000 orderSize := 1000000000 // Trailing Stoploss i_activationPct = input.float(2.45, title='Trailing Stop is activated after price moves x% from Entry', step=0.1) / 100 i_trailOffset = input.float(153560, title='Trailing Stop in ticks', minval=1, step=10) var float activationLevel = na // The price needs to pass this price in order to activate the trailing Stop Loss i_sl = input.float(8.5, title='Stop Loss (%)', step=0.1) / 100 var float stopLossPrice = na // Enter long var float ticks = na if enterLong and strategy.opentrades == 0 entryPrice := close stopLossPrice := entryPrice * (1 - i_sl) strategy.entry('Open Long Position', strategy.long, orderSize, when=strategy.position_size <= 0, comment='Long') activationLevel := entryPrice + entryPrice * i_activationPct strategy.exit('Open Long Position', stop=stopLossPrice, trail_price=activationLevel, trail_offset=i_trailOffset, comment='Long Stop') // Plots var tstop = float(na) if close > activationLevel and strategy.opentrades > 0 tstop := math.max(high - i_trailOffset * syminfo.mintick, nz(tstop[1])) tstop else tstop := na tstop useSellSignal = input(true, title='Use Sell Signal') sellSignalProfit = input.float(0.6, minval=0, step=0.1, title="Sell with at least x% profit")/100 exitWithProfit = (close - entryPrice) / close > sellSignalProfit exitCond = myRSI < myRSI[1] if useSellSignal if exitCond and close < activationLevel and exitWithProfit strategy.close('Open Long Position', comment='Sell Signal') showPlots = input(defval=true, title='Show Plots') plot(showPlots ? entryPrice : na, 'entryPrice', style=plot.style_linebr, color=color.new(color.purple, 0)) plot(showPlots ? activationLevel : na, 'activationLevel', style=plot.style_linebr, color=color.new(color.blue, 0)) plot(showPlots ? stopLossPrice : na, 'stoploss', style=plot.style_linebr, color=color.new(color.red, 0)) plot(showPlots ? tstop : na, 'Trailing Stoploss', style=plot.style_linebr, color=color.new(color.white, 0)) //plot(syminfo.mintick, title="mintick")
错误原因
request.security_lower_tf传参逻辑错误:该函数要求传入的表达式必须直接在目标低周期上下文计算,原始代码先在当前5分钟周期计算出MACD相关值,再把5分钟周期的计算结果传给函数拉取1分钟数据,不符合函数语法要求,直接触发编译错误。- 数据类型不匹配:
request.security_lower_tf返回值是当前5分钟K线对应的所有1分钟K线数值组成的数组,原始代码直接将数组对象用于数值比较,会触发类型错误。 - 策略逻辑不匹配:原始代码写了大量预设规则外的追踪止损、14周期RSI均线拐头平仓逻辑,没有实现要求的RSI下穿70平仓、1%跌幅止损规则。
修复方案
- 调整
request.security_lower_tf调用方式:直接将MACD计算表达式作为参数传入函数,在1分钟周期上下文完成MACD计算。 - 从返回的1分钟数据数组中取最新一根1分钟K线的MACD、信号线数值,判断是否发生金叉。
- 移除预设规则外的无关平仓逻辑,补充实现要求的两个平仓条件。
修复后的可运行代码如下:
//@version=5 strategy("5分钟RSI+EMA+1分钟MACD策略", overlay = true, commission_type = strategy.commission.percent, currency = currency.USD, commission_value = 0.075, slippage = 2, initial_capital = 1000, default_qty_type=strategy.cash) // 主周期指标计算 rsi5 = ta.rsi(close, 5) ema200 = ta.ema(close, 200) // 低周期1分钟MACD获取 macdLineArr = request.security_lower_tf(syminfo.tickerid, "1", ta.macd(close, 12, 26, 9)[0]) signalLineArr = request.security_lower_tf(syminfo.tickerid, "1", ta.macd(close, 12, 26, 9)[1]) // 提取当前5分钟K线内相邻两根1分钟K线的MACD值 arrLen = array.size(macdLineArr) latestMacd = arrLen > 0 ? array.get(macdLineArr, arrLen-1) : na latestSignal = arrLen > 0 ? array.get(signalLineArr, arrLen-1) : na prevMacd = arrLen > 1 ? array.get(macdLineArr, arrLen-2) : latestMacd prevSignal = arrLen > 1 ? array.get(signalLineArr, arrLen-2) : latestSignal // 1分钟MACD金叉判断 macdGoldenCross = prevMacd <= prevSignal and latestMacd > latestSignal // 开仓条件 enterLong = rsi5 < 30 and close > ema200 and macdGoldenCross // 仓位参数 orderStake = input.int(90, '开仓资金占比(%)', minval=0, step=1) / 100 orderSize = strategy.equity * orderStake / close if orderSize > 1000000000 orderSize := 1000000000 var float entryPrice = na // 平仓条件 rsiBearishCross = rsi5[1] >=70 and rsi5 <70 // RSI超买后下穿70 stopLossCond = strategy.opentrades > 0 and (close - entryPrice)/entryPrice < -0.01 // 相对开仓价跌幅超1% exitLong = rsiBearishCross or stopLossCond // 交易执行逻辑 if enterLong and strategy.opentrades == 0 entryPrice := close strategy.entry('多仓', strategy.long, orderSize) if exitLong strategy.close('多仓', comment='平仓') // 绘图 plot(ema200, '200周期EMA', color=color.yellow) plot(entryPrice, '开仓价', style=plot.style_linebr, color=color.purple)
内容的提问来源于stack exchange,提问作者nop
相关产品推荐
相关产品推荐

