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

如何解决Pine Script多品种策略胜率筛选器失效问题

问题诊断

你代码里的GetWinRate()函数调用的是全局的strategy.wintrades和strategy.closedtrades,这两个变量统计的是整个策略的所有交易数据,不是单个品种的。因为你在getsymbolRate里执行的所有交易操作都会被合并到主策略的交易记录中,所以每个品种返回的胜率其实是同一个全局值,无法区分单个品种的胜负情况。

解决方案

需要为每个品种单独维护交易统计变量,在每个品种的逻辑里自行记录盈利交易数、总平仓交易数,而不是依赖全局的策略变量。以下是修改后的完整代码:

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © amjupvc1234

//@version=5
strategy("Table", overlay=true)

// 自定义胜率计算,基于每个品种的本地统计
GetWinRate(winCount, closedCount, includeEvens = false) =>
    winTradeCount = winCount + (includeEvens ? 0 : 0) // 这里可根据需求添加平盘统计
    closedCount > 0 ? (winTradeCount / closedCount) * 100 : na

ATRCalc(length,highcalc,lowcalc,closecalc) =>
    trueRange = na(highcalc[1])? highcalc-lowcalc : math.max(math.max(highcalc - lowcalc, math.abs(highcalc - closecalc[1])), math.abs(lowcalc - closecalc[1]))
    ta.rma(trueRange, length)
    
getsymbolRate(symbol) =>
    // 为当前品种初始化本地统计变量
    var int winCount = 0
    var int closedCount = 0
    var float prevPositionSize = 0

    CloseSym = request.security("BINANCE:"+symbol+".P","60", close)
    OpenSym = request.security("BINANCE:"+symbol+".P","60", open)
    LowSym = request.security("BINANCE:"+symbol+".P","60", low)
    HighSym = request.security("BINANCE:"+symbol+".P","60", high)
    [BBMID, BBUP, BBDOWN] = ta.bb(CloseSym, 20, 2)
    RSI = ta.rsi(CloseSym, 14)
    ATR = ATRCalc(14,HighSym,LowSym,CloseSym)
    longCondition = CloseSym > BBMID and OpenSym < BBMID and RSI > 52
    var float TakeProfit = na
    var float StopLoss = na
    var bool PositionOpen = false

    // 跟踪交易平仓并统计胜负
    currentPosition = strategy.position_size
    if prevPositionSize != 0 and currentPosition == 0
        closedCount += 1
        // 判断这笔交易是否盈利
        if strategy.closedtrades.profit(strategy.closedtrades - 1) > 0
            winCount += 1
    prevPositionSize := currentPosition

    if longCondition and not PositionOpen
        Low = LowSym
        Close = CloseSym
        STOPPRICE = Low - ATR
        StopLoss := STOPPRICE
        SLPCT = ((Close - STOPPRICE) * 100) / STOPPRICE
        TPPCT = SLPCT * 2
        PROFITPRICE = Close
        PROFITPRICE += PROFITPRICE * TPPCT / 100
        TakeProfit := PROFITPRICE
        strategy.entry(symbol + "_Entry", strategy.long) // 为每个品种的订单添加唯一标识
        PositionOpen := true
    if PositionOpen
        strategy.exit(symbol + "_Exit", symbol + "_Entry", stop=StopLoss, limit=TakeProfit)
    if strategy.position_size == 0
        PositionOpen := false

    winrateSym = GetWinRate(winCount, closedCount)
    winrateSym

BTCUSDT = getsymbolRate("BTCUSDT")
ADAUSDT = getsymbolRate("ADAUSDT")
DOTUSDT = getsymbolRate("DOTUSDT")
INCHUSDT = getsymbolRate("1INCHUSDT")

