tensorquantlib 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. tensorquantlib/__init__.py +313 -0
  2. tensorquantlib/__main__.py +315 -0
  3. tensorquantlib/backtest/__init__.py +48 -0
  4. tensorquantlib/backtest/engine.py +240 -0
  5. tensorquantlib/backtest/metrics.py +320 -0
  6. tensorquantlib/backtest/strategy.py +348 -0
  7. tensorquantlib/core/__init__.py +6 -0
  8. tensorquantlib/core/ops.py +70 -0
  9. tensorquantlib/core/second_order.py +465 -0
  10. tensorquantlib/core/tensor.py +928 -0
  11. tensorquantlib/data/__init__.py +16 -0
  12. tensorquantlib/data/market.py +160 -0
  13. tensorquantlib/finance/__init__.py +52 -0
  14. tensorquantlib/finance/american.py +263 -0
  15. tensorquantlib/finance/basket.py +291 -0
  16. tensorquantlib/finance/black_scholes.py +219 -0
  17. tensorquantlib/finance/credit.py +199 -0
  18. tensorquantlib/finance/exotics.py +885 -0
  19. tensorquantlib/finance/fx.py +204 -0
  20. tensorquantlib/finance/greeks.py +133 -0
  21. tensorquantlib/finance/heston.py +543 -0
  22. tensorquantlib/finance/implied_vol.py +277 -0
  23. tensorquantlib/finance/ir_derivatives.py +203 -0
  24. tensorquantlib/finance/jump_diffusion.py +203 -0
  25. tensorquantlib/finance/local_vol.py +146 -0
  26. tensorquantlib/finance/rates.py +381 -0
  27. tensorquantlib/finance/risk.py +344 -0
  28. tensorquantlib/finance/variance_reduction.py +420 -0
  29. tensorquantlib/finance/volatility.py +355 -0
  30. tensorquantlib/py.typed +0 -0
  31. tensorquantlib/tt/__init__.py +43 -0
  32. tensorquantlib/tt/decompose.py +576 -0
  33. tensorquantlib/tt/ops.py +386 -0
  34. tensorquantlib/tt/pricing.py +304 -0
  35. tensorquantlib/tt/surrogate.py +634 -0
  36. tensorquantlib/utils/__init__.py +5 -0
  37. tensorquantlib/utils/validation.py +126 -0
  38. tensorquantlib/viz/__init__.py +27 -0
  39. tensorquantlib/viz/plots.py +331 -0
  40. tensorquantlib-0.3.0.dist-info/METADATA +602 -0
  41. tensorquantlib-0.3.0.dist-info/RECORD +44 -0
  42. tensorquantlib-0.3.0.dist-info/WHEEL +5 -0
  43. tensorquantlib-0.3.0.dist-info/licenses/LICENSE +21 -0
  44. tensorquantlib-0.3.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,313 @@
