DXtrade: count closed-trade P&L, week-long volatility, broker leverage caps, swap in the take-profit
- Transfers: a close books its SETTLEMENT and COMMISSION under one transaction code, and keying by the code alone let the commission overwrite the P&L. Keys now carry the type, so the day-start balance, daily-loss room, realized P&L, daily history and books check all see closed-trade profit and loss. - Volatility from a week of hourly closes (was 48 h), still measured once per trade date, so one quiet weekend can't triple a hold estimate. - Each symbol's margin rate from the account's instrument details caps the position at available funds / rate (Tradeify: 5:1 crypto, 2:1 stocks); the account type's max notional stays as an optional ceiling. - Firms with overnight financing add the swap a winning leg is expected to pay (the winners' mean hold, (A²+2AB)/3σ²) to its take-profit, and the sizing and hold estimate count it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
675b4c89f8
commit
a2d9df5ba4
+12
-3
@@ -7,7 +7,7 @@ import { historyFresh, type PlatformContract } from '@/lib/platform-client';
|
||||
import type { AccountState } from '@/types';
|
||||
import {
|
||||
combineCmeSessions, computeDayPlan, cycleCompletion, resolveEffectiveConfig, currentTradeDateCT,
|
||||
obfuscationStopDollars, dllRoom as computeDllRoom, dllStopDollars, botStopsActive, sizeNotional,
|
||||
obfuscationStopDollars, dllRoom as computeDllRoom, dllStopDollars, botStopsActive, sizeNotional, notionalCap,
|
||||
DEFAULT_TARGET_HOLD_HOURS,
|
||||
LEG_COMPLETION_EPSILON,
|
||||
} from '@/lib/trading-logic';
|
||||
@@ -126,7 +126,8 @@ export async function GET() {
|
||||
|
||||
// DXtrade: size the next leg the way fireLeg would, on the
|
||||
// instrument the selector last picked and today's measured
|
||||
// volatility, to show how long it is expected to hold.
|
||||
// volatility — under the same notional and margin caps —
|
||||
// to show how long it is expected to hold.
|
||||
const pick = (client as { lastPickedContract?: PlatformContract | null }).lastPickedContract;
|
||||
if (plan && plan.remainingToday > 0 && pick?.stepNotional && pick.volatilityPerHour) {
|
||||
const pct = pick.commissionPct ?? f.commissionPct ?? 0;
|
||||
@@ -145,7 +146,13 @@ export async function GET() {
|
||||
commissionPct: pct,
|
||||
spreadFraction: pick.spreadFraction,
|
||||
financingPctPerDay: f.financingPctPerDay ?? 0,
|
||||
maxNotional: cfg.maxNotional ?? 0,
|
||||
// The next leg opens flat: while this one is open its
|
||||
// margin is tied up, so size against the balance.
|
||||
maxNotional: notionalCap({
|
||||
maxNotional: cfg.maxNotional ?? 0,
|
||||
marginRate: pick.marginRate,
|
||||
availableFunds: client.positions[acc.id] ? cash.amount : (cash.availableFunds ?? cash.amount),
|
||||
}),
|
||||
});
|
||||
if (sizing) {
|
||||
holdEstimate = {
|
||||
@@ -154,6 +161,8 @@ export async function GET() {
|
||||
notional: Math.round(sizing.notional),
|
||||
volatilityPerDay: pick.volatilityPerHour * Math.sqrt(24),
|
||||
winProbability: sizing.winProbability,
|
||||
swapReserve: sizing.swapReserve,
|
||||
leverage: pick.marginRate ? Math.round(10 / pick.marginRate) / 10 : null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+5
-2
@@ -393,8 +393,11 @@ function AccountRow({ account, firm, hideDead, privacy, onAssigned }: {
|
||||
{account.holdEstimate && (
|
||||
<span
|
||||
className="text-slate-500"
|
||||
title={`Next leg on ${account.holdEstimate.symbol}: $${Math.round(account.holdEstimate.notional).toLocaleString()} notional at today's measured volatility of ${(account.holdEstimate.volatilityPerDay * 100).toFixed(2)}%/day`
|
||||
+ (account.holdEstimate.winProbability !== null ? `, wins ~${Math.round(account.holdEstimate.winProbability * 100)}% of the time` : '')}
|
||||
title={`Next leg on ${account.holdEstimate.symbol}: $${Math.round(account.holdEstimate.notional).toLocaleString()} notional`
|
||||
+ (account.holdEstimate.leverage !== null ? ` (${account.holdEstimate.leverage}:1 max)` : '')
|
||||
+ ` at a measured volatility of ${(account.holdEstimate.volatilityPerDay * 100).toFixed(2)}%/day over the past week`
|
||||
+ (account.holdEstimate.winProbability !== null ? `, wins ~${Math.round(account.holdEstimate.winProbability * 100)}% of the time` : '')
|
||||
+ (account.holdEstimate.swapReserve > 0 ? `; its take-profit carries ~$${fmt(account.holdEstimate.swapReserve)} of expected swap` : '')}
|
||||
>
|
||||
{' · hold ~'}{account.holdEstimate.hours < 48 ? `${Math.round(account.holdEstimate.hours)}h` : `${(account.holdEstimate.hours / 24).toFixed(1)}d`}
|
||||
</span>
|
||||
|
||||
Reference in New Issue
Block a user