跳转到内容

回测

使用 strategy() 模式在历史数据上模拟交易策略。服务端执行开仓和平仓逻辑,并返回绩效报告。

工作原理

  • 脚本声明使用 strategy(),而非 indicator()
  • 使用 strategy.entry()strategy.close()(或 strategy.exit())模拟交易
  • 使用 --format json 获取完整绩效报告
  • jq 解析报告:.data.report_json | fromjson

策略设置

strategy() 声明的常用参数及默认值:

参数默认值说明
initial_capital1000000初始资金
commission_typestrategy.commission.percent手续费计算方式
commission_value0手续费费率 / 金额(0 = 不收手续费)
slippage0每次成交的滑点(以 tick 为单位)
default_qty_typestrategy.fixed仓位大小的计量方式:strategy.fixed(合约数)、strategy.percent_of_equitystrategy.cash
default_qty_value1默认仓位大小
pyramiding0同方向最大加仓次数(0 = 同时只允许一笔)
risk_free_rate2年化无风险利率(%),用于夏普 / 索提诺计算

自定义设置示例:

pine
strategy("My Strategy",
    initial_capital    = 50000,
    commission_type    = strategy.commission.percent,
    commission_value   = 0.1,
    default_qty_type   = strategy.percent_of_equity,
    default_qty_value  = 10)

EMA 金叉策略

EMA8 上穿 EMA21 时买入;下穿时平仓。

bash
longbridge quant run NVDA.US \
  --start 2025-01-01 --end 2026-04-28 \
  --format json \
  --script '
strategy("EMA Cross", overlay=true)
fast = ta.ema(close, 8)
slow = ta.ema(close, 21)
if ta.crossover(fast, slow)
    strategy.entry("Long", strategy.long)
if ta.crossunder(fast, slow)
    strategy.close("Long")
' | jq '.data.report_json | fromjson | .performanceAll'
json
{
  "netProfit": 4231.00,
  "netProfitPercent": 42.31,
  "grossProfit": 7850.00,
  "grossLoss": 3619.00,
  "profitFactor": 2.17,
  "buyHoldReturnPercent": 31.20,
  "maxDrawdownPercent": -28.15,
  "sharpeRatio": 0.87,
  "sortinoRatio": 1.24,
  "totalClosedTrades": 18,
  "percentProfitable": 50.0,
  "avgWinningTradePercent": 8.72,
  "avgLosingTradePercent": -4.02,
  "commissionPaid": 180.00
}

RSI 均值回归策略

RSI 跌破 30(超卖)时买入;回升至 55 以上时平仓。

bash
longbridge quant run AAPL.US \
  --start 2025-01-01 --end 2026-04-28 \
  --format json \
  --script '
strategy("RSI Reversion", overlay=false)
r = ta.rsi(close, 14)
if ta.crossunder(r, 30)
    strategy.entry("Long", strategy.long)
if ta.crossover(r, 55)
    strategy.close("Long")
' | jq '.data.report_json | fromjson | .performanceAll'

报告参考

解析完整报告对象:

bash
longbridge quant run NVDA.US ... --format json --script '...' \
  | jq '.data.report_json | fromjson'

顶层结构

字段说明
performanceAll全部交易的绩效指标
performanceLong仅多头交易的绩效指标
performanceShort仅空头交易的绩效指标
closedTrades已完成交易记录数组
openTrades回测结束时的未平仓持仓数组
equityCurve每根 K 线的账户净值
drawdownCurve每根 K 线相对净值峰值的回撤
buyHoldCurve每根 K 线的买入持有基准净值
config策略配置快照

绩效指标

performanceAllperformanceLongperformanceShort 结构相同。标注仅 all 的字段在 performanceLong / performanceShort 中始终为 0 / null——它们依赖合并后的净值曲线,无法按方向拆分。

盈亏

字段说明
netProfit净利润(账户货币)
netProfitPercent净利润占初始资金的百分比
grossProfit盈利交易的总利润
grossProfitPercent总利润百分比
grossLoss亏损交易的总亏损(正数)
grossLossPercent总亏损百分比
profitFactor总利润 ÷ 总亏损
buyHoldReturn买入持有收益(账户货币)(仅 all)
buyHoldReturnPercent买入持有收益百分比 (仅 all)

回撤与上涨 (仅 all)

