获取已平仓交易的入场注释
当我们的策略平掉一笔模拟交易后,我们可以使用 strategy.closedtrades.entry_comment() 函数来获取这笔特定已平仓交易的入场注释。这个函数的作用就是提取出当初开仓时,我们在入场订单里写下的那段文本备注。
默认语法结构
该函数的标准语法如下:
strategy.closedtrades.entry_comment(trade_num)
trade_num 是已平仓交易的编号。我们通过一个特定的编号来访问策略历史上的每一笔交易,正是通过这个整数,PineScript才知道要返回哪一笔交易的信息。这个交易编号采用从零开始的索引方式:策略历史上的第一笔已平仓交易,其编号为0;第二笔为1;第三笔为2,以此类推。strategy.closedtrades - 1 这个表达式可以返回最后一笔已平仓交易的编号,我们可以利用这个值来获取最近的交易信息,或在循环中遍历所有已平仓的交易。
这个函数的返回值有两种可能。一是返回一个字符串,即指定已平仓交易在入场时设定的注释。要注意:如果当初的入场订单没有设置注释,或者注释为空字符串,那么该函数会转而返回该入场订单的ID。由于PineScript要求所有订单的ID都必须是一个非空字符串,因此这个函数永远不会返回一个空字符串。二是返回 na 值,这在传入的交易编号 trade_num 不正确(例如小于0,或大于等于当前已平仓交易的总数 strategy.closedtrades),或者策略到目前为止还没有平掉任何一笔交易时会发生。
快速示例
要获取策略历史上的第一笔已平仓交易的入场注释,我们将交易编号设为0:
// 获取策略第一笔已平仓交易的入场注释
firstTradeEntryText = strategy.closedtrades.entry_comment(0)
要获取最近一笔已平仓交易的入场注释,我们使用 strategy.closedtrades - 1 作为交易编号:
// 检索策略最后一笔(即最近一笔)已平仓交易的入场注释
lastEntryComment = strategy.closedtrades.entry_comment(
strategy.closedtrades - 1)
另一个应用场景是遍历所有已平仓的交易,并检查它们的入场注释。这样,我们就可以筛选出特定的交易,并基于它们的注释进行统计分析。
例如,假设我们想统计策略历史上所有基于”SuperTrend”信号的入场次数。我们可以创建一个 for 循环,遍历所有已平仓的交易。在循环中,我们获取每笔交易的入场注释,并使用 str.contains() 函数来检查它是否包含”SuperTrend”这个词。如果包含,就将计数器加一。代码示例如下:
// 统计有多少已平仓交易的入场注释包含了 "SuperTrend"
superTrendEntryCount = 0
for tradeNumber = 0 to strategy.closedtrades - 1
entryComment = strategy.closedtrades.entry_comment(tradeNumber)
if str.contains(entryComment, "SuperTrend")
superTrendEntryCount += 1
// 在图表的最后一根历史K线上,用标签显示统计结果
if barstate.islastconfirmedhistory
label.new(bar_index, high, "策略总共进行了 " +
str.tostring(superTrendEntryCount) +
" 次 SuperTrend 入场交易。")
应用场景
我们可以利用已平仓交易的入场注释来做很多事情。比如在入场注释中存储当时的关键信息(如止损价位),之后再将其与实际成交价进行比较,从而分析滑点;或者根据不同的入场注释(例如突破入场、回调入场)对已平仓交易进行分组,并分别计算它们的平均盈亏、最大浮盈/回撤等,以评估不同交易设置的表现。
还可以根据上一笔交易的入场注释来调整下一笔交易的策略,例如在一笔盈利的RSI入场后暂时跳过下一个信号,或在一笔亏损的突破入场后增大下一次的交易规模;也可以在注释中标记入场订单的类型(如限价单或停止单),然后在回测结束时按类型分别统计总盈利。
要让 strategy.closedtrades.entry_comment() 能够取到值,我们必须在开仓时为订单设置注释,这可以通过 comment 参数来实现。能够开仓并设置入场注释的函数有两个:strategy.entry() 和 strategy.order()。
函数的特性
此函数用于获取已平仓交易的入场注释。要获取当前持仓的入场注释,应使用 strategy.opentrades.entry_comment()。另外,PineScript无法获取尚未成交的挂单的注释。
这个函数只能访问当前策略的模拟交易数据,无法访问其他策略、纸上交易账户或真实交易账户的订单信息。它只能在策略(strategy)脚本中使用,不能在指标(indicator)中使用,并且是自PineScript版本5起才可用的新功能。
示例策略
让我们通过一个完整的策略来看看如何使用 strategy.closedtrades.entry_comment()。下方的脚本会根据两个不同的空头信号进行交易:最低价突破和SMA死叉。
我们为这两种入场设置不同的注释。当策略平仓后,我们检查这笔交易的入场注释是否为”SMA Entry”。如果是,我们就在图表上用一个标签显示这笔交易的盈利。
策略的完整代码如下:
//@version=5
strategy(title="已平仓订单入场注释示例", overlay=true)
// 计算并绘制SMA和最低低点
smaValue = ta.sma(close, 40)
lowestLow = ta.lowest(low, 20)[1]
plot(smaValue, color=color.orange, title="SMA")
plot(lowestLow, color=color.red, linewidth=2, title="最低低点")
// 当价格下穿SMA时做空
if ta.crossunder(close, smaValue)
strategy.entry("Enter Short", strategy.short, comment="SMA Entry")
// 当价格跌破最低低点时做空
if ta.crossunder(low, lowestLow)
strategy.entry("Enter Short", strategy.short, comment="Lowest Low Entry")
// 当价格上穿SMA时,平掉空仓
if ta.crossover(close, smaValue)
strategy.close("Enter Short", "Exit Short")
// 获取最近一笔已平仓交易的入场注释
lastEntryComment = strategy.closedtrades.entry_comment(strategy.closedtrades - 1)
// 判断是否有新的交易被平掉
tradeClosed = strategy.closedtrades > strategy.closedtrades[1]
// 如果策略平掉了一笔其入场注释包含 "SMA" 的交易,
// 就在图表上用标签显示其交易结果
if tradeClosed and str.contains(lastEntryComment, "SMA")
labelText = str.format("SMA 入场\n盈利: {0}",
strategy.closedtrades.profit(strategy.closedtrades - 1))
label.new(bar_index, high, labelText, color=color.black,
textcolor=color.white)
我们首先配置并绘制了所需的技术指标。策略有两个开仓条件,并分别为它们设置了不同的注释:”SMA Entry”和”Lowest Low Entry”。平仓条件是当价格上穿SMA时。
策略的最后一部分代码处理入场注释的逻辑。第一步获取注释:通过 strategy.closedtrades.entry_comment(strategy.closedtrades - 1) 获取最近一笔已平仓交易的入场注释。第二步判断平仓:通过 strategy.closedtrades > strategy.closedtrades[1] 判断当前K线是否有新的交易被平掉。第三步条件显示:一个 if 语句判断是否有新交易被平掉,并且这笔交易的入场注释是否包含”SMA”。如果两个条件都满足,代码就会创建一个标签,显示这笔SMA入场交易的盈利情况。
在图表上,文本标签只会在”SMA Entry”交易平仓后出现。下图中有两个空头入场,第一个是最低价突破入场,其注释不含”SMA”,所以平仓后没有标签。第二个是SMA交叉入场,其注释为”SMA Entry”,所以当它被平仓后,策略在图表上用一个标签显示了其盈利。
简单总结一下:strategy.closedtrades.entry_comment() 函数返回某一个特定已平仓交易的入场订单注释。该函数返回一个非空的字符串,如果开仓时设置了 comment 参数,则返回该注释;否则,默认返回该笔交易的订单ID。我们通过一个交易编号来告知函数我们想要查询哪一笔交易,交易编号对于策略的第一笔已平仓交易是0,对于最近一笔已平仓交易则是 strategy.closedtrades - 1。
获取已平仓交易的平仓注释
在一个策略平掉一个(或多个)模拟交易后,我们可以通过 strategy.closedtrades.exit_comment() 函数来获取某个特定已平仓交易的平仓注释。通过这个函数,代码可以检索到一笔已经平仓的交易,其平仓订单所附带的文本备注。
标准语法格式
该函数的标准语法格式如下:
strategy.closedtrades.exit_comment(trade_num)
trade_num 是已平仓交易的编号。我们通过一个特定的编号来访问策略历史上的每一笔已平仓交易,这个整数参数告诉PineScript要返回哪个交易的信息。这个交易编号是一个从零开始的索引:策略的第一个已平仓交易(即图表上最早的那笔)编号为0,第二个为1,第三个为2,依此类推。我们可以通过 strategy.closedtrades - 1 这个表达式来获取最后一个已平仓交易的编号。
这个函数的返回值有两种可能。一是一个字符串,包含了指定已平仓交易的平仓订单的注释消息。如果那个平仓订单没有设置注释,或者注释为空字符串,那么该函数会返回该平仓订单的ID标识符。由于PineScript要求每个订单都必须有一个非空的ID,这意味着 strategy.closedtrades.exit_comment() 永远不会返回一个空字符串。二是一个 na 值,这在提供的交易编号不正确(例如,小于0或大于等于当前已平仓交易总数),或者策略到目前为止还没有任何已平仓的交易时会发生。
快速示例
要获取策略的第一笔已平仓交易的平仓注释,我们使用订单编号0:
// 检索策略第一笔已平仓交易的平仓注释
firstTradeExitComment = strategy.closedtrades.exit_comment(0)
要获取最近一笔已平仓交易的平仓注释,我们可以使用 strategy.closedtrades - 1 作为交易编号,这个表达式总能准确地定位到最后一笔交易:
// 获取最近一笔已平仓交易的注释
lastExitComment = strategy.closedtrades.exit_comment(strategy.closedtrades - 1)
另一个常见的应用是遍历所有已平仓的交易,并检查它们的平仓注释。这样我们可以寻找特定的注释,或者为特定类型的交易(例如由特定信号触发的平仓)汇总性能指标。
例如,假设我们想统计由RSI信号触发的平仓次数。我们可以使用一个 for 循环来遍历所有已平仓的交易,从0到 strategy.closedtrades - 1。在循环中,我们获取每个交易的平仓注释,并检查其是否以”RSI”开头。实现这一逻辑的代码如下:
// 统计平仓注释以 'RSI' 开头的交易数量
rsiTradeCount = 0.0
for tradeNumber = 0 to strategy.closedtrades - 1
exitComment = strategy.closedtrades.exit_comment(tradeNumber)
if str.startswith(exitComment, "RSI")
rsiTradeCount += 1
// 在最后一根历史K线上,通过标签报告RSI平仓的总次数
if barstate.islastconfirmedhistory
label.new(bar_index, high, "RSI 信号平仓发生了 " +
str.tostring(rsiTradeCount) + " 次")
应用场景
获取已平仓交易的平仓注释可以实现多种功能。比如根据不同的平仓注释,分类统计已平仓交易的盈亏、最大浮盈和最大回撤,从而评估不同平仓信号的有效性;或者将预设的止损价格作为字符串存入订单注释中,之后取回该价格,并与 strategy.closedtrades.exit_price() 返回的实际成交价格进行比较,以衡量滑点。
还可以通过将不同的平仓注释存入一个数组(并确保不重复),在回测结束时用数组的长度来代表策略中使用的独特平仓信号的数量;也可以根据上一笔交易的平仓注释来决定如何处理下一笔交易,例如在连续三次因超级趋势信号止损后,考虑增大下一笔交易的仓位;或者在平仓注释中包含订单类型(如市价、止损、限价),在回测结束时根据不同的平仓订单类型来分别计算性能指标。
如何设置订单注释
一个平仓订单必须有注释,strategy.closedtrades.exit_comment() 才能检索到它。否则,这个函数会默认返回该平仓订单的ID。
要为订单添加注释,我们需要为订单函数的 comment 参数设置一个字符串值。对于 strategy.exit() 函数,还可以使用更具体的 comment_profit、comment_loss 和 comment_trailing 参数来设置注释。
我们可以通过 strategy.exit()、strategy.order()、strategy.close() 和 strategy.close_all() 这些函数来生成平仓订单(并为其附上注释)。
函数的特性
此函数只从已平仓的交易中检索注释。要获取尚未平仓的交易(即当前持仓)的入场注释,应使用 strategy.opentrades.entry_comment() 函数。
我们不能在指标脚本中使用此函数。如果在 indicator() 脚本中调用它,PineScript会报错:you cannot use strategy functions (strategy.closedtrades.exit_comment) in indicator script。
此函数只能访问当前策略模拟的已平仓交易,无法访问尚未成交的挂单或已被取消的订单,也无法访问其他策略、纸上交易账户或真实交易账户的订单信息。它是自PineScript版本5起才可用的新功能,你的策略代码必须以 //@version=5 或更高版本开头才能使用它。
示例策略
让我们通过一个完整的策略来看看如何使用 strategy.closedtrades.exit_comment()。下方的脚本基于20周期的最高高点和最低低点突破进行交易。当价格突破最高高点时做多,跌破最低低点时做空。策略有两个平仓条件:当价格穿越高低点的中线时,或当价格穿越一条加权移动平均线(WMA)时。
策略平仓后,strategy.closedtrades.exit_comment() 会检查这笔交易的平仓注释。如果注释中包含”WMA”字样,我们便将一个计数器加一,并在图表上显示这个数字。通过这种方式,策略就能追踪某个特定的平仓条件被触发了多少次。
策略的完整代码如下:
//@version=5
strategy(title="已平仓订单的平仓注释示例", overlay=true)
// 计算并绘制最高高点、最低低点、中线和WMA
highestHigh = ta.highest(high, 20)[1]
lowestLow = ta.lowest(low, 20)[1]
midPoint = (highestHigh + lowestLow) / 2
wmaValue = ta.wma(close, 15)
plot(highestHigh, color=color.green, title="最高高点")
plot(lowestLow, color=color.red, title="最低低点")
plot(midPoint, color=color.blue, title="中线")
plot(wmaValue, color=color.orange, linewidth=2, title="WMA")
// 生成入场交易
if high > highestHigh
strategy.entry("Enter Long", strategy.long)
if low < lowestLow
strategy.entry("Enter Short", strategy.short)
// 生成平仓交易
if ta.cross(close, midPoint)
strategy.close_all("Exit Midpoint") // 中线平仓
if ta.cross(close, wmaValue)
strategy.close_all("Exit WMA") // WMA平仓
// 创建一个持久性变量,用于统计WMA平仓的次数
var wmaExits = 0
// 判断是否有新的交易被平掉
if strategy.closedtrades > strategy.closedtrades[1]
// 获取最近一笔已平仓交易的平仓注释
lastExitComment = strategy.closedtrades.exit_comment(strategy.closedtrades - 1)
// 如果平仓注释包含 "WMA",则计数并显示总数
if str.contains(lastExitComment, "WMA")
wmaExits += 1
label.new(bar_index, high + 4 * ta.tr,
"WMA 平仓次数: " + str.tostring(wmaExits),
color=color.black, textcolor=color.white)
我们首先配置策略并计算绘制了所需的几个价格水平。入场逻辑是标准的高低点突破。
平仓逻辑有两个:当价格穿越中线或WMA时,我们都使用 strategy.close_all() 来清仓。关键在于,我们为这两种平仓设置了不同的注释(ID):”Exit Midpoint”和”Exit WMA”。
现在,我们来统计由WMA触发的平仓次数。首先,我们创建一个持久性变量 wmaExits 来计数:
// 创建一个持久性变量,用于统计WMA平仓的次数
var wmaExits = 0
然后,我们检查是否有新的交易被平掉,并检查其平仓注释:
// 判断是否有新的交易被平掉
if strategy.closedtrades > strategy.closedtrades[1]
// 获取最近一笔已平仓交易的平仓注释
lastExitComment = strategy.closedtrades.exit_comment(strategy.closedtrades - 1)
// 如果平仓注释包含 "WMA",则计数并显示总数
if str.contains(lastExitComment, "WMA")
wmaExits += 1
label.new(...)
这段 if 语句首先通过 strategy.closedtrades > strategy.closedtrades[1] 判断当前K线是否有新的交易被平掉。如果有,代码便获取这最后一笔已平仓交易的平仓注释。
接着,一个嵌套的 if 语句使用 str.contains() 函数来检查这个注释中是否包含”WMA”这个词。由于我们之前将WMA平仓的ID(注释)设为了”Exit WMA”,这个条件就能准确地筛选出由WMA触发的平仓。当条件满足时,我们将计数器 wmaExits 加一,并创建一个新的标签来在图表上显示当前的WMA平仓总次数。
在图表上,策略会根据中线或WMA信号来平仓。当由WMA触发平仓后,一个黑色的标签便会出现在图表上,并显示WMA平仓的累计次数。例如,在下方的以太坊(ETHUSD)图表中,第805次WMA平仓刚刚发生:
简单总结一下:strategy.closedtrades.exit_comment() 函数返回某一个特定已平仓交易的平仓订单注释。该函数返回一个非空的字符串,如果平仓时设置了 comment 参数,则返回该注释;否则,默认返回该笔平仓交易的订单ID。我们通过一个交易编号来告知函数我们想要查询哪一笔交易,交易编号对于策略的第一笔已平仓交易是0,对于最近一笔已平仓交易则是 strategy.closedtrades - 1。




