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 dd = Math.max(0, opts.payout?.drawdown ?? 0);
|
||||||
|
|
||||||
const today = currentTradeDateCT();
|
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);
|
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];
|
else sim = [...sim];
|
||||||
const funds = [...opts.fundTransactions];
|
const funds = [...opts.fundTransactions];
|
||||||
let balance = opts.balance;
|
let balance = opts.balance;
|
||||||
@@ -479,8 +485,7 @@ export function projectPerfectPath(opts: {
|
|||||||
// Book the rest of today silently — the perfect path finishes today too.
|
// Book the rest of today silently — the perfect path finishes today too.
|
||||||
// Skipped when "today" is a weekend date (Saturday, or Friday evening
|
// Skipped when "today" is a weekend date (Saturday, or Friday evening
|
||||||
// after the roll): there is no session to finish.
|
// after the roll): there is no session to finish.
|
||||||
const todayDow = new Date(`${today}T00:00:00Z`).getUTCDay();
|
if (todayHasSession) {
|
||||||
if (todayDow !== 0 && todayDow !== 6) {
|
|
||||||
const eff = effectiveNow();
|
const eff = effectiveNow();
|
||||||
const plan = computeDayPlan(
|
const plan = computeDayPlan(
|
||||||
accountId, today, eff.profitTarget, eff.consistency, sim, eff.minDayPnL,
|
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
|
// Fires the payout ON the given date — the trading day the cycle's final
|
||||||
// day books (or today, when the cycle already stands complete), the
|
// required day books (the last traded day, when the cycle already stands
|
||||||
// payout becomes requestable. The withdrawal takes the completed stage's
|
// 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
|
// 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
|
// balance), capped. Prop payouts come out of profit, never the funded
|
||||||
// principal. Returns true when the projection should stop (no further
|
// principal. Returns true when the projection should stop (no further
|
||||||
@@ -527,9 +532,10 @@ export function projectPerfectPath(opts: {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Already complete right now — target hit and min days done? Then the
|
// Already complete right now — target hit and min days done? The payout
|
||||||
// payout is requestable TODAY, whatever day of the week it is, not on
|
// anchors to the trading day the cycle finished: the last traded day,
|
||||||
// the next session.
|
// 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 eff = effectiveNow();
|
||||||
const probe = nextTradingDate(today);
|
const probe = nextTradingDate(today);
|
||||||
@@ -539,7 +545,11 @@ export function projectPerfectPath(opts: {
|
|||||||
);
|
);
|
||||||
if (plan && plan.dayTarget <= 0 && eff.minTradingDays <= qualifyingDays(eff.minDayPnL, probe)) {
|
if (plan && plan.dayTarget <= 0 && eff.minTradingDays <= qualifyingDays(eff.minDayPnL, probe)) {
|
||||||
const stage = 1 + funds.filter((f) => f.amount < 0).length;
|
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