Entry cost is one tick of spread; fees can be added later if they matter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
37 lines
1.6 KiB
TypeScript
37 lines
1.6 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { getCachedCatalog } from '@/lib/firm-catalog';
|
|
import {
|
|
ensureMarket, firmInstruments, futuresRootsHere, instrumentStatsFor, instrumentsSource, isFuturesFirm, simulateDraws,
|
|
} from '@/lib/instruments';
|
|
import { CME_ROOTS } from '@/lib/instrument-specs';
|
|
|
|
export const dynamic = 'force-dynamic';
|
|
|
|
/** The leg the overview sizes holds for: $1,000, stopless, one contract. */
|
|
const EXAMPLE_LEG = { leg: 1000, stopDollars: Infinity, maxPositionSize: 0 };
|
|
|
|
/**
|
|
* GET /api/instruments — what each firm trades (the master's lists) and, for
|
|
* futures firms, how the Auto draw sees every instrument right now: a tick
|
|
* of spread, one contract's daily move, the hold of a $1,000 leg, the chance.
|
|
* ?simulate=N adds N draws from the real draw code — no orders.
|
|
*/
|
|
export async function GET(req: NextRequest) {
|
|
await ensureMarket(CME_ROOTS, 8_000);
|
|
const n = Math.min(100_000, Math.max(0, Math.floor(Number(req.nextUrl.searchParams.get('simulate')) || 0)));
|
|
const firms = getCachedCatalog().map((firm) => {
|
|
const instruments = firmInstruments(firm);
|
|
const futures = isFuturesFirm(firm);
|
|
return {
|
|
id: firm.id,
|
|
name: firm.name,
|
|
platform: firm.platform,
|
|
source: instrumentsSource(firm),
|
|
instruments,
|
|
...(futures ? { stats: instrumentStatsFor(firm, { ...EXAMPLE_LEG, account: 'a $1,000 leg' }) } : {}),
|
|
...(futures && n > 0 ? { simulated: simulateDraws(instruments, EXAMPLE_LEG, n) } : {}),
|
|
};
|
|
});
|
|
return NextResponse.json({ roots: futuresRootsHere(), firms });
|
|
}
|