Revert: remove daily_budget_reset from PEAD backtest

Feature was added to wrong system (PEAD backtester). Fully reverted.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
main
I Luk Kim 4 months ago
parent 189aa58343
commit 0cae86aa87

@ -211,7 +211,6 @@ class BacktestRunner:
self._equity_curve: list[DailyPortfolioState] = []
self._candidate_map: dict[str, Candidate] = {} # trade_id → candidate
self._fixed_capital_sizing = config.risk.fixed_capital_sizing
self._daily_budget_reset = config.risk.daily_budget_reset
self._primary_candidate_slate_stats: dict[dt.date, dict[str, int]] = {}
# Cash parking (idle cash → SPY/QQQ/SGOV)
@ -316,19 +315,20 @@ class BacktestRunner:
@property
def _sizing_equity(self) -> float:
"""Equity used for position sizing. Returns initial_capital when fixed_capital_sizing or daily_budget_reset is enabled."""
if self._fixed_capital_sizing or self._daily_budget_reset:
"""Equity used for position sizing. Returns initial_capital when fixed_capital_sizing is enabled."""
if self._fixed_capital_sizing:
return self.initial_equity
return self._equity
def _sleeve_equity_est(self, date: dt.date) -> float:
"""Equity estimate for sleeve budget calculations.
When ``fixed_capital_sizing`` or ``daily_budget_reset`` is enabled, returns
``initial_equity`` so that sleeve allocations stay proportional to the
starting capital rather than compounding with portfolio growth.
When ``fixed_capital_sizing`` is enabled, returns ``initial_equity`` so
that sleeve allocations (parking, form4, ownership, risk-off, idle-alpha)
stay proportional to the starting capital rather than compounding with
portfolio growth.
"""
if self._fixed_capital_sizing or self._daily_budget_reset:
if self._fixed_capital_sizing:
return float(self.initial_equity)
market_value = self._compute_positions_market_value(date)
return self._cash + market_value + self._get_parking_value(date)
@ -7396,11 +7396,7 @@ class BacktestRunner:
date=date,
equity=self._equity,
sizing_equity=self._sizing_equity,
cash_available=(
self._compute_buying_power(float(self.initial_equity), 0.0)
if self._daily_budget_reset
else self._compute_buying_power(self._equity, gross_exposure)
),
cash_available=self._compute_buying_power(self._equity, gross_exposure),
gross_exposure=gross_exposure,
net_exposure=net_exposure,
reserved_risk_budget=self._daily_new_risk_used,

