Symbol stats: the win chance with no commission, spread or swap beside the real one

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Brandon Li
2026-09-26 18:47:50 -05:00
co-authored by Claude Opus 5.5
parent 957b9a50fe
commit 302e9b4911
6 changed files with 21 additions and 6 deletions
+13 -5
View File
@@ -14,7 +14,11 @@ import {
planLegSize, rankForTarget, maxLossRoom, lastStand, DEFAULT_TARGET_HOLD_HOURS,
} from './trading-logic';
export type CandidateLeg = SymbolStats['symbols'][number] & { swapReserve: number; leverage: number | null };
export type CandidateLeg = SymbolStats['symbols'][number] & {
swapReserve: number;
leverage: number | null;
winProbabilityNoFees: number | null;
};
interface FirmSizing {
commissionPct?: number;
@@ -47,18 +51,21 @@ export function rankNextLeg(o: {
const funds = o.client.positions?.[o.accountId] ? o.cash.amount : (o.cash.availableFunds ?? o.cash.amount);
const sized = candidates.flatMap((c): CandidateLeg[] => {
if (!c.volatilityPerHour) return [];
const p = planLegSize({
const plan = (costs: boolean) => planLegSize({
leg: o.leg,
contract: c,
commissionPct: c.commissionPct ?? o.firm.commissionPct ?? 0,
contract: costs ? c : { ...c, spreadFraction: 0 },
commissionPct: costs ? (c.commissionPct ?? o.firm.commissionPct ?? 0) : 0,
targetHoldHours: target,
financingPctPerDay: o.firm.financingPctPerDay ?? 0,
financingPctPerDay: costs ? (o.firm.financingPctPerDay ?? 0) : 0,
dailyLossLimit: o.cfg.dailyLossLimit ?? 0,
// Without fees the day's room would also have its fees back — but
// only this leg's are known, so the room stays as it is.
dllRoom: o.dllRoom ?? Infinity,
maxLossRoom: floorRoom,
obfuscationDollars: o.obfuscationDollars,
availableFunds: funds,
});
const p = plan(true);
if (!p.sizing || p.cost === null) return [];
const leverage = c.marginRate ? Math.round(10 / c.marginRate) / 10 : null;
return [{
@@ -70,6 +77,7 @@ export function rankNextLeg(o: {
holdHours: Math.round(p.sizing.predictedHoldHours * 10) / 10,
cost: Math.round(p.cost),
winProbability: p.sizing.winProbability,
winProbabilityNoFees: plan(false).sizing?.winProbability ?? null,
volatilityPerDay: c.volatilityPerHour * Math.sqrt(24),
spreadFraction: c.spreadFraction ?? 0,
swapReserve: p.sizing.swapReserve,