Category-driven event signal pipeline for public equities. Ingests company news, maps headlines to tickers, scores distress likelihood, and emits ranked trade signal candidates.
This is a decision-support tool, not automated execution.
These signals are for event-driven individual stock trades β a different strategy from the macro ETF swings in trump-macro and econ-monitor.
The edge here is identifying company-specific distress events (recall, fraud, clinical failure, going concern) before the full price impact is reflected. The system waits for the stock to get hit, then watches for either:
- A bounce entry (LONG): stock is oversold, volume spike, RSI washed out β buy the panic low
- A continuation short (SHORT): fraud, going concern, short-seller report β expect further decline
Step-by-step:
- Alert fires with ticker, entry price, stop, and target
- Check whether it's a LONG (bounce trade) or SHORT (distress continuation)
- For LONG β enter near the oversold low, stop below the event low, target a partial reversion
- For SHORT β enter on a weak bounce or break of support, stop above recent high, target further decline
- Hold for 1β10 trading days depending on category (fraud/going-concern plays develop slower than recalls)
- Exit at target, stop, or if the narrative changes (company resolves the issue)
Why these hold longer than macro ETF trades: Individual stock events develop over days to weeks. An E. coli recall hits the stock hard on day 1, but litigation risk, FDA investigations, and sales impact take time to price in. A fraud allegation may keep selling for 5β15 trading days. The system tracks T+1, T+5, T+10, and T+20 return horizons to identify where each category's edge actually lives.
Higher risk than macro ETF trades: Single stocks can move 20β50% on events. Always use the stop shown in the alert. Position size smaller than you would for an ETF macro trade.
Every buy signal emitted is tracked in data/signal_outcomes.csv. At each service cycle the system checks whether signals have enough price history to evaluate and records:
- Return at T+1, T+5, T+10, T+20 trading days
- Whether stop or target was hit during the hold window
Self-improvement loop: Run the outcome summary to see which event categories and confidence levels actually predict price moves:
from src.outcome_tracker import summarize_outcomes
import json
# Win rates at T+5
result = summarize_outcomes("data/signal_outcomes.csv", horizon=5)
print(json.dumps(result, indent=2))Output breaks down win rate and mean return by:
- Event category (
product_safety_recall,fraud_accounting_enforcement, etc.) β which event types have signal - Confidence level (high/medium/low) β whether the scoring thresholds are calibrated
Use that data to tune distress score thresholds, per-category RSI/drop requirements, and confidence gates in config/settings.json.
cybersecurity Β· clinical_regulatory_binary Β· product_safety_recall Β· fraud_accounting_enforcement Β· supply_chain_disruption Β· financial_distress Β· dilutive_financing Β· ma_corporate_action Β· leadership_scandal Β· positive_earnings_catalyst
RSS ingestion β ticker extraction β distress scoring β price/technical analysis β signal ranking β alerts β outcome tracking
# Docker (recommended, always-on)
docker compose up -d --build
docker logs catastrophe-analyzer -f
# One cycle smoke test
docker exec catastrophe-analyzer python3 src/monitor.py --once --quiet
# Python CLI (dev/debug)
cd src && python3 main.pyconfig/settings.json β categories, sources, thresholds, distress gate
config/alerts_config.json β ntfy (my-catastrophe-alerts-7f3k9q), email, Twilio credentials
Entity validation mode (no rebuild needed):
# Switch to deterministic rules (no API cost)
CATASTROPHE_ENTITY_VALIDATION_MODE=strict_rules docker exec catastrophe-analyzer python3 src/monitor.py --once --quietDefault mode is agent (Claude Haiku validates extracted entities before any ticker lookup).
Three options β set stock_analysis.data_source in config/settings.json:
| Value | Notes |
|---|---|
"yfinance" |
Free, no token needed. |
"tiingo" |
Better quality EOD data. Set TIINGO_API_TOKEN in env. |
"ibkr" |
Live bars from IB Gateway. Requires ib-gateway container running. Set IBKR_HOST/IBKR_PORT/IBKR_CLIENT_ID in env or .env. Current setting. |
Note: StockAnalyzer reads data_source once at container startup. Changing settings.json requires a container restart (docker compose restart catastrophe-analyzer) to take effect.
src/monitor.pyβ scheduled service loopsrc/main.pyβ interactive CLIsrc/news_scraper.pyβ source ingestionsrc/entity_extractor.pyβ ticker mapping and validationsrc/stock_analyzer.pyβ price/technical contextsrc/signal_generator.pyβ signal logic and rankingsrc/outcome_tracker.pyβ paper trading: T+1/T+5/T+10/T+20 return trackingsrc/database_manager.pyβ CSV persistencedocs/EVENT_CATEGORIES_AND_IMPACT.mdβ category taxonomy and expansion targets
ANTHROPIC_API_KEY=
TIINGO_API_TOKEN= # optional, falls back to yfinance