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

基于CRSI指标的Pine Script策略二次/三次开仓失效问题排查

Pine Script CRSI策略二次/三次开仓故障排查

我编写了一个基于CRSI指标的Pine Script交易策略,计划通过CRSI指标触发开仓,且二次、三次开仓需满足指定等待时长和价格差值条件,但目前二次、三次开仓功能无法正常运行,请求协助排查故障原因。

原策略代码

//@version=5
strategy(title="1bln", overlay = true, initial_capital = 1000)

src = close
lenrsi = input(3, "RSI Length")
lenupdown = input(1, "UpDown Length")
lenroc = input(100, "ROC Length")
updown(s) =>
    isEqual = s == s[1]
    isGrowing = s > s[1]
    ud = 0.0
    ud := isEqual ? 0 : isGrowing ? (nz(ud[1]) <= 0 ? 1 : nz(ud[1])+1) : (nz(ud[1]) >= 0 ? -1 : nz(ud[1])-1)
rsi = ta.rsi(src, lenrsi)
updownrsi = ta.rsi(updown(src), lenupdown)
percentrank = ta.percentrank(ta.roc(src, 1), lenroc)
crsi = math.avg(rsi, updownrsi, percentrank) // Connors rsi

if crsi > 70
    strategy.close_all()

var first_entry_time = strategy.opentrades.entry_time(0)
var second_entry_time = strategy.opentrades.entry_time(1)
var make_first_entry = first_entry_time + 5 * 60 * 1000 // time out first take
var make_second_entry = second_entry_time + 10 * 60 * 1000 // time out second take
var initial_entry_price = strategy.opentrades.entry_price(0)
var second_entry_price = strategy.opentrades.entry_price(1)
lowestLow = ta.lowest(low, 100)
var initial_price_decrease = initial_entry_price - initial_entry_price * 0.005
var second_price_decrease = second_entry_price - second_entry_price * 0.008

if(crsi == 15 and make_second_entry == time and second_price_decrease <= lowestLow)
    strategy.entry("take_3", strategy.long, limit = strategy.initial_capital * 0.25) 
else if(crsi < 20 and make_first_entry == time and initial_price_decrease <= lowestLow)
    strategy.entry("take_2", strategy.long, limit = strategy.initial_capital * 0.2) 
else
    strategy.entry("take_1", strategy.long, limit = strategy.initial_capital * 0.15) 

核心故障点分析

  • var变量初始化逻辑错误:所有用var声明的变量(如first_entry_time、initial_entry_price)只会在脚本启动时初始化一次,后续不会随新仓更新,导致超时时间、价格阈值永远固定,无法触发后续开仓条件。
  • 精确时间匹配无效:make_second_entry == time这种毫秒级精确匹配几乎不可能触发,K线时间是每根K线的结束时间,与计算的超时时间几乎不会完全重合。
  • CRSI值精确判断不合理:crsi == 15是浮点值精确等于判断,CRSI作为计算指标几乎不会刚好等于15,触发概率极低。
  • 开仓逻辑顺序错误:else分支会在任何不满足前两个条件的情况触发take_1,导致频繁重复开仓,干扰二次、三次开仓的状态判断。
  • 价格阈值未动态更新:initial_price_decrease用var声明后,只会计算首次开仓价格的跌幅,后续开仓的价格不会更新该值,价格条件判断失效。
  • 未校验持仓状态:没有判断当前是否已持有对应仓位,会导致重复开仓,逻辑混乱。

修正后的策略代码

//@version=5
strategy(title="1bln", overlay = true, initial_capital = 1000, default_qty_type=strategy.cash)

src = close
lenrsi = input(3, "RSI Length")
lenupdown = input(1, "UpDown Length")
lenroc = input(100, "ROC Length")

updown(s) =>
    isEqual = s == s[1]
    isGrowing = s > s[1]
    ud = 0.0
    ud := isEqual ? 0 : isGrowing ? (nz(ud[1]) <= 0 ? 1 : nz(ud[1])+1) : (nz(ud[1]) >= 0 ? -1 : nz(ud[1])-1)

rsi = ta.rsi(src, lenrsi)
updownrsi = ta.rsi(updown(src), lenupdown)
percentrank = ta.percentrank(ta.roc(src, 1), lenroc)
crsi = math.avg(rsi, updownrsi, percentrank) // Connors RSI

// CRSI超70时平仓所有仓位
if crsi > 70
    strategy.close_all()

// 动态跟踪持仓状态与开仓信息
has_take1 = strategy.opentrades.size > 0 and strategy.opentrades.entry_id(0) == "take_1"
has_take2 = strategy.opentrades.size > 1 and strategy.opentrades.entry_id(1) == "take_2"

first_entry_time = has_take1 ? strategy.opentrades.entry_time(0) : na
make_first_entry = first_entry_time + 5 * 60 * 1000 // 首次开仓后5分钟可二次开仓
initial_entry_price = has_take1 ? strategy.opentrades.entry_price(0) : na
initial_price_decrease = initial_entry_price * 0.995 // 下跌0.5%阈值

second_entry_time = has_take2 ? strategy.opentrades.entry_time(1) : na
make_second_entry = second_entry_time + 10 * 60 * 1000 // 二次开仓后10分钟可三次开仓
second_entry_price = has_take2 ? strategy.opentrades.entry_price(1) : na
second_price_decrease = second_entry_price * 0.992 // 下跌0.8%阈值

lowestLow = ta.lowest(low, 100)

// 分层开仓逻辑:先判断持仓状态,再判断时间、价格、CRSI条件
if not has_take1 and crsi < 20
    strategy.entry("take_1", strategy.long, qty=strategy.initial_capital * 0.15)
elif has_take1 and not has_take2 and time >= make_first_entry and initial_price_decrease <= lowestLow and crsi < 20
    strategy.entry("take_2", strategy.long, qty=strategy.initial_capital * 0.2)
elif has_take2 and time >= make_second_entry and second_price_decrease <= lowestLow and crsi <= 15
    strategy.entry("take_3", strategy.long, qty=strategy.initial_capital * 0.25)

修正说明

  • 移除不必要的var声明,让开仓时间、价格等变量随K线循环动态更新
  • 将精确时间匹配改为time >= make_first_entry,确保超时后能触发条件
  • 将crsi ==15改为crsi <=15,提升条件触发概率
  • 添加持仓状态判断(has_take1、has_take2),避免重复开仓
  • 调整开仓逻辑顺序,分层判断仓位状态与触发条件,消除else分支的误触发
  • 优化价格跌幅计算方式,直接基于当前开仓价格动态生成阈值

内容的提问来源于stack exchange,提问作者Magish

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 12:45:49