mirror of
https://github.com/Mihirkansara/nexus-quant-terminal.git
synced 2026-08-12 18:18:05 +00:00
Full-stack forex options analytics terminal with Bloomberg-inspired UI. Backend (FastAPI + Python): - Garman-Kohlhagen options pricing engine with full Greeks - Goldman Sachs gs-quant AI signals (RSI, MACD, Bollinger, Hurst, OU) - Monte Carlo GBM simulation and volatility surface generation - CFTC COT institutional positioning + Forex Factory economic calendar - Live data proxy: OpenSky aircraft + USGS earthquakes (CORS-safe) - Multi-leg strategy library (straddle, iron condor, butterfly, spreads) Frontend (React 18 + Vite): - NEXUS animated orbital logo (3-ring SVG) + canvas favicon animation - Bloomberg terminal design: JetBrains Mono, color-mix() tokens - 11 dashboard tabs: Greeks, Chart, AI Signals, 3D Surfaces, Breakeven, Scenarios, Monte Carlo, Institutional, Calendar, Live Map, Live Feeds - Live World Map (react-leaflet): aircraft, earthquakes, weather radar - Live Feeds: CoinGecko crypto top-12 + Windy.com global webcams - Economic calendar with filters + institutional flow (CFTC COT) - Animated landing page + session-based routing - Fully responsive dark-only terminal design system Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
45 lines
1.6 KiB
Python
45 lines
1.6 KiB
Python
"""montecarlo.py — GBM Monte Carlo for forex options (uses GK cost basis)."""
|
|
|
|
import numpy as np
|
|
from .garman_kohlhagen import gk_price
|
|
|
|
|
|
def run_montecarlo(options, S0, sigma, r_d, r_f, T, n_paths=1000, n_steps=100):
|
|
"""Simulate GBM price paths and compute P&L distribution at expiry."""
|
|
dt = T / n_steps
|
|
Z = np.random.standard_normal((n_paths, n_steps))
|
|
paths = np.zeros((n_paths, n_steps + 1)); paths[:,0] = S0
|
|
|
|
# GBM: dS = (r_d - r_f)·S·dt + σ·S·dW (Garman-Kohlhagen drift)
|
|
for t in range(1, n_steps + 1):
|
|
paths[:,t] = paths[:,t-1] * np.exp(
|
|
(r_d - r_f - 0.5*sigma**2)*dt + sigma*np.sqrt(dt)*Z[:,t-1]
|
|
)
|
|
|
|
terminal = paths[:,-1]
|
|
pnl = np.zeros(n_paths)
|
|
for opt in options:
|
|
K, qty = float(opt["K"]), float(opt["qty"])
|
|
payoff = (np.maximum(terminal - K, 0) if opt["type"]=="call"
|
|
else np.maximum(K - terminal, 0))
|
|
pnl += payoff * qty
|
|
|
|
# Subtract initial GK cost
|
|
cost = sum(
|
|
gk_price(S0, float(o["K"]), float(o.get("T",T)), r_d, r_f, sigma, o["type"])
|
|
* float(o["qty"]) for o in options
|
|
)
|
|
pnl -= cost
|
|
|
|
idx = np.random.choice(n_paths, size=min(60, n_paths), replace=False)
|
|
return {
|
|
"time_axis": [round(i*dt, 4) for i in range(n_steps+1)],
|
|
"sample_paths": paths[idx].tolist(),
|
|
"pnl": pnl.tolist(),
|
|
"pnl_mean": round(float(pnl.mean()), 5),
|
|
"pnl_std": round(float(pnl.std()), 5),
|
|
"pnl_5pct": round(float(np.percentile(pnl, 5)), 5),
|
|
"pnl_95pct": round(float(np.percentile(pnl, 95)), 5),
|
|
"prob_profit": round(float((pnl > 0).mean()), 4),
|
|
}
|