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:
co-authored by
Claude Opus 5.5
parent
957b9a50fe
commit
302e9b4911
+13
-5
@@ -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,
|
||||
|
||||
@@ -139,6 +139,9 @@ export interface SymbolStats {
|
||||
/** Expected spread, commissions and swap. */
|
||||
cost: number;
|
||||
winProbability: number | null;
|
||||
/** The same leg and daily room with no commission, spread or swap —
|
||||
* what the costs take off the win chance. Optional. */
|
||||
winProbabilityNoFees?: number | null;
|
||||
volatilityPerDay: number;
|
||||
spreadFraction: number;
|
||||
}[];
|
||||
|
||||
+1
-1
@@ -427,7 +427,7 @@ function symbolStatsFor(
|
||||
at: new Date().toISOString(),
|
||||
symbols: next.candidates.map((c) => ({
|
||||
symbol: c.symbol, notional: c.notional, multiplier: c.multiplier, maxMultiplier: c.maxMultiplier,
|
||||
holdHours: c.holdHours, cost: c.cost, winProbability: c.winProbability,
|
||||
holdHours: c.holdHours, cost: c.cost, winProbability: c.winProbability, winProbabilityNoFees: c.winProbabilityNoFees,
|
||||
volatilityPerDay: c.volatilityPerDay, spreadFraction: c.spreadFraction,
|
||||
})),
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user