Anchor payouts to the trading day the cycle finishes, not the report day
A completed cycle's payout now lands on its last traded day (requestable after that session's close) instead of whatever day the projection ran — a Friday finish viewed over the weekend stayed pinned to Sunday. Also stop inserting the platform's stale weekend realizedPnL as a Sat/Sun P&L row, which fabricated an extra qualifying day and made accounts one day short look already complete. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
1996937ef2
commit
9597db08f7
+20
-10
@@ -428,8 +428,14 @@ export function projectPerfectPath(opts: {
|
||||
const dd = Math.max(0, opts.payout?.drawdown ?? 0);
|
||||
|
||||
const today = currentTradeDateCT();
|
||||
// A weekend "today" (Saturday, or Sunday before the evening open) has no
|
||||
// session — the platform's realizedPnL is the LAST session's stale number,
|
||||
// already booked in cycleDailyPnL under its own date. Adding it as a
|
||||
// weekend row would fabricate an extra qualifying day.
|
||||
const todayDow = new Date(`${today}T00:00:00Z`).getUTCDay();
|
||||
const todayHasSession = todayDow !== 0 && todayDow !== 6;
|
||||
let sim = opts.cycleDailyPnL.filter((d) => d.date !== today);
|
||||
if (opts.realizedPnL !== 0) sim = [...sim, { date: today, pnl: opts.realizedPnL }];
|
||||
if (todayHasSession && opts.realizedPnL !== 0) sim = [...sim, { date: today, pnl: opts.realizedPnL }];
|
||||
else sim = [...sim];
|
||||
const funds = [...opts.fundTransactions];
|
||||
let balance = opts.balance;
|
||||
@@ -479,8 +485,7 @@ export function projectPerfectPath(opts: {
|
||||
// Book the rest of today silently — the perfect path finishes today too.
|
||||
// Skipped when "today" is a weekend date (Saturday, or Friday evening
|
||||
// after the roll): there is no session to finish.
|
||||
const todayDow = new Date(`${today}T00:00:00Z`).getUTCDay();
|
||||
if (todayDow !== 0 && todayDow !== 6) {
|
||||
if (todayHasSession) {
|
||||
const eff = effectiveNow();
|
||||
const plan = computeDayPlan(
|
||||
accountId, today, eff.profitTarget, eff.consistency, sim, eff.minDayPnL,
|
||||
@@ -497,9 +502,9 @@ export function projectPerfectPath(opts: {
|
||||
}
|
||||
}
|
||||
|
||||
// Fires the payout ON the given date — the day the cycle's final trading
|
||||
// day books (or today, when the cycle already stands complete), the
|
||||
// payout becomes requestable. The withdrawal takes the completed stage's
|
||||
// Fires the payout ON the given date — the trading day the cycle's final
|
||||
// required day books (the last traded day, when the cycle already stands
|
||||
// complete), the payout becomes requestable after that session. The withdrawal takes the completed stage's
|
||||
// share of the EQUITY PROFIT (for a $0-start account that is the whole
|
||||
// balance), capped. Prop payouts come out of profit, never the funded
|
||||
// principal. Returns true when the projection should stop (no further
|
||||
@@ -527,9 +532,10 @@ export function projectPerfectPath(opts: {
|
||||
return true;
|
||||
};
|
||||
|
||||
// Already complete right now — target hit and min days done? Then the
|
||||
// payout is requestable TODAY, whatever day of the week it is, not on
|
||||
// the next session.
|
||||
// Already complete right now — target hit and min days done? The payout
|
||||
// anchors to the trading day the cycle finished: the last traded day,
|
||||
// requestable after that session's close. Never "today" — a projection
|
||||
// computed over the weekend must not slide a Friday finish to Sunday.
|
||||
{
|
||||
const eff = effectiveNow();
|
||||
const probe = nextTradingDate(today);
|
||||
@@ -539,7 +545,11 @@ export function projectPerfectPath(opts: {
|
||||
);
|
||||
if (plan && plan.dayTarget <= 0 && eff.minTradingDays <= qualifyingDays(eff.minDayPnL, probe)) {
|
||||
const stage = 1 + funds.filter((f) => f.amount < 0).length;
|
||||
if (finishCycle(today, 0, stage, eff.drain)) return out;
|
||||
const traded = sim.filter((d) => d.pnl !== 0);
|
||||
const doneOn = traded.length > 0
|
||||
? traded.reduce((a, b) => (a.date > b.date ? a : b)).date
|
||||
: today;
|
||||
if (finishCycle(doneOn, 0, stage, eff.drain)) return out;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user