Pine Script:基于动态基准值从指标转策略并按指定K线平仓
RSI指标转交易策略及动态K线平仓解决方案
问题概述
基于相对强弱指数(RSI)指标开发了交易触发条件,但无法完成从指标向交易策略的转换,同时不知道如何在开仓后第p4根(p4为动态计算值)指定K线位置平仓,核心难点是p4并非固定值,会持续动态变化。
核心解决方案
解决关键在于开仓时记录当时的p4值,避免后续p4动态变化干扰平仓时机判断。以下是修改后的Pine Script策略代码:
//@version=5 strategy(title="RSI 动态平仓策略", shorttitle="RSI Strategy", max_bars_back = 2000, overlay=false, default_qty_type=strategy.cash, default_qty_value=10000, initial_capital=100000) ma(source, length, type) => switch type "SMA" => ta.sma(source, length) "Bollinger Bands" => ta.sma(source, length) "EMA" => ta.ema(source, length) "SMMA (RMA)" => ta.rma(source, length) "WMA" => ta.wma(source, length) "VWMA" => ta.vwma(source, length) // RSI 设置 rsiLengthInput = input.int(14, minval=1, title="RSI 长度", group="RSI 设置") rsiSourceInput = input.source(close, "数据源", group="RSI 设置") maTypeInput = input.string("SMA", title="均线类型", options=["SMA", "Bollinger Bands", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group="均线设置") maLengthInput = input.int(14, title="均线长度", group="均线设置") bbMultInput = input.float(2.0, minval=0.001, maxval=50, title="布林带标准差倍数", group="均线设置") up = ta.rma(math.max(ta.change(rsiSourceInput), 0), rsiLengthInput) down = ta.rma(-math.min(ta.change(rsiSourceInput), 0), rsiLengthInput) rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down)) rsiMA = ma(rsi, maLengthInput, maTypeInput) isBB = maTypeInput == "Bollinger Bands" // 绘图部分 plot(rsiMA, "RSI 均线", color=color.yellow) rsiUpperBand = hline(70, "RSI 上轨", color=#787B86) midline = hline(50, "RSI 中轨", color=color.new(#787B86, 50)) rsiLowerBand = hline(30, "RSI 下轨", color=#787B86) fill(rsiUpperBand, rsiLowerBand, color=color.rgb(126, 87, 194, 90), title="RSI 背景填充") bbUpperBand = plot(isBB ? rsiMA + ta.stdev(rsi, maLengthInput) * bbMultInput : na, title = "布林带上轨", color=color.green) bbLowerBand = plot(isBB ? rsiMA - ta.stdev(rsi, maLengthInput) * bbMultInput : na, title = "布林带下轨", color=color.green) fill(bbUpperBand, bbLowerBand, color= isBB ? color.new(color.green, 90) : na, title="布林带背景填充") // 形态判断变量 a = input.int(70, '水平线') var int bars = 0 var int p1 = 0 var int p2 = 0 var int p = 0 var l1 = 0 var l = 0 isCond21 = ta.crossunder(rsiMA, a) isCond11 = ta.crossover(rsiMA, a) l1 := nz(ta.barssince(isCond21) + 1) l := nz(ta.barssince(isCond11) + 1) bars := ta.valuewhen(isCond11, bar_index, 0) - ta.valuewhen(isCond11, bar_index, 1) p := int(math.max(1, l)) p1 := int(math.max(1, l1)) p2 := l1[1] - l[1] p3 = bars + l[1] p4 = int((p1[1] - p)/2) p5 = p < 20 ? 20 : p p6 = p3 - p5 // 价格与指标极值计算 highpclose2 = int(ta.lowest(close, int(math.max(1, nz(p1[1]))))) highpclose3 = int(ta.highest(close, int(math.max(1, nz(p3))))) highpclose1 = int(ta.highest(close, int(math.max(1, nz(p))))) highpind2 = int(ta.lowest(rsiMA, int(math.max(1, nz(p1[1]))))) highpind3 = int(ta.highest(rsiMA, int(math.max(1, nz(p3))))) highpind1 = int(ta.highest(rsiMA, int(math.max(1, nz(p))))) // 开仓条件判断 fc = highpclose3[p5] > highpclose1 and highpclose1 > highpclose2 ? 1 : na fi = highpind3[p5] > highpind1 and highpind1 > highpind2 or highpind1 > highpind3[p5] and highpind3[p5] > highpind2 ? 1 : na // 存储开仓信息:开仓bar索引、对应的平仓p4值 var array<int> entry_bars = array.new_int() var array<int> exit_p4_values = array.new_int() // 开仓逻辑 if isCond21 and fc == 1 and fi == 1 strategy.entry("空头开仓", strategy.short) // 记录当前开仓的bar索引和此时的p4值 array.push(entry_bars, bar_index) array.push(exit_p4_values, p4) // 绘图标记 label.new(bar_index, rsiMA,'开仓', color = color.aqua) label.new(bar_index+p4, 0, '平仓', color = color.red) line.new(x1 = bar_index, y1 = rsiMA, x2 = bar_index+p4, y2 = 0, color = color.red) label.new(bar_index+p4, 20, str.tostring(p4), color = color.yellow) // 平仓逻辑:遍历所有未平仓的开仓记录,判断是否达到平仓K线 for i from 0 to array.size(entry_bars)-1 entry_bar = array.get(entry_bars, i) exit_p4 = array.get(exit_p4_values, i) // 如果当前bar等于开仓bar + 记录的p4,且对应仓位仍持有 if bar_index == entry_bar + exit_p4 and strategy.position_size < 0 strategy.close("空头开仓") // 移除已平仓的记录 array.remove(entry_bars, i) array.remove(exit_p4_values, i) break // 避免索引混乱,一次处理一个平仓
关键说明
- 策略转换:将原代码的
indicator改为strategy,设置了资金管理参数(可根据需求调整) - 动态值固化:开仓时用数组存储当时的
bar_index和p4值,确保平仓时机不受后续p4变化影响 - 平仓逻辑:每根K线遍历开仓记录,判断当前K线是否达到开仓时约定的平仓位置,满足则平仓并移除对应记录
- 多仓处理:通过数组管理多个开仓记录,支持分批开仓、分别平仓的场景
内容的提问来源于stack exchange,提问作者Владислав Паршаков
相关产品推荐
相关产品推荐