@ -42,7 +42,6 @@ def run_backtest_session_sync(
non_core_allocator_v2_mode: str | None = None,
snapshot_id_override: str | None = None,
fixed_capital_sizing: bool = False,
daily_budget_reset: bool = False,
) -> dict[str, Any]:
"""Run a single strategy using BacktestRunner (same as research backtester).
@ -90,7 +89,6 @@ def run_backtest_session_sync(
config.non_core_allocator_v2.enabled = True
config.non_core_allocator_v2.mode = non_core_allocator_v2_mode
config.risk.fixed_capital_sizing = fixed_capital_sizing
config.risk.daily_budget_reset = daily_budget_reset
# Use merged store (train+valid+test) to cover the full date range.
store = _build_merged_snapshot_store(manifest, config, snapshot_dir_override=None)

@ -44,7 +44,6 @@ def main():
non_core_allocator_v2_mode = None
snapshot_id_override = None
fixed_capital = False
daily_budget_reset = False
remaining = sys.argv[7:]
i = 0
while i < len(remaining):
@ -72,9 +71,6 @@ def main():
elif remaining[i] == "--fixed-capital":
fixed_capital = True
i += 1
elif remaining[i] == "--daily-budget-reset":
daily_budget_reset = True
i += 1
else:
i += 1
@ -86,8 +82,7 @@ def main():
(f" · risk_off={risk_off_alpha_sleeve_preset}" if risk_off_alpha_sleeve_preset else "") +
(f" · ncav2={non_core_allocator_v2_mode}" if non_core_allocator_v2_mode else "") +
(f" · snapshot={snapshot_id_override}" if snapshot_id_override else "") +
(" · fixed_capital" if fixed_capital else "") +
(" · daily_budget_reset" if daily_budget_reset else ""))
(" · fixed_capital" if fixed_capital else ""))
sys.stdout.flush()
from apps.paper_trader.backtest_sim import run_backtest_session_sync
@ -106,7 +101,6 @@ def main():
non_core_allocator_v2_mode=non_core_allocator_v2_mode,
snapshot_id_override=snapshot_id_override,
fixed_capital_sizing=fixed_capital,
daily_budget_reset=daily_budget_reset,
)
result_file.parent.mkdir(parents=True, exist_ok=True)

@ -396,7 +396,6 @@ class BacktestRequest(BaseModel):
non_core_allocator_v2_mode: str | None = None # shadow|live
snapshot_id: str | None = None # override dataset_snapshot_id (e.g. for OOT periods)
fixed_capital: bool = False # non-compounding: size positions using initial capital
daily_budget_reset: bool = False # research mode: buying power resets to initial_equity each day
class BatchBacktestRequest(BaseModel):
@ -434,7 +433,6 @@ def _make_task(
non_core_allocator_v2_mode: str | None = None,
snapshot_id: str | None = None,
fixed_capital: bool = False,
daily_budget_reset: bool = False,
) -> dict[str, Any]:
return {
"task_id": str(uuid.uuid4()),
@ -452,7 +450,6 @@ def _make_task(
"error": None,
"pid": None,
"fixed_capital": fixed_capital,
"daily_budget_reset": daily_budget_reset,
"mode": mode,
"has_direct_result": False,
"parking": parking,
@ -933,7 +930,6 @@ def _launch_direct_backtest(req: BacktestRequest) -> dict[str, Any]:
non_core_allocator_v2_mode=eff_non_core_allocator_v2_mode,
snapshot_id=req.snapshot_id,
fixed_capital=req.fixed_capital,
daily_budget_reset=req.daily_budget_reset,
)
task_id = task["task_id"]
@ -966,8 +962,6 @@ def _launch_direct_backtest(req: BacktestRequest) -> dict[str, Any]:
cmd += ["--snapshot-id", req.snapshot_id]
if req.fixed_capital:
cmd += ["--fixed-capital"]
if req.daily_budget_reset:
cmd += ["--daily-budget-reset"]
with open(log_file, "wb") as log_fp:
proc = subprocess.Popen(

File diff suppressed because one or more lines are too long

@ -5,7 +5,7 @@
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Fithia2</title>
<script type="module" crossorigin src="/assets/index-CuJd8vEh.js"></script>
<script type="module" crossorigin src="/assets/index-BdTCIlkw.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-AVDbFxMk.css">
</head>
<body>

@ -222,7 +222,6 @@ export interface BacktestRequest {
non_core_allocator_v2_mode?: 'shadow' | 'live' | null;
snapshot_id?: string | null; // override dataset snapshot
fixed_capital?: boolean;
daily_budget_reset?: boolean;
}
export interface BacktestLastParams {
@ -249,7 +248,6 @@ export interface BacktestTask {
mode?: 'cli' | 'direct';
has_direct_result?: boolean;
fixed_capital?: boolean;
daily_budget_reset?: boolean;
parking?: string | null;
idle_alpha?: string | null;
form4_sleeve?: string | null;
@ -343,6 +341,7 @@ export interface IntradayTask {
start_date: string | null;
end_date: string | null;
compound_returns: boolean | null;
daily_budget_reset?: boolean | null;
status: 'queued' | 'running' | 'completed' | 'failed' | 'cancelled';
created_at: string;
started_at: string | null;
@ -434,6 +433,7 @@ export interface IntradayStrategy {
sim_bar_minutes?: number;
orb_minutes?: number;
compound_returns?: boolean;
daily_budget_reset?: boolean;
entry_minutes_after_open?: number | null;
exit_minutes_before_close?: number | null;
top_n?: number | null;
@ -472,6 +472,7 @@ export const intradayApi = {
start_date?: string | null;
end_date?: string | null;
compound_returns?: boolean;
daily_budget_reset?: boolean;
initial_capital?: number;
}) =>
request<{ task_id: string; status: string }>('/intraday/backtest/submit', {

@ -98,7 +98,6 @@ interface DupState {
end: string | null;
no_trades: boolean;
fixed_capital: boolean;
daily_budget_reset: boolean;
parking: string | null;
idle_alpha: string | null;
form4_sleeve: string | null;
@ -117,7 +116,6 @@ function makeDupState(task: BacktestTask): DupState {
end: !isYear ? task.end_date ?? null : null,
no_trades: task.no_trades ?? false,
fixed_capital: task.fixed_capital ?? false,
daily_budget_reset: task.daily_budget_reset ?? false,
parking: task.parking ?? null,
idle_alpha: task.idle_alpha ?? null,
form4_sleeve: task.form4_sleeve ?? null,
@ -214,7 +212,6 @@ export function BacktestPage() {
const [capital, setCapital] = useState('10000');
const [noTrades, setNoTrades] = useState(false);
const [fixedCapital, setFixedCapital] = useState(false);
const [dailyBudgetReset, setDailyBudgetReset] = useState(false);
const [directMode, setDirectMode] = useState(true);
const [parking, setParking] = useState('');
const [idleAlpha, setIdleAlpha] = useState('');
@ -247,7 +244,6 @@ export function BacktestPage() {
setNoTrades(s.no_trades ?? false);
dupFixedCapitalRef.current = s.fixed_capital ?? false;
setFixedCapital(s.fixed_capital ?? false);
setDailyBudgetReset(s.daily_budget_reset ?? false);
setParking(s.parking ?? '');
setIdleAlpha(s.idle_alpha ?? '');
setForm4Sleeve(s.form4_sleeve ?? '');
@ -390,7 +386,6 @@ export function BacktestPage() {
: (endDate || null),
no_trades: noTrades,
fixed_capital: fixedCapital,
daily_budget_reset: dailyBudgetReset,
parking: parking || null,
idle_alpha: idleAlpha || null,
form4_sleeve: form4Sleeve || null,
@ -833,10 +828,6 @@ export function BacktestPage() {
<input type="checkbox" checked={fixedCapital} onChange={e => setFixedCapital(e.target.checked)} style={{ width: 13, height: 13 }} />
<span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: fixedCapital ? 'var(--orange)' : 'var(--text3)' }}>Fixed Capital (Simple Return)</span>
</label>
<label style={{ display: 'flex', alignItems: 'center', gap: 6, cursor: 'pointer' }}>
<input type="checkbox" checked={dailyBudgetReset} onChange={e => setDailyBudgetReset(e.target.checked)} style={{ width: 13, height: 13 }} />
<span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: dailyBudgetReset ? 'var(--purple)' : 'var(--text3)' }}>Daily Budget Reset</span>
</label>
<label style={{ display: 'flex', alignItems: 'center', gap: 6, cursor: selectedExps.length === 1 ? 'pointer' : 'not-allowed', opacity: selectedExps.length === 1 ? 1 : 0.4 }}>
<input
type="checkbox"
@ -1089,7 +1080,7 @@ export function BacktestPage() {
<td style={{ padding: '11px 14px', fontFamily: 'var(--font-mono)', fontSize: 13, color: 'var(--cyan)', whiteSpace: 'nowrap' }}>
${task.capital?.toLocaleString() ?? '—'}
</td>
<td style={{ padding: '11px 14px', whiteSpace: 'nowrap', display: 'flex', gap: 4, alignItems: 'center' }}>
<td style={{ padding: '11px 14px', whiteSpace: 'nowrap' }}>
{task.fixed_capital && (
<span style={{
fontFamily: 'var(--font-mono)', fontSize: 10,
@ -1099,15 +1090,6 @@ export function BacktestPage() {
borderRadius: 3, padding: '1px 5px',
}}>FC</span>
)}
{task.daily_budget_reset && (
<span style={{
fontFamily: 'var(--font-mono)', fontSize: 10,
color: 'var(--purple)',
background: 'color-mix(in srgb, var(--purple) 12%, transparent)',
border: '1px solid color-mix(in srgb, var(--purple) 25%, transparent)',
borderRadius: 3, padding: '1px 5px',
}}>DBR</span>
)}
</td>
<td style={{ padding: '11px 14px', fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--text2)' }}>
{task.start_date ? (

@ -1681,7 +1681,6 @@ class RiskConfig(BaseModel):
veto_unknown_direction: bool = True # block if event_direction == "unknown"
veto_bearish_direction: bool = True # block if event_direction == "bearish"
fixed_capital_sizing: bool = False # when True, position sizing uses initial_capital instead of current equity
daily_budget_reset: bool = False # each day, sizing and buying power reset to initial_equity regardless of open positions (for research)
reaction_size_cap_threshold: float | None = None # abs(reaction)% above which size scales down (e.g. 0.08)
momentum_size_scaler_threshold: float | None = None # pre-event mom_20d above which size scales down (e.g. 0.10)
momentum_size_scaler_floor: float = 0.3 # minimum scaler for high-momentum entries

Loading…
Cancel
Save