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

如何实现订单下达后14根K线未成交则自动取消?

Pine Script实现未成交挂单14K线后自动取消

问题描述

我编写了一段Pine Script代码,会在特定条件下触发做空单,下单时会同时设置止损(SL)和止盈(TP)。现在需要实现:若订单在14根K线内仍未成交,则自动取消该订单。我尝试用变量实现,但搞不懂变量的生命周期。以下是我已有的代码片段及完整代码:

代码片段

if condition1 and close and high < ema and high < sma and ema < sma
    strategy.entry("Short" + str.tostring(bar_index), strategy.short, stop=low)
    strategy.exit("Exit short", str.tostring(bar_index), stop = high, limit = high - 3 * (high - low))

完整代码

//@version=5
strategy("ara", overlay=true, margin_long=100, margin_short=100)

inventoryretracementpercentage = input.int(45, title='Inventory Retracement Percentage %', maxval=100)
sma = request.security(syminfo.tickerid, "60", ta.ema(close, 20))
ema = ta.ema(close, 40)

candlerange = math.abs(high - low)
candlebody = math.abs(close - open)
percenttodecimal = inventoryretracementpercentage / 100
rangeverification = candlebody < percenttodecimal * candlerange
pricelevelforretracementx = low + percenttodecimal * candlerange
pricelevelforretracementy = high - percenttodecimal * candlerange
sl = rangeverification == 1 and high > pricelevelforretracementy and close < pricelevelforretracementy and open < pricelevelforretracementy
ss = rangeverification == 1 and low < pricelevelforretracementx and close > pricelevelforretracementx and open > pricelevelforretracementx
li = sl ? pricelevelforretracementy : ss ? pricelevelforretracementx : (pricelevelforretracementx + pricelevelforretracementy) / 2
plotshape(sl, style=shape.arrowdown, location=location.abovebar, color=color.new(color.red, 0), title='Long Bar')
plotshape(ss, style=shape.arrowup, location=location.belowbar, color=color.new(color.green, 0), title='Short Bar')
plot(sma, title='Slow Speed Line', linewidth=2, color=color.new(#ffffff, 0))
plot(ema, title='Fast Primary Trend Line', linewidth=3, color=color.new(#cfe600, 0))
alertcondition(sl, title='BUY', message='BUY')
alertcondition(ss, title='SELL', message='SELL')

if ss and close and low > ema and low > sma and ema > sma
    strategy.entry("Short" + str.tostring(bar_index), strategy.short, stop=low)
    strategy.exit("Exit short", str.tostring(bar_index), stop = high, limit = high - 3 * (high - low))

if ss and close and high < ema and high < sma and ema < sma
    strategy.entry("Short" + str.tostring(bar_index), strategy.short, stop=low)
    strategy.exit("Exit short", "Short" + str.tostring(bar_index), stop = high, limit = high - 3 * (high - low))

解决方案

要实现挂单超时取消,核心是用持久化数组跟踪每个挂单的创建时间——Pine Script普通变量会逐bar重置,只有用var声明的变量能保留跨bar数据。具体步骤:

  1. 用两个var数组分别存储挂单ID和对应的创建bar索引
  2. 触发做空条件时,改用strategy.order()发送挂单(比strategy.entry()更便于跟踪),同时记录订单ID和当前bar索引
  3. 逐bar检查数组中的订单,若订单创建后超过14根K线且未成交,则取消订单并从数组中移除
  4. 绑定止损止盈到对应的挂单ID

修改后的完整代码

//@version=5
strategy("ara", overlay=true, margin_long=100, margin_short=100)

// 1. 定义持久化数组存储挂单ID和创建时的bar索引
var string[] pendingOrderIds = array.new_string()
var int[] pendingOrderBars = array.new_int()
// 超时K线数
timeoutBars = input.int(14, title="挂单超时K线数")

inventoryretracementpercentage = input.int(45, title='Inventory Retracement Percentage %', maxval=100)
sma = request.security(syminfo.tickerid, "60", ta.ema(close, 20))
ema = ta.ema(close, 40)

candlerange = math.abs(high - low)
candlebody = math.abs(close - open)
percenttodecimal = inventoryretracementpercentage / 100
rangeverification = candlebody < percenttodecimal * candlerange
pricelevelforretracementx = low + percenttodecimal * candlerange
pricelevelforretracementy = high - percenttodecimal * candlerange
sl = rangeverification == 1 and high > pricelevelforretracementy and close < pricelevelforretracementy and open < pricelevelforretracementy
ss = rangeverification == 1 and low < pricelevelforretracementx and close > pricelevelforretracementx and open > pricelevelforretracementx
li = sl ? pricelevelforretracementy : ss ? pricelevelforretracementx : (pricelevelforretracementx + pricelevelforretracementy) / 2
plotshape(sl, style=shape.arrowdown, location=location.abovebar, color=color.new(color.red, 0), title='Long Bar')
plotshape(ss, style=shape.arrowup, location=location.belowbar, color=color.new(color.green, 0), title='Short Bar')
plot(sma, title='Slow Speed Line', linewidth=2, color=color.new(#ffffff, 0))
plot(ema, title='Fast Primary Trend Line', linewidth=3, color=color.new(#cfe600, 0))
alertcondition(sl, title='BUY', message='BUY')
alertcondition(ss, title='SELL', message='SELL')

// 2. 处理做空条件,发送挂单并记录信息
if ss and close and low > ema and low > sma and ema > sma
    orderId = "Short_" + str.tostring(bar_index)
    // 发送止损空单
    strategy.order(orderId, strategy.short, stop=low)
    // 绑定止损止盈
    strategy.exit("Exit_" + orderId, orderId, stop=high, limit=high - 3*(high-low))
    // 记录订单信息到数组
    array.push(pendingOrderIds, orderId)
    array.push(pendingOrderBars, bar_index)

if ss and close and high < ema and high < sma and ema < sma
    orderId = "Short_" + str.tostring(bar_index)
    strategy.order(orderId, strategy.short, stop=low)
    strategy.exit("Exit_" + orderId, orderId, stop=high, limit=high - 3*(high-low))
    array.push(pendingOrderIds, orderId)
    array.push(pendingOrderBars, bar_index)

// 3. 检查并取消超时未成交的挂单
// 倒序遍历数组,避免移除元素导致索引混乱
for i = array.size(pendingOrderIds) - 1 to 0 by -1
    orderId = array.get(pendingOrderIds, i)
    createBar = array.get(pendingOrderBars, i)
    // 检查是否超时且订单未成交
    if bar_index - createBar >= timeoutBars and strategy.order_status(orderId) == strategy.order_status.queued
        strategy.cancel(orderId)
        // 从数组中移除已取消的订单
        array.remove(pendingOrderIds, i)
        array.remove(pendingOrderBars, i)

关键说明

  • 变量生命周期:用var声明的数组会在脚本运行全程保留数据,不会逐bar重置;普通变量每次bar计算后都会重新初始化,无法存储跨bar的状态。
  • 订单跟踪:strategy.order_status()用于判断订单状态,strategy.order_status.queued表示订单未成交仍在挂单中。
  • 倒序遍历:遍历数组时从后往前,避免移除元素后前面的索引错位导致漏处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 12:07:04