1
+ """TensorQuantLib — Tensor-Train surrogate pricing engine with autodiff."""
2
+
3
+ __version__ = "0.3.0"
4
+ __author__ = "TensorQuantLib Contributors"
5
+
6
+ # ── Core autograd ───────────────────────────────────────────────────
7
+ from tensorquantlib.core.tensor import (
8
+ Tensor,
9
+ tensor_sin,
10
+ tensor_cos,
11
+ tensor_tanh,
12
+ tensor_abs,
13
+ tensor_clip,
14
+ tensor_where,
15
+ tensor_softmax,
16
+ )
17
+
18
+ # ── Second-order autodiff ───────────────────────────────────────────
19
+ from tensorquantlib.core.second_order import (
20
+ hvp,
21
+ hessian,
22
+ hessian_diag,
23
+ vhp,
24
+ mixed_partial,
25
+ gamma_autograd,
26
+ vanna_autograd,
27
+ volga_autograd,
28
+ second_order_greeks,
29
+ )
30
+
31
+ # ── Finance — Black-Scholes ─────────────────────────────────────────
32
+ from tensorquantlib.finance.black_scholes import (
33
+ bs_delta,
34
+ bs_gamma,
35
+ bs_price_numpy,
36
+ bs_price_tensor,
37
+ bs_rho,
38
+ bs_theta,
39
+ bs_vega,
40
+ )
41
+
42
+ # ── Finance — Implied Volatility ────────────────────────────────────
43
+ from tensorquantlib.finance.implied_vol import (
44
+ implied_vol,
45
+ implied_vol_batch,
46
+ implied_vol_nr,
47
+ iv_surface,
48
+ )
49
+
50
+ # ── Finance — Heston Model ──────────────────────────────────────────
51
+ from tensorquantlib.finance.heston import (
52
+ HestonParams,
53
+ HestonCalibrator,
54
+ heston_price,
55
+ heston_price_mc,
56
+ heston_greeks,
57
+ )
58
+
59
+ # ── Finance — American Options (LSM) ───────────────────────────────
60
+ from tensorquantlib.finance.american import (
61
+ american_option_lsm,
62
+ american_option_grid,
63
+ american_greeks,
64
+ )
65
+
66
+ # ── Finance — Exotic Options ────────────────────────────────────────
67
+ from tensorquantlib.finance.exotics import (
68
+ asian_price_mc,
69
+ asian_geometric_price,
70
+ digital_price,
71
+ digital_price_mc,
72
+ digital_greeks,
73
+ barrier_price,
74
+ barrier_price_mc,
75
+ lookback_fixed_analytic,
76
+ lookback_floating_analytic,
77
+ lookback_price_mc,
78
+ cliquet_price_mc,
79
+ rainbow_price_mc,
80
+ )
81
+
82
+ # ── Finance — Volatility Surface Models ─────────────────────────────
83
+ from tensorquantlib.finance.volatility import (
84
+ sabr_implied_vol,
85
+ sabr_calibrate,
86
+ svi_raw,
87
+ svi_implied_vol,
88
+ svi_calibrate,
89
+ svi_surface,
90
+ )
91
+
92
+ # ── Finance — Interest Rate Models ──────────────────────────────────
93
+ from tensorquantlib.finance.rates import (
94
+ vasicek_bond_price,
95
+ vasicek_yield,
96
+ vasicek_option_price,
97
+ vasicek_simulate,
98
+ cir_bond_price,
99
+ cir_yield,
100
+ cir_simulate,
101
+ feller_condition,
102
+ nelson_siegel,
103
+ nelson_siegel_calibrate,
104
+ bootstrap_yield_curve,
105
+ )
106
+
107
+ # ── Finance — FX Options ────────────────────────────────────────────
108
+ from tensorquantlib.finance.fx import (
109
+ garman_kohlhagen,
110
+ gk_greeks,
111
+ fx_forward,
112
+ quanto_option,
113
+ )
114
+
115
+ # ── Finance — Credit Risk ───────────────────────────────────────────
116
+ from tensorquantlib.finance.credit import (
117
+ merton_default_prob,
118
+ merton_credit_spread,
119
+ survival_probability,
120
+ hazard_rate_from_spread,
121
+ cds_spread,
122
+ cds_price,
123
+ )
124
+
125
+ # ── Finance — Variance Reduction ────────────────────────────────────
126
+ from tensorquantlib.finance.variance_reduction import (
127
+ bs_price_antithetic,
128
+ asian_price_cv,
129
+ bs_price_qmc,
130
+ bs_price_importance,
131
+ bs_price_stratified,
132
+ compare_variance_reduction,
133
+ )
134
+
135
+ # ── Finance — Risk Metrics ──────────────────────────────────────────
136
+ from tensorquantlib.finance.risk import (
137
+ PortfolioRisk,
138
+ OptionPosition,
139
+ var_parametric,
140
+ var_historical,
141
+ var_mc,
142
+ cvar,
143
+ scenario_analysis,
144
+ greeks_portfolio,
145
+ )
146
+
147
+ # ── Finance — Jump-Diffusion Models ─────────────────────────────────
148
+ from tensorquantlib.finance.jump_diffusion import (
149
+ merton_jump_price,
150
+ merton_jump_price_mc,
151
+ kou_jump_price_mc,
152
+ )
153
+
154
+ # ── Finance — Local Volatility ──────────────────────────────────────
155
+ from tensorquantlib.finance.local_vol import (
156
+ dupire_local_vol,
157
+ local_vol_mc,
158
+ )
159
+
160
+ # ── Finance — IR Derivatives (Black76) ──────────────────────────────
161
+ from tensorquantlib.finance.ir_derivatives import (
162
+ black76_caplet,
163
+ black76_floorlet,
164
+ cap_price,
165
+ floor_price,
166
+ swap_rate,
167
+ swaption_price,
168
+ swaption_parity,
169
+ )
170
+
171
+ # ── Finance — Basket & Greeks ───────────────────────────────────────
172
+ from tensorquantlib.finance.basket import (
173
+ build_pricing_grid,
174
+ build_pricing_grid_analytic,
175
+ simulate_basket,
176
+ )
177
+ from tensorquantlib.finance.greeks import compute_greeks, compute_greeks_vectorized
178
+
179
+ # ── TT Compression ──────────────────────────────────────────────────
180
+ from tensorquantlib.tt.decompose import tt_round, tt_svd, tt_cross
181
+ from tensorquantlib.tt.ops import (
182
+ tt_add,
183
+ tt_compression_ratio,
184
+ tt_dot,
185
+ tt_error,
186
+ tt_eval,
187
+ tt_eval_batch,
188
+ tt_frobenius_norm,
189
+ tt_hadamard,
190
+ tt_memory,
191
+ tt_ranks,
192
+ tt_scale,
193
+ tt_to_full,
194
+ )
195
+ from tensorquantlib.tt.surrogate import TTSurrogate
196
+ from tensorquantlib.tt.pricing import (
197
+ heston_surrogate,
198
+ american_surrogate,
199
+ exotic_surrogate,
200
+ jump_diffusion_surrogate,
201
+ )
202
+
203
+ # ── Visualization ────────────────────────────────────────────────────
204
+ from tensorquantlib.viz import plot_greeks_surface, plot_pricing_surface, plot_tt_ranks
205
+
206
+ # ── Backtesting ──────────────────────────────────────────────────────
207
+ from tensorquantlib.backtest import (
208
+ BacktestEngine,
209
+ BacktestResult,
210
+ SlippageModel,
211
+ CommissionModel,
212
+ ZERO_COST,
213
+ EQUITY_COMM,
214
+ FX_COMM,
215
+ EQUITY_SLIP,
216
+ ILLIQUID_SLIP,
217
+ Strategy,
218
+ Trade,
219
+ DeltaHedgeStrategy,
220
+ GammaScalpingStrategy,
221
+ DeltaGammaHedgeStrategy,
222
+ StraddleStrategy,
223
+ sharpe_ratio,
224
+ max_drawdown,
225
+ sortino_ratio,
226
+ win_rate,
227
+ profit_factor,
228
+ annualized_return,
229
+ calmar_ratio,
230
+ information_ratio,
231
+ turnover,
232
+ hedge_pnl_attribution,
233
+ hedge_efficiency,
234
+ )
235
+
236
+ __all__ = [
237
+ # Core
238
+ "Tensor",
239
+ "tensor_sin", "tensor_cos", "tensor_tanh", "tensor_abs",
240
+ "tensor_clip", "tensor_where", "tensor_softmax",
241
+ # Black-Scholes
242
+ "bs_price_numpy", "bs_price_tensor",
243
+ "bs_delta", "bs_gamma", "bs_vega", "bs_theta", "bs_rho",
244
+ # Implied volatility
245
+ "implied_vol", "implied_vol_batch", "implied_vol_nr", "iv_surface",
246
+ # Heston
247
+ "HestonParams", "HestonCalibrator",
248
+ "heston_price", "heston_price_mc", "heston_greeks",
249
+ # American options
250
+ "american_option_lsm", "american_option_grid", "american_greeks",
251
+ # Exotics
252
+ "asian_price_mc", "asian_geometric_price",
253
+ "digital_price", "digital_price_mc", "digital_greeks",
254
+ "barrier_price", "barrier_price_mc",
255
+ "lookback_fixed_analytic", "lookback_floating_analytic", "lookback_price_mc",
256
+ "cliquet_price_mc", "rainbow_price_mc",
257
+ # Volatility surface
258
+ "sabr_implied_vol", "sabr_calibrate",
259
+ "svi_raw", "svi_implied_vol", "svi_calibrate", "svi_surface",
260
+ # Interest rates
261
+ "vasicek_bond_price", "vasicek_yield", "vasicek_option_price", "vasicek_simulate",
262
+ "cir_bond_price", "cir_yield", "cir_simulate", "feller_condition",
263
+ "nelson_siegel", "nelson_siegel_calibrate", "bootstrap_yield_curve",
264
+ # FX options
265
+ "garman_kohlhagen", "gk_greeks", "fx_forward", "quanto_option",
266
+ # Credit risk
267
+ "merton_default_prob", "merton_credit_spread",
268
+ "survival_probability", "hazard_rate_from_spread",
269
+ "cds_spread", "cds_price",
270
+ # Variance reduction
271
+ "bs_price_antithetic", "asian_price_cv", "bs_price_qmc",
272
+ "bs_price_importance", "bs_price_stratified", "compare_variance_reduction",
273
+ # Risk
274
+ "PortfolioRisk", "OptionPosition",
275
+ "var_parametric", "var_historical", "var_mc", "cvar",
276
+ "scenario_analysis", "greeks_portfolio",
277
+ # Jump-diffusion
278
+ "merton_jump_price", "merton_jump_price_mc", "kou_jump_price_mc",
279
+ # Local volatility
280
+ "dupire_local_vol", "local_vol_mc",
281
+ # IR derivatives
282
+ "black76_caplet", "black76_floorlet", "cap_price", "floor_price",
283
+ "swap_rate", "swaption_price", "swaption_parity",
284
+ # Basket & Greeks
285
+ "simulate_basket", "build_pricing_grid", "build_pricing_grid_analytic",
286
+ "compute_greeks", "compute_greeks_vectorized",
287
+ # Second-order autodiff
288
+ "hvp", "hessian", "hessian_diag", "vhp", "mixed_partial",
289
+ "gamma_autograd", "vanna_autograd", "volga_autograd", "second_order_greeks",
290
+ # TT compression
291
+ "TTSurrogate",
292
+ "tt_svd", "tt_round", "tt_cross",
293
+ "tt_eval", "tt_eval_batch", "tt_to_full",
294
+ "tt_ranks", "tt_memory", "tt_error", "tt_compression_ratio",
295
+ "tt_add", "tt_scale", "tt_hadamard", "tt_dot", "tt_frobenius_norm",
296
+ # TT-accelerated pricers
297
+ "heston_surrogate", "american_surrogate",
298
+ "exotic_surrogate", "jump_diffusion_surrogate",
299
+ # Visualization
300
+ "plot_pricing_surface", "plot_greeks_surface", "plot_tt_ranks",
301
+ # Backtesting — engine
302
+ "BacktestEngine", "BacktestResult",
303
+ "SlippageModel", "CommissionModel",
304
+ "ZERO_COST", "EQUITY_COMM", "FX_COMM", "EQUITY_SLIP", "ILLIQUID_SLIP",
305
+ # Backtesting — strategies
306
+ "Strategy", "Trade",
307
+ "DeltaHedgeStrategy", "GammaScalpingStrategy",
308
+ "DeltaGammaHedgeStrategy", "StraddleStrategy",
309
+ # Backtesting — metrics
310
+ "sharpe_ratio", "max_drawdown", "sortino_ratio", "win_rate", "profit_factor",
311
+ "annualized_return", "calmar_ratio", "information_ratio", "turnover",
312
+ "hedge_pnl_attribution", "hedge_efficiency",
313
+ ]
@@ -0,0 +1,315 @@
1
+ """
2
+ Command-line interface for TensorQuantLib.
3
+
4
+ Usage examples::
5
+
6
+ # European option pricing
7
+ python -m tensorquantlib price --S 100 --K 100 --T 1 --r 0.05 --sigma 0.2
8
+
9
+ # Implied volatility
10
+ python -m tensorquantlib iv --price 10.45 --S 100 --K 100 --T 1 --r 0.05
11
+
12
+ # American option (LSM)
13
+ python -m tensorquantlib american --S 100 --K 100 --T 1 --r 0.05 --sigma 0.2
14
+
15
+ # Heston model price
16
+ python -m tensorquantlib heston --S 100 --K 100 --T 1 --r 0.05 --kappa 2 --theta 0.04 --xi 0.3 --rho -0.7 --v0 0.04
17
+
18
+ # Asian option
19
+ python -m tensorquantlib asian --S 100 --K 100 --T 1 --r 0.05 --sigma 0.2
20
+
21
+ # Barrier option
22
+ python -m tensorquantlib barrier --S 100 --K 100 --T 1 --r 0.05 --sigma 0.2 --barrier 90 --barrier-type down-and-out
23
+
24
+ # Portfolio risk
25
+ python -m tensorquantlib risk --sigma 0.20 --horizon 1 --alpha 0.95
26
+
27
+ # VaR comparison methods
28
+ python -m tensorquantlib compare-vr --S 100 --K 100 --T 1 --r 0.05 --sigma 0.2
29
+ """
30
+
31
+ from __future__ import annotations
32
+
33
+ import argparse
34
+ import sys
35
+ from typing import NoReturn
36
+
37
+
38
+ def _print_table(rows: list[tuple[str, str]]) -> None:
39
+ """Print a two-column table."""
40
+ if not rows:
41
+ return
42
+ w = max(len(r[0]) for r in rows) + 2
43
+ print("-" * (w + 20))
44
+ for k, v in rows:
45
+ print(f" {k:<{w}}{v}")
46
+ print("-" * (w + 20))
47
+
48
+
49
+ def cmd_price(args: argparse.Namespace) -> None:
50
+ """European Black-Scholes pricing."""
51
+ from tensorquantlib.finance.black_scholes import (
52
+ bs_price_numpy, bs_delta, bs_gamma, bs_vega, bs_theta, bs_rho,
53
+ )
54
+ price = bs_price_numpy(args.S, args.K, args.T, args.r, args.sigma, q=args.q, option_type=args.type)
55
+ delta = bs_delta(args.S, args.K, args.T, args.r, args.sigma, q=args.q, option_type=args.type)
56
+ gamma = bs_gamma(args.S, args.K, args.T, args.r, args.sigma, q=args.q)
57
+ vega = bs_vega(args.S, args.K, args.T, args.r, args.sigma, q=args.q)
58
+ theta = bs_theta(args.S, args.K, args.T, args.r, args.sigma, q=args.q, option_type=args.type)
59
+ rho = bs_rho(args.S, args.K, args.T, args.r, args.sigma, q=args.q, option_type=args.type)
60
+
61
+ print(f"\nBlack-Scholes European {args.type.upper()}")
62
+ _print_table([
63
+ ("S", f"{args.S:.4f}"),
64
+ ("K", f"{args.K:.4f}"),
65
+ ("T", f"{args.T:.4f} yr"),
66
+ ("r", f"{args.r:.4%}"),
67
+ ("sigma", f"{args.sigma:.4%}"),
68
+ ("q", f"{args.q:.4%}"),
69
+ ("Price", f"{float(price):.6f}"),
70
+ ("Delta", f"{float(delta):.6f}"),
71
+ ("Gamma", f"{float(gamma):.6f}"),
72
+ ("Vega", f"{float(vega):.6f}"),
73
+ ("Theta", f"{float(theta):.6f}"),
74
+ ("Rho", f"{float(rho):.6f}"),
75
+ ])
76
+
77
+
78
+ def cmd_iv(args: argparse.Namespace) -> None:
79
+ """Implied volatility inversion."""
80
+ from tensorquantlib.finance.implied_vol import implied_vol_nr
81
+ try:
82
+ iv = implied_vol_nr(args.price, args.S, args.K, args.T, args.r, q=args.q, option_type=args.type)
83
+ print(f"\nImplied Volatility: {iv:.6f} ({iv*100:.2f}%)")
84
+ except ValueError as e:
85
+ print(f"\nError: {e}", file=sys.stderr)
86
+ sys.exit(1)
87
+
88
+
89
+ def cmd_american(args: argparse.Namespace) -> None:
90
+ """American option pricing via Longstaff-Schwartz LSM."""
91
+ from tensorquantlib.finance.american import american_option_lsm
92
+ price, stderr = american_option_lsm(
93
+ args.S, args.K, args.T, args.r, args.sigma, q=args.q,
94
+ option_type=args.type, n_paths=args.paths, n_steps=args.steps,
95
+ seed=args.seed, return_stderr=True,
96
+ )
97
+ print(f"\nAmerican LSM {args.type.upper()}")
98
+ _print_table([
99
+ ("Price", f"{price:.6f}"),
100
+ ("StdErr", f"{stderr:.6f}"),
101
+ ("n_paths", f"{args.paths:,}"),
102
+ ("n_steps", f"{args.steps}"),
103
+ ])
104
+
105
+
106
+ def cmd_heston(args: argparse.Namespace) -> None:
107
+ """Heston stochastic volatility pricing."""
108
+ from tensorquantlib.finance.heston import HestonParams, heston_price, heston_greeks
109
+ params = HestonParams(kappa=args.kappa, theta=args.theta, xi=args.xi, rho=args.rho, v0=args.v0)
110
+ price = heston_price(args.S, args.K, args.T, args.r, params, q=args.q, option_type=args.type)
111
+ greeks = heston_greeks(args.S, args.K, args.T, args.r, params, q=args.q, option_type=args.type)
112
+ print(f"\nHeston Model {args.type.upper()}")
113
+ print(f"Feller condition: {'satisfied' if params.feller_satisfied() else 'VIOLATED (possible instability)'}")
114
+ _print_table([
115
+ ("Price", f"{price:.6f}"),
116
+ ("Delta", f"{greeks['delta']:.6f}"),
117
+ ("Gamma", f"{greeks['gamma']:.6f}"),
118
+ ("Theta", f"{greeks['theta']:.6f}"),
119
+ ("Vega", f"{greeks['vega']:.6f} (per unit v0)"),
120
+ ])
121
+
122
+
123
+ def cmd_asian(args: argparse.Namespace) -> None:
124
+ """Asian option pricing."""
125
+ from tensorquantlib.finance.exotics import asian_price_mc, asian_geometric_price
126
+ price_mc, stderr = asian_price_mc(
127
+ args.S, args.K, args.T, args.r, args.sigma, q=args.q,
128
+ option_type=args.type, average_type=args.avg,
129
+ n_paths=args.paths, n_steps=args.steps, seed=args.seed, return_stderr=True,
130
+ )
131
+ print(f"\nAsian {args.avg.capitalize()} Average {args.type.upper()}")
132
+ _print_table([
133
+ ("MC Price", f"{price_mc:.6f}"),
134
+ ("MC StdErr", f"{stderr:.6f}"),
135
+ ])
136
+ if args.avg == "geometric":
137
+ analytic = asian_geometric_price(args.S, args.K, args.T, args.r, args.sigma, q=args.q, option_type=args.type)
138
+ print(f" {'Analytic Geo:':<20}{analytic:.6f}")
139
+
140
+
141
+ def cmd_barrier(args: argparse.Namespace) -> None:
142
+ """Barrier option pricing."""
143
+ from tensorquantlib.finance.exotics import barrier_price, barrier_price_mc
144
+ try:
145
+ analytic = barrier_price(args.S, args.K, args.T, args.r, args.sigma,
146
+ args.barrier, args.barrier_type, q=args.q,
147
+ option_type=args.type)
148
+ except Exception:
149
+ analytic = float("nan")
150
+ mc, stderr = barrier_price_mc(
151
+ args.S, args.K, args.T, args.r, args.sigma,
152
+ args.barrier, args.barrier_type, q=args.q,
153
+ option_type=args.type, n_paths=args.paths, n_steps=args.steps,
154
+ seed=args.seed, return_stderr=True,
155
+ )
156
+ print(f"\nBarrier Option [{args.barrier_type}] {args.type.upper()}")
157
+ _print_table([
158
+ ("Barrier", f"{args.barrier:.2f}"),
159
+ ("Analytic", f"{analytic:.6f}"),
160
+ ("MC Price", f"{mc:.6f}"),
161
+ ("MC StdErr",f"{stderr:.6f}"),
162
+ ])
163
+
164
+
165
+ def cmd_risk(args: argparse.Namespace) -> None:
166
+ """Portfolio risk metrics — VaR, CVaR, Sharpe."""
167
+ from tensorquantlib.finance.risk import var_parametric, var_mc, PortfolioRisk
168
+ import numpy as np
169
+
170
+ print(f"\nRisk Metrics (S={args.S}, sigma={args.sigma:.1%}, alpha={args.alpha:.0%}, horizon={int(args.horizon)}d)")
171
+ var_p = var_parametric(0.0, args.sigma, alpha=args.alpha, horizon=args.horizon / 252.0)
172
+ var_v, cvar_v = var_mc(args.S, args.sigma, horizon=args.horizon / 252.0, alpha=args.alpha,
173
+ n_paths=100_000, seed=42)
174
+ _print_table([
175
+ ("Param VaR (1d)", f"{var_p * args.S:.4f} ({var_p:.4%} of S)"),
176
+ ("MC VaR", f"{var_v * args.S:.4f} ({var_v:.4%} of S)"),
177
+ ("MC CVaR (ES)", f"{cvar_v * args.S:.4f} ({cvar_v:.4%} of S)"),
178
+ ])
179
+
180
+ # Simulate a return history and report portfolio-level stats
181
+ rng = np.random.default_rng(42)
182
+ ret_hist = rng.normal(0.0, args.sigma / np.sqrt(252), 252)
183
+ pr = PortfolioRisk(ret_hist, alpha=args.alpha)
184
+ stats = pr.summary()
185
+ print("\n Simulated 1-year daily return history:")
186
+ _print_table([(k, f"{v:.4f}") for k, v in stats.items()])
187
+
188
+
189
+ def cmd_compare_vr(args: argparse.Namespace) -> None:
190
+ """Compare variance reduction methods."""
191
+ from tensorquantlib.finance.variance_reduction import compare_variance_reduction
192
+ results = compare_variance_reduction(
193
+ args.S, args.K, args.T, args.r, args.sigma, n_paths=args.paths, seed=42,
194
+ )
195
+ print(f"\nVariance Reduction Comparison ({args.type.upper()} S={args.S} K={args.K} T={args.T})")
196
+ print(f" {'Method':<25} {'Price':>10} {'StdErr':>12} {'VR Ratio':>10}")
197
+ print(" " + "-" * 60)
198
+ for name, res in results.items():
199
+ print(f" {name:<25} {res['price']:>10.5f} {res['stderr']:>12.6f} {res['vr_ratio']:>10.2f}x")
200
+
201
+
202
+ def build_parser() -> argparse.ArgumentParser:
203
+ """Construct the CLI argument parser."""
204
+ parser = argparse.ArgumentParser(
205
+ prog="python -m tensorquantlib",
206
+ description="TensorQuantLib — quantitative finance toolkit CLI",
207
+ formatter_class=argparse.RawDescriptionHelpFormatter,
208
+ epilog=__doc__,
209
+ )
210
+ sub = parser.add_subparsers(dest="command", metavar="COMMAND")
211
+
212
+ # ---- shared arguments ----
213
+ def add_bs_args(p: argparse.ArgumentParser) -> None:
214
+ p.add_argument("--S", type=float, required=True, help="Spot price")
215
+ p.add_argument("--K", type=float, required=True, help="Strike")
216
+ p.add_argument("--T", type=float, required=True, help="Time to expiry (years)")
217
+ p.add_argument("--r", type=float, required=True, help="Risk-free rate")
218
+ p.add_argument("--sigma", type=float, required=True, help="Volatility")
219
+ p.add_argument("--q", type=float, default=0.0, help="Dividend yield (default 0)")
220
+ p.add_argument("--type", choices=["call", "put"], default="call")
221
+
222
+ def add_mc_args(p: argparse.ArgumentParser) -> None:
223
+ p.add_argument("--paths", type=int, default=100_000, help="MC paths")
224
+ p.add_argument("--steps", type=int, default=252, help="Time steps")
225
+ p.add_argument("--seed", type=int, default=None, help="Random seed")
226
+
227
+ # ---- price ----
228
+ p_price = sub.add_parser("price", help="Black-Scholes European option price and Greeks")
229
+ add_bs_args(p_price)
230
+ p_price.set_defaults(func=cmd_price)
231
+
232
+ # ---- iv ----
233
+ p_iv = sub.add_parser("iv", help="Implied volatility solver")
234
+ p_iv.add_argument("--price", type=float, required=True, help="Market price")
235
+ p_iv.add_argument("--S", type=float, required=True)
236
+ p_iv.add_argument("--K", type=float, required=True)
237
+ p_iv.add_argument("--T", type=float, required=True)
238
+ p_iv.add_argument("--r", type=float, required=True)
239
+ p_iv.add_argument("--q", type=float, default=0.0)
240
+ p_iv.add_argument("--type", choices=["call", "put"], default="call")
241
+ p_iv.set_defaults(func=cmd_iv)
242
+
243
+ # ---- american ----
244
+ p_am = sub.add_parser("american", help="American option via LSM Monte Carlo")
245
+ add_bs_args(p_am)
246
+ add_mc_args(p_am)
247
+ p_am.set_defaults(func=cmd_american)
248
+
249
+ # ---- heston ----
250
+ p_heston = sub.add_parser("heston", help="Heston stochastic volatility model")
251
+ p_heston.add_argument("--S", type=float, required=True)
252
+ p_heston.add_argument("--K", type=float, required=True)
253
+ p_heston.add_argument("--T", type=float, required=True)
254
+ p_heston.add_argument("--r", type=float, required=True)
255
+ p_heston.add_argument("--q", type=float, default=0.0)
256
+ p_heston.add_argument("--type", choices=["call", "put"], default="call")
257
+ p_heston.add_argument("--kappa", type=float, default=2.0)
258
+ p_heston.add_argument("--theta", type=float, default=0.04)
259
+ p_heston.add_argument("--xi", type=float, default=0.3)
260
+ p_heston.add_argument("--rho", type=float, default=-0.7)
261
+ p_heston.add_argument("--v0", type=float, default=0.04)
262
+ p_heston.set_defaults(func=cmd_heston)
263
+
264
+ # ---- asian ----
265
+ p_asian = sub.add_parser("asian", help="Asian average-rate option")
266
+ add_bs_args(p_asian)
267
+ add_mc_args(p_asian)
268
+ p_asian.add_argument("--avg", choices=["arithmetic", "geometric"], default="arithmetic")
269
+ p_asian.set_defaults(func=cmd_asian)
270
+
271
+ # ---- barrier ----
272
+ p_barrier = sub.add_parser("barrier", help="Single-barrier European option")
273
+ add_bs_args(p_barrier)
274
+ add_mc_args(p_barrier)
275
+ p_barrier.add_argument("--barrier", type=float, required=True, help="Barrier level")
276
+ p_barrier.add_argument(
277
+ "--barrier-type",
278
+ dest="barrier_type",
279
+ choices=["down-and-in", "down-and-out", "up-and-in", "up-and-out"],
280
+ default="down-and-out",
281
+ )
282
+ p_barrier.set_defaults(func=cmd_barrier)
283
+
284
+ # ---- risk ----
285
+ p_risk = sub.add_parser("risk", help="Risk metrics: VaR, CVaR, Sharpe, drawdown")
286
+ p_risk.add_argument("--S", type=float, default=100.0, help="Spot / position size")
287
+ p_risk.add_argument("--sigma", type=float, required=True, help="Annualised volatility")
288
+ p_risk.add_argument("--horizon", type=float, default=1.0, help="Horizon in trading days (default 1)")
289
+ p_risk.add_argument("--alpha", type=float, default=0.95, help="Confidence level (default 0.95)")
290
+ p_risk.set_defaults(func=cmd_risk)
291
+
292
+ # ---- compare-vr ----
293
+ p_vr = sub.add_parser("compare-vr", help="Compare variance reduction methods")
294
+ add_bs_args(p_vr)
295
+ p_vr.add_argument("--paths", type=int, default=50_000)
296
+ p_vr.set_defaults(func=cmd_compare_vr)
297
+
298
+ return parser
299
+
300
+
301
+ def main(argv: list[str] | None = None) -> int:
302
+ """Entry point for the CLI."""
303
+ parser = build_parser()
304
+ args = parser.parse_args(argv)
305
+
306
+ if not args.command:
307
+ parser.print_help()
308
+ return 1
309
+
310
+ args.func(args)
311
+ return 0
312
+
313
+
314
+ if __name__ == "__main__":
315
+ sys.exit(main())
@@ -0,0 +1,48 @@
1
+ """Backtesting framework: strategy simulation and P&L tracking."""
2
+ from tensorquantlib.backtest.metrics import (
3
+ sharpe_ratio,
4
+ max_drawdown,
5
+ sortino_ratio,
6
+ win_rate,
7
+ profit_factor,
8
+ annualized_return,
9
+ calmar_ratio,
10
+ information_ratio,
11
+ turnover,
12
+ hedge_pnl_attribution,
13
+ hedge_efficiency,
14
+ )
15
+ from tensorquantlib.backtest.engine import (
16
+ BacktestEngine,
17
+ BacktestResult,
18
+ SlippageModel,
19
+ CommissionModel,
20
+ ZERO_COST,
21
+ EQUITY_COMM,
22
+ FX_COMM,
23
+ EQUITY_SLIP,
24
+ ILLIQUID_SLIP,
25
+ )
26
+ from tensorquantlib.backtest.strategy import (
27
+ Strategy,
28
+ Trade,
29
+ DeltaHedgeStrategy,
30
+ GammaScalpingStrategy,
31
+ DeltaGammaHedgeStrategy,
32
+ StraddleStrategy,
33
+ )
34
+
35
+ __all__ = [
36
+ # metrics
37
+ "sharpe_ratio", "max_drawdown", "sortino_ratio", "win_rate", "profit_factor",
38
+ "annualized_return", "calmar_ratio", "information_ratio", "turnover",
39
+ "hedge_pnl_attribution", "hedge_efficiency",
40
+ # engine
41
+ "BacktestEngine", "BacktestResult",
42
+ "SlippageModel", "CommissionModel",
43
+ "ZERO_COST", "EQUITY_COMM", "FX_COMM", "EQUITY_SLIP", "ILLIQUID_SLIP",
44
+ # strategy
45
+ "Strategy", "Trade",
46
+ "DeltaHedgeStrategy", "GammaScalpingStrategy",
47
+ "DeltaGammaHedgeStrategy", "StraddleStrategy",
48
+ ]