You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

11 KiB

ACE-F v1 — US Stock Event Swing Trading System

AI-powered event-driven swing trading system that uses SEC filings and free market data to identify 1-5 day continuation trades in US equities.

Core principle: AI/LLM is a document interpreter, not a price predictor. Entry signals come from official filings + price confirmation, never from social data alone.

SEC Filings → Document Parser → Feature Builder → Signal Ranker
    ↓                                                  ↓
Price/Volume Confirmation ←──── Backtest Engine ←── Risk Engine
    ↓                                                  ↓
Attention Overlay (optional) ──→ Execution Engine → Post-trade Review

Architecture

apps/                        # Application entry points
├── backtester/              # Event-driven backtest simulation & CLI
├── pipeline/                # Multi-stage data processing
│   ├── filing_poller/       #   Poll SEC EDGAR for new filings
│   ├── filing_fetcher/      #   Download filing documents
│   ├── event_parser/        #   Parse events from filings (rule + LLM)
│   ├── feature_builder/     #   Generate scoring features
│   ├── label_generator/     #   Create forward-return labels
│   └── dataset_export/      #   Export Parquet snapshots for backtesting
├── sync/                    # Data synchronization
│   ├── issuer_sync/         #   Company metadata from Stock Oracle
│   ├── macro_sync/          #   FRED macro indicators
│   └── short_volume_sync/   #   FINRA short sale volume
├── tracker/                 # Strategy improvement tracking CLI
├── tools/                   # Analysis & utility scripts
├── review/                  # Manual review queue
└── qa/                      # Data quality checks

libs/                        # Core libraries
├── backtest/                # Backtesting engine
│   ├── domain.py            #   Pydantic domain models (30+)
│   ├── tracker.py           #   SQS scoring, journal I/O, leaderboard
│   ├── execution.py         #   Entry/exit simulation
│   ├── allocator.py         #   Position sizing & entry gates
│   ├── scoring.py           #   Candidate scoring (PEAD, composite)
│   ├── selector.py          #   Candidate filtering & ranking
│   ├── metrics.py           #   21-metric performance bundle + bootstrap CIs
│   ├── artifacts.py         #   Run output writer (Parquet, JSON, CSV)
│   ├── manifests.py         #   Experiment config resolution
│   ├── snapshot_store.py    #   Parquet data loader
│   ├── splits.py            #   Walk-forward window generation
│   └── calendar.py          #   Trading day utilities
├── common/                  # Logging, config, time utils
├── db/                      # PostgreSQL models (async SQLAlchemy)
├── oracle_client/           # Stock Oracle API client
├── parser/                  # Filing document parser
├── features/                # Feature engineering
├── labeler/                 # Label generation
├── schemas/                 # Shared data schemas
├── export/                  # Snapshot export
├── review/                  # Review logic
└── llm/                     # LLM integration layer

configs/
├── backtest/                # Base backtest configs (defaults.json)
├── experiments/             # 66 experiment manifests
├── app.yaml                 # Application settings
└── symbols_*.yaml           # Asset universe definitions

data/                        # Data storage (parquet snapshots, cache)
runs/                        # Backtest execution outputs
journal/                     # Strategy improvement journal & leaderboard
tests/
├── unit/                    # Unit tests (270+)
├── integration/             # Integration tests (requires PostgreSQL)
└── replay/                  # Determinism replay tests

Setup

Requirements: Python 3.11+, PostgreSQL 16 (via Docker)

# Install dependencies
pip install -e ".[dev]"

# Start PostgreSQL
docker compose up -d

# Run database migrations
alembic upgrade head

# Copy and configure environment
cp .env.example .env

Key environment variables:

Variable Default Description
STOCK_ORACLE_URL http://localhost:18001 Stock Oracle API endpoint
POSTGRES_DSN postgresql+asyncpg://acef:acef@localhost:5432/acef Database connection
DATA_ROOT ./data Data storage root
LOG_LEVEL INFO Logging level
LLM_ENABLED false Enable LLM document parsing

Usage

Data Pipeline

# Sync company metadata
python -m apps.sync.issuer_sync.main

# Fetch and parse filings
python -m apps.pipeline.filing_poller.main
python -m apps.pipeline.filing_fetcher.main
python -m apps.pipeline.event_parser.main

# Build features and labels
python -m apps.pipeline.feature_builder.main
python -m apps.pipeline.label_generator.main

# Export Parquet snapshot for backtesting
python -m apps.pipeline.dataset_export.main

Backtesting

# Single split backtest
python -m apps.backtester.run \
  --manifest configs/experiments/pead_midcap_step1_fixedr.json \
  --split test --output-root runs/midcap_steps

# 3-split backtest (train/valid/test)
for split in train valid test; do
  python -m apps.backtester.run \
    --manifest configs/experiments/pead_midcap_step1_fixedr.json \
    --split $split --output-root runs/midcap_steps
done

# Walk-forward cross-validation
python -m apps.backtester.run \
  --manifest configs/experiments/pead_midcap_step1_fixedr.json \
  --walk-forward --wf-train-days 252 --wf-test-days 63

# Output includes SQS score after each run:
# Run complete: bt_baseline_swing_v1_...
# Trades: 95
# Total return: -0.46%
# SQS: 39.7 (profitability=23.9, risk=52.4, consistency=24.8, robustness=80.7)

Experiment Configuration

