保持敬畏之心
交易是一场持久战

Pine Script(225):未平仓订单函数总览 - 入场价格与K线编号

#Pine Script入门教学

哪些函数可以返回未平仓订单的数据?

当一个策略持有订单时,我们可以通过一系列专门的函数来获取这些订单的详细信息。这样,代码就可以查明某个特定订单的入场价格、合约数量、入场时间以及当前的浮动盈亏。

这些用于返回特定持仓订单信息的函数如下:strategy.opentrades.entry_price() 返回订单的入场价格;strategy.opentrades.entry_bar_index() 返回订单的入场K线编号;strategy.opentrades.entry_id() 返回订单的ID标识符(即名称);strategy.opentrades.entry_time() 返回订单的入场时间;strategy.opentrades.size() 返回订单的大小(交易的合约、股票或单位数量);strategy.opentrades.profit() 返回订单的当前浮动盈亏;strategy.opentrades.commission() 返回订单的入场佣金;strategy.opentrades.max_runup() 返回订单的最大浮盈;strategy.opentrades.max_drawdown() 返回订单的最大回撤。

在逐一介绍每个函数的快速示例之前,我们先来了解一下这些函数是如何查找订单数据的。

通过订单编号(索引)访问持仓订单

为了能正常工作,上面的每一个函数都需要一个订单编号。这个值告诉PineScript要从哪个订单中返回数据。没有它,PineScript就无法知道我们指的是哪个持仓订单。

订单编号是一个从零开始的索引。要访问第一个(即最早开立的)持仓订单,我们使用编号0。第二个持仓订单使用1,第三个需要2,依此类推。

最后一个(即最近开立的)持仓订单的编号,取决于当前总共有多少个持仓订单。当策略持有3个订单时,那么编号2就会返回最后一个订单的数据。

我们可以通过 strategy.opentrades 这个内置变量来获取策略当前的持仓订单总数。由于订单编号是从零开始的,所以我们需要从这个值中减去1。因此,strategy.opentrades - 1 这个表达式就能返回最后一个持仓订单的编号。

如果我们提供的订单编号是错误的——例如,策略当前只有2个持仓订单,而我们却试图访问编号4——那么函数不会返回订单数据,而是会返回一个 na 值。

各函数的使用示例

先看入场价格。要获取第一个订单的成交价,我们使用订单编号0:

// 获取持仓中第一笔订单的入场价格
initialEntryPrice = strategy.opentrades.entry_price(0)

要找出最近一笔订单的成交价,我们可以这样做:

// 获取持仓中最后一笔订单的入场价格
lastEntryPrice = strategy.opentrades.entry_price(strategy.opentrades - 1)

接着是入场K线编号。要获取第一笔订单是在哪根K线上成交的,我们使用:

// 获取持仓中第一笔订单的入场K线编号
firstEntryBar = strategy.opentrades.entry_bar_index(0)

要获取最近一笔订单的入场K线编号,则使用:

// 获取持仓中最后一笔(即最近的)订单的入场K线编号
lastEntryBar = strategy.opentrades.entry_bar_index(strategy.opentrades - 1)

然后是订单的ID标识符。要获取第一笔订单的ID名称,我们使用:

// 获取第一笔持仓订单的ID
firstOrderID = strategy.opentrades.entry_id(0)

要获取最近一笔订单的ID,则使用:

// 获取最近一笔持仓订单的ID
lastOrderID = strategy.opentrades.entry_id(strategy.opentrades - 1)

入场时间也是类似。要获取第一笔订单的入场时间(以毫秒为单位的时间戳),我们使用:

// 获取持仓中第一笔订单的入场时间
firstEntryTime = strategy.opentrades.entry_time(0)

要获取最近一笔订单的入场时间,则使用:

// 获取最后一笔(即最近的)订单的入场时间
lastEntryTime = strategy.opentrades.entry_time(strategy.opentrades - 1)

再看订单的大小。要获取第一笔订单的交易数量,我们使用:

// 获取持仓中第一笔订单的大小
initialEntrySize = strategy.opentrades.size(0)

要获取最近一笔订单的交易数量,则使用:

// 获取当前持仓中最后一笔订单的大小
lastEntrySize = strategy.opentrades.size(strategy.opentrades - 1)

浮动盈亏方面,要获取第一笔订单当前的浮动盈亏,我们使用:

// 获取持仓中第一笔订单的浮动盈亏
firstEntryProfit = strategy.opentrades.profit(0)

要获取最近一笔订单的浮动盈亏,则使用:

// 获取持仓中最后一笔订单的浮动盈亏
lastEntryProfit = strategy.opentrades.profit(strategy.opentrades - 1)

