分析

@tradecanvas/analytics は、ポートフォリオの追跡とリスク指標のサマリー計算を備えた、 ヘッドレスでバーごとに進む戦略バックテスターを提供します。 リプレイモードと組み合わせると、チャート上で取引を可視化できます。

ライブバックテスト — SMA(10/30) クロス

365 日分の合成価格データ、初期資金 $10k、手数料 0.05%、スリッページ 0.03%。

バックテストを実行中…

↑ 365 日分の決定的な合成データで動く、SMA(10/30) クロスオーバーのライブバックテストです。 スライダーを動かすか 「再生」を押すと、エクイティカーブをバーごとに進めて確認できます。

Backtester

執行モデル:

  • 戦略関数は各バーの終値で実行されます。
  • バー N で出した注文はバー N+1 で約定します。成行注文は始値で、指値 / 逆指値注文はそのバーがトリガー価格を通過したときに約定します。
  • エクイティは毎バーの終値で評価されます。
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現在のバー。
index入力系列における bar のインデックス。
historybar を含む、それまでのすべてのバー。
position現在のポジション、または null。
cash利用可能な現金。
equity現金 + ポジションの時価評価額。
placeOrder(order)次のバーで執行する注文をキューに入れます。
close(tag?)現在のポジションを成行で決済します。
cancel(orderId)未約定の注文を取り消します。

手数料とスリッページのモデル

  • FixedCommission(perTrade)
  • PercentCommission(rate) — 想定元本に対する比率。例:0.001 = 10 bps。
  • PerShareCommission(perShare, minimum?)
  • PercentSlippage(rate) — 価格に対して不利な方向への比率。
  • RangeBasedSlippage(factor) — バーの値幅に比例します。

Portfolio

現金、1 つのネットポジション、実現損益、エクイティカーブを追跡します。

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