"""Constant-real-£ withdrawal (the classic 4% rule shape). Withdraw `state.initial_withdrawal` in year 0, then keep that real-£ amount fixed for the rest of retirement. In a 4% / £1M setup the year-0 draw is £40k, then £40k real every year after. The strategy's `initial_rate` is kept only as a fallback for callers that don't feed `state.initial_withdrawal`. """ from __future__ import annotations from fire_planner.strategies.base import StrategyState, WithdrawalStrategy DEFAULT_INITIAL_RATE = 0.04 class TrinityStrategy(WithdrawalStrategy): name = "trinity" def __init__(self, initial_rate: float = DEFAULT_INITIAL_RATE) -> None: self.initial_rate = initial_rate def propose_withdrawal(self, state: StrategyState) -> float: if state.year_idx == 0: # Year 0 = the user's target spending. Falls back to # initial_rate × initial_portfolio if no target was provided # (zero or missing) for backwards compatibility. if state.initial_withdrawal > 0: return state.initial_withdrawal return state.initial_portfolio * self.initial_rate return state.last_withdrawal