佣金成本方面,要获取第一笔订单的佣金成本,我们使用:

// 获取持仓中第一笔订单的佣金成本
firstEntryCosts = strategy.opentrades.commission(0)

要获取最近一笔订单的佣金成本,则使用:

// 获取最后一笔(即最近的)订单的佣金成本
lastEntryCosts = strategy.opentrades.commission(strategy.opentrades - 1)

接下来是最大浮盈。最大浮盈指的是该订单自开仓以来所达到的历史最佳盈利。对于多头订单,它是从入场价到后续最高价之间的利润;对于空头订单,则是从入场价到后续最低价之间的利润。要获取第一笔订单的最大浮盈,我们使用:

// 获取持仓中第一笔订单的最大浮盈
firstEntryRunUp = strategy.opentrades.max_runup(0)

要获取最近一笔订单的最大浮盈,则使用:

// 获取最近一笔持仓订单的最大浮盈
lastEntryRunUp = strategy.opentrades.max_runup(strategy.opentrades - 1)

最后是最大回撤。最大回撤指的是该订单自开仓以来所经历的历史最大亏损。对于多头订单,它是从入场价到后续最低价之间的亏损;对于空头订单,则是从入场价到后续最高价之间的亏损。要获取第一笔订单的最大回撤,我们使用:

// 获取持仓中第一笔订单的最大回撤
firstEntryDrawdown = strategy.opentrades.max_drawdown(0)

要获取最近一笔订单的最大回撤,则使用:

// 获取最近一笔订单的最大回撤值
lastEntryDrawdown = strategy.opentrades.max_drawdown(strategy.opentrades - 1)

简单总结一下:当策略持有一个或多个订单时,PineScript允许我们通过一系列专门的函数来检索这些订单的信息。这些函数的名称都以 strategy.opentrades. 开头。每个函数都需要一个订单编号(索引),以便PineScript知道要从哪个订单返回数据。这些订单编号是从零开始的:第一个(最早的)订单编号是0,第二个是1,第三个是2,以此类推。

获取未平仓订单的入场价格

当策略持有仓位时,我们可以使用 strategy.opentrades.entry_price() 函数来获取某一个特定开仓订单的入场价格。通过这个函数,策略就能获知其模拟订单的具体成交价格。

默认语法结构

该函数的定义如下:

strategy.opentrades.entry_price(trade_num)

trade_num 是一个整数,用于指定你想查询哪一笔开仓订单的价格。这个编号采用从零开始的索引方式:第一笔开仓订单的编号是0,第二笔是1,第三笔是2,以此类推。我们可以通过 strategy.opentrades - 1 来获取最后一笔(即最新一笔)入场订单的编号。

这个函数的返回值有两种可能:一是返回一个浮点数,代表指定开仓订单的入场价格;二是返回 na 值,这在传入的订单编号 trade_num 不正确(例如小于0,或大于等于当前开仓订单的总数 strategy.opentrades),或者策略当前没有任何持仓时会发生。

快速示例

要获取第一笔开仓订单(即最早的那一笔)的入场价格,我们可以这样做:

// 获取仓位中第一笔入场的成交价格
initialEntryPrice = strategy.opentrades.entry_price(0)

如果我们想获取最后一笔开仓订单(即最新的一笔)的入场价格,可以这样使用:

// 获取仓位中最后一笔入场的成交价格:
lastEntryPrice = strategy.opentrades.entry_price(strategy.opentrades - 1)

另一个应用场景是遍历所有开仓的交易。例如,假设我们想计算所有开仓订单的平均入场价。我们可以创建一个 for 循环,遍历从0到 strategy.opentrades - 1 的所有订单,将它们的入场价格累加起来,最后再除以订单总数。代码示例如下:

// 累加所有开仓交易的入场价格
priceSum = 0.0
for tradeNumber = 0 to strategy.opentrades - 1
    priceSum += strategy.opentrades.entry_price(tradeNumber)

// 计算平均入场价格
avgEntryPrice = priceSum / strategy.opentrades

顺便一提,虽然这个例子展示了如何遍历所有开仓订单,但如果你的目的仅仅是获取平均入场价,一个更高效的方法是直接使用内置变量 strategy.position_avg_price

函数的特性

strategy.opentrades.entry_price() 函数只返回当前持仓中的订单入场价格。一旦某个订单被平仓,其数据就无法再通过此函数访问。要查询已平仓的交易数据,你需要使用 strategy.closedtrades.entry_price() 函数。

