- Add unrealized_pnl_pct_above/below and holding_days_above/below fields
to StockCondition so AI can generate rules like 'P&L > 3% → SELL'
- Evaluate new fields in ScenarioEngine.evaluate_condition() with same
AND-combining logic as existing technical indicator fields
- Include position fields in _build_match_details() for audit logging
- Parse new fields from AI JSON response in PreMarketPlanner._parse_scenario()
- Update prompt schema example to show new position-aware condition fields
- Add 13 tests covering all new condition combinations and edge cases
Closes#171
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add current_holdings parameter to generate_playbook() and _build_prompt()
- Inject '## Current Holdings' section into Gemini prompt with qty, entry
price, unrealized PnL%, and holding days for each held position
- Instruct AI to generate SELL/HOLD scenarios for held stocks even if not
in scanner candidates list
- Allow held stock codes in _parse_response() valid_codes set so AI-
generated SELL scenarios for holdings pass validation
- Add 6 tests covering prompt inclusion, omission, and response parsing
Closes#170
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When gemini-2.5-flash quota is exhausted (20 RPD free tier), generate_playbook()
fell back to _defensive_playbook() which only had price_change_pct_below: -3.0 SELL
conditions — no BUY conditions — causing zero trades on US market despite scanner
finding strong momentum/oversold candidates.
Changes:
- Add _smart_fallback_playbook() that uses scanner signals to build BUY conditions:
- momentum signal: BUY when volume_ratio_above=VOL_MULTIPLIER
- oversold signal: BUY when rsi_below=RSI_OVERSOLD_THRESHOLD
- always: SELL stop-loss at price_change_pct_below=-3.0
- Use _smart_fallback_playbook() instead of _defensive_playbook() on Gemini failure
- Add 10 new tests for _smart_fallback_playbook() covering momentum/oversold/empty cases
- Update existing test_gemini_failure_returns_defensive to match new behavior
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add build_self_market_scorecard() to read previous day's own market
performance, and include it in the Gemini planning prompt alongside
cross-market context.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
KR planner now reads US scorecard from previous day (timezone-aware),
and generate_playbook uses STRATEGIC context selection.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Review findings addressed:
- Finding 1 (ImportError): false positive — ContextLayer is re-exported from
src.context.store, import works correctly at runtime
- Finding 2 (timezone): generate_playbook() and build_cross_market_context()
now accept optional today parameter for market-local date injection
- Finding 3 (lint): removed unused imports (UTC, datetime, PlaybookStatus),
fixed line-too-long in prompt template
- Tests simplified: replaced date patching with direct today= parameter
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>