字段说明
maxDrawdown最大净值回撤(账户货币)
maxDrawdownPercent最大回撤百分比
maxRunup最大净值上涨(账户货币)
maxRunupPercent最大上涨百分比

风险调整收益 (仅 all)

字段说明
sharpeRatio年化夏普比率
sortinoRatio年化索提诺比率

交易统计

字段说明
totalClosedTrades已完成交易次数
totalOpenTrades回测结束时的未平仓数量
numWinningTrades盈利交易数(profit > 0)
numLosingTrades亏损交易数(profit < 0)
numEvenTrades保本交易数 (仅 all)
percentProfitable胜率(0–100)

平均交易

字段说明
avgTrade每笔交易平均盈亏
avgTradePercent每笔交易平均盈亏百分比
avgWinningTrade盈利交易的平均利润
avgWinningTradePercent盈利交易平均利润百分比
avgLosingTrade亏损交易的平均亏损
avgLosingTradePercent亏损交易平均亏损百分比
ratioAvgWinLoss平均盈利 ÷ 平均亏损
largestWinningTrade单笔最大利润
largestWinningTradePercent单笔最大利润百分比
largestLosingTrade单笔最大亏损
largestLosingTradePercent单笔最大亏损百分比

持仓时长

字段说明
avgBarsInTrades每笔交易平均持仓 K 线数
avgBarsInWinningTrades盈利交易平均持仓 K 线数
avgBarsInLosingTrades亏损交易平均持仓 K 线数

其他

字段说明
commissionPaid已付总手续费
maxContractsHeld同时持仓的峰值合约数
marginCalls触发保证金追缴次数

交易历史

closedTrades 中每条记录代表一次完整的开平仓:

字段说明
tradeNum交易编号(从 0 开始)
entrySide"Long""Short"
entryId入场指令 ID
entryPrice入场成交价
entryTime入场时间戳(Unix ms)
exitId出场指令 ID
exitPrice出场成交价
exitTime出场时间戳(Unix ms)
quantity交易合约数 / 股数
profit已实现盈亏(扣除手续费后)
profitPercent已实现盈亏百分比
cumulativeProfit含本笔交易的累计盈亏
cumulativeProfitPercent累计盈亏占初始资金的百分比
maxRunup / maxRunupPercent持仓期间最大浮盈
maxDrawdown / maxDrawdownPercent持仓期间最大浮亏
commission本笔交易手续费(入场 + 出场)
bash
# 逐笔打印交易摘要
longbridge quant run NVDA.US --start 2025-01-01 --end 2026-04-28 \
  --format json --script '...' \
  | jq -r '.data.report_json | fromjson | .closedTrades[]
    | "#\(.tradeNum) \(.entrySide)  entry=\(.entryPrice)  exit=\(.exitPrice)  P&L=\(.profitPercent)%"'

openTrades 结构相同,但无出场字段,profit 为当前浮盈亏。

净值曲线

三个平行数组,每个元素对应一根 K 线(索引 0 = 第一根):

字段说明
equityCurve每根 K 线收盘时的账户净值
drawdownCurve相对净值峰值的回撤(始终 ≥ 0)
buyHoldCurve假设买入持有的基准净值
bash
# 最终净值
jq '.data.report_json | fromjson | .equityCurve[-1]'

# 最大回撤值
jq '.data.report_json | fromjson | .drawdownCurve | max'

策略配置

config 记录 strategy() 声明中的参数:

字段说明
initialCapital初始资金
commissionTypePerContractPerTradePercentOfValue
commissionValue手续费金额
slippage滑点(以 tick 为单位)
pyramiding同方向最大加仓次数
riskFreeRate用于夏普/索提诺计算的年化无风险利率(%)

表格输出(快速预览)

不加 --format json 时,表格会显示每个绘制序列 — 适合在运行完整回测前直观检查信号时机:

bash
longbridge quant run NVDA.US \
  --start 2025-01-01 --end 2026-04-28 \
  --script '
strategy("EMA Cross", overlay=true)
fast = ta.ema(close, 8)
slow = ta.ema(close, 21)
plot(fast, "EMA8")
plot(slow, "EMA21")
if ta.crossover(fast, slow)
    strategy.entry("Long", strategy.long)
if ta.crossunder(fast, slow)
    strategy.close("Long")
'