另外,这个函数是自PineScript版本5起才可用的新功能,在版本4及更早的版本中不存在。如果你的策略代码以 //@version=4 或更低版本号开头,则无法使用此函数。

示例策略

让我们通过一个完整的策略来看看如何使用入场价格。下方的脚本基于一个简单移动平均线(SMA)和一个指数移动平均线(EMA)进行多头交易。当快线EMA下穿慢线SMA时,平仓离场。

我们使用 strategy.opentrades.entry_price() 函数来在图表上绘制出最后一笔入场的价格。这使得我们能很方便地观察当前价格相对于最新入场成本的位置。

策略的完整代码如下:

//@version=5
strategy(title="获取最后一笔开仓的入场价格", pyramiding=3, overlay=true)

// 计算并绘制移动平均线
emaValue = ta.ema(close, 20)
smaValue = ta.sma(close, 50)
plot(emaValue, color=color.orange, title="EMA")
plot(smaValue, color=color.teal, linewidth=2, title="SMA")

// 生成交易
if close > emaValue and emaValue > smaValue
    strategy.entry("Enter Long", strategy.long)

if ta.crossunder(emaValue, smaValue)
    strategy.close("Enter Long")

// 获取当前持仓中最后一笔入场的成交价格
lastEntryPrice = strategy.opentrades.entry_price(strategy.opentrades - 1)

// 在图表上绘制最后一笔入场的价格
plot(lastEntryPrice, color=color.fuchsia, style=plot.style_circles,
     linewidth=3, title="最新入场价格")

我们首先用 strategy() 函数配置策略,设置了 pyramiding=3 允许在同方向最多进行3次开仓。接着,代码计算并绘制了20周期的EMA和50周期的SMA。

然后,一个 if 语句定义了开仓条件:当收盘价高于EMA,且EMA高于SMA时,通过 strategy.entry() 做多。另一个 if 语句则在EMA下穿SMA时,通过 strategy.close() 平掉多头仓位。

接下来,我们获取策略最新的入场价格:

// 获取当前持仓中最后一笔入场的成交价格
lastEntryPrice = strategy.opentrades.entry_price(strategy.opentrades - 1)

我们使用 strategy.opentrades.entry_price() 函数,并通过 strategy.opentrades - 1 这个表达式来获取最后一笔交易的编号,从而得到其入场价格。

最后,我们调用 plot() 函数将这个价格绘制在图表上,样式为紫红色的圆圈。由于当策略空仓时,strategy.opentrades.entry_price() 会返回 na,所以这个绘图也会在策略平仓后自动隐藏。

当我们将此策略应用到图表时,它会用实心圆点来标记最新一次的入场价格。当有新的加仓时,圆点的位置也会随之更新:

简单总结一下:strategy.opentrades.entry_price() 函数返回某一个特定开仓订单的入场价格。我们通过一个订单编号来告知函数我们想要查询哪一笔订单。订单编号从0开始,代表第一笔开仓的交易,并以 strategy.opentrades - 1 结束,代表最后一笔(即最新一笔)入场交易。

获取未平仓订单的入场K线编号

当一个策略持有仓位时,我们可以通过 strategy.opentrades.entry_bar_index() 函数来获取某个特定订单是在哪一根K线上开仓的。这样,代码就能知道策略的模拟交易是在哪个K线编号上建立的。

标准语法格式

该函数的标准语法格式如下:

strategy.opentrades.entry_bar_index(trade_num)

trade_num 是持仓订单的编号。这个整数参数告诉PineScript我们想获取哪个持仓订单的入场K线编号。这个编号是从零开始的索引:策略开立的第一个订单编号为0,第二个为1,第三个为2,以此类推。我们可以通过 strategy.opentrades - 1 来获取最后一个(即最近的)持仓订单的编号,这个表达式也常用于遍历所有持仓订单。

这个函数的返回值有两种可能。一是一个整数,代表指定持仓订单的K线编号——在PineScript中,K线编号也是从零开始的,图表的第一根K线编号为0,第25根K线的索引则为24,因此该函数返回的值与 bar_index 变量的类型和逻辑是相同的。二是一个 na 值,这在提供的订单编号不正确(例如,小于0或大于等于当前持仓订单总数),或者策略当前没有任何持仓订单时会发生。

快速示例

如果我们想找出第一个(即最早的)持仓订单的K线编号,可以这样做:

// 获取持仓中第一笔订单的入场K线编号
firstEntryBar = strategy.opentrades.entry_bar_index(0)

要获取最后一个(即最近的)持仓订单的K线编号,则可以这样使用该函数:

// 获取持仓中最后一笔(即最近的)订单的入场K线编号
lastEntryBar = strategy.opentrades.entry_bar_index(strategy.opentrades - 1)

