When the rule parser can't classify an 8-K and falls back to Stock Oracle's
filing-events API, Oracle's vocabulary (e.g. earnings_result, shareholder_vote,
regulation_fd) was being written verbatim into events.event_type. The DB has
no CHECK constraint (libs/db/models.py:189), so 22 distinct Oracle values
silently leaked into a column the strategy's engine filters expect to be in
its 4-event vocabulary. Result: ~1,069 live rows silently dropped from
strategy candidate pool.
Files:
- NEW libs/parser/event_type_normalizer.py: normalize_oracle_event_type()
with conservative synonym map; normalize_oracle_event() additionally
uses _classify_event_type from rule_parser when an item_number is
present (item-code path is more reliable than Oracle's event taxonomy)
- MOD apps/pipeline/event_parser/main.py: oracle-fallback branch (~line
140) now calls normalize_oracle_event before writing to DB; emits
oracle_event_type_normalized log event when value changes
- NEW tests/unit/test_event_type_normalizer.py: 60 tests covering
identity, synonyms, case/separator insensitivity, None/empty,
non-string, item_number-precedence
Mapping highlights (justifications in test docstrings):
earnings_result/earnings_announcement/earnings -> earnings_release
guidance_revision/guidance_change/regulation_fd -> guidance_update
material_definitive_agreement/definitive_agreement -> material_contract
shareholder_vote/acquisition_disposition/bankruptcy/other -> other_material_event
Reg FD -> guidance_update mirrors rule_parser's Item 7.01 mapping for
internal consistency. Debatable but auditable.
Conservative pass-through for ambiguous values (financial_obligation,
articles_amendment, contract_termination, etc., 14 distinct values).
Visible filter-drop > silent re-tag.
Live DB counts that would reclassify on a future --reparse pass:
412 earnings_result -> earnings_release
409 shareholder_vote -> other_material_event
237 regulation_fd -> guidance_update
7 acquisition_disposition -> other_material_event
4 other -> other_material_event
TOTAL 1,069 rows currently in oracle-fallback dead-zone.
60/60 normalizer tests pass; combined parser+schema validator suite 86/86.
Follow-up flagged: run --reparse on historical oracle-fallback rows after
extending reparse_events() to also re-normalize known oracle-fallback
values (currently only re-parses event_type='unknown').
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- v7.356 config: swap dataset_snapshot_id from manual_only ftb_fix_v2 to
auto_full_rebuild base canonical so paper trader can refresh snapshot
(root cause of processed_events=0 for 30 days)
- Multi-session order isolation (1.A.2/1.A.3): tag client_order_id with
pt-{session_id[:8]}-{uuid} prefix on all entry orders; _cancel_stale_orders
filters by own session prefix so one session no longer ghost-cancels another's
orders on shared Alpaca account
- Pipeline halt on failure (1.B.1): _run_pipeline returns bool and stops on
first subprocess failure instead of silently progressing with stale data
- Daemon restart window skip (2.2): run_open/run_close only marked completed
if processed_phases DB confirms prior execution — no more trading-less days
after mid-day restart
- event_parser: periodic batch commits every 500 docs (hypothesis fix for
3h hangs; unverified — may just be slow serial Oracle calls)
- Tests updated for _verify_order_fill tuple return + new cross-session
isolation test; all 23 paper_trader unit tests green
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds earnings surprise extraction to parser/features/labeler pipeline,
improves filing fetcher robustness, and extends snapshot export with
new field support.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>