var tbl = table.new(position.top_right, 6, 11, frame_color=#151715, frame_width=1, border_width=2, border_color=color.new(color.white, 100))
if barstate.islastconfirmedhistory or barstate.isrealtime
    table.clear(tbl, 0, 0, 5, 10)
    table.cell(tbl, 0, 0, 'SYMBOL',     text_halign = text.align_center, bgcolor = color.rgb(252, 252, 252), text_color = color.rgb(3, 3, 3), text_size = size.small)
    table.cell(tbl, 1, 0, 'WINRATE%',      text_halign = text.align_center, bgcolor = color.rgb(255, 255, 255), text_color = color.rgb(0, 0, 0), text_size = size.small)
    table.cell(tbl, 3, 0, 'PNL',        text_halign = text.align_center, bgcolor = color.rgb(255, 255, 255), text_color = color.rgb(7, 7, 7), text_size = size.small)
    
    // BTCUSDT行
    table.cell(tbl,0,1,"BTCUSDT",text_halign = text.align_center, bgcolor = color.rgb(239, 255, 67), text_color = color.rgb(0, 0, 0), text_size = size.small)
    if not na(BTCUSDT) and BTCUSDT >= 50
        table.cell(tbl,1,1,str.tostring(BTCUSDT,"0.00"),text_halign = text.align_center, bgcolor = color.rgb(101, 255, 74), text_color = color.rgb(3, 3, 3), text_size = size.small)
    else
        table.cell(tbl,1,1,na(BTCUSDT) ? "N/A" : str.tostring(BTCUSDT,"0.00"),text_halign = text.align_center, bgcolor = color.rgb(255, 74, 74), text_color = color.rgb(255, 255, 255), text_size = size.small)
    
    // ADAUSDT行
    table.cell(tbl,0,2,"ADAUSDT",text_halign = text.align_center, bgcolor = color.rgb(239, 255, 67), text_color = color.rgb(0, 0, 0), text_size = size.small)
    if not na(ADAUSDT) and ADAUSDT >= 50
        table.cell(tbl,1,2,str.tostring(ADAUSDT,"0.00"),text_halign = text.align_center, bgcolor = color.rgb(101, 255, 74), text_color = color.rgb(3, 3, 3), text_size = size.small)
    else
        table.cell(tbl,1,2,na(ADAUSDT) ? "N/A" : str.tostring(ADAUSDT,"0.00"),text_halign = text.align_center, bgcolor = color.rgb(255, 74, 74), text_color = color.rgb(255, 255, 255), text_size = size.small)
    
    // DOTUSDT行
    table.cell(tbl,0,3,"DOTUSDT",text_halign = text.align_center, bgcolor = color.rgb(239, 255, 67), text_color = color.rgb(0, 0, 0), text_size = size.small)
    if not na(DOTUSDT) and DOTUSDT >= 50
        table.cell(tbl,1,3,str.tostring(DOTUSDT,"0.00"),text_halign = text.align_center, bgcolor = color.rgb(101, 255, 74), text_color = color.rgb(3, 3, 3), text_size = size.small)
    else
        table.cell(tbl,1,3,na(DOTUSDT) ? "N/A" : str.tostring(DOTUSDT,"0.00"),text_halign = text.align_center, bgcolor = color.rgb(255, 74, 74), text_color = color.rgb(255, 255, 255), text_size = size.small)
    
    // 1INCHUSDT行
    table.cell(tbl,0,4,"1INCHUSDT",text_halign = text.align_center, bgcolor = color.rgb(239, 255, 67), text_color = color.rgb(0, 0, 0), text_size = size.small)
    if not na(INCHUSDT) and INCHUSDT >= 50
        table.cell(tbl,1,4,str.tostring(INCHUSDT,"0.00"),text_halign = text.align_center, bgcolor = color.rgb(101, 255, 74), text_color = color.rgb(3, 3, 3), text_size = size.small)
    else
        table.cell(tbl,1,4,na(INCHUSDT) ? "N/A" : str.tostring(INCHUSDT,"0.00"),text_halign = text.align_center, bgcolor = color.rgb(255, 74, 74), text_color = color.rgb(255, 255, 255), text_size = size.small)
关键修改点说明
  • 本地交易统计:在getsymbolRate函数内添加了winCount和closedCount变量,单独统计当前品种的盈利交易数和总平仓交易数。
  • 订单唯一标识:为每个品种的entry和exit订单添加了symbol + "_"前缀,避免不同品种的订单互相干扰。
  • 平仓胜负判断:通过跟踪prevPositionSize和currentPosition的变化,检测交易平仓事件,然后通过strategy.closedtrades.profit判断这笔交易是否盈利,更新对应品种的统计数据。
  • 空值处理:在表格显示时添加了na判断,避免无交易时显示错误数值。

内容的提问来源于stack exchange,提问作者Welder Pasha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 15:27:50