Seed leg splits per prefix group so like accounts split targets alike

Like accounts in a batch previously carved legs with independent
Math.random, so near-identical day targets could split very differently.
Leg fractions are now drawn from groupLegFraction(prefix, tradeDate,
legIndex) — FNV-1a seeded like dailyBump — so accounts of the same
account type on the same leg of the same day split identically when
their remaining targets match, and proportionally close otherwise.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Brandon Li
2026-09-08 22:03:23 -05:00
co-authored by Claude Fable 5
parent 3516e6c288
commit 5d2f4d607a
2 changed files with 26 additions and 4 deletions
+10 -4
View File
@@ -12,7 +12,7 @@ import { getClients } from './clients';
import { getTradableFirms } from './firm-catalog';
import { getAccountConfig } from './account-type-resolver';
import {
combineCmeSessions, computeDayPlan, pickLegAmount, resolveEffectiveConfig, currentTradeDateCT,
combineCmeSessions, computeDayPlan, groupLegFraction, pickLegAmount, resolveEffectiveConfig, currentTradeDateCT,
LEG_COMPLETION_EPSILON, MAX_LEGS_PER_DAY, POINT_VALUES,
type DayPlan,
} from './trading-logic';
@@ -354,8 +354,12 @@ export async function runTrade(action: 'Buy' | 'Sell' | 'Auto', symbol: string)
}
// Trade one leg toward today's remaining target. Split-allowed big days carve a
// random ≥$800 piece; everything else trades the full remaining amount in one go.
const legAmount = item.plan.splitAllowed ? pickLegAmount(item.plan.remainingToday) : item.plan.remainingToday;
// ≥$800 piece; everything else trades the full remaining amount in one go. The
// carve fraction is seeded per (prefix, date, leg number) so like accounts in a
// batch split their targets the same way, or close to it when remainders differ.
const legAmount = item.plan.splitAllowed
? pickLegAmount(item.plan.remainingToday, () => groupLegFraction(item.prefix, tradeDate, legsToday(acc.id, tradeDate)))
: item.plan.remainingToday;
recordLeg(acc.id, tradeDate);
const rawContracts = Math.max(1, Math.ceil(legAmount / 1000));
@@ -563,7 +567,9 @@ export async function copyTrade() {
const { client, acc, contract } = item;
const cfg = getAccountConfig(acc.id).accountType!;
const legAmount = item.plan.splitAllowed ? pickLegAmount(item.plan.remainingToday) : item.plan.remainingToday;
const legAmount = item.plan.splitAllowed
? pickLegAmount(item.plan.remainingToday, () => groupLegFraction(item.prefix, tradeDate, legsToday(acc.id, tradeDate)))
: item.plan.remainingToday;
recordLeg(acc.id, tradeDate);
const rawContracts = Math.max(1, Math.ceil(legAmount / 1000));