获取策略的盈利交易数量
在PineScript策略中,我们可以通过内置变量 strategy.wintrades 来获取盈利交易的总笔数。这个变量会返回一个整数,代表所有以盈利状态被平仓的交易数量。它的统计范围从图表的第一根K线开始,一直累计到当前的K线。
当策略运行至图表末尾,处理完所有价格K线后,strategy.wintrades 返回的值就是策略在整个回测期间的盈利交易总数。当然,我们也可以在任何一根K线上调用此变量,从而得知策略截至该时间点的累计盈利笔数。
应用实例
strategy.wintrades 变量的用法多种多样。最直接的用法是获取当前的盈利笔数,在代码中需要这个数值的地方直接调用即可。例如,我们可以检查盈利笔数是否超过了某个预设的门槛:
// 检查策略的盈利交易是否已超过125笔
if strategy.wintrades > 125
label.new(bar_index, high, text="盈利已超过125笔!")
通过这类比较,策略可以将盈利笔数作为其交易决策的一个条件。比方说,我们可以设定一个规则,只在累计盈利笔数少于75笔时才允许执行某些开仓指令:
// 当价格下穿简单移动平均线,且累计盈利交易少于75笔时,才开仓做空。
if ta.crossunder(close, ta.sma(hlc3, 15)) and strategy.wintrades < 75
strategy.entry("Enter Short", strategy.short)
另一种常见的用法是比较 strategy.wintrades 的当前值与其历史值。借助历史操作符([]),我们可以得知相对于过去的某个时间点,策略新增了多少笔盈利交易。例如,要判断在最近30根K线内是否产生了超过10笔盈利交易,我们可以这样写:
// 判断最近30根K线的盈利交易笔数是否超过了设定的阈值
if strategy.wintrades - strategy.wintrades[30] > 10
label.new(bar_index, high, text="最近30根K线盈利超过10笔!")
有时,只需将 strategy.wintrades 与上一根K线的值进行比较就足够了。这能帮助我们判断是否刚刚有一笔新的盈利交易被平仓。例如:
// 当盈利交易笔数增加时(这通常发生在盈利交易被平仓的K线上),
// 就将图表背景涂成绿色。
bgcolor(strategy.wintrades > strategy.wintrades[1] ?
color.new(color.green, 85) : na)
由于 strategy.wintrades 在每根K线上都返回一个数值,构成了序列值,因此PineScript中的各种函数都可以对其进行运算。例如,要计算并绘制盈利笔数的指数移动平均线(EMA),我们可以这样做:
// 计算并绘制盈利笔数的EMA
plot(ta.ema(strategy.wintrades, 35), color=color.teal, title="盈利笔数EMA")
核心特性
使用 strategy.wintrades 时,有几个特性值得留意。
动态累计:它的值会随着策略在图表上逐根K线地处理而发生变化。在第200根K线上的值,和在第15,800根K线上的值通常是不同的(假设策略在此期间产生了新的盈利交易)。
成本影响:盈利交易的数量会直接受到佣金和滑点的负面影响。交易成本越高,一笔原本微利的交易就可能变成亏损,从而导致 strategy.wintrades 记录的盈利笔数减少。
策略特定性:strategy.wintrades 的值仅与当前图表上运行的这一个特定策略相关,它无法获取其他策略的盈利数据。
交易与头寸的区别:strategy.wintrades 统计的是以盈利收盘的交易笔数,而不是盈利的头寸数量。多个独立的交易可能只是为了构建一个头寸。例如,当我们分批建仓时,我们可能会有5笔入场订单(即5次交易),但这些交易最终只构成1个头寸。
数据范围:统计包含了策略所有已平仓的盈利交易,无论这些交易发生在历史数据回测阶段,还是在实时数据模拟阶段。
不含持仓:strategy.wintrades 不会计算当前尚未平仓的头寸。要判断当前持仓是否盈利,应当检查 strategy.openprofit 变量的值是否大于零。而 strategy.opentrades.profit() 函数则可以具体指明当前持有的哪些交易是盈利的。
使用限制:strategy.wintrades 不能在指标(indicator)脚本中使用。如果尝试这样做,PineScript会抛出错误:cannot use strategy functions in indicator script(不能在指标脚本中使用策略函数)。
策略范例
让我们通过一个完整的策略来看看 strategy.wintrades 的实际应用。下方的脚本使用Stochastics振荡器进行多空双向交易。
在这个策略中,我们不仅会用 strategy.wintrades 变量来绘制盈利笔数的累计曲线及其移动平均线,还会在每当有新的盈利交易产生时,通过高亮背景色来给予提示。策略的完整代码如下:
//@version=5
strategy(title="盈利交易示例")
// 计算Stochastic指标的%K和%D线
kValue = ta.sma(ta.stoch(close, high, low, 9), 3)
dValue = ta.sma(kValue, 3)
// 基于Stochastics指标生成交易信号
if ta.crossover(kValue, dValue) and kValue < 20
strategy.entry("Enter Long", strategy.long)
if ta.crossunder(kValue, dValue) and kValue > 80
strategy.entry("Enter Short", strategy.short)
// 将策略的总盈利交易笔数用黑色粗线绘制出来
plot(strategy.wintrades, color=color.black, linewidth=2)
// 计算并绘制盈利交易笔数的EMA
winEma = ta.ema(strategy.wintrades, 30)
plot(winEma, color=color.teal, title="盈利交易EMA")
// 当有新的盈利交易产生时,将背景设为绿色,否则设为灰色。
newWinner = strategy.wintrades > strategy.wintrades[1]
bgcolor(newWinner ? color.new(color.green, 60) :
color.new(color.gray, 92.5))
首先,我们用 strategy() 函数进行策略声明,并通过 title 参数为脚本命名。
为了计算Stochastics指标,我们先调用 ta.stoch() 函数得到原始值,然后用 ta.sma() 对其进行平滑处理,从而得到指标的%K线。接着,我们对%K线再次进行简单移动平均计算,得出%D线。
随后的两个 if 语句负责产生交易信号。第一个使用 ta.crossover() 函数判断%K线是否上穿了%D线,并附加了%K值需低于20的条件。当两者同时满足时,strategy.entry() 函数执行多头开仓。另一个 if 语句则使用 ta.crossunder() 函数,判断%K线是否下穿了%D线,并要求%K值高于80。当这些条件满足时,执行空头开仓。
接下来,我们绘制策略的盈利笔数:
// 将策略的总盈利交易笔数用黑色粗线绘制出来
plot(strategy.wintrades, color=color.black, linewidth=2)
这里的 plot() 函数将 strategy.wintrades 变量的值绘制在图表上。由于没有指定绘图类型,PineScript默认会画一条常规的折线。我们将其颜色设为黑色,并加粗了线条(linewidth=2)。
之后,我们计算盈利笔数的移动平均线:
// 计算并绘制盈利交易笔数的EMA
winEma = ta.ema(strategy.wintrades, 30)
plot(winEma, color=color.teal, title="盈利交易EMA")
这段代码通过 ta.ema() 函数计算了盈利交易笔数的30周期指数移动平均线。然后,plot() 函数将这条平均线以青色绘制在图表上。
最后一段代码,则用于判断策略是否刚刚平掉了一笔盈利的交易:
// 当有新的盈利交易产生时,将背景设为绿色,否则设为灰色。
newWinner = strategy.wintrades > strategy.wintrades[1]
bgcolor(newWinner ? color.new(color.green, 60) :
color.new(color.gray, 92.5))
我们在这里比较 strategy.wintrades 的当前值是否大于它在上一根K线的值。如果大于,说明有新的盈利交易平仓,表达式返回 true,否则返回 false。我们将这个布尔结果存入 newWinner 变量。
然后 bgcolor() 函数根据条件运算符(?:)的判断结果来为图表背景上色。运算符会检查 newWinner 变量的值:如果为 true,就返回一个带透明度的绿色作为背景色;如果为 false,则返回灰色。
当策略应用于图表时,你将看到代表当前和平均盈利笔数的曲线。同时,图表背景会根据是否有新的盈利交易产生而显示为绿色或灰色:
简单总结一下:strategy.wintrades 变量返回的是策略当前已平仓的盈利交易总笔数。它不考虑未平仓的交易,并且其统计结果会受到策略的佣金和滑点成本的影响而减少。在每一根K线上,strategy.wintrades 都会返回一个累计值,这使得我们可以进行跨时间的比较,也允许其他函数利用这个序列值进行更复杂的计算。
获取策略的亏损交易数量
在PineScript策略中,我们可以通过 strategy.losstrades 变量获取亏损交易的总笔数。该变量返回一个整数,用以表示策略有多少笔交易最终是以亏损状态平仓的。它会从图表的第一根K线开始,一路累计到当前K线。
当策略在图表末尾处理完所有历史数据后,strategy.losstrades 返回的便是整个回测期间的亏损交易总数。如果我们在回测过程中的任意一根K线上调用该变量,它则会告诉我们策略截至那一刻累计产生了多少笔亏损交易。
应用实例
strategy.losstrades 变量有多种实用的方法。最直接的用法是获取当前累计的亏损笔数,将变量直接用于需要此信息的代码逻辑中。例如,要判断亏损笔数是否仍在可接受的范围内,可以这样写:
// 检查策略的亏损笔数是否仍低于45笔
if strategy.losstrades < 45
label.new(bar_index, high, text="亏损交易仍少于45笔!")
策略可以将这类评估融入其核心决策逻辑中。比如说,我们可以设定一个风控规则:只有在累计亏损笔数少于100笔时,才允许建立新的多头仓位。这样,我们就能避免在策略表现不佳、亏损持续扩大时继续交易。代码实现如下:
// 仅当价格上穿EMA且亏损交易少于100笔时,才建立多头仓位
// (否则不交易)
if ta.crossover(close, ta.ema(close, 20)) and strategy.losstrades < 100
strategy.entry("Enter Long", strategy.long)
另一种用法是将 strategy.losstrades 的当前值与其历史值进行比较。我们通过历史操作符([])并指定回溯的K线数量来实现这一点。通过以下代码,我们可以判断在过去50根K线内,是否新增了超过15笔亏损交易:
// 测试过去50根K线的亏损交易增量是否超过某一阈值
if strategy.losstrades - strategy.losstrades[50] > 15
label.new(bar_index, high, text="最近50根K线内亏损超过15笔!")
我们并不总是需要回溯很长的周期。仅仅知道亏损笔数在当前K线上是否刚刚增加,也非常有用。这能告诉我们策略是否正好完成了一笔亏损的平仓操作。相应的PineScript代码如下:
// 当亏损交易笔数增加时(即刚有一笔亏损交易平仓时),
// 将背景渲染为红色
bgcolor(strategy.losstrades > strategy.losstrades[1] ?
color.new(color.red, 80) : na)
由于 strategy.losstrades 在每根K线上都返回一个数值,因此函数也可以直接处理这些数据。我们只需将该变量作为参数传递给函数即可。例如,要在图表上展示亏损交易笔数的加权移动平均线(WMA),我们可以这样做:
// 计算并绘制亏损笔数的WMA
plot(ta.wma(strategy.losstrades, 20), color=color.fuchsia, title="亏损笔数WMA")
核心特性
使用 strategy.losstrades 时,有几点需要留意。
随着策略处理K线并生成交易,它的值会动态变化。因此,在第125根K线和第5430根K线上,它的值通常是不同的(假设策略在此期间产生了亏损交易)。
亏损交易的数量会受到策略设置的佣金和滑点的影响。这些交易成本越高,就越有可能将一些小幅盈利的交易变成亏损,从而导致 strategy.losstrades 的值增加。
strategy.losstrades 的值仅反映当前运行的这个策略,它无法获知其他策略或任何手动交易的表现。
它统计的是亏损交易的笔数,而非亏损头寸的数量。这两者有细微差别:一个完整的头寸可能由多次入场交易构成。例如,如果我们通过3次交易分批建仓了1个头寸,且这3笔交易最终都以亏损平仓,那么结果是3笔亏损交易,但只有1个亏损头寸。
它的值并非总是逐一增加。当策略在同一根K线上平仓了3笔亏损交易时,该变量的值可能会直接从42跳升至45。
strategy.losstrades 不包含当前未平仓头寸的数据。要判断持仓是否亏损,应检查 strategy.openprofit 变量是否小于零。要了解具体是哪些持仓交易在亏损以及亏损持仓的数量,应使用 strategy.opentrades.profit() 函数。
最后,strategy.losstrades 是策略脚本的专属变量,不能在指标脚本中使用。否则,PineScript会产生编译错误,提示无法在指标脚本中使用策略函数。
策略范例
让我们通过一个完整的策略来演示如何使用 strategy.losstrades 变量。下方案例脚本使用相对强弱指数(RSI)振荡器进行多空双向交易。
我们将使用 strategy.losstrades 来绘制策略当前的累计亏损笔数,并计算其移动平均线。同时,每当有新的亏损交易发生时,我们会高亮显示图表背景。策略的完整代码如下:
//@version=5
strategy(title="亏损交易示例")
// 计算相对强弱指数 (RSI)
rsiValue = ta.rsi(close, 5)
// 进行RSI的多空双向交易
if ta.crossover(rsiValue, 20)
strategy.entry("Enter Long", strategy.long)
if ta.crossunder(rsiValue, 80)
strategy.entry("Enter Short", strategy.short)
// 绘制策略的总亏损交易笔数
plot(strategy.losstrades, color=color.maroon, linewidth=2)
// 计算并绘制亏损笔数的移动平均线
lossCountSma = ta.sma(strategy.losstrades, 100)
plot(lossCountSma, color=color.fuchsia, title="亏损交易SMA")
// 当有新亏损时,将背景涂成红色,否则使用白色
newLoss = strategy.losstrades > strategy.losstrades[1]
bgcolor(newLoss ? color.new(color.red, 80) : color.white)
脚本以 strategy() 函数开始,通过 title 参数为脚本命名。接着,ta.rsi() 函数基于收盘价(close)计算了周期为5的相对强弱指数,我们将其数值存入 rsiValue 变量。
随后的两个 if 语句负责生成交易信号。第一个使用 ta.crossover() 函数判断RSI是否上穿20(超卖区),若是,则 strategy.entry() 函数建立一个多头仓位。第二个 if 语句则使用 ta.crossunder() 函数判断RSI是否下穿80(超买区),若是,则建立一个空头仓位。
然后,我们绘制累计亏损笔数:
// 绘制策略的总亏损交易笔数
plot(strategy.losstrades, color=color.maroon, linewidth=2)
此处的 plot() 函数将 strategy.losstrades 变量的值绘制在图表上。由于未指定绘图类型,默认会以常规线图的形式,用栗色(color.maroon)来展示。
接下来,我们展示亏损交易的平均趋势:
// 计算并绘制亏损笔数的移动平均线
lossCountSma = ta.sma(strategy.losstrades, 100)
plot(lossCountSma, color=color.fuchsia, title="亏损交易SMA")
ta.sma() 函数计算了亏损交易笔数的简单移动平均值。然后 plot() 函数将这个平均值以紫红色的线图形式绘制出来。
最后,我们判断策略是否刚刚产生了一笔亏损交易,并据此为背景着色:
// 当有新亏损时,将背景涂成红色,否则使用白色
newLoss = strategy.losstrades > strategy.losstrades[1]
bgcolor(newLoss ? color.new(color.red, 80) : color.white)
我们首先判断 strategy.losstrades 的当前值是否大于其前一根K线的值。如果大于,说明策略刚刚平仓了一笔亏损交易,此时我们的 newLoss 变量为 true,否则为 false。
然后 bgcolor() 函数根据 newLoss 的值来渲染背景色。通过条件运算符(?:),当 newLoss 为 true 时,运算符返回一个半透明的红色;当为 false 时,则返回白色。这样就实现了根据条件显示红色或白色背景的效果。
在图表上,该策略会绘制出累计亏损笔数的实时曲线及其平均线。而背景色的变化则清晰地标示出每一笔新亏损交易发生的时刻:
简单总结一下:strategy.losstrades 变量返回的是策略已平仓的亏损交易总笔数。它会忽略当前尚未平仓的交易,且数值会受到策略设置的佣金和滑点成本的影响。在每一根K线上,strategy.losstrades 都有一个对应的值,这使得与历史数据进行比较成为可能,也方便了各类函数对其进行计算。
获取策略的保本交易数量
在PineScript策略中,我们可以通过内置变量 strategy.eventrades 来获取恰好保本(即不亏不盈)的交易总笔数。该变量会返回一个整数,代表所有以零盈亏状态被平仓的交易数量。它的统计范围从图表的第一根K线开始,一直累计到当前的K线。
当策略处理完所有K线,运行至图表末端时,strategy.eventrades 返回的值就是策略在整个回测期间的保本交易总数。当然,我们也可以在任何一根K线上调用此变量,从而得知策略截至该时间点的累计保本笔数。
应用实例
strategy.eventrades 变量的用法灵活多样。最直接的用法是获取策略当前的保本交易笔数,在代码中需要这个数值的地方直接调用即可。例如,我们可以检查保本交易笔数是否超过了85笔:
// 验证保本交易的数量是否超过了设定的阈值
if strategy.eventrades > 85
label.new(bar_index, high, text="保本交易已超过85笔!")
策略也可以将这类比较用作其交易决策的一部分。比方说,我们设定一个规则,只在累计保本交易少于55笔时,才允许执行某种特定的多头开仓指令:
// 当7周期相对强弱指数(RSI)上穿50,且保本交易笔数低于55时,才执行做多
if ta.cross(ta.rsi(close, 7), 50) and strategy.eventrades < 55
strategy.entry("Enter Long #2", strategy.long)
第二种用法是结合历史操作符([]),来获取策略在过去某一根K线上的保本交易数。通过比较变量的当前值与若干根K线之前的值,我们就能知道在此期间策略产生了多少笔保本交易:
// 测试策略在过去30根K线内,是否有过以保本价格平仓的交易
if strategy.eventrades - strategy.eventrades[30] > 0
label.new(bar_index, high, text="最近30根K线内有一次保本交易")
有时,只需与上一根K线进行比较就足够了。通过比较 strategy.eventrades 的当前值与前一根K线的值,我们能准确地捕捉到策略平掉一笔保本交易的那个瞬间:
// 当有新的保本交易发生时,将图表背景涂成橙色
bgcolor(strategy.eventrades > strategy.eventrades[1] ?
color.new(color.orange, 80) : na)
第三种用法,是将 strategy.eventrades 与其他函数结合起来使用。因为这个变量在每根K线上都返回一个数值,构成了序列值,所以PineScript中的各种函数都可以对其进行运算。例如,我们可以计算保本交易笔数的指数移动平均线(EMA):
// 计算并绘制保本交易笔数的EMA
plot(ta.ema(strategy.eventrades, 20), color=color.maroon,
title="保本交易EMA")
核心特性
使用 strategy.eventrades 时,有几个特性值得留意。
动态累计:随着策略在图表上逐K地运行并产生交易,它的值也会随之变化。在第250根K线上的值,和在第15,700根K线上的值通常是不同的(前提是策略在此期间产生了新的保本交易)。
成本影响:保本交易的数量会受到策略设置的佣金和滑点的影响。如果出现大量的保本交易,通常意味着策略可能没有设置交易成本,因为在实际交易中,即使价格回到入场点,交易成本也会导致小额亏损。
非线性增长:strategy.eventrades 的值并非总是逐一递增。例如,当策略在同一根K线上同时平掉2笔保本交易时,它的值可能会直接从21跳增到23。
交易与头寸的区别:strategy.eventrades 统计的是保本的交易笔数,而不是保本的头寸数量。一个头寸可能由多次交易构成。比如,我们通过9笔交易分批建仓一个头寸,最终所有交易都在保本点平仓,那么这将产生9笔保本交易,但只对应1个保本头寸。
仅限平仓交易:strategy.eventrades 只统计已平仓的交易。要判断当前持有的头寸是否处于保本状态,应检查 strategy.openprofit 变量的值是否等于零。而 strategy.opentrades.profit() 函数则可以具体指明当前持有的哪些交易处于保本状态。
扩展亏损定义:如果我们将保本交易也归类为亏损交易(因为它们没有产生利润),那么策略的非盈利交易总数可以这样计算:strategy.eventrades + strategy.losstrades。
使用限制:strategy.eventrades 不能在指标(indicator)脚本中使用。如果尝试这样做,PineScript会抛出错误:cannot use strategy functions in indicator script(不能在指标脚本中使用策略函数)。
策略范例
让我们通过一个完整的策略来看看 strategy.eventrades 的实际应用。下方的脚本基于两条移动平均线的关系进行交易。
当连续两根K线的收盘价都高于指数移动平均线(EMA),且EMA本身也位于简单移动平均线(SMA)之上时,我们开仓做多。反之,当连续两根K线收于EMA之下,且EMA也位于SMA之下时,我们则建立空头头寸。
在这个策略中,我们会使用 strategy.eventrades 来绘制保本交易的累计笔数,并计算其移动平均线,同时在有新的保本交易产生时用背景色进行高亮提示。策略的完整代码如下:
//@version=5
strategy(title="保本交易示例")
// 计算移动平均线
emaValue = ta.ema(close, 20)
smaValue = ta.sma(close, 50)
// 定义交易逻辑
if close > emaValue and close[1] > emaValue[1] and emaValue > smaValue
strategy.entry("Enter Long", strategy.long)
if close < emaValue and close[1] < emaValue[1] and emaValue < smaValue
strategy.entry("Enter Short", strategy.short)
// 展示策略的总保本交易笔数
plot(strategy.eventrades, color=color.fuchsia, linewidth=2)
// 计算并绘制保本交易的移动平均线
evenTradesSMA = ta.sma(strategy.eventrades, 20)
plot(evenTradesSMA, color=color.yellow, title="保本交易SMA")
// 当有新的保本交易发生时,将背景涂成灰色
newEvenTrade = strategy.eventrades > strategy.eventrades[1]
bgcolor(newEvenTrade ? color.new(color.gray, 80) : na)
我们从 strategy() 函数开始,通过 title 参数为脚本命名。接着,ta.ema() 函数计算20周期的EMA,ta.sma() 函数计算50周期的SMA,两者都基于收盘价(close)。
随后的两个 if 语句负责产生交易信号。第一个判断当前和上一根K线的收盘价是否都高于EMA,并且EMA是否高于SMA。当这个形态出现时,strategy.entry() 执行多头开仓。另一个 if 语句则判断当前和上一根K线的收盘价是否都低于EMA,并且EMA是否低于SMA。在这种情况下,执行空头开仓。
接下来,我们把保本交易的数量展示在图表上:
// 展示策略的总保本交易笔数
plot(strategy.eventrades, color=color.fuchsia, linewidth=2)
这里的 plot() 函数将 strategy.eventrades 的当前值绘制出来。由于没有指定绘图类型,PineScript默认画出一条常规的折线,颜色设为紫红色。
然后,我们计算保本交易的移动平均线:
// 计算并绘制保本交易的移动平均线
evenTradesSMA = ta.sma(strategy.eventrades, 20)
plot(evenTradesSMA, color=color.yellow, title="保本交易SMA")
ta.sma() 函数计算保本交易笔数的20周期简单移动平均线。然后,plot() 函数将这条平均线以黄色绘制在图表上。
最后,我们高亮显示新产生的保本交易:
// 当有新的保本交易发生时,将背景涂成灰色
newEvenTrade = strategy.eventrades > strategy.eventrades[1]
bgcolor(newEvenTrade ? color.new(color.gray, 80) : na)
我们首先比较 strategy.eventrades 的当前值是否大于其在上一根K线的值。如果大于,说明有新的保本交易被平仓,表达式返回 true,否则返回 false。我们将这个布尔结果存入 newEvenTrade 变量。
然后 bgcolor() 函数根据 newEvenTrade 的值来为图表背景上色。这里用到了条件运算符(?:):如果 newEvenTrade 为 true(即刚发生一笔保本交易),运算符就返回一个带透明度的灰色;如果为 false,则返回 na 值,取消背景色。
当这个策略应用于图表时,你将看到代表保本交易笔数及其移动平均线的曲线,并且每当有新的保本交易平仓时,图表背景都会被染成灰色:
简单总结一下:strategy.eventrades 变量返回的是策略的保本交易总笔数。它只统计已平仓的交易,忽略当前持有的未平仓交易。策略的佣金和滑点设置会影响保本交易的数量。strategy.eventrades 在每一根K线上都返回一个累计值,这使得我们可以进行跨时间的比较,也允许其他函数利用这个序列值进行更复杂的计算。





