Package Exports
- nanuquant-ts
Readme
nanuquant-ts
Zero-dependency TypeScript library for quantitative finance. Covers return metrics, risk analysis, portfolio optimization, and backtesting.
TypeScript port of nanuquant (Python). Both libraries produce identical numerical output within tight tolerance.
Install
npm install nanuquant-tsQuick Start
import { sharpe, maxDrawdown, cagr, volatility } from 'nanuquant-ts';
const returns = [0.01, -0.02, 0.015, -0.01, 0.02];
sharpe(returns); // Sharpe ratio
maxDrawdown(returns); // Max drawdown (negative)
cagr(returns); // Compound annual growth rate
volatility(returns); // Annualized volatilityAll returns are decimal fractions: 0.01 = 1%.
Features
Core Metrics
- Returns:
comp,cagr,avgReturn,winRate,payoffRatio,profitFactor,consecutiveWins,consecutiveLosses - Risk:
volatility,varMetric,cvar,historicalVar,historicalCvar,cornishFisherVar,maxDrawdown,drawdownDetails,ulcerIndex,downsideDeviation - Performance:
sharpe,sortino,calmar,omega,greeks,informationRatio,treynorRatio,kellyCriterion - Correlation:
correlation,covariance,downsideCorrelation,upsideCorrelation,rollingCorrelation - Distribution:
skewness,kurtosis,geometricMean,outliers - Rolling:
rollingVolatility,rollingSharpe,rollingSortino,rollingBeta,rollingGreeks - Timeseries:
cumulativeReturns,yearlyReturns,monthlyReturns,histogram,periodReturns
Portfolio Optimization
- Allocation: Equal weight, inverse volatility, risk parity, Hierarchical Risk Parity (HRP)
- Covariance: Sample, Ledoit-Wolf shrinkage, EWMA
- Optimizer: Nelder-Mead simplex with softmax weight transform
- Rebalance Pipeline: 3-step allocate/constrain/drift-gate pipeline
- Backtest: Walk-forward rebalance backtester with transaction costs
- Plateau Sweep: Parameter grid search for robustness scoring
- Trust Haircut: Live vs backtest deviation scoring
- Correlation Reducer: Pairwise correlation penalties
Transfer-Adjusted Returns
- TWR: Time-Weighted Return (geometric linking across periods)
- MWR: Money-Weighted Return (IRR via Newton-Raphson)
Examples
Risk Analysis
import {
volatility, varMetric, cvar,
historicalVar, cornishFisherVar,
drawdownDetails, maxDrawdownDuration
} from 'nanuquant-ts';
const returns = [0.01, -0.03, 0.02, -0.05, 0.015, 0.008, -0.01];
volatility(returns); // Annualized vol
varMetric(returns, { confidence: 0.95 }); // Parametric VaR
cvar(returns, { confidence: 0.95 }); // Expected Shortfall
historicalVar(returns, { confidence: 0.95 }); // Empirical VaR
cornishFisherVar(returns); // Skew/kurtosis adjusted VaR
const episodes = drawdownDetails(returns); // Individual drawdown episodes
maxDrawdownDuration(returns); // Duration of worst drawdownPortfolio Optimization
import {
equalWeight, inverseVolatility, riskParity, hrp,
sampleCovMatrix, shrinkCovMatrix,
computeRebalanceWeights,
runRebalanceBacktest
} from 'nanuquant-ts';
// Strategy return series (each inner array = one strategy's returns)
const strategies = [
[0.01, -0.02, 0.015, 0.008, -0.01],
[0.005, 0.01, -0.008, 0.012, -0.003],
[-0.01, 0.02, 0.005, -0.015, 0.01],
];
// Allocation methods
equalWeight(3); // [0.333, 0.333, 0.333]
inverseVolatility(strategies); // Lower vol -> higher weight
riskParity(strategies); // Equal risk contribution
// Covariance estimation
const cov = sampleCovMatrix(strategies); // Sample covariance
const shrunk = shrinkCovMatrix(strategies); // Ledoit-Wolf
// Full rebalance pipeline
const result = computeRebalanceWeights({
returnMatrix: strategies,
method: 'risk_parity',
minWeight: 0.05,
maxWeight: 0.60,
driftThreshold: 0.05,
currentWeights: [0.33, 0.33, 0.34],
});
// Walk-forward backtest
const backtest = runRebalanceBacktest({
returnMatrix: strategies,
method: 'inverse_volatility',
rebalanceFrequency: 'weekly',
transactionCostBps: 10,
});Transfer-Adjusted Returns
import { twr, mwr } from 'nanuquant-ts';
// Time-Weighted Return
const entries = [
{ date: new Date('2024-01-01'), portfolioValue: 10000 },
{ date: new Date('2024-02-01'), portfolioValue: 10500, transfer: 1000 },
{ date: new Date('2024-03-01'), portfolioValue: 12000 },
];
twr(entries); // TWR excluding impact of cash flows
// Money-Weighted Return (IRR)
const cashFlows = [
{ date: new Date('2024-01-01'), amount: -10000 },
{ date: new Date('2024-06-01'), amount: -5000 },
{ date: new Date('2024-12-31'), amount: 16000 },
];
mwr(cashFlows); // IRR reflecting timing of flowsConfiguration
import { MetricsConfig, setConfig, resetConfig } from 'nanuquant-ts';
setConfig(new MetricsConfig({
riskFreeRate: 0.04, // 4% risk-free rate
periodsPerYear: 252, // Trading days
ddof: 1, // Sample std deviation
varConfidence: 0.95, // 95% VaR confidence
}));
// Per-call overrides always available
sharpe(returns, { riskFreeRate: 0.05, periodsPerYear: 12 });
resetConfig(); // Back to defaultsDesign Principles
- Zero dependencies -- Pure TypeScript, no external packages
- Decimal fractions -- All returns as decimals (0.01 = 1%), never percentages
- Validation first -- All functions validate inputs, drop NaN by default
- Config-driven -- Global defaults with per-call overrides
- Python parity -- Matches nanuquant Python output within tight tolerance
- Stack-safe -- Iterative algorithms avoid V8 call stack limits on large arrays
API Reference
See API.md for the complete API reference.
Acknowledgments
QuantStats by Ran Aroussi was the original inspiration. It introduced a clean API for portfolio analytics in Python and popularized many of the metric naming conventions used here. NanuQuant goes further -- full portfolio optimization, walk-forward backtesting, covariance estimation, and advanced risk metrics -- but QuantStats deserves credit for pointing the way. If you need tearsheets, that's still QuantStats' strength.
Related Projects
- nanuquant -- The original Python library (Polars-based)