Files
autofirmer-expanded/app/api/firms/[id]/orders/route.ts
T
Brandon LiandClaude Opus 5.5 5ec5abde6e Remove broker session rest
Reverts 062ec07 and 5eb0ea7: every firm's broker session stays logged in
around the clock again, renewing its token on the fixed timer as before.
The tree is back to 6dd2528's. A session_rest row left in settings is
unused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 23:39:53 -05:00

55 lines
2.4 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { getCachedFirm } from '@/lib/firm-catalog';
import { firmInstruments, isFuturesFirm } from '@/lib/instruments';
import { getClients } from '@/lib/clients';
export async function POST(
req: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const { id: firmId } = await params;
const body = await req.json() as {
accountId: number;
symbol: string; // product name, e.g. "NQ"
qty: number;
action: 'Buy' | 'Sell';
orderType?: 'Market' | 'Limit';
price?: number;
};
const { accountId, symbol, qty, action, orderType = 'Market', price } = body;
if (!accountId || !symbol || !qty || !action) {
return NextResponse.json({ error: 'Missing required fields: accountId, symbol, qty, action' }, { status: 400 });
}
const clients = getClients();
const client = clients.get(firmId);
if (!client) return NextResponse.json({ error: 'Client not found for firm' }, { status: 404 });
// A futures firm trades only what its instrument list (master Firms
// page) names.
const firm = getCachedFirm(firmId);
if (firm && isFuturesFirm(firm) && !firmInstruments(firm).includes(symbol)) {
return NextResponse.json({ error: `${symbol} isn't on ${firm.name}'s instrument list` }, { status: 400 });
}
// 1. Find the active contract chosen by the shared resolver
const contract = await client.findFrontMonthContract(symbol);
if (!contract) {
return NextResponse.json({ error: `Could not find an active contract for ${symbol}` }, { status: 404 });
}
console.log(`[order] active contract: ${contract.name} (id=${contract.id})`);
// 2. Place the order — resolves with the fill event (includes commission/fees)
const fill = await client.sendOrder(accountId, contract.name, qty, action, orderType, price);
console.log(`[order] fill received: price=${fill.price} qty=${fill.qty} commission=$${fill.commission} perContract=$${fill.perContractFee}`);
return NextResponse.json({ contract: { id: contract.id, name: contract.name }, fill });
} catch (err: any) {
console.error('[POST /api/firms/[id]/orders]', err);
return NextResponse.json({ error: err?.message ?? 'Order failed' }, { status: 500 });
}
}