另一个常见的应用是遍历所有持仓交易。例如,我们可以计算所有持仓订单的平均入场K线编号。为此,我们使用一个 for 循环来遍历所有订单,在循环中将每个订单的入场K线编号累加起来,最后除以订单总数即可。实现这一逻辑的代码如下:

// 对当前所有持仓交易的入场K线编号进行求和
entryBarSum = 0
for tradeNumber = 0 to strategy.opentrades - 1
    entryBarSum += strategy.opentrades.entry_bar_index(tradeNumber)

// 计算平均入场K线编号
avgEntryBar = entryBarSum / strategy.opentrades

函数的特性

strategy.opentrades.entry_bar_index() 函数只对当前持有的订单有效。一旦某个订单被策略平仓,就无法再通过此函数获取其数据。届时,我们需要改用 strategy.closedtrades.entry_bar_index() 函数来查询已平仓交易的入场K线编号。

另外,这个函数是从PineScript版本5开始才可用的。在版本4及更早的版本中,该函数并不存在。如果你的策略代码以 //@version=4(或更低的版本号)开头,那么将无法使用此函数。

示例策略

让我们通过一个完整的策略来看看如何应用一个持仓订单的入场K线编号。下面的脚本基于相对强弱指数(RSI)进行交易。当RSI上穿30时,开立一个多头仓位;当RSI下穿70时,则平仓。

我们使用 strategy.opentrades.entry_bar_index() 函数来计算持仓K线数。如果一个仓位持有了超过15根K线但仍未盈利,我们就会将其强制平仓。

该策略的完整代码如下:

//@version=5
strategy(title="Open trade entry bar index", pyramiding=5)

// 计算相对强弱指数 (RSI)
rsiValue = ta.rsi(close, 7)

// 绘制RSI及其超买超卖线
plot(rsiValue, color=color.fuchsia, title="RSI")
hline(30, title="Oversold")
hline(70, title="Overbought")

// 当RSI穿越30时开仓
if ta.cross(rsiValue, 30)
    strategy.entry("Enter Long", strategy.long)

// 当RSI下穿70时平仓
if ta.crossunder(rsiValue, 70)
    strategy.close("Enter Long", comment="Exit Long")

// 计算持仓K线数
barsSinceEntry = bar_index - strategy.opentrades.entry_bar_index(0)

// 如果持仓超过15根K线但仍不盈利,则平仓
if barsSinceEntry > 15 and strategy.openprofit <= 0
    strategy.close("Enter Long", comment="Bar Count Exit")

我们首先用 strategy() 函数配置脚本的基本属性。然后计算并绘制7周期的RSI及其30/70的超卖超买线。

ta.cross() 函数检测到RSI穿越30线时,strategy.entry() 开立一个多头仓位。当 ta.crossunder() 检测到RSI下穿70时,strategy.close() 将多头仓位平掉。

接着,我们计算仓位已经持有了多少根K线:

// 计算持仓K线数
barsSinceEntry = bar_index - strategy.opentrades.entry_bar_index(0)

为了计算这个持仓周期,我们用 strategy.opentrades.entry_bar_index(0) 来获取第一笔(也是本策略中唯一一笔)持仓订单的入场K线编号,然后用当前的K线编号(bar_index)减去它,结果就是持仓的K线数量。

我们在最后一个 if 语句中使用了这个持仓周期:

// 如果持仓超过15根K线但仍不盈利,则平仓
if barsSinceEntry > 15 and strategy.openprofit <= 0
    strategy.close("Enter Long", comment="Bar Count Exit")

这个条件判断持仓时间是否超过了15根K线,并且当前仓位的浮动盈亏是否小于或等于零。如果两个条件都满足,strategy.close() 就会以持仓K线数超时为由将仓位平掉。

在图表上,我们可以看到策略在RSI下穿70时正常退出交易。而当这种情况没有发生,且交易在15根K线后仍不盈利时,”Bar Count Exit”订单就会平掉该仓位:

简单总结一下:strategy.opentrades.entry_bar_index() 函数返回一个特定持仓订单的开仓K线编号。一个订单编号(索引)参数告诉函数要返回哪个订单的数据,我们使用0来代表第一个(最早的)订单,使用 strategy.opentrades - 1 来代表最后一个(最近的)订单。该函数返回的K线编号是从零开始的,与内置变量 bar_index 的逻辑一致。

赞(0)
未经允许不得转载:图道交易 » Pine Script(225):未平仓订单函数总览 - 入场价格与K线编号
分享到

评论 抢沙发

登录

找回密码

注册