Pine Script DCA定投策略后续加仓订单不触发问题求助
Pine Script DCA策略加仓失效问题分析
核心问题原因
- 订单重复下发覆盖:当前下单逻辑直接写在
if within_window()判断块中,该判断每根K线都会触发执行,每次执行都会重新下发基础订单与加仓单,未成交的旧加仓单会被新订单直接覆盖,无法等到价格跌到触发位。 - 同ID订单冲突:所有加仓单均使用
'SO placed'这一相同ID,Pine Script中strategy.entry()方法遇到相同ID的订单时,会默认先取消同ID的未成交旧订单再下发新单,循环中下发的加仓单最终只会保留最后一张,其余全部被自动取消。 - 缺少状态校验逻辑:没有判断当前是否已有持仓、是否已经下发过加仓单,只要处于时间窗口内就会反复执行发单逻辑,导致订单逻辑混乱。
- 参数使用错误:
strategy.entry()的long参数传入了strategy.long常量,而非明确的布尔值true,可能导致订单方向判断异常。
修正方案
核心逻辑调整
- 新增订单下发状态标记,确保整套订单仅在无持仓、未发单、处于时间窗口时执行一次,避免重复发单
- 每个加仓单使用独立ID,防止同ID订单被覆盖
- 匹配你预设的价格偏差、加仓步长缩放参数计算加仓价格,替换写死的0.99比例
- 补充止盈平仓逻辑,完成策略闭环
修正后核心代码示例
//@version=4 strategy("DCA calculcator - version 2.0", shorttitle = 'DCA calculator', overlay = false) base_order = input(title = 'Base order value', type = input.integer, defval = 100) safe_order = input(title = 'Safe order value', type = input.integer, defval = 100) take_profit = input(title = 'Take profit level', type = input.integer, defval = 2) / 100 price_deviation = input(1.5, type=input.float, title="Price deviation to open safety order (%)", minval=0.0, step=0.1)/100 safe_order_step_scale = input(1.0, type=input.float, title="Safety Order Step Scale", step=0.1) max_safe_order = input(title = 'Max safe order', type = input.integer, defval = 4) start_time = input(type = input.time, title = 'Trade start time', defval = timestamp("1 April 2021 06:00"), group = "Trade start and end time") end_time = input(type = input.time, title = 'Trade end time', defval = timestamp("1 July 2021 06:00"), group = "Trade start and end time") //declarations var bo_price = 0.0 var last_so_level = 0.0 var orders_placed = false // 新增订单下发状态标记 //utility functions within_window() => time >= start_time and time <= end_time safety_order_deviation(index) => price_deviation * pow(safe_order_step_scale, index - 1) safety_order_price(index, last_safety_order_price) => last_safety_order_price * (1 - safety_order_deviation(index)) // 下单逻辑 if within_window() and strategy.opentrades == 0 and not orders_placed bo_price := close strategy.entry("BO placed", limit=bo_price, long=true, qty=base_order/bo_price) last_so_level := bo_price for index = 1 to max_safe_order so_price = safety_order_price(index, last_so_level) // 每个加仓单使用独立ID strategy.entry('SO placed ' + str.tostring(index), long=true, limit=so_price, qty = safe_order / so_price) last_so_level := so_price orders_placed := true // 标记订单已下发,后续不再重复执行 // 止盈平仓逻辑 if strategy.opentrades > 0 avg_cost = strategy.position_avg_price strategy.exit("TP Exit", "BO placed", limit=avg_cost * (1 + take_profit)) // 订单全部平仓后重置状态,可开启下一轮交易 if strategy.opentrades == 0 and orders_placed and not within_window() orders_placed := false plot(bo_price, color = color.green, title = 'Base Order Price') plot(last_so_level, color = color.blue, title = 'Last Safety Order Price')
内容的提问来源于stack exchange,提问作者Renat Ishmukhamedov
相关产品推荐
相关产品推荐

