Payout projection: payoutable same-equity accounts loop without explicit stages
A payoutable account with no withdrawal stages (e.g. MFFU same-equity) now withdraws its share and re-targets the same equity each cycle instead of stopping after the first payout. Non-payoutable evals still stop at one completion. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
70eab33d1b
commit
a6a79bba7e
+10
-1
@@ -380,6 +380,10 @@ export function projectPerfectPath(opts: {
|
||||
profitTarget: number; consistency: number; minDayPnL: number;
|
||||
minTradingDays: number; accountSize: number; targetSameEquity: boolean;
|
||||
withdrawalStages: WithdrawalStage[]; splitEnabled: boolean;
|
||||
/** True = completing a cycle pays out and the account keeps going
|
||||
* (withdraw, reset, re-target). False = it just PASSES once (an
|
||||
* eval) and the projection stops. */
|
||||
payoutable?: boolean;
|
||||
};
|
||||
/** Current-cycle daily P&L (account.dailyPnL). */
|
||||
cycleDailyPnL: { date: string; pnl: number }[];
|
||||
@@ -491,12 +495,17 @@ export function projectPerfectPath(opts: {
|
||||
// balance), capped. Prop payouts come out of profit, never the funded
|
||||
// principal. Returns true when the projection should stop (no further
|
||||
// stages).
|
||||
// A cycle that completes keeps looping when the account has withdrawal
|
||||
// stages OR is simply payoutable — a same-equity payout account (no
|
||||
// explicit stages) withdraws its share and re-targets the same equity,
|
||||
// over and over. Only a non-payoutable eval stops after one completion.
|
||||
const loops = cfg.withdrawalStages.length > 0 || cfg.payoutable === true;
|
||||
const finishCycle = (onDate: string, dayPnl: number, stage: number, drain: boolean): boolean => {
|
||||
const { pct, cap } = stagePayout();
|
||||
const rawGross = round2(Math.max(0, balance - cfg.accountSize) * pct);
|
||||
const gross = cap > 0 ? Math.min(rawGross, round2(cap)) : rawGross;
|
||||
const net = round2(gross * profitSplit);
|
||||
if (cfg.withdrawalStages.length > 0 && withdrawals < maxWithdrawals && gross > 1) {
|
||||
if (loops && withdrawals < maxWithdrawals && gross > 1) {
|
||||
funds.push({ date: onDate, amount: -gross });
|
||||
balance = round2(balance - gross);
|
||||
sim = []; // withdrawal excludes its day — fresh cycle
|
||||
|
||||
Reference in New Issue
Block a user