Pine Script设calc_on_order_fills=true时单K线仅开仓一次问题求解
Pine Script开启calc_on_order_fills后禁止同K线重复开仓方案
原有写法失效原因
之前尝试的两类判断逻辑无法生效,核心是对strategy.closedtrades相关API的取值规则理解有误:
- 第一类写法
strategy.closedtrades.entry_bar_index(strategy.closedtrades) != bar_index、strategy.closedtrades.entry_time(strategy.closedtrades) != timestrategy.closedtrades本身返回的是已完成平仓的交易总数量,是从0开始递增的整数值,而strategy.closedtrades.entry_bar_index()要求传入的参数是有效交易索引,合法范围为0到strategy.closedtrades - 1。传入总数量作为索引时,指向的是还未发生的未来交易,接口永远返回na值,na和当前K线的bar_index、time做不等于判断的结果恒为真,完全无法起到拦截作用。 - 第二类写法
strategy.closedtrades.entry_bar_index(strategy.closedtrades-1) < bar_index
存在两个致命问题:- 策略刚启动、没有任何已平仓交易时,
strategy.closedtrades值为0,传入索引-1属于非法参数,接口返回na,数值和na做小于比较的结果恒为false,导致第一笔交易永远无法触发,这就是加上这段判断后策略无法正常运行的直接原因。 - 即使存在历史交易,这个判断只在平仓触发的瞬间生效,没有持久化记录「当前K线已经开过仓」的状态,同K线后续tick重新满足开仓条件时,依然会重复提交开仓订单,无法彻底阻断同K线多次开仓的问题。
- 策略刚启动、没有任何已平仓交易时,
正确实现逻辑
核心思路是单独持久化记录上一次开仓所在的K线索引,只要当前K线已经执行过开仓动作,不管后续是否在同K线被追踪止损、止盈或其他逻辑平仓,本根K线剩余时间内一律禁止开新仓,直到下一根K线才恢复开仓权限。
具体实现代码如下:
// 声明持久化变量,记录上一次开仓的K线索引,初始值设为-1保证第一根K线可正常开仓 var last_entry_bar = -1 // 多单开仓逻辑 if LongCondition and time > timestamp(2022, 07, 01, 06, 00) and bar_index > last_entry_bar strategy.entry(id = "Long", direction = strategy.long, alert_message = "Place Long Order", comment = "Long Entry") // 开仓成功后立刻更新记录,当前K线后续所有tick都无法再触发开仓 last_entry_bar := bar_index // 空单开仓逻辑 if ShortCondition and time > timestamp(2022, 07, 01, 06, 00) and bar_index > last_entry_bar strategy.entry(id = "Short", direction = strategy.short, alert_message = "Place Short Order", comment = "Short Entry") // 开仓成功后立刻更新记录 last_entry_bar := bar_index
这个方案可以完美适配1小时周期同K线被追踪止损平仓的场景:12点K线开仓后,last_entry_bar会被立刻更新为当前K线的bar_index,哪怕同K线内被止损平仓,后续所有tick的开仓条件都会因为bar_index > last_entry_bar不成立被拦截,直到13点新K线生成,bar_index自增后判断条件重新成立,才允许提交新的开仓订单。
内容的提问来源于stack exchange,提问作者TomTucker
相关产品推荐
相关产品推荐

