Skip to content

Test: lock in risk-off regime guard blocking new buys - #24

Open
claude[bot] wants to merge 1 commit into
mainfrom
auto-refine/issue-23-2026-07-21
Open

Test: lock in risk-off regime guard blocking new buys#24
claude[bot] wants to merge 1 commit into
mainfrom
auto-refine/issue-23-2026-07-21

Conversation

@claude

@claude claude Bot commented Jul 21, 2026

Copy link
Copy Markdown

Summary

Today's daily post-market refinement review of issue #23 (2026-07-21 snapshot) investigated three data points to see if any code change was justified:

  1. momentum_weekly_churn_control__news_on backtest variant is byte-identical to momentum_only_weekly.
  2. Daily analysis reported 40 BUY signals / 10 HOLD / 0 SELL, market regime "risk-off", yet 0 trades and 0 positions in the latest paper run.
  3. Incubation gate failing min_trading_days and backtest_oos_positive at day 2/20.

Investigation verdict: all three are expected, documented design, not bugs.

  • (1) The news archive (src/news_archive.py, added 2026-07-19) only started accumulating 2 days ago, so it has zero coverage over the historical backtest replay window. ablation_verdict() in src/news_ablation.py correctly reports insufficient_data whenever news_days_used <= 0 — this is called out explicitly in that module's own comments and will self-resolve as the archive accumulates days.
  • (2) src/daily_analysis.py tags BUY/HOLD/SELL for display only; the actual gate is USE_MARKET_REGIME_GUARD in src/paper_trader.py (~line 611-617), which sets risk_block_new_buys = True whenever regime.get("risk_on") is False, regardless of signal count. With 0 existing positions, there is also nothing to sell, so 0 trades total is correct — this matches the documented intent in src/market_regime.py ("bot should not force new risk when the broad market trend is weak").
  • (3) min_trading_days is a plain day-count gate (MIN_TRADING_DAYS = 20) that fails by construction at day 2. backtest_oos_positive independently requires ≥2 of 3 walk-forward folds positive (src/incubation_report.py); today's artifact shows only 1/3 folds positive, so the gate is correctly protecting against a strategy whose OOS edge is driven by a single lucky fold.

Since no bug exists, per the refinement rules no strategy/behavior change is warranted. However, the investigation found one real gap: there was no dedicated unit test proving that the risk-off regime guard actually blocks new BUY orders — existing coverage (test_post_close_run_replaces_preliminary_same_day_snapshot) only sets risk_on: False incidentally, while testing an unrelated snapshot-replacement path with an existing position, and never asserts new-buy blocking.

Change

Adds test_market_regime_risk_off_blocks_new_buys to tests/test_paper_trader.py, modeled on the existing test_circuit_breaker_blocks_new_buys_but_allows_stop_sells test. It reproduces today's exact scenario (risk-off regime, BUY-ranked candidates, 0 existing positions) and asserts:

  • no positions are opened,
  • no pending orders are queued,
  • risk_block_new_buys is set on the snapshot.

This is test-only — no strategy parameters, execution logic, or trading behavior changed. Paper-trading only; the one-month incubation rule and readiness gate are untouched.

Validation

python -m unittest discover -s tests -p "test_*.py"

Ran 83 tests (up from 82), 1 pre-existing unrelated failure (test_news_archive fails to import due to a missing requests package in this sandbox — confirmed present on main before this change via git stash, not introduced by this PR). All other tests pass, including the new one.

Expected effect on readiness gate

None. This is a test-coverage addition only; it does not change min_trading_days, backtest_oos_positive, or any other incubation check, and does not touch trade execution logic.

Closes #23

Today's issue #23 snapshot (2026-07-21) showed 40 BUY signals with 0
existing positions and 0 trades under a risk-off NIFTY regime. That
matches the intended market_regime_guard behavior in paper_trader.py,
but no test asserted it directly (only indirect coverage via a
same-day snapshot-replacement test with an existing position). Add a
dedicated regression test for the exact scenario: risk-off regime +
BUY targets + no existing positions -> zero new orders queued.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto-refinement Automated daily paper-trading refinement PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Post-market dummy refinement: 2026-07-21

0 participants