Skip to main content
Glama
Ademscodeisnotsobad

Quant Companion MCP

summarizeVolRegime.ts8.98 kB
/** * MCP Tool: summarize_vol_regime * * Multi-step analysis tool that summarizes the volatility regime for a symbol. * Fetches options chain, computes vol surface, and generates a human-readable report. */ import { z } from "zod"; import { computeVolSurface, computeHistoricalVol, type QuantError, } from "@quant-companion/core"; import { getDefaultProvider } from "../marketData"; import { createError } from "../errors"; export const summarizeVolRegimeSchema = z.object({ symbol: z.string().describe("Stock/ETF ticker symbol (e.g., AAPL, SPY, NVDA)"), historicalWindow: z .number() .min(5) .max(252) .default(30) .describe("Window for historical vol calculation (default: 30 days)"), }); export type SummarizeVolRegimeInput = z.infer<typeof summarizeVolRegimeSchema>; export interface SummarizeVolRegimeOutput { symbol: string; spot: number; asOf: string; /** Historical (realized) volatility */ historicalVol: { window: number; value: number; }; /** Implied volatility summary */ impliedVol: { atmNearTerm: number; atmLongTerm: number; avgAtm: number; }; /** Vol premium/discount */ volPremium: { value: number; interpretation: "expensive" | "cheap" | "fair"; }; /** Term structure */ termStructure: { shape: "contango" | "backwardation" | "flat"; slope: number | null; interpretation: string; }; /** Skew summary */ skew: { avgRiskReversal: number | null; direction: "put" | "call" | "neutral"; interpretation: string; }; /** Overall regime classification */ regime: { level: "low_vol" | "normal" | "elevated" | "crisis"; description: string; }; /** Human-readable summary */ summary: string; /** Actionable insights */ insights: string[]; } export const summarizeVolRegimeDefinition = { name: "summarize_vol_regime", description: `Generate a comprehensive volatility regime summary for a symbol. This multi-step tool: 1. Fetches current price and options chain 2. Computes historical volatility 3. Builds vol surface from options data 4. Analyzes term structure and skew 5. Generates human-readable report with insights Returns: - Historical vs implied vol comparison - Term structure shape and interpretation - Skew analysis - Overall regime classification - Actionable trading insights Use this for: - Quick volatility regime assessment - Comparing implied vs realized vol - Generating volatility reports`, inputSchema: { type: "object" as const, properties: { symbol: { type: "string", description: "Stock/ETF ticker symbol" }, historicalWindow: { type: "number", description: "Historical vol window in days (default: 30)", default: 30, }, }, required: ["symbol"], }, }; export async function summarizeVolRegime( input: SummarizeVolRegimeInput ): Promise<SummarizeVolRegimeOutput | { error: QuantError }> { const provider = getDefaultProvider(); const symbol = input.symbol.toUpperCase(); try { // Step 1: Fetch options chain const chain = await provider.getOptionsChain({ symbol }); const spot = chain.underlyingPrice; // Step 2: Compute historical volatility const end = new Date(); const start = new Date(); start.setDate(start.getDate() - input.historicalWindow - 10); // Extra buffer const historical = await provider.getHistoricalOHLCV({ symbol, start, end, interval: "1d", }); const closes = historical.map((c) => c.close); const hvResult = computeHistoricalVol(closes, input.historicalWindow); // Step 3: Compute vol surface const surface = computeVolSurface({ chain, maxExpirations: 8, minOpenInterest: 10, }); // Step 4: Analyze const nearTermSmile = surface.smiles[0]; const longTermSmile = surface.smiles[surface.smiles.length - 1]; const atmNearTerm = nearTermSmile?.atmIv ?? surface.stats.avgAtmIv; const atmLongTerm = longTermSmile?.atmIv ?? surface.stats.avgAtmIv; const avgAtmIv = surface.stats.avgAtmIv; // Vol premium (IV vs HV) const volPremiumValue = avgAtmIv - hvResult.volatility; let volPremiumInterpretation: "expensive" | "cheap" | "fair" = "fair"; if (volPremiumValue > 0.05) volPremiumInterpretation = "expensive"; else if (volPremiumValue < -0.03) volPremiumInterpretation = "cheap"; // Term structure let termShape: "contango" | "backwardation" | "flat" = "flat"; if (surface.stats.termSlope !== null) { if (surface.stats.termSlope > 0.03) termShape = "contango"; else if (surface.stats.termSlope < -0.03) termShape = "backwardation"; } const termInterpretation = termShape === "contango" ? "Longer-dated options trading at higher IV; typical calm market structure" : termShape === "backwardation" ? "Near-term IV elevated above long-term; suggests near-term event risk or stress" : "Flat term structure; no significant time-based IV differences"; // Skew const rrValues = surface.smiles .map((s) => s.skew.riskReversal25d) .filter((v): v is number => v !== null); const avgRR = rrValues.length > 0 ? rrValues.reduce((a, b) => a + b, 0) / rrValues.length : null; let skewDirection: "put" | "call" | "neutral" = "neutral"; if (avgRR !== null) { if (avgRR > 0.02) skewDirection = "put"; else if (avgRR < -0.02) skewDirection = "call"; } const skewInterpretation = skewDirection === "put" ? "Puts trading at premium to calls; market hedging downside risk" : skewDirection === "call" ? "Calls trading at premium to puts; bullish sentiment or upside hedging" : "Balanced put-call pricing; no strong directional bias"; // Regime classification let regimeLevel: "low_vol" | "normal" | "elevated" | "crisis" = "normal"; if (avgAtmIv < 0.15) regimeLevel = "low_vol"; else if (avgAtmIv > 0.40) regimeLevel = "crisis"; else if (avgAtmIv > 0.25) regimeLevel = "elevated"; const regimeDescription = regimeLevel === "low_vol" ? "Low volatility environment; options are cheap, consider buying premium" : regimeLevel === "crisis" ? "Crisis-level volatility; high uncertainty, consider hedging" : regimeLevel === "elevated" ? "Elevated volatility; increased uncertainty, premium selling may be attractive" : "Normal volatility regime; balanced market conditions"; // Generate summary const summary = `${symbol} is currently in a ${regimeLevel.replace("_", " ")} regime with ATM IV at ${(avgAtmIv * 100).toFixed(1)}% vs ${(hvResult.volatility * 100).toFixed(1)}% realized vol. Options are ${volPremiumInterpretation} relative to historical. Term structure is in ${termShape} with ${skewDirection} skew.`; // Generate insights const insights: string[] = []; if (volPremiumInterpretation === "expensive") { insights.push("Consider selling premium (credit spreads, iron condors) given elevated IV"); } else if (volPremiumInterpretation === "cheap") { insights.push("Options appear cheap; consider buying premium for directional bets or hedges"); } if (termShape === "backwardation") { insights.push("Near-term event risk priced in; calendar spreads may benefit from term structure normalization"); } if (skewDirection === "put") { insights.push("Put skew elevated; put credit spreads or put ratio spreads may offer value"); } else if (skewDirection === "call") { insights.push("Call skew elevated; covered calls or call spreads may be attractive"); } if (regimeLevel === "low_vol") { insights.push("Low vol environment favors long gamma strategies (straddles, strangles)"); } else if (regimeLevel === "elevated" || regimeLevel === "crisis") { insights.push("High vol favors short gamma strategies, but manage risk carefully"); } return { symbol, spot, asOf: chain.asOf, historicalVol: { window: input.historicalWindow, value: hvResult.volatility, }, impliedVol: { atmNearTerm, atmLongTerm, avgAtm: avgAtmIv, }, volPremium: { value: volPremiumValue, interpretation: volPremiumInterpretation, }, termStructure: { shape: termShape, slope: surface.stats.termSlope, interpretation: termInterpretation, }, skew: { avgRiskReversal: avgRR, direction: skewDirection, interpretation: skewInterpretation, }, regime: { level: regimeLevel, description: regimeDescription, }, summary, insights, }; } catch (error) { const message = error instanceof Error ? error.message : "Unknown error"; return { error: createError("COMPUTATION_ERROR", `Failed to summarize vol regime: ${message}`), }; } }

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