← Back to Dashboard

System State Machine Diagrams

Comprehensive State Documentation for Polymarket Earnings Trading System

Version: 1.8 | Created: January 11, 2026 | Last Updated: May 31, 2026

v1.8 Changes (Apr 27, 2026 — Database Integrity Audit Phase 3 / Finding #258): - §8 "Watchdog v3" REPLACED by polymarket-integrity-monitor.service running src/data_tracker/integrity_monitor.py. The state machine below is retained as historical context — current operative health-check architecture is the ~51-rule declarative monitor. See docs/DATA_INTEGRITY.md §2 + docs/OPERATIONS.md §8.A. - Both polymarket-watchdog.service (v2) and polymarket-watchdog-v3.service were decommissioned by deploy/deploy_from_github.sh Apr 27, 2026.

v1.7 / v1.4 / v1.3 / v1.2 / v1.1 Changes: see git history.


Table of Contents

  1. System Overview
  2. Trading Orchestrator
  3. Order Executor
  4. 3.4 Fractional Shares Flow
  5. 3.5 Exit Verification Flow
  6. Signal Generator
  7. Risk Manager
  8. Batch Order Manager
  9. IBKR Gateway Monitor
  10. Integrity Monitor (replaces Watchdog v2/v3)
  11. Position Lifecycle
  12. Data Collection Pipeline
  13. Fractional Shares

1. System Overview

1.1 High-Level Architecture

┌─────────────────────────────────────────────────────────────────────────┐
│                        TRADING SYSTEM ARCHITECTURE                       │
└─────────────────────────────────────────────────────────────────────────┘

     ┌──────────────────┐     ┌──────────────────┐     ┌──────────────────┐
     │   DATA LAYER     │     │  DECISION LAYER  │     │ EXECUTION LAYER  │
     └────────┬─────────┘     └────────┬─────────┘     └────────┬─────────┘
              │                        │                        │
              ▼                        ▼                        ▼
   ┌──────────────────┐    ┌──────────────────┐    ┌──────────────────┐
   │ Data Collectors  │───▶│ Signal Generator │───▶│ Order Executor   │
   │ • Prices         │    │ • Conviction     │    │ • Entries        │
   │ • Orderbooks     │    │ • Timing         │    │ • Exits          │
   │ • Trades         │    │ • Priority       │    │ • Stop-Loss      │
   └──────────────────┘    └──────────────────┘    └──────────────────┘
              │                        │                        │
              │                        ▼                        │
              │            ┌──────────────────┐                 │
              │            │Trading Orchestrator│◀──────────────┘
              │            │ • Schedule        │
              │            │ • Coordination    │
              │            │ • Position Mgmt   │
              │            └──────────────────┘
              │                        │
              │                        ▼
              │            ┌──────────────────┐
              │            │  Risk Manager    │
              │            │ • Position Size  │
              │            │ • Circuit Breakers│
              │            │ • Exposure Limits│
              │            └──────────────────┘
              │                        │
              ▼                        ▼
   ┌──────────────────┐    ┌──────────────────┐    ┌──────────────────┐
   │ Integrity Monitor│    │    Dashboard     │    │  IBKR Gateway    │
   │ • Service Health │    │ • Visualization  │    │ • Connection     │
   │ • Data Quality   │    │ • Monitoring     │    │ • Orders         │
   │ • Alerts         │    │ • History        │    │ • Account        │
   └──────────────────┘    └──────────────────┘    └──────────────────┘

1.2 Component Dependencies

                    ┌─────────────────────────────────┐
                    │     TradingOrchestrator         │
                    │ (Main Controller - Entry Point) │
                    └───────────────┬─────────────────┘
                                    │
           ┌────────────────────────┼────────────────────────┐
           │                        │                        │
           ▼                        ▼                        ▼
   ┌───────────────┐      ┌─────────────────┐      ┌─────────────────┐
   │SignalGenerator│      │  RiskManager    │      │ OrderExecutor   │
   │               │      │                 │      │                 │
   │ Dependencies: │      │ Dependencies:   │      │ Dependencies:   │
   │ • Database    │      │ • TradingMode   │      │ • IBKRClient    │
   │ • Yahoo API   │      │ • IBKRClient    │      │ • RiskManager   │
   │ • Market Cal  │      │                 │      │                 │
   └───────────────┘      └─────────────────┘      └─────────────────┘
           │                        │                        │
           │                        │                        ▼
           │                        │              ┌─────────────────┐
           │                        │              │BatchOrderManager│
           │                        │              │                 │
           │                        │              │ Dependencies:   │
           │                        │              │ • OrderExecutor │
           │                        │              │ • RiskManager   │
           │                        │              └─────────────────┘
           │                        │
           ▼                        ▼
   ┌───────────────┐      ┌─────────────────┐
   │EarningsDetector│      │  AuditLogger   │
   │               │      │                 │
   │ Dependencies: │      │ Dependencies:   │
   │ • Alpha Vantage│      │ • Database     │
   │ • Yahoo API   │      │                 │
   └───────────────┘      └─────────────────┘

2. Trading Orchestrator

2.1 Main States

┌──────────────────────────────────────────────────────────────────────────┐
│                    TRADING ORCHESTRATOR STATE MACHINE                     │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │   INITIALIZING   │
                          │                  │
                          │ • Load config    │
                          │ • Init components│
                          │ • Load positions │
                          └────────┬─────────┘
                                   │
                                   │ Components ready
                                   ▼
                          ┌──────────────────┐
                          │    STARTING      │
                          │                  │
                          │ • Setup schedule │
                          │ • Start monitoring│
                          │ • Startup check  │
                          └────────┬─────────┘
                                   │
                  ┌────────────────┴────────────────┐
                  │                                 │
                  │ Market Open                     │ Market Closed
                  ▼                                 ▼
         ┌──────────────────┐              ┌──────────────────┐
         │   RUNNING        │              │    IDLE          │
         │                  │              │                  │
         │ • Execute cycles │◀────────────▶│ • Wait for market│
         │ • Monitor exits  │  Market      │ • Background sync│
         │ • Check earnings │  Open/Close  │                  │
         └────────┬─────────┘              └──────────────────┘
                  │
     ┌────────────┼────────────────────────┐
     │            │                        │
     │ Error      │ Circuit Breaker        │ Shutdown Signal
     ▼            ▼                        ▼
┌──────────┐ ┌──────────────┐      ┌──────────────────┐
│  ERROR   │ │   PAUSED     │      │   SHUTTING_DOWN  │
│          │ │              │      │                  │
│ • Log    │ │ • No new     │      │ • Close positions│
│ • Alert  │ │   trades     │      │ • Save state     │
│ • Recover│ │ • Monitor    │      │ • Send alerts    │
└──────────┘ │   existing   │      └──────────────────┘
             └──────────────┘

2.2 Trading Mode States

┌──────────────────────────────────────────────────────────────────────────┐
│                         TRADING MODE STATE MACHINE                        │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │      PAPER       │
                          │                  │
                          │ Simulated trades │
                          │ No real money    │
                          │ Full position    │
                          └────────┬─────────┘
                                   │
                                   │ Enable TESTING_PROD
                                   ▼
                          ┌──────────────────┐
                          │  TESTING_PROD    │◀─────────────────┐
                          │                  │                  │
                          │ • Real money     │                  │
                          │ • 50% sizing     │                  │ Trade < 100
                          │ • Track 100 trades│                 │
                          └────────┬─────────┘                  │
                                   │                            │
                    ┌──────────────┴──────────────┐            │
                    │                             │            │
                    │ 100 trades                  │ Any trade  │
                    │ completed                   │ result     │
                    │ successfully                │            │
                    ▼                             └────────────┘
           ┌──────────────────┐
           │      LIVE        │
           │                  │
           │ • Full position  │
           │ • All features   │
           └────────┬─────────┘
                    │
                    │ Manual pause / Circuit breaker
                    ▼
           ┌──────────────────┐
           │     PAUSED       │
           │                  │
           │ • No new trades  │
           │ • Monitor only   │
           │ • Manual review  │
           └──────────────────┘

2.3 Market Status States

┌──────────────────────────────────────────────────────────────────────────┐
│                         MARKET STATUS STATE MACHINE                       │
└──────────────────────────────────────────────────────────────────────────┘

         4:00 AM ET                                      8:00 PM ET
             │                                               │
             ▼                                               ▼
   ┌──────────────────┐  9:30 AM ET  ┌──────────────────┐   
   │   PRE_MARKET     │─────────────▶│      OPEN        │
   │                  │              │                  │
   │ 4:00 AM - 9:30 AM│              │ 9:30 AM - 4:00 PM│
   │                  │              │                  │
   │ • Extended hours │              │ • Regular trading│
   │ • NASDAQ active  │              │ • Full liquidity │
   │ • NYSE limited   │              │ • All order types│
   └──────────────────┘              └────────┬─────────┘
             ▲                                │
             │                                │ 4:00 PM ET
             │                                ▼
   ┌──────────────────┐              ┌──────────────────┐
   │     CLOSED       │◀─────────────│   AFTER_HOURS    │
   │                  │  8:00 PM ET  │                  │
   │ 8:00 PM - 4:00 AM│              │ 4:00 PM - 8:00 PM│
   │                  │              │                  │
   │ • No trading     │              │ • Extended hours │
   │ • Prep for next  │              │ • NASDAQ active  │
   │ • System maint.  │              │ • NYSE limited   │
   └──────────────────┘              └──────────────────┘

2.4 Daily Trading Cycle

┌──────────────────────────────────────────────────────────────────────────┐
│                           DAILY TRADING CYCLE                             │
└──────────────────────────────────────────────────────────────────────────┘

   TIME (ET)    EVENT                        STATE TRANSITIONS
   ─────────    ─────                        ─────────────────

   4:00 AM      Market Pre-Open              CLOSED → PRE_MARKET
       │
   9:30 AM      Market Opens                 PRE_MARKET → OPEN
       │
  10:30 AM      AMC Signal Check
       │        ┌─────────────────────────────────────────────────┐
  10:30 AM ────▶│ run_amc_cycle()                                 │
       │        │ • Check AMC signals for today's earnings        │
       │        │ • If signals found → schedule entry at 10:34 AM │
       │        └─────────────────────────────────────────────────┘
       │
  10:32 AM      BMO Exit Time (1h after open)
       │        ┌─────────────────────────────────────────────────┐
  10:32 AM ────▶│ execute_scheduled_exits(BMO)                    │
       │        │ • Close all BMO positions from previous day     │
       │        │ • LIMIT → MARKET fallback                       │
       │        └─────────────────────────────────────────────────┘
       │
  10:34 AM      AMC Entry Time (1h 4min after open)
       │        ┌─────────────────────────────────────────────────┐
  10:34 AM ────▶│ execute_batch_entries(AMC)                      │
       │        │ • Execute all AMC entries in batch              │
       │        │ • Attach stop-loss to each                      │
       │        └─────────────────────────────────────────────────┘
       │
   3:50 PM      BMO Signal Check
       │        ┌─────────────────────────────────────────────────┐
   3:50 PM ────▶│ run_bmo_cycle()                                 │
       │        │ • Check BMO signals for tomorrow's earnings     │
       │        │ • Calculate batch sizes                         │
       │        │ • If signals found → schedule entry at 3:58 PM  │
       │        └─────────────────────────────────────────────────┘
       │
   3:57 PM      AMC Exit Time
       │        ┌─────────────────────────────────────────────────┐
   3:57 PM ────▶│ execute_scheduled_exits(AMC)                    │
       │        │ • Close all AMC positions                       │
       │        │ • 1-min buffer before BMO entries               │
       │        └─────────────────────────────────────────────────┘
       │
   3:58 PM      BMO Entry Time
       │        ┌─────────────────────────────────────────────────┐
   3:58 PM ────▶│ execute_batch_entries(BMO)                      │
       │        │ • Execute all BMO entries in batch              │
       │        │ • 2 minutes before market close                 │
       │        └─────────────────────────────────────────────────┘
       │
   4:00 PM      Market Closes                OPEN → AFTER_HOURS
       │
   8:00 PM      After-Hours End              AFTER_HOURS → CLOSED

3. Order Executor

3.1 Order Status States

┌──────────────────────────────────────────────────────────────────────────┐
│                         ORDER STATUS STATE MACHINE                        │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │    PENDING       │
                          │                  │
                          │ Order created,   │
                          │ not yet submitted│
                          └────────┬─────────┘
                                   │
                                   │ Submit to IBKR
                                   ▼
                          ┌──────────────────┐
                          │   SUBMITTED      │
                          │                  │
                          │ Waiting for fill │
                          └────────┬─────────┘
                                   │
         ┌─────────────────────────┼─────────────────────────┐
         │                         │                         │
         │ Full fill               │ Partial fill            │ Rejected/Error
         ▼                         ▼                         ▼
┌──────────────────┐    ┌──────────────────┐    ┌──────────────────┐
│     FILLED       │    │PARTIALLY_FILLED  │    │     FAILED       │
│                  │    │                  │    │                  │
│ Order complete   │    │ Some shares      │    │ Order rejected   │
│ Position updated │    │ filled           │    │ Error logged     │
└──────────────────┘    └────────┬─────────┘    └──────────────────┘
                                 │
                    ┌────────────┴────────────┐
                    │                         │
                    │ Remaining fills         │ Cancelled
                    ▼                         ▼
           ┌──────────────────┐     ┌──────────────────┐
           │     FILLED       │     │   CANCELLED      │
           │                  │     │                  │
           │ All shares       │     │ Remaining shares │
           │ executed         │     │ not filled       │
           └──────────────────┘     └──────────────────┘

3.2 Guaranteed Fill Process (LIMIT → MARKET Fallback)

┌──────────────────────────────────────────────────────────────────────────┐
│                      GUARANTEED FILL STATE MACHINE                        │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │   START          │
                          │                  │
                          │ Calculate limit  │
                          │ price with buffer│
                          └────────┬─────────┘
                                   │
                                   │ Submit LIMIT order
                                   ▼
                          ┌──────────────────┐
                          │ LIMIT_PENDING    │
                          │                  │
                          │ Timeout: 12 sec  │
                          │ (batch mode)     │
                          └────────┬─────────┘
                                   │
                  ┌────────────────┴────────────────┐
                  │                                 │
                  │ Filled within timeout           │ Timeout reached
                  ▼                                 ▼
         ┌──────────────────┐              ┌──────────────────┐
         │  LIMIT_FILLED    │              │ CANCEL_LIMIT     │
         │                  │              │                  │
         │ Record slippage  │              │ Cancel LIMIT     │
         │ Log fill details │              │ Submit MARKET    │
         └────────┬─────────┘              └────────┬─────────┘
                  │                                 │
                  │                                 ▼
                  │                        ┌──────────────────┐
                  │                        │ MARKET_PENDING   │
                  │                        │                  │
                  │                        │ Wait for fill    │
                  │                        │ (usually instant)│
                  │                        └────────┬─────────┘
                  │                                 │
                  │                                 │ Filled
                  │                                 ▼
                  │                        ┌──────────────────┐
                  │                        │ MARKET_FILLED    │
                  │                        │                  │
                  │                        │ Record as        │
                  │                        │ LIMIT_FALLBACK   │
                  │                        └────────┬─────────┘
                  │                                 │
                  └─────────────────┬───────────────┘
                                    │
                                    ▼
                          ┌──────────────────┐
                          │   COMPLETE       │
                          │                  │
                          │ • ExecutionResult│
                          │ • Slippage logged│
                          │ • Commission     │
                          └──────────────────┘

3.3 Order Type by Exchange and Session

┌──────────────────────────────────────────────────────────────────────────┐
│                    ORDER TYPE DECISION STATE MACHINE                      │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │  DETERMINE_TYPE  │
                          │                  │
                          │ Input: Exchange, │
                          │ Session, Action  │
                          └────────┬─────────┘
                                   │
              ┌────────────────────┴────────────────────┐
              │                                         │
              │ Exchange == NASDAQ                      │ Exchange == NYSE
              ▼                                         ▼
     ┌──────────────────┐                     ┌──────────────────┐
     │    NASDAQ        │                     │      NYSE        │
     │                  │                     │                  │
     │ All sessions:    │                     │ Check session:   │
     │ • Entry: LIMIT   │                     │                  │
     │ • Exit: MARKET   │                     └────────┬─────────┘
     │ • Stop: STOP     │                              │
     └──────────────────┘             ┌────────────────┴────────────────┐
                                      │                                 │
                                      │ Regular Hours                   │ Extended Hours
                                      │ (9:30 AM - 4:00 PM)             │ (Pre/Post)
                                      ▼                                 ▼
                             ┌──────────────────┐             ┌──────────────────┐
                             │ NYSE_REGULAR     │             │ NYSE_EXTENDED    │
                             │                  │             │                  │
                             │ Same as NASDAQ:  │             │ LIMIT only:      │
                             │ • Entry: LIMIT   │             │ • Entry: LIMIT   │
                             │ • Exit: MARKET   │             │ • Exit: LIMIT    │
                             │ • Stop: STOP     │             │ • Stop: STOP-LMT │
                             └──────────────────┘             └──────────────────┘

3.4 Position Sizing Flow (Updated Jan 20, 2026)

The system uses WHOLE SHARES ONLY for all orders.

CRITICAL BUG FIX (Jan 20, 2026 - Finding #51): IBKR's cashQty feature does NOT work reliably: - Error 10244: "Cash Quantity cannot be used for this order" - Fails with extended hours trading (outsideRth=True) - Has stock-specific restrictions that are unpredictable

Solution: Always use whole shares. If position size < stock price, skip the trade.

┌──────────────────────────────────────────────────────────────────────────┐
│                 POSITION SIZING STATE MACHINE (v3 - Whole Shares Only)    │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │   START          │
                          │                  │
                          │ Target: $100.00  │
                          │ Price: $90.00    │
                          └────────┬─────────┘
                                   │
                                   │ Calculate whole shares
                                   │ shares = int(target / price)
                                   ▼
                          ┌──────────────────┐
                          │ CALC_WHOLE_SHARES│
                          │                  │
                          │ $100 / $90 = 1.11│
                          │ int(1.11) = 1    │
                          └────────┬─────────┘
                                   │
                  ┌────────────────┴────────────────┐
                  │                                 │
                  │ shares >= 1                     │ shares == 0
                  ▼                                 ▼
         ┌──────────────────┐              ┌──────────────────┐
         │ PLACE_ORDER      │              │ SKIP_POSITION    │
         │                  │              │                  │
         │ totalQuantity=1  │              │ Target < Price   │
         │ (whole shares)   │              │ Cannot buy 1 sh  │
         │                  │              │                  │
         │ Order placed!    │              │ Log warning      │
         └────────┬─────────┘              └────────┬─────────┘
                  │                                 │
                  │                                 │
                  ▼                                 ▼
         ┌──────────────────┐              ┌──────────────────┐
         │ ORDER_DOLLAR     │              │ ORDER_WHOLE      │
         │                  │              │                  │
         │ totalQuantity=0  │              │ Use int type     │
         │ cashQty=$121.13  │              │ is_fractional=F  │
         │ is_fractional=T  │              │                  │
         │                  │              │                  │
         │ IBKR handles     │              │ Actual: $0       │
         │ fractional calc  │              │ (skipped - <1 sh)│
         └────────┬─────────┘              └────────┬─────────┘
                  │                                 │
                  └─────────────────┬───────────────┘
                                    │
                                    ▼
                          ┌──────────────────┐
                          │ SUBMIT_TO_IBKR   │
                          │                  │
                          │ Uses existing    │
                          │ LIMIT→MARKET     │
                          │ fallback flow    │
                          └──────────────────┘

API Order Syntax:

# WRONG (Error 10243)
order = LimitOrder('BUY', Decimal('0.7219'), 168.13)

# CORRECT (Dollar-based order)
order = LimitOrder('BUY', 0, 168.13)  # totalQuantity=0
order.cashQty = 121.13                # Dollar amount

Eligible Exchanges: - NYSE, NASDAQ, AMEX, ARCA, BATS, IEX - Canadian and European exchanges (limited)

Not Eligible: - OTC/Pink Sheet stocks - Low-liquidity stocks - Some non-USD denominated stocks

Minimum Order: - Dollar-based: $1.00 minimum cashQty - Whole shares: 1 share minimum

Database Tracking (Migration 012):

-- trading_positions
is_fractional BOOLEAN        -- True if cashQty was used
shares_fractional NUMERIC(12,4)  -- Display/tracking only

-- trade_audit_log
is_fractional BOOLEAN
shares_fractional NUMERIC(12,4)
fractional_reason VARCHAR(50)
fractional_capital_saved NUMERIC(10,2)

3.5 Exit Verification Flow (Added Jan 11, 2026)

┌──────────────────────────────────────────────────────────────────────────┐
│                    EXIT VERIFICATION STATE MACHINE                        │
└──────────────────────────────────────────────────────────────────────────┘

                         ┌──────────────────┐
                         │   EXIT_ORDERED   │
                         │                  │
                         │ Exit order sent  │
                         │ to IBKR          │
                         └────────┬─────────┘
                                  │
                                  │ Wait for fill
                                  ▼
                         ┌──────────────────┐
                         │  WAIT_FOR_FILL   │
                         │                  │
                         │ • LIMIT: 5s      │
                         │ • NYSE: 30s      │
                         │ • Fallback: MKT  │
                         └────────┬─────────┘
                                  │
                 ┌────────────────┴────────────────┐
                 │                                 │
                 │ Filled                          │ Not Filled
                 ▼                                 ▼
        ┌──────────────────┐              ┌──────────────────┐
        │ VERIFY_IBKR_POS  │              │ MARKET_FALLBACK  │
        │                  │              │                  │
        │ Query IBKR       │              │ Cancel LIMIT     │
        │ positions()      │              │ Place MARKET     │
        └────────┬─────────┘              └────────┬─────────┘
                 │                                 │
                 │ Check shares                    │
                 ▼                                 ▼
        ┌──────────────────┐              ┌──────────────────┐
        │ Position = 0?    │              │  VERIFY_IBKR_POS │
        └────────┬─────────┘              └────────┬─────────┘
                 │                                 │
    ┌────────────┴────────────┐                    │
    │                         │                    │
    │ Yes                     │ No                 │
    ▼                         ▼                    ▼
┌──────────────┐     ┌──────────────────┐   ┌──────────────┐
│  VERIFIED    │     │ VERIFICATION_    │   │  VERIFIED    │
│              │     │ FAILED           │   │  (if 0)      │
│ exit_verified│     │                  │   └──────────────┘
│ = True       │     │ • Log error      │
│              │     │ • Send CRITICAL  │
│ Mark DB      │     │   alert          │
│ closed       │     │ • Keep DB open   │
└──────────────┘     │ • Manual review  │
                     │   required       │
                     └──────────────────┘

Exit Verification Outcomes

Outcome Action Database Alert
Verified (shares=0) Position closed status='closed', exit_verified=TRUE None
Failed (shares>0) Investigation required status='open', exit_verified=FALSE 🚨 CRITICAL
Error (query failed) Retry on next cycle No change ⚠️ WARNING

Position Reconciliation (Startup)

┌──────────────────────────────────────────────────────────────────────────┐
│                 POSITION RECONCILIATION STATE MACHINE                     │
└──────────────────────────────────────────────────────────────────────────┘

                         ┌──────────────────┐
                         │ LOAD_DB_POSITIONS│
                         │                  │
                         │ Query open       │
                         │ positions from   │
                         │ trading_positions│
                         └────────┬─────────┘
                                  │
                                  ▼
                         ┌──────────────────┐
                         │ LOAD_IBKR_POS    │
                         │                  │
                         │ Query ib.        │
                         │ positions()      │
                         └────────┬─────────┘
                                  │
                                  ▼
                         ┌──────────────────┐
                         │ COMPARE          │
                         │                  │
                         │ For each DB pos: │
                         │ • Find in IBKR   │
                         │ • Check shares   │
                         │ For each IBKR:   │
                         │ • Find in DB     │
                         └────────┬─────────┘
                                  │
         ┌────────────────────────┼────────────────────────┐
         │                        │                        │
         ▼                        ▼                        ▼
┌──────────────┐        ┌──────────────┐        ┌──────────────┐
│  ORPHANED    │        │  MISMATCH    │        │  EXTERNAL    │
│              │        │              │        │              │
│ In DB but    │        │ Shares       │        │ In IBKR but  │
│ not IBKR     │        │ differ       │        │ not in DB    │
│              │        │              │        │              │
│ → Alert      │        │ → Alert      │        │ → Alert      │
│ → Mark       │        │ → Log        │        │ → Log to     │
│   orphaned   │        │ → Manual fix │        │   external_  │
│              │        │              │        │   trades     │
└──────────────┘        └──────────────┘        └──────────────┘

Database Tracking (Migration 013)

-- trading_positions
exit_verified BOOLEAN
exit_verified_at TIMESTAMPTZ
ibkr_position_at_exit NUMERIC(12,4)
last_reconciled_at TIMESTAMPTZ
reconciliation_status VARCHAR(20)  -- 'synced', 'mismatch', 'orphaned', 'external'

-- trade_audit_log
ibkr_client_id INTEGER  -- Bot uses clientId=1

-- New Tables
external_trades  -- Log detected external trades
position_reconciliation_log  -- Audit reconciliation runs

4. Signal Generator

4.1 Signal Generation Flow

┌──────────────────────────────────────────────────────────────────────────┐
│                     SIGNAL GENERATION STATE MACHINE                       │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │ GET_EARNINGS     │
                          │                  │
                          │ Query earnings_  │
                          │ markets table    │
                          └────────┬─────────┘
                                   │
                                   │ List of upcoming earnings
                                   ▼
                          ┌──────────────────┐
                          │ FETCH_ORDERBOOKS │
                          │                  │
                          │ Get Polymarket   │
                          │ orderbook data   │
                          └────────┬─────────┘
                                   │
                                   │ For each market
                                   ▼
                          ┌──────────────────┐
                          │CALC_CONVICTION   │
                          │                  │
                          │ Conviction =     │
                          │ (YES bid + ask)/2│
                          └────────┬─────────┘
                                   │
                  ┌────────────────┴────────────────┐
                  │                                 │
                  │ 70% ≤ Conviction               │ Conviction ≤ 30%
                  │ (LONG signal)                  │ (SHORT signal)
                  ▼                                 ▼
         ┌──────────────────┐              ┌──────────────────┐
         │ VALIDATE_LONG    │              │ VALIDATE_SHORT   │
         │                  │              │                  │
         │ • Check spread   │              │ • Check spread   │
         │ • Check volume   │              │ • Check volume   │
         │ • Check timing   │              │ • Calc confidence│
         │                  │              │ (1 - conviction) │
         └────────┬─────────┘              └────────┬─────────┘
                  │                                 │
                  │ Valid                           │ Valid
                  ▼                                 ▼
         ┌──────────────────┐              ┌──────────────────┐
         │ CLASSIFY_MCAP    │              │ CLASSIFY_MCAP    │
         │                  │              │                  │
         │ • >$100B = LARGE │              │ • >$100B = LARGE │
         │ • $10-100B = MID │              │ • $10-100B = MID │
         │ • <$10B = SMALL  │              │ • <$10B = SMALL  │
         └────────┬─────────┘              └────────┬─────────┘
                  │                                 │
                  └─────────────┬───────────────────┘
                                │
                                ▼
                       ┌──────────────────┐
                       │ CALC_PRIORITY    │
                       │                  │
                       │ Market Cap +     │
                       │ Conviction +     │
                       │ Volume → Score   │
                       │ (0-8, #313)      │
                       └────────┬─────────┘
                                │
               ┌────────────────┴────────────────┐
               │                                 │
               │ Score > 0                       │ Score == 0
               ▼                                 ▼
      ┌──────────────────┐              ┌──────────────────┐
      │ CREATE_SIGNAL    │              │      SKIP        │
      │                  │              │                  │
      │ TradingSignal    │              │ Log reason:      │
      │ dataclass        │              │ • Small cap      │
      │ populated        │              │ • NYSE small     │
      └────────┬─────────┘              │ • Low conviction │
               │                        └──────────────────┘
               │
               ▼
      ┌──────────────────┐
      │ PRIORITIZE       │
      │                  │
      │ Sort by priority │
      │ Filter SKIP      │
      │ Return list      │
      └──────────────────┘

4.2 Signal Direction Decision

┌──────────────────────────────────────────────────────────────────────────┐
│                    SIGNAL DIRECTION STATE MACHINE                         │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │ CHECK_CONVICTION │
                          │                  │
                          │ Input: conviction│
                          │ (0.0 - 1.0)      │
                          └────────┬─────────┘
                                   │
         ┌─────────────────────────┼─────────────────────────┐
         │                         │                         │
         │ conviction ≥ 0.70       │ 0.30 < conv < 0.70     │ conviction ≤ 0.30
         │ (Beat expected)         │ (No edge)               │ (Miss expected)
         ▼                         ▼                         ▼
┌──────────────────┐    ┌──────────────────┐    ┌──────────────────┐
│      LONG        │    │     NO_SIGNAL    │    │      SHORT       │
│                  │    │                  │    │                  │
│ • BUY stock      │    │ Skip this market │    │ • SELL stock     │
│ • Stop: 3/4/5%   │    │ No trading edge  │    │ • Stop: 3/4/5%   │
│ • Exit: +move    │    │                  │    │ • Exit: +move    │
└──────────────────┘    └──────────────────┘    └──────────────────┘

Stop levels: 3% / 4% / 5% by mcap tier, placed as STP-LMT orders (Findings #202 / #179).

4.3 Earnings Timing Classification

┌──────────────────────────────────────────────────────────────────────────┐
│                    EARNINGS TIMING STATE MACHINE                          │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │ DETERMINE_TIMING │
                          │                  │
                          │ Input: endDate   │
                          │ from Polymarket  │
                          └────────┬─────────┘
                                   │
                 Priority 1: Check earnings_timing.py (centralized)
                                   │
               ┌───────────────────┴───────────────────┐
               │                                       │
               │ Found in lookup                       │ Not in lookup
               ▼                                       ▼
      ┌──────────────────┐                   ┌──────────────────┐
      │ USE_KNOWN_TIMING │                   │ INFER_FROM_TIME  │
      │                  │                   │                  │
      │ e.g., JPM → BMO  │                   │ Parse endDate    │
      │ e.g., NFLX → AMC │                   │ UTC hour         │
      └──────────────────┘                   └────────┬─────────┘
                                                      │
                             ┌────────────────────────┼────────────────────────┐
                             │                        │                        │
                             │ hour < 15 UTC          │ hour ≥ 21 UTC          │ else
                             │ (before 11 AM ET)      │ (after 5 PM ET)        │
                             ▼                        ▼                        ▼
                    ┌──────────────────┐   ┌──────────────────┐   ┌──────────────────┐
                    │       BMO        │   │       AMC        │   │       TBD        │
                    │                  │   │                  │   │                  │
                    │ Before Market    │   │ After Market     │   │ Ambiguous        │
                    │ Open             │   │ Close            │   │ Fallback to Yahoo│
                    │                  │   │                  │   │                  │
                    │ Entry: 3:58 PM   │   │ Entry: 10:34 AM  │   │ Entry: TBD       │
                    │ Exit: 10:32 AM   │   │ Exit: 3:57 PM    │   │                  │
                    └──────────────────┘   └──────────────────┘   └──────────────────┘

5. Risk Manager

5.1 Risk Level States

┌──────────────────────────────────────────────────────────────────────────┐
│                        RISK LEVEL STATE MACHINE                           │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │     NORMAL       │
                          │                  │
                          │ • Full trading   │
                          │ • 100% sizing    │
                          │ • VIX < 20       │
                          └────────┬─────────┘
                                   │
                                   │ VIX > 20 OR Losses > 1%
                                   ▼
                          ┌──────────────────┐
                          │    ELEVATED      │
                          │                  │
                          │ • 75% sizing     │
                          │ • VIX 20-25      │
                          │ • Daily loss 1-2%│
                          └────────┬─────────┘
                                   │
                                   │ VIX > 25 OR Losses > 2%
                                   ▼
                          ┌──────────────────┐
                          │      HIGH        │
                          │                  │
                          │ • 50% sizing     │
                          │ • VIX 25-30      │
                          │ • Daily loss 2-3%│
                          │ • Minimal new    │
                          └────────┬─────────┘
                                   │
                                   │ VIX > 30 OR Losses > 3%
                                   ▼
                          ┌──────────────────┐
                          │    CRITICAL      │
                          │                  │
                          │ • No new trades  │
                          │ • VIX > 30       │
                          │ • Daily loss >3% │
                          │ • Circuit breaker│
                          └──────────────────┘

   Recovery Path (when conditions improve):
   CRITICAL → HIGH → ELEVATED → NORMAL
   (Gradual de-escalation with cooldown periods)

5.2 Circuit Breaker States

┌──────────────────────────────────────────────────────────────────────────┐
│                     CIRCUIT BREAKER STATE MACHINE                         │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │     INACTIVE     │
                          │                  │
                          │ No breakers      │
                          │ Normal trading   │
                          └────────┬─────────┘
                                   │
      ┌────────────────────────────┼────────────────────────────┐
      │                            │                            │
      │ Daily Loss > 3%            │ Drawdown > 10%             │ VIX > 30
      ▼                            ▼                            ▼
┌───────────────┐         ┌───────────────┐         ┌───────────────┐
│  DAILY_LOSS   │         │   DRAWDOWN    │         │     VIX       │
│               │         │               │         │               │
│ Resume: EOD   │         │ Resume: Manual│         │ Resume: <25   │
└───────────────┘         └───────────────┘         └───────────────┘

      │                            │                            │
      │ Consec. Loss > 3           │ Slippage > 1%              │ Manual
      ▼                            ▼                            ▼
┌───────────────┐         ┌───────────────┐         ┌───────────────┐
│CONSEC_LOSS    │         │ EXEC_QUALITY  │         │ MANUAL_PAUSE  │
│               │         │               │         │               │
│ Resume: 24h   │         │ Resume: 1h    │         │ Resume: Manual│
└───────────────┘         └───────────────┘         └───────────────┘

                                   │
                                   ▼
                          ┌──────────────────┐
                          │  BREAKER_ACTIVE  │
                          │                  │
                          │ • No new trades  │
                          │ • Monitor only   │
                          │ • Log all events │
                          │ • Send alerts    │
                          └────────┬─────────┘
                                   │
                                   │ resume_at reached OR manual clear
                                   ▼
                          ┌──────────────────┐
                          │   RESUMING       │
                          │                  │
                          │ • Clear breaker  │
                          │ • Log recovery   │
                          │ • Resume trading │
                          └────────┬─────────┘
                                   │
                                   ▼
                          ┌──────────────────┐
                          │     INACTIVE     │
                          └──────────────────┘

5.3 Position Sizing Decision

┌──────────────────────────────────────────────────────────────────────────┐
│                    POSITION SIZING STATE MACHINE                          │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │  CHECK_CAPITAL   │
                          │                  │
                          │ Get available    │
                          │ capital from IBKR│
                          └────────┬─────────┘
                                   │
                                   ▼
                          ┌──────────────────┐
                          │  CHECK_EXPOSURE  │
                          │                  │
                          │ Current exposure │
                          │ vs 1.40x cap     │
                          └────────┬─────────┘
                                   │
                  ┌────────────────┴────────────────┐
                  │                                 │
                  │ Exp < 1.40x cap                 │ Exp ≥ 1.40x cap
                  ▼                                 ▼
         ┌──────────────────┐              ┌──────────────────┐
         │ CHECK_MARKET_CAP │              │    REJECT        │
         │                  │              │                  │
         │ Size by tier:    │              │ Max exposure     │
         │ • LARGE: 30%     │              │ reached          │
         │ • MID: 22%       │              │                  │
         │ • SMALL: 15%     │              └──────────────────┘
         └────────┬─────────┘
                  │
                  ▼
         ┌──────────────────┐
         │  APPLY_MODIFIERS │
         │                  │
         │ • Risk level     │
         │ • Trading mode   │
         │ • BMO reservation│
         └────────┬─────────┘
                  │
                  ▼
         ┌──────────────────┐
         │  FINAL_SIZE      │
         │                  │
         │ Calculate shares │
         │ Round to whole   │
         │ Min 1 share      │
         └──────────────────┘

Exposure cap: uniform 1.40 across regimes (Finding #317). The legacy MAX_TOTAL_EXPOSURE_PCT (the old 70% limit) is vestigial (Finding #315). Sizing tiers: Large 30% / Mid 22% / Small 15% (Finding #211).


6. Batch Order Manager

6.1 Batch Execution Flow

┌──────────────────────────────────────────────────────────────────────────┐
│                    BATCH ORDER MANAGER STATE MACHINE                      │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │   INITIALIZE     │
                          │                  │
                          │ Generate batch_id│
                          │ Record start time│
                          └────────┬─────────┘
                                   │
                                   ▼
                          ┌──────────────────┐
                          │  CALC_SIZES      │
                          │                  │
                          │ Fair allocation  │
                          │ by priority &    │
                          │ market cap       │
                          └────────┬─────────┘
                                   │
                                   ▼
                          ┌──────────────────┐
                          │  SUBMIT_ORDERS   │
                          │                  │
                          │ Sequential submit│
                          │ 50ms between     │
                          │ orders           │
                          └────────┬─────────┘
                                   │
                                   │ All orders submitted
                                   ▼
                          ┌──────────────────┐
                          │  MONITOR_FILLS   │
                          │                  │
                          │ Parallel monitor │
                          │ 12 sec timeout   │
                          │ per order        │
                          └────────┬─────────┘
                                   │
              ┌────────────────────┼────────────────────┐
              │                    │                    │
              │ All filled         │ Some timeout       │ All timeout
              ▼                    ▼                    ▼
     ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
     │   COMPLETE       │ │  MARKET_FALLBACK │ │  ALL_FALLBACK    │
     │                  │ │                  │ │                  │
     │ All LIMIT fills  │ │ Cancel unfilled  │ │ All went to      │
     │ Record results   │ │ Submit MARKET    │ │ MARKET           │
     └──────────────────┘ │ for timeout      │ └────────┬─────────┘
                          └────────┬─────────┘          │
                                   │                    │
                                   ▼                    │
                          ┌──────────────────┐          │
                          │ MARKET_MONITOR   │          │
                          │                  │          │
                          │ Wait for MARKET  │          │
                          │ fills (instant)  │          │
                          └────────┬─────────┘          │
                                   │                    │
                                   └────────────────────┤
                                                        │
                                                        ▼
                                               ┌──────────────────┐
                                               │   FINALIZE       │
                                               │                  │
                                               │ • Place stop-loss│
                                               │ • Update DB      │
                                               │ • Send alerts    │
                                               │ • Return results │
                                               └──────────────────┘

6.2 Batch Type States

┌──────────────────────────────────────────────────────────────────────────┐
│                         BATCH TYPE STATE MACHINE                          │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │  DETERMINE_TYPE  │
                          │                  │
                          │ Input: action    │
                          │ from orchestrator│
                          └────────┬─────────┘
                                   │
         ┌─────────────────────────┼─────────────────────────┐
         │                         │                         │
         │ New positions           │ Scheduled exits         │ Earnings detected
         ▼                         ▼                         ▼
┌──────────────────┐    ┌──────────────────┐    ┌──────────────────┐
│   BATCH_ENTRY    │    │   BATCH_EXIT     │    │ BATCH_INSTANT_   │
│                  │    │                  │    │      EXIT        │
│ • BUY orders     │    │ • SELL orders    │    │                  │
│ • Attach stops   │    │ • Cancel stops   │    │ • MARKET orders  │
│ • Pre-calc sizes │    │ • Multiple exits │    │ • No stops       │
│ • 12s timeout    │    │ • 12s timeout    │    │ • Immediate      │
└──────────────────┘    └──────────────────┘    └──────────────────┘

7. IBKR Gateway Monitor

7.1 Connection States

┌──────────────────────────────────────────────────────────────────────────┐
│                    GATEWAY CONNECTION STATE MACHINE                       │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │     UNKNOWN      │
                          │                  │
                          │ Initial state    │
                          │ before first     │
                          │ check            │
                          └────────┬─────────┘
                                   │
                                   │ First health check
                                   ▼
                  ┌────────────────┴────────────────┐
                  │                                 │
                  │ Connection successful           │ Connection failed
                  ▼                                 ▼
         ┌──────────────────┐              ┌──────────────────┐
         │   CONNECTING     │              │     ERROR        │
         │                  │              │                  │
         │ Handshake in     │              │ • Log error      │
         │ progress         │              │ • Send alert     │
         └────────┬─────────┘              │ • Retry later    │
                  │                        └────────┬─────────┘
                  │ Authenticated                   │
                  ▼                                 │
         ┌──────────────────┐                       │
         │   CONNECTED      │                       │
         │                  │                       │
         │ • API ready      │                       │
         │ • Account data   │                       │
         │ • Trading allowed│                       │
         └────────┬─────────┘                       │
                  │                                 │
                  │ Connection lost                 │
                  ▼                                 │
         ┌──────────────────┐                       │
         │  DISCONNECTED    │◀──────────────────────┘
         │                  │
         │ • Alert sent     │
         │ • Positions safe │
         │ • Stops active   │
         └────────┬─────────┘
                  │
                  │ Retry connection
                  ▼
         ┌──────────────────┐
         │   CONNECTING     │ (Loop back)
         └──────────────────┘

7.2 Gateway Session Lifecycle

┌──────────────────────────────────────────────────────────────────────────┐
│                    GATEWAY SESSION STATE MACHINE                          │
│                    Updated: January 26, 2026 (v3.0)                       │
└──────────────────────────────────────────────────────────────────────────┘

   WEEKLY CYCLE (Sunday 6:00 UTC = 10:00 AM Abu Dhabi)
   ────────────────────────────────────────────────────
   ** 2FA REQUIRED - User must approve on IBKR app **

         ┌──────────────────┐
         │  SESSION_ACTIVE  │◀────────────────────────────────┐
         │                  │                                  │
         │ • Trading allowed│                                  │
         │ • API connected  │                                  │
         │ • Session token  │                                  │
         │   valid (7 days) │                                  │
         └────────┬─────────┘                                  │
                  │                                            │
                  │ Sunday 6:00 UTC: IBKR resets all tokens    │
                  ▼                                            │
         ┌──────────────────┐                                  │
         │ SESSION_EXPIRED  │                                  │
         │                  │                                  │
         │ • Weekly token   │                                  │
         │   expiry (IBKR)  │                                  │
         │ • 2FA required   │                                  │
         └────────┬─────────┘                                  │
                  │                                            │
                  │ IBC enters credentials automatically       │
                  ▼                                            │
         ┌──────────────────┐                                  │
         │  AWAITING_2FA    │                                  │
         │                  │                                  │
         │ • 2FA notification│                                 │
         │   sent to phone  │                                  │
         │ • 180 sec timeout│                                  │
         └────────┬─────────┘                                  │
                  │                                            │
     ┌────────────┴────────────┐                               │
     │                         │                               │
     │ 2FA approved            │ 2FA timeout                   │
     ▼                         ▼                               │
┌──────────────────┐  ┌──────────────────┐                     │
│  LOGIN_SUCCESS   │  │  LOGIN_FAILED    │                     │
│                  │  │                  │                     │
│ • New session    │  │ • Retry in 120s  │                     │
│ • Token valid    │  │ • Send alert     │                     │
│ • Resume trading │  │ • Manual VNC     │                     │
└────────┬─────────┘  └────────┬─────────┘                     │
         │                     │                               │
         │                     │ ReloginAfter...Timeout=yes    │
         │                     └───────────────────────────────│
         │                                                     │
         └─────────────────────────────────────────────────────┘


   DAILY CYCLE (Mon-Sat 6:00 UTC = 10:00 AM Abu Dhabi) - SESSION PRESERVATION
   ──────────────────────────────────────────────────────────────────────────
   ** NO 2FA - IBC's AutoRestart is in-process and keeps the session (#437) **

         ┌──────────────────┐
         │  SESSION_ACTIVE  │
         │                  │
         │ • Session token  │
         │   valid          │
         └────────┬─────────┘
                  │
                  │ 6:00 UTC: IBC "Re-starting session" (same JVM)
                  │           :4001 closed ~20-40 s
                  ▼
         ┌──────────────────┐
         │  RESTARTING      │
         │                  │
         │ • No 2FA         │
         │ • ibkr-monitor   │
         │   SLA 180 s      │
         └────────┬─────────┘
                  │
                  │ "Login has completed" + :4001 back
                  │ trader reattaches / attach-bounces once (#441)
                  ▼
         ┌──────────────────┐
         │  SESSION_ACTIVE  │
         │                  │
         │ • Original token │
         │   PRESERVED      │
         │ • NO 2FA needed  │
         │ • Trading resumes│
         └──────────────────┘

   No Telegram on a healthy restart. :4001 still down after 180 s → one
   ibkr-monitor page (lever: systemctl restart ibgateway-ibc), page-only (#448).
   History (retired #476): gateway_restart_manager.sh waited at 05:58 for a
   "dual process" and killed the newer one; the restart is in-process, so
   that state never occurred.


   OVERNIGHT RECOVERY (Smart Restart - Added Jan 26, 2026)
   ────────────────────────────────────────────────────────
   ** Handles IBKR's internal shutdown at ~23:45 UTC (3:45 AM Abu Dhabi) **

         ┌──────────────────┐
         │  SESSION_ACTIVE  │
         │                  │
         │ • Trading complete│
         │ • Night time     │
         └────────┬─────────┘
                  │
                  │ 23:45 UTC (3:45 AM): IBKR internal shutdown
                  │           Gateway exits with status 0
                  ▼
         ┌──────────────────┐
         │ GATEWAY_STOPPED  │
         │                  │
         │ • IBC exits      │
         │ • systemd triggers│
         │   Restart=always │
         └────────┬─────────┘
                  │
                  │ ibc_smart_restart.sh checks current hour
                  ▼
         ┌──────────────────┐
         │ SMART_WAIT       │ (Hour 22-05 UTC only)
         │                  │
         │ • Outside active │
         │   hours detected │
         │ • Telegram alert │
         │ • Sleep until    │
         │   05:00 UTC      │
         └────────┬─────────┘
                  │
                  │ 05:00 UTC (09:00 AM Abu Dhabi): Wake up
                  ▼
         ┌──────────────────┐
         │  STARTING_IBC    │
         │                  │
         │ • Start Gateway  │
         │ • IBC enters     │
         │   credentials    │
         └────────┬─────────┘
                  │
                  │ IBKR sends 2FA (if Sunday or session expired)
                  ▼
         ┌──────────────────┐
         │  AWAITING_2FA    │
         │                  │
         │ • Approve on     │
         │   IBKR app       │
         │ • 3 min window   │
         └────────┬─────────┘
                  │
                  ▼
         ┌──────────────────┐
         │  SESSION_ACTIVE  │
         │                  │
         │ • Ready before   │
         │   market open    │
         └──────────────────┘

   Telegram: "⚠️ Gateway restarting at 09:00 AM. Please approve 2FA."

8. Integrity Monitor (replaces Watchdog v2/v3 — Apr 27, 2026, Finding #258)

§8 redirect: the operative health-check architecture is now src/data_tracker/integrity_monitor.py running under polymarket-integrity-monitor.service. State below is retained as historical reference for the v2/v3 lifecycle that preceded it. The current monitor uses a declarative-rule model rather than the per-service state-machine model below — ~51 rules across 6 categories (was ~47 pre-#383, 37, and 34 pre-#269/#291) (freshness, null_rate, systemd, artifact, storage, meta), each with ok/warn/fail/unknown status persisted to the integrity_status table. See docs/DATA_INTEGRITY.md §2 for architecture, docs/OPERATIONS.md §8.A for runbook.

8.1 Service Health States (LEGACY — pre-Apr-27 watchdog v2/v3)

┌──────────────────────────────────────────────────────────────────────────┐
│                    WATCHDOG SERVICE HEALTH STATE MACHINE                  │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │     HEALTHY      │
                          │                  │
                          │ • Service running│
                          │ • Data fresh     │
                          │ • No errors      │
                          └────────┬─────────┘
                                   │
                                   │ Check fails
                                   ▼
                          ┌──────────────────┐
                          │   DEGRADED       │
                          │                  │
                          │ • 1-2 failures   │
                          │ • Log warning    │
                          │ • No alert yet   │
                          └────────┬─────────┘
                                   │
                                   │ 3+ consecutive failures
                                   ▼
                          ┌──────────────────┐
                          │    UNHEALTHY     │
                          │                  │
                          │ • Send alert     │
                          │ • Attempt restart│
                          │ • Log critical   │
                          └────────┬─────────┘
                                   │
                  ┌────────────────┴────────────────┐
                  │                                 │
                  │ Restart successful              │ Restart failed
                  ▼                                 ▼
         ┌──────────────────┐              ┌──────────────────┐
         │   RECOVERING     │              │   CRITICAL       │
         │                  │              │                  │
         │ • Watching for   │              │ • 3+ restart     │
         │   stability      │              │   attempts       │
         │ • No new restarts│              │ • Escalate alert │
         │   for 5 min      │              │ • Manual review  │
         └────────┬─────────┘              └──────────────────┘
                  │
                  │ Stable for 5 min
                  ▼
         ┌──────────────────┐
         │     HEALTHY      │
         │                  │
         │ Recovery complete│
         │ Send recovery    │
         │ notification     │
         └──────────────────┘

8.2 Alert Level Escalation

┌──────────────────────────────────────────────────────────────────────────┐
│                     ALERT ESCALATION STATE MACHINE                        │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │      NONE        │
                          │                  │
                          │ All systems OK   │
                          └────────┬─────────┘
                                   │
                                   │ Minor issue detected
                                   ▼
                          ┌──────────────────┐
                          │      INFO        │
                          │                  │
                          │ • Log only       │
                          │ • No notification│
                          │ • e.g., brief    │
                          │   spike          │
                          └────────┬─────────┘
                                   │
                                   │ Issue persists > 5 min
                                   ▼
                          ┌──────────────────┐
                          │    WARNING       │
                          │                  │
                          │ • Telegram alert │
                          │ • ⚠️ icon        │
                          │ • Auto-restart   │
                          │   attempted      │
                          └────────┬─────────┘
                                   │
                                   │ Restart fails OR critical service
                                   ▼
                          ┌──────────────────┐
                          │    CRITICAL      │
                          │                  │
                          │ • Urgent alert   │
                          │ • 🚨 icon        │
                          │ • Repeat every   │
                          │   15 min         │
                          │ • Manual review  │
                          └────────┬─────────┘
                                   │
                                   │ Issue resolved
                                   ▼
                          ┌──────────────────┐
                          │    RECOVERY      │
                          │                  │
                          │ • ✅ notification│
                          │ • Log recovery   │
                          │ • Clear counters │
                          └────────┬─────────┘
                                   │
                                   ▼
                          ┌──────────────────┐
                          │      NONE        │
                          └──────────────────┘

9. Position Lifecycle

Implementation Note (Phase 4B+4D - Feb 7, 2026): The position lifecycle is formalized in src/earnings/position_state.py as a PositionState enum with validated transitions: PENDING -> OPEN -> CLOSING -> CLOSED (or FAILED). IBKR is the source of truth for live state via IBKRPositionCache. Stop fills are detected in real-time via IBKR orderStatusEvent callbacks through the EventBus (Phase 4D), with periodic reconciliation as backup.

9.1 Complete Position State Machine

┌──────────────────────────────────────────────────────────────────────────┐
│                      POSITION LIFECYCLE STATE MACHINE                     │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │   SIGNAL_GEN     │
                          │                  │
                          │ Signal generated │
                          │ for earnings     │
                          └────────┬─────────┘
                                   │
                                   │ Risk check passed
                                   ▼
                          ┌──────────────────┐
                          │   SCHEDULED      │
                          │                  │
                          │ Entry scheduled  │
                          │ for specific time│
                          └────────┬─────────┘
                                   │
                                   │ Entry time reached
                                   ▼
                          ┌──────────────────┐
                          │  ENTERING        │
                          │                  │
                          │ Order submitted  │
                          │ Waiting for fill │
                          └────────┬─────────┘
                                   │
                  ┌────────────────┴────────────────┐
                  │                                 │
                  │ Fill successful                 │ Fill failed
                  ▼                                 ▼
         ┌──────────────────┐              ┌──────────────────┐
         │     ACTIVE       │              │    FAILED        │
         │                  │              │                  │
         │ • Stop-loss set  │              │ Log error        │
         │ • Exit scheduled │              │ Alert sent       │
         │ • Monitoring     │              └──────────────────┘
         └────────┬─────────┘
                  │
     ┌────────────┼────────────────────────┐
     │            │                        │
     │ Stop-loss  │ Earnings               │ Scheduled
     │ triggered  │ detected wrong         │ exit time
     ▼            ▼                        ▼
┌───────────┐ ┌──────────────┐    ┌──────────────────┐
│ STOPPED   │ │INSTANT_EXIT  │    │ SCHED_EXIT       │
│           │ │              │    │                  │
│ Stop hit  │ │ Wrong predict│    │ Normal exit      │
│ Loss taken│ │ Fast exit    │    │ Take profit/loss │
└─────┬─────┘ └──────┬───────┘    └────────┬─────────┘
      │              │                     │
      └──────────────┴─────────────────────┘
                     │
                     ▼
            ┌──────────────────┐
            │    CLOSED        │
            │                  │
            │ • P&L calculated │
            │ • DB updated     │
            │ • Audit logged   │
            │ • Capital freed  │
            └──────────────────┘

9.2 Exit Type Decision Tree

┌──────────────────────────────────────────────────────────────────────────┐
│                       EXIT TYPE DECISION STATE MACHINE                    │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │   ACTIVE_POS     │
                          │                  │
                          │ Position open    │
                          │ Monitoring...    │
                          └────────┬─────────┘
                                   │
   ┌───────────────────────────────┼───────────────────────────────┐
   │                               │                               │
   │ Price hits stop               │ Earnings released             │ Exit time
   │                               │                               │ reached
   ▼                               ▼                               ▼
┌───────────────┐         ┌───────────────┐         ┌───────────────┐
│  STOP_LOSS    │         │ CHECK_RESULT  │         │ SCHED_EXIT    │
│               │         │               │         │               │
│ IBKR native   │         │ Compare actual│         │ At scheduled  │
│ stop triggers │         │ vs consensus  │         │ exit time     │
│ automatically │         │ EPS           │         │               │
└───────┬───────┘         └───────┬───────┘         └───────┬───────┘
        │                         │                         │
        │                ┌────────┴────────┐                │
        │                │                 │                │
        │                │ Prediction      │ Prediction     │
        │                │ correct         │ WRONG          │
        │                ▼                 ▼                │
        │       ┌───────────────┐ ┌───────────────┐         │
        │       │ HOLD_TO_EXIT  │ │ INSTANT_EXIT  │         │
        │       │               │ │               │         │
        │       │ Keep to       │ │ MARKET order  │         │
        │       │ scheduled exit│ │ immediately   │         │
        │       └───────┬───────┘ └───────┬───────┘         │
        │               │                 │                 │
        │               │                 │                 │
        └───────────────┴─────────────────┴─────────────────┘
                                  │
                                  ▼
                         ┌───────────────┐
                         │    CLOSED     │
                         │               │
                         │ Exit complete │
                         │ Record result │
                         └───────────────┘

10. Data Collection Pipeline

10.1 Collector Service States

┌──────────────────────────────────────────────────────────────────────────┐
│                    DATA COLLECTOR STATE MACHINE                           │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │   INITIALIZING   │
                          │                  │
                          │ • Load config    │
                          │ • Connect to DB  │
                          │ • Verify schema  │
                          └────────┬─────────┘
                                   │
                                   ▼
                          ┌──────────────────┐
                          │   SYNC_MARKETS   │
                          │                  │
                          │ • Fetch markets  │
                          │   from Gamma API │
                          │ • Update markets │
                          │   table          │
                          └────────┬─────────┘
                                   │
                                   ▼
                          ┌──────────────────┐◀─────────────────┐
                          │   COLLECTING     │                  │
                          │                  │                  │
                          │ For each market: │                  │
                          │ • Orderbooks     │                  │
                          │ • Prices         │                  │
                          │ • Trades         │                  │
                          └────────┬─────────┘                  │
                                   │                            │
                                   │ Cycle complete             │
                                   ▼                            │
                          ┌──────────────────┐                  │
                          │    SLEEPING      │──────────────────┘
                          │                  │   Sleep interval
                          │ Wait for next    │   (15 min for
                          │ collection cycle │   market sync)
                          └──────────────────┘

10.2 Earnings Market Sync States

┌──────────────────────────────────────────────────────────────────────────┐
│                    EARNINGS MARKET SYNC STATE MACHINE                     │
└──────────────────────────────────────────────────────────────────────────┘

                          ┌──────────────────┐
                          │  FETCH_EVENTS    │
                          │                  │
                          │ GET /events/     │
                          │ pagination?      │
                          │ tag_id=1013      │
                          └────────┬─────────┘
                                   │
                                   │ Paginate through all
                                   ▼
                          ┌──────────────────┐
                          │  EXTRACT_DATA    │
                          │                  │
                          │ • Parse ticker   │
                          │ • Parse date     │
                          │ • Parse timing   │
                          │ • Get condition  │
                          │   IDs            │
                          └────────┬─────────┘
                                   │
                                   ▼
                          ┌──────────────────┐
                          │  SYNC_TO_DB      │
                          │                  │
                          │ UPSERT into      │
                          │ earnings_markets │
                          │ table            │
                          └────────┬─────────┘
                                   │
                                   │ Every 1 hour
                                   ▼
                          ┌──────────────────┐
                          │    COMPLETE      │
                          │                  │
                          │ Log stats        │
                          │ Schedule next run│
                          └──────────────────┘

Appendix A: State Transition Summary Table

Component States Transitions Key Events
TradingOrchestrator 6 12 Market open/close, signals, errors
TradingMode 4 5 Trade count, manual toggle
MarketStatus 4 4 Time-based (4/9:30/16/20)
OrderStatus 5 6 Submit, fill, cancel, fail
RiskLevel 4 6 VIX, P&L, circuit breakers
CircuitBreaker 2 7 Loss, drawdown, VIX, manual
ConnectionState 5 8 Connect, disconnect, error
ServiceHealth 4 6 Check, fail, restart, recover
Position 6 8 Entry, exit, stop, close
BatchOrder 4 5 Submit, fill, timeout, fallback

Appendix B: Critical Paths

B.1 Happy Path: BMO Trade

Signal Generated → Risk Check → Entry Scheduled → Entry Filled → 
Stop-Loss Set → Earnings Released (correct) → Scheduled Exit → Closed

B.2 Instant Exit Path

Position Active → Earnings Released (wrong) → Instant Exit Triggered → 
MARKET Order → Filled → Closed

B.3 Stop-Loss Path

Position Active → Price Drops → Stop Triggered (IBKR) → 
Filled at Stop → Closed

B.4 Circuit Breaker Path

Trade Executed → Loss Recorded → Daily Loss > 3% → 
Circuit Breaker DAILY_LOSS → No New Trades → EOD Reset → Resume

Document generated: January 11, 2026 System Version: Polymarket Earnings Trading System v4.1