求助:如何实现入场前25根K线内两类均线交叉最多各1次的策略逻辑
问题:限制25根K线内交叉信号触发次数以控制开仓条件
需求说明
- 开仓(多/空单)前需验证:过去25根K线内,以下两个信号各自最多触发1次
- 多头交叉信号:
bullishMACross = ta.crossover(close, thirdmaHigh) - 空头交叉信号:
bearishMACross = ta.crossunder(close, thirdmaLow)
- 多头交叉信号:
原错误代码
var int trend_countbullishMACross = 0 if bullishMACross trend_countbullishMACross := trend_countbullishMACross + 1 // Increment the counter if condition is met var int trend_countbearishMACross = 0 if bearishMACross trend_countbearishMACross := trend_countbearishMACross + 1 // Increment the counter if condition is met trend_counterbullishMA = trend_countbullishMACross <= 1 trend_counterbearishMA = trend_countbearishMACross <= 1 entryAllowed = (trend_counterbullishMA == true) and (trend_counterbearishMA == true) if (entryAllowed) strategy.entry("Long", strategy.long, alert_message = "US30 Long Entry Taken") trend_countbullishMACross:=0 trend_countbearishMACross:=0
问题分析与修正代码
原代码核心问题:
var声明的计数器仅初始化一次,会持续累加所有历史信号,无法限制过去25根K线内的触发次数- 开仓后直接重置计数器,违背了"时间窗口内统计"的逻辑
方案1:滑动窗口计数(简洁准确)
使用ta.sum()直接统计指定窗口内的信号触发次数,逻辑清晰且符合需求:
// 定义交叉信号 bullishMACross = ta.crossover(close, thirdmaHigh) bearishMACross = ta.crossunder(close, thirdmaLow) // 统计过去25根K线内的信号触发次数 bullishCount = ta.sum(bullishMACross ? 1 : 0, 25) bearishCount = ta.sum(bearishMACross ? 1 : 0, 25) // 验证开仓条件:两个信号各自触发≤1次 entryAllowed = bullishCount <= 1 and bearishCount <= 1 // 执行开仓 if entryAllowed strategy.entry("Long", strategy.long, alert_message = "US30 Long Entry Taken")
方案2:带窗口重置的计数器(适配原逻辑)
若需保留计数器模式,需在信号超出25K窗口后重置计数:
// 定义交叉信号 bullishMACross = ta.crossover(close, thirdmaHigh) bearishMACross = ta.crossunder(close, thirdmaLow) // 初始化计数器与记录变量 var int bullishCounter = 0 var int bearishCounter = 0 var int lastBullishBar = 0 var int lastBearishBar = 0 // 更新多头计数器:超出25K窗口则重置,否则累加 if bullishMACross if ta.bar_index - lastBullishBar > 25 bullishCounter := 1 else bullishCounter := bullishCounter + 1 lastBullishBar := ta.bar_index // 更新空头计数器 if bearishMACross if ta.bar_index - lastBearishBar > 25 bearishCounter := 1 else bearishCounter := bearishCounter + 1 lastBearishBar := ta.bar_index // 验证开仓条件 entryAllowed = bullishCounter <= 1 and bearishCounter <= 1 // 执行开仓 if entryAllowed strategy.entry("Long", strategy.long, alert_message = "US30 Long Entry Taken")
关键修正点
- 用
ta.sum(condition, length)实现滑动窗口内的信号统计,自动淘汰超出窗口的旧信号 - 移除开仓后强制重置计数器的逻辑,确保统计范围始终是"过去25根K线"
内容的提问来源于stack exchange,提问作者marcq
相关产品推荐
相关产品推荐

