Análisis
@tradecanvas/analytics incluye un backtester de estrategias sin
interfaz que avanza barra a barra, con seguimiento de cartera y una calculadora
de métricas de riesgo resumidas. Combínalo con el modo de repetición para ver las operaciones sobre el gráfico.
Backtest en vivo — cruce SMA(10/30)
365 días de precios sintéticos, $10k de capital inicial, comisión del 0.05%, deslizamiento del 0.03%.
↑ Backtest en vivo de un cruce SMA(10/30) sobre 365 días de datos sintéticos deterministas. Mueve el control deslizante o pulsa Reproducir para recorrer la curva de capital barra a barra.
Backtester
Modelo de ejecución:
- La función de estrategia se ejecuta al cierre de cada barra.
- Las órdenes enviadas en la barra N se ejecutan en la barra N+1: las de mercado a la apertura; las límite/stop cuando la barra atraviesa el precio de activación.
- El capital se valora al cierre de cada barra.
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
| Campo / método | Descripción |
|---|---|
bar | Barra actual. |
index | Índice de bar en la serie de entrada. |
history | Barras hasta bar, incluida. |
position | Posición actual o null. |
cash | Efectivo disponible. |
equity | Efectivo + valor de mercado de la posición. |
placeOrder(order) | Pone en cola una orden para la barra siguiente. |
close(tag?) | Cierra a mercado la posición actual. |
cancel(orderId) | Cancela una orden pendiente. |
Modelos de comisión y deslizamiento
FixedCommission(perTrade)PercentCommission(rate)— fracción del nocional, p. ej.0.001= 10 pb.PerShareCommission(perShare, minimum?)PercentSlippage(rate)— fracción adversa del precio.RangeBasedSlippage(factor)— proporcional al rango de la barra.
Cartera
Registra el efectivo, una posición neta, las ganancias y pérdidas realizadas y la curva de capital.
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 Métricas de riesgo
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 Combina el equityCurve del resultado con EquityCurveRenderer para visualizar los backtests.
Biblioteca de estrategias
Estrategias de referencia listas para usar; cada una devuelve una 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 })) Monte Carlo
Baraja N veces el orden de las operaciones realizadas para revelar la dependencia de la secuencia. Una ventaja sólida mantiene estrecha la banda P5/P95; una estrategia que depende de una secuencia afortunada se abre en abanico.
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