Pine Script策略编译正常但无回测数据,求调试指引
问题描述
首次使用Pine Script构建交易策略,参考TradingView公开策略编写,代码编译无报错,但设置参数和回测时间范围(2021.12.05-2022.01.26)后无数据返回,接触Pine Script仅5天,不知如何调试。
原代码如下:
//@version=5 // // INPUTS // Time Duration for BACKTEST fromDay = 5 fromMonth =12 fromYear = 2021 toDay = 26 toMonth =1 toYear = 2022 startDate = timestamp(fromYear, fromMonth, fromDay, 00, 00) finishDate = timestamp(toYear, toMonth, toDay, 00, 00) time_cond = time >= startDate and time <= finishDate //Trading Time //AOM=input.bool(true,'Follow',inline = "00")//,group="ENTRY EXIT TIME" ) i_sess = input.session("0000-2345", "Trading Time",inline = "00")//,group="ENTRY EXIT TIME") tradingTime = time(timeframe.period, i_sess) onMarket=false if(time == tradingTime ) onMarket:=true onMonday=input.bool(true,'Monday',inline = "01",group="TRADING DAY SETTINGS") onTuesday=input.bool(true,'Tuesday',inline = "02",group="TRADING DAY SETTINGS") onWednesday=input.bool(true,'Wednesday',inline = "03",group="TRADING DAY SETTINGS") onThursday=input.bool(true,'Thursday',inline = "04",group="TRADING DAY SETTINGS") onFriday=input.bool(true,'Friday',inline = "05",group="TRADING DAY SETTINGS") TradeToday= false if ( onMonday==true and dayofweek ==2 ) or ( onTuesday==true and dayofweek ==3 ) or ( onWednesday==true and dayofweek ==4 ) or ( onThursday==true and dayofweek ==5 ) or ( onFriday==true and dayofweek ==6 ) TradeToday:= true // === LOGIC === length = input.int(defval=14, minval=1, title='Length') longOnly = input(defval=false, title='Long Only') fast = ta.ema(50, length) slow = ta.ema(200, length) plot(fast, linewidth=2, color=color.new(color.orange, 0), title='Fast') plot(slow, linewidth=2, color=color.new(color.blue, 0), title='Slow') longEntry = ta.crossover(fast, slow) shortEntry = ta.crossunder(fast, slow) plotshape(longEntry ? close : na, style=shape.triangleup, color=color.new(color.green, 0), location=location.belowbar, size=size.small, title='Long Triangle') plotshape(shortEntry and not longOnly ? close : na, style=shape.triangledown, color=color.new(color.red, 0), location=location.abovebar, size=size.small, title='Short Triangle') plotshape(shortEntry and longOnly ? close : na, style=shape.xcross, color=color.new(color.black, 0), location=location.abovebar, size=size.small, title='Exit Sign') // LONG POSITION EXECUTION enterLong = ta.crossover(fast, slow) exitLong = longOnly and ta.crossunder(fast, slow) if (time_cond== true and enterLong and onMarket and TradeToday) strategy.entry("Long", strategy.long, comment="Long") if (exitLong) strategy.close("Long") // SHORT POSITION EXECUTION enterShort = not longOnly and ta.crossunder(fast, slow) exitShort = false if (time_cond== true and enterShort and onMarket and TradeToday) strategy.entry("Short", strategy.short) if (exitShort) strategy.close("Short")
核心问题分析
交易时段判断逻辑错误
原代码用time == tradingTime判断是否在交易时段,这个条件几乎永远不成立——time(timeframe.period, i_sess)返回的是时段内的时间戳序列,和当前K线的time直接匹配概率极低。正确的判断方式是检查当前时间是否属于指定时段,即not na(time(timeframe.period, i_sess))。EMA指标计算错误
原代码ta.ema(50, length)是把固定数值50作为数据源计算EMA,这完全不符合策略逻辑,应该用价格数据(比如close)作为输入,同时调整参数对应正确的均线周期。回测时间范围实现不规范
手动判断time_cond容易出错,建议直接用strategy()函数的fromdate和todate参数定义回测时段,更稳定可靠。
调试&修正步骤
1. 分步验证过滤条件
把time_cond、onMarket、TradeToday这些布尔变量可视化,确认它们在回测时段内是否正常触发:
// 添加以下代码到原脚本中 plot(time_cond ? 1 : 0, title="回测时段触发", color=color.purple) plot(onMarket ? 1 : 0, title="交易时段触发", color=color.yellow) plot(TradeToday ? 1 : 0, title="允许交易日期", color=color.gray)
如果某条线始终为0,说明对应条件逻辑有问题。
2. 修正核心逻辑
替换错误的EMA计算和交易时段判断,修正后的核心代码片段:
// 用strategy参数定义回测时段,替代手动time_cond判断 strategy("EMA交叉策略", overlay=true, fromdate=timestamp(2021,12,5,0,0), todate=timestamp(2022,1,26,0,0)) // 正确判断交易时段 onMarket = not na(time(timeframe.period, i_sess)) // 修正EMA计算:用收盘价作为数据源,对应正确周期 fast = ta.ema(close, 50) slow = ta.ema(close, 200)
3. 简化策略逐步排查
先去掉所有过滤条件,只保留核心开仓逻辑:
if (ta.crossover(fast, slow)) strategy.entry("Long", strategy.long)
如果此时有回测数据,再逐步添加onMarket、TradeToday等过滤条件,定位问题所在。
4. 检查品种数据有效性
确认你选择的交易品种在2021.12.05-2022.01.26时段内有完整的K线数据,避免因品种无数据导致回测无结果。
完整修正代码
//@version=5 strategy("修正后的EMA交叉策略", overlay=true, fromdate=timestamp(2021,12,5,0,0), todate=timestamp(2022,1,26,0,0)) // 交易时段设置 i_sess = input.session("0000-2345", "交易时段") onMarket = not na(time(timeframe.period, i_sess)) // 交易日期设置 onMonday=input.bool(true,'周一',inline = "01",group="交易日期设置") onTuesday=input.bool(true,'周二',inline = "02",group="交易日期设置") onWednesday=input.bool(true,'周三',inline = "03",group="交易日期设置") onThursday=input.bool(true,'周四',inline = "04",group="交易日期设置") onFriday=input.bool(true,'周五',inline = "05",group="交易日期设置") TradeToday = (onMonday and dayofweek == dayofweek.monday) or (onTuesday and dayofweek == dayofweek.tuesday) or (onWednesday and dayofweek == dayofweek.wednesday) or (onThursday and dayofweek == dayofweek.thursday) or (onFriday and dayofweek == dayofweek.friday) // 核心指标逻辑 fast = ta.ema(close, 50) slow = ta.ema(close, 200) plot(fast, linewidth=2, color=color.orange, title='快速EMA') plot(slow, linewidth=2, color=color.blue, title='慢速EMA') longEntry = ta.crossover(fast, slow) shortEntry = ta.crossunder(fast, slow) longOnly = input.bool(false, title='仅做多') plotshape(longEntry ? close : na, style=shape.triangleup, color=color.green, location=location.belowbar, size=size.small, title='做多信号') plotshape(shortEntry and not longOnly ? close : na, style=shape.triangledown, color=color.red, location=location.abovebar, size=size.small, title='做空信号') plotshape(shortEntry and longOnly ? close : na, style=shape.xcross, color=color.black, location=location.abovebar, size=size.small, title='平仓信号') // 仓位执行 enterLong = longEntry exitLong = longOnly and shortEntry if (enterLong and onMarket and TradeToday) strategy.entry("做多", strategy.long, comment="做多") if (exitLong) strategy.close("做多") enterShort = not longOnly and shortEntry if (enterShort and onMarket and TradeToday) strategy.entry("做空", strategy.short)
内容的提问来源于stack exchange,提问作者marcq

