import { useMemo } from "react"; import { useQuery } from "@tanstack/react-query"; import type { GexProfile, Summary } from "@shared/schema"; import { useSymbol } from "@/lib/symbol-context"; import { fmtCompactCurrency, fmtStrike, fmtPct } from "@/lib/format"; import { GexChart } from "@/components/gex-chart"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { MetricTooltip } from "@/components/metric-tooltip"; import { LoadingBlock } from "@/components/loading-block"; import { cn } from "@/lib/utils"; export default function GammaLevelsPage() { const { symbol } = useSymbol(); const summary = useQuery({ queryKey: ["/api/market", symbol, "summary"] }); const gex = useQuery({ queryKey: ["/api/market", symbol, "gex"] }); const s = summary.data; const g = gex.data; // Sort bars by absolute net gex magnitude — the top 10 are the meaningful walls. const ranked = useMemo(() => { if (!g) return []; return [...g.bars] .map((b) => ({ ...b, magnitude: Math.abs(b.netGex), absCall: Math.abs(b.callGex), absPut: Math.abs(b.putGex), })) .sort((a, b) => b.magnitude - a.magnitude) .slice(0, 12); }, [g]); return (

Gamma levels

Dealer gamma by strike with the top concentration zones. Use this view to identify pin candidates and break levels.

{s && (
)}
Gamma exposure profile {g ? : } Top strike concentrations

Strikes ranked by absolute net gamma. Positive net values indicate dealer-long gamma; negative values indicate dealer-short gamma.

Strike Call GEX Put GEX Net GEX Distance {ranked.map((row) => { const dist = s ? ((row.strike - s.spot) / s.spot) * 100 : 0; return ( {fmtStrike(row.strike)} {fmtCompactCurrency(row.callGex)} {fmtCompactCurrency(row.putGex)} = 0 ? "text-pos" : "text-neg", )} > {fmtCompactCurrency(row.netGex)} {fmtPct(dist)} ); })}
); } function KeyLevel({ color, label, value, from, tooltipMetric, }: { color: "hvl" | "call-wall" | "put-wall"; label: string; value: string; from: number; tooltipMetric: "hvl" | "callWall" | "putWall"; }) { const numericValue = Number(value.replace(/,/g, "")); const distPct = ((numericValue - from) / from) * 100; return ( {label} {value} {fmtPct(distPct)} ); }