Skip to main content
Glama
Ademscodeisnotsobad

Quant Companion MCP

monteCarlo.ts3.48 kB
/** * Monte Carlo option pricing engine */ import { MonteCarloParams, MonteCarloResult } from "./types"; import { randomNormal, mean, stdDev } from "./utils"; /** Maximum paths to return full payoff array (for memory efficiency) */ const MAX_PATHS_FOR_FULL_PAYOFFS = 10000; /** Z-score for 95% confidence interval */ const Z_95 = 1.96; /** * Price a European option using Monte Carlo simulation * * Uses Geometric Brownian Motion under risk-neutral measure: * S_T = S_0 * exp((r - q - 0.5*σ²)*T + σ*√T*Z) * * @param params - Monte Carlo parameters * @returns Price estimate, standard error, confidence interval, and optionally payoffs */ export function priceOptionMonteCarlo(params: MonteCarloParams): MonteCarloResult { const { spot, strike, rate, vol, timeToMaturity, optionType, paths, steps = 1, dividendYield = 0, } = params; // Validate inputs if (paths <= 0) { throw new Error("paths must be positive"); } if (timeToMaturity < 0) { throw new Error("timeToMaturity cannot be negative"); } // Edge case: expired option if (timeToMaturity === 0) { const intrinsic = optionType === "call" ? Math.max(spot - strike, 0) : Math.max(strike - spot, 0); return { price: intrinsic, standardError: 0, confidenceInterval: { lower: intrinsic, upper: intrinsic, level: 0.95 }, payoffs: [intrinsic], }; } const dt = timeToMaturity / steps; const drift = (rate - dividendYield - 0.5 * vol * vol) * dt; const diffusion = vol * Math.sqrt(dt); const discountFactor = Math.exp(-rate * timeToMaturity); const payoffs: number[] = []; for (let i = 0; i < paths; i++) { let s = spot; // Simulate path for (let j = 0; j < steps; j++) { const z = randomNormal(); s = s * Math.exp(drift + diffusion * z); } // Calculate payoff at maturity const payoff = optionType === "call" ? Math.max(s - strike, 0) : Math.max(strike - s, 0); payoffs.push(payoff); } // Discount payoffs to present value const discountedPayoffs = payoffs.map((p) => p * discountFactor); const price = mean(discountedPayoffs); const standardError = stdDev(discountedPayoffs) / Math.sqrt(paths); // 95% confidence interval const margin = Z_95 * standardError; const confidenceInterval = { lower: price - margin, upper: price + margin, level: 0.95, }; // Only return full payoffs array if paths <= threshold (memory efficiency) const result: MonteCarloResult = { price, standardError, confidenceInterval, }; if (paths <= MAX_PATHS_FOR_FULL_PAYOFFS) { result.payoffs = payoffs; } return result; } /** * Simulate terminal prices for analysis (not option pricing) * * @param params - Simulation parameters * @returns Array of terminal stock prices */ export function simulateTerminalPrices(params: { spot: number; rate: number; vol: number; timeToMaturity: number; dividendYield?: number; paths: number; }): number[] { const { spot, rate, vol, timeToMaturity, dividendYield = 0, paths } = params; const drift = (rate - dividendYield - 0.5 * vol * vol) * timeToMaturity; const diffusion = vol * Math.sqrt(timeToMaturity); const prices: number[] = []; for (let i = 0; i < paths; i++) { const z = randomNormal(); const sT = spot * Math.exp(drift + diffusion * z); prices.push(sT); } return prices; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Ademscodeisnotsobad/Quant-Companion-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server