分析
@tradecanvas/analytics 提供一个无界面、逐K线运行的策略回测器,
附带投资组合跟踪和汇总风险指标计算器。
与回放模式搭配使用,即可在图表上直观展示交易。
实时回测 — SMA(10/30) 交叉
365 天合成价格数据,初始资金 $10k,手续费 0.05%,滑点 0.03%。
正在回测…
↑ 基于 365 天确定性合成数据的 SMA(10/30) 交叉策略实时回测。 拖动滑块或点击“播放”,即可逐根K线查看权益曲线的变化。
Backtester
执行模型:
- 策略函数在每根K线收盘时运行。
- 在第 N 根K线下的订单于第 N+1 根K线成交——市价单按开盘价成交;限价单 / 止损单在K线价格穿过触发价时成交。
- 权益按每根K线的收盘价计值。
import { Backtester, FixedCommission, PercentSlippage } from '@tradecanvas/analytics'
const bt = new Backtester({
initialCash: 10_000,
commission: new FixedCommission(2),
slippage: new PercentSlippage(0.0005),
allowShort: true,
})
const result = bt.run(historicalBars, (ctx) => {
if (!ctx.position) {
ctx.placeOrder({ side: 'long', type: 'market', quantity: 1 })
} else if (ctx.bar.close > ctx.position.averagePrice * 1.02) {
ctx.close()
}
})
console.log(result.metrics.sharpe, result.metrics.maxDrawdownPct) StrategyContext
| 字段 / 方法 | 说明 |
|---|---|
bar | 当前K线。 |
index | bar 在输入序列中的索引。 |
history | 截至并包含 bar 的所有K线。 |
position | 当前持仓,或 null。 |
cash | 可用现金。 |
equity | 现金 + 按市值计价的持仓价值。 |
placeOrder(order) | 将订单排入队列,在下一根K线执行。 |
close(tag?) | 以市价平掉当前持仓。 |
cancel(orderId) | 撤销一个挂单。 |
手续费与滑点模型
FixedCommission(perTrade)PercentCommission(rate)— 名义金额的比例,例如0.001= 10 个基点。PerShareCommission(perShare, minimum?)PercentSlippage(rate)— 按价格比例计算的不利滑点。RangeBasedSlippage(factor)— 与K线的价格区间成正比。
Portfolio
跟踪现金、一个净持仓、已实现盈亏以及权益曲线。
const portfolio = new Portfolio({ initialCash: 10_000 })
portfolio.applyFill({ ... })
portfolio.mark(time, price) // record equity point
portfolio.getPosition() // → { side, quantity, averagePrice, ... } | null
portfolio.getTrades() // → closed trades
portfolio.getEquityCurve() // → equity points
portfolio.equity(price) // mark-to-market 风险指标
import { computeRiskMetrics } from '@tradecanvas/analytics'
const m = computeRiskMetrics(initialCash, equityCurve, trades, {
periodsPerYear: 252, // optional; auto-detected from timestamps
riskFreeRate: 0.03,
})
m.totalReturnPct
m.cagr
m.sharpe
m.sortino
m.calmar
m.maxDrawdownPct
m.winRate
m.profitFactor
m.expectancy 将结果中的 equityCurve 与 EquityCurveRenderer 搭配,即可可视化回测结果。
策略库
开箱即用的参考策略——每个都返回一个 StrategyFn:
import {
Backtester,
smaCrossStrategy,
rsiReversionStrategy,
donchianBreakoutStrategy,
bollingerReversionStrategy,
} from '@tradecanvas/analytics'
const bt = new Backtester({ initialCash: 10_000 })
bt.run(bars, smaCrossStrategy({ fastPeriod: 10, slowPeriod: 30 })) 蒙特卡洛模拟
将已实现交易的顺序随机打乱 N 次,以揭示路径依赖性。 稳健的优势会让 P5/P95 区间保持收敛;依赖幸运交易顺序的策略,区间则会大幅发散。
import { runMonteCarlo } from '@tradecanvas/analytics'
const result = bt.run(bars, smaCrossStrategy())
const mc = runMonteCarlo(10_000, result.trades, {
simulations: 1000,
seed: 42, // deterministic
})
mc.equityBands // per-step P5/P25/P50/P75/P95
mc.finalEquityPercentiles // { p5, p25, p50, p75, p95 }
mc.probabilityProfitable
mc.worstMaxDrawdownPct