Experiments are defined as JSON manifests in configs/experiments/:

{
  "experiment_name": "pead_midcap_step1_fixedr",
  "dataset_snapshot_id": "midcap-filtered",
  "base_config": "configs/backtest/defaults.json",
  "overrides": {
    "signal": { "scoring_model": "pead", "pead_reaction_threshold": 0.07 },
    "execution": { "target_model": "fixed_r", "target_1_r": 2.0 },
    "risk": { "max_positions": 8 }
  },
  "tags": ["pead", "midcap"]
}

Strategy Improvement Tracking System

A structured system to prevent duplicate experiments, enable data-driven decisions, and track the best strategy via a leaderboard.

Strategy Quality Score (SQS)

Composite score (0-100) computed from test split metrics only. Higher is better.

Category Weight Sub-metric Weight 0 pts 100 pts
Profitability 40% profit_factor 60% ≤0.8 ≥2.0
total_return_pct 40% ≤-5% ≥+5%
Risk 25% max_drawdown_pct (inv) 50% ≥10% ≤1%
sharpe_ratio 50% ≤-1.0 ≥2.0
Consistency 20% win_rate 50% ≤0.35 ≥0.65
monthly_win_rate 50% ≤0.30 ≥0.70
Robustness 15% equity_curve_r_squared 50% ≤0.0 ≥0.80
trade_count 50% ≤10 ≥100

Low-trade penalty: If test trades < 20, SQS is halved.

SQS Range Interpretation
0-20 Losing strategy
20-40 Near breakeven
40-55 Promising, needs work
55-70 Good, has OOS edge
70-85 Strong, live candidate
85-100 Exceptional (check for data issues)

Journal & Leaderboard

journal/
├── improvement_journal.jsonl   ← Append-only improvement cycle log
├── experiment_registry.json    ← Leaderboard data (regenerated)
└── LEADERBOARD.md              ← Human-readable leaderboard (regenerated)

Each journal entry records one improvement cycle:

{
  "entry_id": "IMP-0001",
  "timestamp": "2026-03-16T19:30:00",
  "experiment_name": "pead_midcap_step3_10pct",
  "hypothesis": "Raise reaction threshold to 10% for stronger signals",
  "results": {
    "train": { "run_id": "bt_...", "trade_count": 420, "profit_factor": 0.95, ... },
    "valid": { "run_id": "bt_...", ... },
    "test":  { "run_id": "bt_...", ... }
  },
  "sqs_score": 38.5,
  "sqs_breakdown": { "profitability": 35.2, "risk": 45.0, "consistency": 30.0, "robustness": 42.0 },
  "verdict": "better",
  "verdict_reasoning": "Test PF 0.89 -> 1.00, breakeven achieved",
  "next_direction": "Combine 10% threshold + maxcand3"
}

Tracker CLI

# Record experiment results to journal
python -m apps.tracker.cli record \
  --journal-dir journal/ \
  --runs-dir runs/midcap_steps/ \
  --experiment pead_midcap_step3_10pct \
  --hypothesis "Raise reaction threshold to 10%" \
  --baseline pead_7pct_midcap \
  --verdict better \
  --reasoning "Test PF improved from 0.89 to 1.00" \
  --next "Combine 10% threshold + maxcand3"

# View leaderboard
python -m apps.tracker.cli leaderboard --journal-dir journal/

#  # Experiment                                 SQS    PF   Ret% Trades
# ------------------------------------------------------------------
#  1 pead_7pct_longshort_v2                    60.7  1.31   +2.0     55
#  2 pead_midcap_step3_10pct                   38.5  1.00   +0.0     85

# Show entry details
python -m apps.tracker.cli show --journal-dir journal/ IMP-0001

# Check for duplicate experiments
python -m apps.tracker.cli check-duplicate \
  --journal-dir journal/ --experiment pead_midcap_step3_10pct

Improvement Workflow

1. Create experiment config     configs/experiments/my_experiment.json
2. Run 3-split backtest         for split in train valid test; do ... done
3. Record to journal            python -m apps.tracker.cli record ...
4. Check leaderboard            python -m apps.tracker.cli leaderboard ...
5. Plan next experiment         based on verdict + SQS breakdown
6. Check for duplicates         python -m apps.tracker.cli check-duplicate ...
7. Repeat from step 1

Testing

# Unit tests (fast, no external deps)
pytest tests/unit/ -v

# Backtest module tests only
pytest tests/unit/backtest/ -v

# Integration tests (requires PostgreSQL)
pytest tests/integration/ -v

# Full CI check (lint + typecheck + unit tests)
make ci

Data Sources

Source Role Cost
SEC EDGAR Primary event source (8-K, 10-Q, 6-K filings) Free
Stock Oracle API Market data (OHLCV bars, company info) Internal
FRED Macro regime indicators (rates, spreads) Free
FINRA Short sale volume (crowding signal) Free
Wikimedia Retail attention via pageviews Free
YouTube Channel-based attention tracking Free (quota limited)
Yahoo RSS Headline burst detection Free

Tech Stack

Component Technology
Language Python 3.11+
Models Pydantic v2
Database PostgreSQL 16 + async SQLAlchemy
Research data DuckDB + Parquet
Containers Docker Compose
Linting Ruff
Type checking MyPy (strict)
Testing Pytest + asyncio
Logging structlog (JSON)

License

Private project. All rights reserved.