Use cycle net target (not profit target) for consistency cap

The consistency cap was using profitTarget × consistency, which is
correct only when starting equity = 0 (fresh stage). After a loss within
a cycle, the cap should still respect the cycle's intended net total.

Now computes:
  cycleStartEquity = equityProfit − tradingProfit (constant per cycle)
  cycleNetTarget   = profitTarget − cycleStartEquity
  maxConsistencyDay = cycleNetTarget × consistency

This way prior losses don't expand the daily cap. For PAAPEX stage 2
with -$3000 day 1 and $7100 target: today's cap = $1421.95 (50% of the
cycle's $2843.90 net target), preserving consistency at exactly $7100.

Stage 1 behavior unchanged (cycleStartEquity = 0 → cycleNetTarget = profitTarget).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Brandon Li
2026-05-04 18:21:14 -05:00
co-authored by Claude Opus 4.6
parent 3da96fe73a
commit f6b2ee27fd
+15 -7
View File
@@ -122,12 +122,18 @@ export function computeDailyTarget(
const cappedByFuture = remaining - futureReserve;
// 3. Consistency cap.
// Day 1: min(remaining × consistency, profitTarget × consistency).
// Day 2+: max(maxDay, profitTarget × consistency).
// - If maxDay ≤ profitTarget × consistency: room to grow days up to that ceiling.
// - If maxDay > profitTarget × consistency: consistency already broken at target,
// total must grow to at least maxDay / consistency. Each day can be up to maxDay
// (going higher creates a new maxDay requiring even more total).
// cycleStartEquity = equityProfit tradingProfit (equity at the start of this cycle).
// cycleNetTarget = profitTarget cycleStartEquity (cycle's net P&L needed to hit target).
// maxConsistencyDay = cycleNetTarget × consistency — the largest day the rule allows
// measured against the cycle's net total (not against profitTarget directly), so prior
// losses don't artificially expand the cap.
//
// Day 1: min(remaining × consistency, maxConsistencyDay).
// Day 2+: max(maxDay, maxConsistencyDay).
// - If maxDay ≤ maxConsistencyDay: room to grow days up to that ceiling.
// - If maxDay > maxConsistencyDay: consistency already broken at target, total must
// grow to at least maxDay / consistency. Each day can be up to maxDay (going higher
// creates a new maxDay requiring even more total).
let consistencyCap: number;
let path: 'first_day' | 'normal_day' | 'reduced_day';
@@ -135,7 +141,9 @@ export function computeDailyTarget(
consistencyCap = Infinity;
path = daysTraded === 0 ? 'first_day' : 'reduced_day';
} else {
const maxConsistencyDay = profitTarget * consistency;
const cycleStartEquity = equityProfit - tradingProfit;
const cycleNetTarget = Math.max(0, profitTarget - cycleStartEquity);
const maxConsistencyDay = cycleNetTarget * consistency;
if (daysTraded === 0) {
consistencyCap = Math.min(remaining * consistency, maxConsistencyDay);
path = 'first_day';