You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者Владислав Паршаков

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 14:07:10