Session goal: Implement Phase 3 Deliverable #2 — fee_gate.py prototype with full test suite. Fee gate is the critical first-class component that blocks every signal unless net edge exceeds fees. Based on IBKR AU rates and capital-size-dependent frequency tiers from trade-pattern-v1.md.
Context from previous sessions:
- Phase 1 complete: BH + annual rebalancing confirmed optimal, DRIP study done (+485pp)
- Fee drag analysis: quarterly rebalancing costs $509/quarter for 19-ticker universe
- Phase 3 architecture design (signal-engine-v2-design.md) complete
- Phase 3 Deliverable #2: “Fee gate module (fee_gate.py) prototype” — ⬜ Next
Work completed:
Fee Gate Module (scripts/paper_trading/fee_gate.py) — Phase 3 Deliverable #2 ✅
Implemented the fee gate as a standalone, well-tested Python module. Every signal must pass four gate checks before being allowed to trade:
| # | Check | Rule | Rationale |
|---|---|---|---|
| 1 | Net edge | net_edge > 0 required | Signal must produce positive return after fees |
| 2 | Fee cap | Fee cost ≤ 1% of portfolio capital | Never spend >1% on fees (IBKR flat rates) |
| 3 | Frequency gate | Must be ≥ min days since last rebalance | Enforces capital-tier frequency (annual for $2K, etc.) |
| 4 | Drift override | High drift (>threshold) allows early rebalance | Positions that drifted >2% can rebalance outside schedule |
Capital Tier System
Four tiers matching trade-pattern-v1.md and fee-drag sensitivity analysis:
| Capital | Frequency | Min days between | Drift threshold |
|---|---|---|---|
| 5K | Annual | 365 | 2% |
| 20K | Semi-annual | 180 | 2% |
| 50K | Quarterly | 90 | 2% |
| $50K+ | Full-quarterly | 90 | 2% |
Test Suite (tests/test_fee_gate.py) — 24 tests, all passing ✅
- Constants & FeeSchedule: 4 tests
- Capital tier classification: 6 parameterised tests (75K → full-quarterly)
- Net edge gate: 2 tests (pass positive, block negative)
- Fee cap gate: 2 tests (block fee > 1% capital, pass within limit)
- Frequency/drift gate: 4 tests (block early low-drift, allow high-drift override, allow after full period, skip when no dates)
- Batch/rebalance report: 3 tests (mixed batch, report structure, summary stats)
- Edge cases: 3 tests (zero capital, zero fee cost, zero net edge boundary, large portfolio quarterly allowed)
Progress log:
- HH:MM — Session created, reviewed project state and signal-engine-v2-design.md
- HH:MM — Implemented fee_gate.py with GateResult, gate_signal(), gate_universe_rebalance(), gate_report()
- HH:MM — Wrote 24 unit tests covering all four gate checks + capital tiers + edge cases
- HH:MM — All 24 tests passing. Fixed one test (test_blocks_fee_exceeds_1pct_capital) — signal was blocked by check 1 (net edge) before reaching check 2 (fee cap); corrected fixture to have positive net_edge so fee cap check is actually exercised.
Outputs:
scripts/paper_trading/fee_gate.py(~8.7KB) — complete fee gate moduletests/test_fee_gate.py(~9.4KB) — 24 passing unit tests
Issues / Questions:
- None. Fee gate is production-ready for Phase 3 integration.
Status: done — Phase 3 Deliverable #2 complete. Next: Dividend layer spec (Deliverable #3).