Futures legs respect a firm's per-instrument contract limit
A firm can cap how many contracts of an instrument its accounts may hold (the catalog's instrumentLimits, set on the master's Firms page). A leg trades one contract per $1,000, capped by the account type's max contracts and that limit. The Auto draw sizes each instrument's hold with the capped count, so a limit that slows a leg past 12 hours takes it out of the draw. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
b125257d4e
commit
58e7414849
+14
-4
@@ -36,6 +36,7 @@ export interface FirmLike {
|
||||
id?: string;
|
||||
platform: string;
|
||||
instruments?: string[];
|
||||
instrumentLimits?: Record<string, number>;
|
||||
bannedSymbols?: string[];
|
||||
symbolMap?: Record<string, { symbol: string }[]>;
|
||||
}
|
||||
@@ -155,6 +156,8 @@ export interface LegShape {
|
||||
leg: number;
|
||||
stopDollars: number;
|
||||
maxPositionSize: number;
|
||||
/** The firm's most contracts per instrument, by root (absent = none). */
|
||||
limits?: Record<string, number>;
|
||||
}
|
||||
|
||||
function progressNow(now: Date): number | null {
|
||||
@@ -188,11 +191,13 @@ export function futuresBoard(roots: readonly string[], leg: LegShape | null, now
|
||||
disabled: string[];
|
||||
wide: string[];
|
||||
} {
|
||||
const contracts = leg ? futuresContracts(leg.leg, leg.maxPositionSize) : 1;
|
||||
const max = maxEntrySpread();
|
||||
const candidates = roots.filter((r) => CME_SPECS[r]).map((root) => {
|
||||
const dailyMove = market.get(root)?.dailyMove ?? null;
|
||||
const spread = entrySpread(root, now.getTime());
|
||||
// The size this leg would trade on this root: a firm's cap on the
|
||||
// instrument slows it, and may push it past the hold cap.
|
||||
const contracts = leg ? futuresContracts(leg.leg, leg.maxPositionSize, leg.limits?.[root] ?? 0) : 1;
|
||||
return {
|
||||
symbol: root,
|
||||
spreadDollars: spread.dollars,
|
||||
@@ -254,10 +259,10 @@ export function instrumentStatsFor(
|
||||
lead: (LegShape & { account: string }) | null,
|
||||
): InstrumentStats {
|
||||
const listed = firmInstruments(firm);
|
||||
const board = futuresBoard(listed, lead);
|
||||
const limits = firm.instrumentLimits ?? {};
|
||||
const board = futuresBoard(listed, lead ? { ...lead, limits } : null);
|
||||
const disabled = new Set(board.disabled);
|
||||
const max = maxEntrySpread();
|
||||
const leg = lead ? { leg: lead.leg, stopDollars: lead.stopDollars, contracts: futuresContracts(lead.leg, lead.maxPositionSize) } : null;
|
||||
return {
|
||||
at: new Date().toISOString(),
|
||||
account: lead?.account ?? null,
|
||||
@@ -268,7 +273,12 @@ export function instrumentStatsFor(
|
||||
quoteSource: quoteSource(),
|
||||
instruments: CME_ROOTS.map((root) => {
|
||||
const dailyMove = market.get(root)?.dailyMove ?? null;
|
||||
const holdHours = leg ? expectedHoldHours({ ...leg, dailyMove }) : null;
|
||||
const holdHours = lead
|
||||
? expectedHoldHours({
|
||||
leg: lead.leg, stopDollars: lead.stopDollars, dailyMove,
|
||||
contracts: futuresContracts(lead.leg, lead.maxPositionSize, limits[root] ?? 0),
|
||||
})
|
||||
: null;
|
||||
const spread = entrySpread(root);
|
||||
return {
|
||||
symbol: root,
|
||||
|
||||
Reference in New Issue
Block a user