Hide the next stop on a booked day; label min day P&L as such
On 2026-10-08 a Tradeify min day ($150) stopped out at −$306 on its 2× stop of $300. The dashboard then read "stop $912": the next-stop label is recomputed from the remaining target, which the loss grew to $456, for a leg that never fires — the day is booked and the make-back rides tomorrow, stopless. - obfuscationDayBooked() holds the scheduler's booked-day check; the state route asks it too and shows no next stop, last stand or hold on a booked day. - The account page's "Daily Loss Limit" showed minDayPnL. It now shows the type's real daily loss limit, with Min Day P&L on its own row; the objective that passed on total profit ≥ minDayPnL is gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c3b58c8d8b
commit
c0261f42ae
@@ -409,7 +409,10 @@ export default function AccountPage() {
|
||||
const fundTransactions = account.fundTransactions ?? [];
|
||||
const fundMap = new Map(fundTransactions.map((f) => [f.date, f.amount]));
|
||||
|
||||
const hasLossLimit = cfg != null && cfg.minDayPnL !== -999;
|
||||
// The firm's hard daily loss limit, and the least a day must make to count
|
||||
// as a trading day — two different numbers; neither is set on every type.
|
||||
const dailyLossLimit = (cfg?.dailyLossLimit ?? 0) > 0 ? cfg!.dailyLossLimit! : null;
|
||||
const minDayPnL = (cfg?.minDayPnL ?? 0) > 0 ? cfg!.minDayPnL : null;
|
||||
const daysPassed = cfg != null && account.daysTraded >= cfg.minTradingDays;
|
||||
// Dead when balance hits the liquidation floor — Tradovate reports its
|
||||
// (positive) floor; TopstepX floors are reconstructed MLLs, negative or
|
||||
@@ -427,7 +430,6 @@ export default function AccountPage() {
|
||||
const profitPassed = cfg != null && totalProfit >= (account.effectiveProfitTarget ?? cfg.profitTarget);
|
||||
// dailyTarget is computed server-side in the state API — single source of truth.
|
||||
const dailyTarget = account.dailyTarget ?? null;
|
||||
const lossPassed = !hasLossLimit || (cfg != null && totalProfit >= cfg.minDayPnL);
|
||||
|
||||
// Consistency target: the total profit level at which the best day no longer
|
||||
// violates the consistency ratio. Only meaningful once a positive day exists.
|
||||
@@ -610,7 +612,8 @@ export default function AccountPage() {
|
||||
positive={profitPct != null && profitPct >= 0}
|
||||
/>
|
||||
<PerfRow label="Trading Days" value={account.daysTraded} />
|
||||
<PerfRow label="Daily Loss Limit" value={hasLossLimit ? `$${fmt(cfg!.minDayPnL)}` : 'None'} />
|
||||
<PerfRow label="Daily Loss Limit" value={dailyLossLimit !== null ? `$${fmt(dailyLossLimit)}` : 'None'} />
|
||||
<PerfRow label="Min Day P&L" value={minDayPnL !== null ? `$${fmt(minDayPnL)}` : 'None'} />
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col w-1/2 bg-white border border-slate-200 rounded-xl shadow-sm p-6">
|
||||
@@ -632,13 +635,6 @@ export default function AccountPage() {
|
||||
label="Trading Days"
|
||||
value={cfg ? `${account.daysTraded} of ${cfg.minTradingDays}` : '—'}
|
||||
/>
|
||||
{hasLossLimit && (
|
||||
<ObjRow
|
||||
passed={lossPassed}
|
||||
label="Daily Loss Limit"
|
||||
value={`$${fmt(cfg!.minDayPnL)}`}
|
||||
/>
|
||||
)}
|
||||
{dailyTarget != null && (
|
||||
<div className="flex items-center justify-between py-3 border-b border-slate-100 last:border-0">
|
||||
<span className="text-slate-500 text-sm">Next Trading Day Amount</span>
|
||||
|
||||
+10
-3
@@ -5,6 +5,7 @@ import { getCachedCatalog } from '@/lib/firm-catalog';
|
||||
import { getAccountConfig, getInferredSize, matchAccountType } from '@/lib/account-type-resolver';
|
||||
import { historyFresh } from '@/lib/platform-client';
|
||||
import { rankNextLeg } from '@/lib/leg-estimate';
|
||||
import { obfuscationDayBooked } from '@/lib/auto-trade';
|
||||
import type { AccountState } from '@/types';
|
||||
import {
|
||||
combineCmeSessions, computeDayPlan, cycleCompletion, resolveEffectiveConfig, currentTradeDateCT,
|
||||
@@ -123,8 +124,14 @@ export async function GET() {
|
||||
balance: cash.amount, accountSize: cfg.accountSize, maxLoss: cfg.maxLoss ?? 0,
|
||||
autoLiqThreshold: client.autoLiqThresholds?.[acc.id],
|
||||
});
|
||||
lastStandNext = dllRoom !== null && isLastStand({ dllRoom, dailyLossLimit: dll, maxLossRoom: floorRoom });
|
||||
if (plan && (botStopsActive(cfg))) {
|
||||
// A day an obfuscation stop booked has no next leg — the
|
||||
// make-back rides tomorrow, stopless — so no next stop, last
|
||||
// stand or hold to show. Its remaining target has grown by
|
||||
// the loss: a $150 min day stopped at −$306 would read
|
||||
// "stop $912" for a leg that never fires.
|
||||
const dayBooked = obfuscationDayBooked(cfg, acc.id, tradeDate, combined.realizedPnL) !== null;
|
||||
lastStandNext = !dayBooked && dllRoom !== null && isLastStand({ dllRoom, dailyLossLimit: dll, maxLossRoom: floorRoom });
|
||||
if (plan && !dayBooked && botStopsActive(cfg)) {
|
||||
const obf = obfuscationStopDollars(cfg, dailyPnL, plan, combined.tradeDate, plan.remainingToday);
|
||||
const hard = dllRoom !== null && !lastStandNext
|
||||
? dllStopDollars({ room: dllRoom, dailyLossLimit: dll, entryFee: 0, commissionPct: 0 })
|
||||
@@ -135,7 +142,7 @@ export async function GET() {
|
||||
|
||||
// DXtrade: the next leg sized on every surveyed instrument as
|
||||
// fireLeg would, and the one a batch would pick.
|
||||
if (plan && plan.remainingToday > 0) {
|
||||
if (plan && !dayBooked && plan.remainingToday > 0) {
|
||||
const best = rankNextLeg({
|
||||
client, accountId: acc.id, cfg, firm: f, leg: plan.remainingToday, dllRoom,
|
||||
obfuscationDollars: obfuscationStopDollars(cfg, dailyPnL, plan, combined.tradeDate, plan.remainingToday),
|
||||
|
||||
Reference in New Issue
Block a user