Technical Architecture Deep-Dive

Technical Reference

Complete source-level documentation of the Intellect FinLab architecture. Every module, class, interface, database schema, and execution pathway β€” documented at engineering depth with flow diagrams.

Python 3.11+FastAPI 0.115+ ib_async 2.1+React 19 SQLite Β· 3 DBsSingle Event Loop 80+ Scanners0DTE Options
πŸ›οΈ
Section 01
Architecture Overview
Two-process system sharing one async event loop β€” trading engine + FastAPI backend bridged by ib_async over a single Python asyncio loop via nest-asyncio.

Intellect FinLab is a two-process system: a Python trading engine (main.py) and a FastAPI backend (backend/app/main.py). Both share one async event loop via nest-asyncio. The IBKR API (ib_async) runs on the same loop β€” zero thread handoff, zero latency penalty on the critical execution path.

πŸ“ Full System Architecture β€” Layers & Data Flow
Broker
IBKR TWS (port 7497/7496) Market Data Streams Order Routing Engine Option Chain API
ib_async β‰₯2.1 Β· single asyncio event loop via nest-asyncio
Engine
80+ Scanners Signal Pool Hunter Loop Strategy Engine Order Executor Risk Manager Loss Protection Wealth Model
Backend
FastAPI 0.115 40+ Services (DI) WebSocket Channels Lifecycle Bridge Config Engine (5s TTL) Background Workers
Storage
config.db intellect_finlab_next.db intellect.db (paper) intellect.db (live)
Frontend
React 19 + TypeScript Zustand (live state) TanStack Query v5 uPlot Charts WS Hooks (5 channels) Vite 6
πŸ”‘
Single Source of Truth Principle

Config β†’ backend/data/config.db (5s TTL cache). Trade truth β†’ backend/runtime/intellect_finlab_next.db. Wealth state β†’ runtime/paper/intellect.db or runtime/live/intellect.db. Paths are never hardcoded β€” always resolved via Settings properties on the Pydantic settings class.

Project Layout

PathPurpose
main.pyTrading engine entry point β€” constructs all modules, starts single event loop
backend/app/main.pyFastAPI app factory + build_container() β€” dependency injection root
modules/scanners/80+ technical scanners inheriting BaseScanner
modules/strategy/Signal pool, Hunter Loop, rule evaluator, score engine
modules/execution/Order executor, position tracker, watchdog, order state
modules/risk/Risk manager, loss protection, rapid/day shields
modules/options/Option chain loader, greek cache, delta strike picker
modules/wealth_model/Wealth DB, manager, trade diary, finalization
modules/alerts/Email + Telegram alert manager and templates
backend/app/services/Business logic β€” one service per domain (40+ services)
backend/app/api/routes/FastAPI routers β€” thin, delegate to services
backend/app/workers/Background threads: sync, flow, scanner, delta ladder
backend/app/bridges/Legacy↔modern integration: LifecycleEventBridge, TradeDiaryBridge
backend/app/core/Settings, enums, interfaces, trade models, state machine
frontend/src/React 19 + TypeScript operator dashboard
βš™οΈ
Section 02
Technology Stack
Every dependency, version, and its exact role in the system β€” from runtime to frontend to testing.
LayerTechnologyVersionRole
RuntimePython3.11+ (3.13 rec.)Trading engine, backend API
API FrameworkFastAPIβ‰₯ 0.115REST + WebSocket, ORJSONResponse default
IBKR Bridgeib_asyncβ‰₯ 2.1Interactive Brokers async API β€” event-driven
Async Loopnest-asynciolatestSingle event loop shared by IBKR + FastAPI + engine
ASGI ServerUvicornβ€”Production-grade async HTTP/WS server
ValidationPydantic v2 + pydantic-settingsv2Settings, schema validation, all request/response models
PersistenceSQLiteβ€”Config DB, lifecycle DB, wealth DB (3 separate files)
Analyticspandas / numpy / pyarrowβ€”Market data processing, backtest engine, analytics
ConfigPyYAMLβ€”YAML fallback configs (DB is runtime source of truth)
FrontendReact 19 + TypeScriptReact 19Operator dashboard β€” full real-time UI
BuildVite 66Frontend dev server and production build
StateZustandβ€”Global frontend live state (WebSocket data)
Data FetchingTanStack Query v5v5REST data fetching, caching, background refresh
ChartsuPlotβ€”High-performance financial charting
Testing (Python)pytest + hypothesisβ‰₯ 8.0 / β‰₯ 6.0Unit + property-based tests
Testing (Frontend)Vitest + fast-checkβ€”Frontend unit + property-based tests
3
SQLite Databases
Config Β· Lifecycle Β· Wealth
1
Event Loop
IBKR + FastAPI + Engine
40+
Backend Services
One per domain, DI wired
80+
Technical Scanners
All inherit BaseScanner
πŸ”„
Section 03
Async Event Loop Design
The entire system β€” IBKR API, trading engine, FastAPI β€” runs on one Python asyncio event loop. No thread context switches on the critical execution path.

This is the foundational performance guarantee: scanner β†’ fill confirmation in ~35–40ms because there are no thread handoffs on the hot path. nest-asyncio allows the IBKR event-driven API and Uvicorn to share the same loop.

πŸ”„ Single Event Loop β€” Zero Thread Handoffs
asyncio event loop πŸ“‘ IBKR TWS port 7497/7496 ib_async β‰₯2.1 ⚑ Trading Engine main.py Β· scanners 🌐 FastAPI + WS REST + WebSocket πŸ–₯️ React Dashboard React 19 + Vite 6 ↔
⚑ ~35ms scanner β†’ fill confirmation πŸ”’ Zero thread context switches on hot path πŸ”„ nest-asyncio patches loop for shared access
Python Β· main.py
import nest_asyncio nest_asyncio.apply() # allows IBKR + FastAPI to share one loop # ib_async and Uvicorn run on THE SAME asyncio event loop # Fill events arrive via ib_async callbacks β†’ dispatched immediately # No thread.Queue, no sleep() calls on the critical path # Measured: scanner fire β†’ IBKR order submit β‰ˆ 12ms # Measured: order submit β†’ fill confirm β‰ˆ 23ms (total β‰ˆ 35ms)
⚑
Event-Driven vs Polling

SignalPool._publish_event is a threading.Event that fires on every publish(). The Hunter Loop calls wait_for_signal(timeout=1.0) β€” it wakes instantly when a scanner fires, eliminating the 1-second polling latency of the legacy design. OrderStatusCache provides O(1) order status lookups, replacing slow ib.openTrades() full scans.

Key Async Patterns

🎯
notify_tick() β€” Heartbeat
RuntimeSyncWorker calls notify_tick() on every IBKR bar event. This wakes the engine from its event wait β€” no busy polling. The event loop returns to idle between ticks.
πŸ“¨
EventBus β€” State Propagation
The EventBus dispatches state change events (fills, cancels, position updates) to subscribers without polling. Subscribers register callbacks; the bus fires them synchronously on the event loop.
πŸ”
SafeLock β€” Instrument Guard
SafeLock is an async re-entrant lock that prevents concurrent entry AND exit operations for the same instrument. Critical for preventing double-entry when scanner fires during an active close.
πŸ“‘
Section 04
Scanner System β€” 80+ Modules
All scanners inherit BaseScanner. Each implements scan() β†’ list[dict]. BaseScanner.run() wraps every scanner with a 4-layer defence stack before signals reach the pool.
Scanner Defence Stack β€” evaluated in order on every run() call
0. Config Gateenabled flag Β· es_only_mode
β†’
1. Market HoursRTH / ETH per instrument
β†’
2. Cooldown WallDB β†’ override β†’ TF map
β†’
3. Bar Identitysame bar_time β†’ skip
β†’
βœ“ FIREsignal key published

Cooldown Resolution Priority

Priority 1 β€” Databaseconfig_scanner.cooldown β€” runtime configurable, takes precedence
Priority 2 β€” Per-scanner override_SCANNER_COOLDOWN_OVERRIDE dict in scanner class
Priority 3 — Timeframe default_COOLDOWN_MAP: 5m→300s · 15m→900s · 1hr→3600s

Market Hours Logic per Instrument

InstrumentTrading SessionGate Method
ES / NQ (Futures)Sun 6PM β†’ Fri 5PM ET (except 5–6PM daily maintenance)_check_es_session()
SPX / VIX9:30AM – 4:00PM ET weekdays onlyRTH gate
SPY / QQQ4:00AM – 8:00PM ET weekdaysExtended hours

Production Scanner Inventory

SPX_V3_CALL/PUTSPX_FIB_1HR_CALL/PUT SPX_FIB_10M_CALL/PUTES_CALL_V3/PUT_V3 ES_FIB_CALL_1HR/PUT_1HRES_ZONE_BREAKOUT_CALL/PUT SPX_10MIN_MOMENTUM_UP/DOWNSPX_10MIN_MACD_UP/DOWN SPX_1HR_MACD_UP/DOWNSPX_4HR_STOCHASTIC_MOMENTUM_CALL/PUT SPX_EMA21_TRIFECTA_CALL/PUTSPX_ADX_5M SPX_15M_RSI_OVERSOLDSPX_ZONE_BREAKOUT_CALL/PUT SPY_21_200_CALL/PUTVIX_21_200_CALL/PUT NQ_CALL_V3/PUT_V3NQ_1HR_MACD_UP/DOWN QQQ_CALL_V3/PUT_V380+ total in production
intellect Β· scanner engine Β· live feed
LIVE
09:31:02SCANNERSPX_FIB_1HR_CALL fired Β· score 87 Β· price 5938 Β· cooldown reset 3600s
09:31:04GREEKSdelta 0.30 Β· theta βˆ’4.2 Β· gamma 0.012 Β· IV 18.3%
09:31:05PREFLIGHTrisk check PASSED Β· gate OPEN Β· positions 0/3 Β· gamma 0.012 < 0.15
09:31:06SUBMITBUY 2 SPX 5940C 0DTE @ MKT Β· order_id 4471 Β· SafeLock acquired
09:31:07FILLfilled @ 4.20 Β· slippage 0.02 Β· LP daemon armed Β· T1: 5.17 (+23%)
09:42:18RISKgrace period expired Β· trail stop armed @ entry + breakeven Β· fast_poll: every 5s
09:58:33CLOSESELL 2 SPX 5940C @ 5.18 Β· PnL +$196 Β· +23.3% Β· hold 27m 26s Β· T1 target
09:58:34WEALTHcapital updated Β· WM235K W4 milestone T1 βœ“ Β· ladder: T2

Scanner Category Map

CategoryLogic TypeRepresentative Scanners
FibonacciState-based β€” fires while price is in fib zoneSPX_FIB_1HR_CALL, ES_FIB_CALL_1HR
EMA CrossCross-based β€” fires on the actual cross barSPX_V3_CALL, ES_CALL_V3, NQ_CALL_V3
MACDCross-based β€” MACD signal line crossSPX_10MIN_MACD_UP, SPX_1HR_MACD_UP
Momentum / SMIState-based β€” SMI Ergodic level thresholdSPX_10MIN_MOMENTUM_UP, SPX_4HR_STOCHASTIC_MOMENTUM
ADX / TrendThreshold β€” ADX strength gateSPX_ADX_5M, ES_ADX_5M
RSIThreshold β€” RSI level reversal signalSPX_15M_RSI_OVERSOLD
Zone BreakoutState β€” price outside consolidation boxSPX_ZONE_BREAKOUT_CALL, ES_ZONE_BREAKOUT
TrifectaMulti-condition AND β€” EMA21 + MACD + momentumSPX_EMA21_TRIFECTA_CALL/PUT
🎯
Section 05
Signal Pool Architecture
Thread-safe in-memory store β€” one SignalEntry per scanner name. publish() always overwrites. Strategy engine reads via get(max_age_seconds). Event-driven wake β€” zero polling.
Python Β· modules/strategy/signal_pool.py
# publish β€” called from BaseScanner.run() after all 4 gates pass pool.publish("SPX_FIB_1HR_CALL", {"direction": "CALL", "price": 5800, "score": 87}) # get β€” strategy engine checks freshness window entry = pool.get("SPX_FIB_1HR_CALL", max_age_seconds=300) if entry: # signal is live and within age window direction = entry.data["direction"] # wait_for_signal β€” event-driven wake (REQ-HFT: no polling) arrived = pool.wait_for_signal(timeout=1.0) # blocks until publish() fires # _publish_event: threading.Event fires on every publish() # Hunter Loop wakes INSTANTLY β€” eliminates 1s polling latency
StorageDict[scanner_name β†’ SignalEntry] β€” one entry per scanner, publish overwrites
Thread Safetythreading.Lock protects all read/write ops
Wake Mechanismthreading.Event β€” fires on publish(), Hunter Loop wait_for_signal()
Freshnessget(max_age_seconds) filters stale entries β€” default 300s
Snapshotsnapshot(max_age_seconds) returns thread-safe copy for strategy eval
🧠
Section 06
Strategy Engine β€” VeeraStrategy
Config-driven strategies loaded from config_veera_strategies DB table. No code change needed to add a strategy β€” create and edit from the UI operator console.
FieldTypePurpose
strategy_idstrUnique identifier, matches DB row primary key
scanner_patterns_calllist[str]Scanner names that trigger a CALL entry
scanner_patterns_putlist[str]Scanner names that trigger a PUT entry
scanner_confirmation_window_minutesintMulti-scanner confirmation window (default 5 min)
veera_rules_enabledboolMaster toggle for Veera Rules market-regime pre-filter
target_profit_pctintExit target percentage (23 = +23%)
shieldstr|None"rapid_shield" or "day_shield" or None (global LP)
wealth_modelstr|NoneCapital plan override (e.g. "WM235K")
hunterloopdict{"mode":"context_plus_trigger","engine":"..."}
priorityintLower = evaluated first (1 = highest priority)
enabledboolActive in evaluation cycle β€” toggle without deleting
πŸ”¬
Section 07
Veera Rules Gate β€” UniversalPreFilter
Optional market-regime pre-filter in modules/strategy/universal_prefilter.py. Applied per strategy after scanner pattern match. Each rule is independently toggleable from the UI.
Rule FieldCondition CheckedTimeframeDefault
veera_rule_spy_ema_enabledSPY EMA21 > EMA2005mOFF
veera_rule_vix_ema_enabledVIX EMA5 < EMA12 (vol falling)5mOFF
veera_rule_macd_enabledMACD Fast/Slow cross aligned10mOFF
veera_rule_ema_slope_enabledEMA21 slope positive5mOFF
veera_rule_adx_5m_enabledADX > 20 (trend strength confirmed)5mOFF
veera_rule_vix_21_200_enabledVIX EMA21 vs EMA200 regime5mOFF
veera_rule_stoch_10m_enabledStochastic direction aligned10mOFF
veera_rule_es_5_12_10m_enabledES EMA5 / EMA12 cross10mOFF
veera_rule_nq_5_12_10m_enabledNQ EMA5 / EMA12 cross10mOFF
veera_rule_qqq_5_12_10m_enabledQQQ EMA5 / EMA12 cross10mOFF
πŸ’‘
Design Note

All Veera Rules default to OFF so strategies work out-of-the-box. They are additive filters β€” turn on only the rules that match your market regime thesis. Rules are evaluated as AND logic: all enabled rules must pass for the trade to proceed.

πŸ¦…
Section 08
Hunter Loop Optimizer
modules/strategy/hunter_loop_optimizer.py β€” strategic gating layer between strategy match and order submission. Manages context accumulation and trigger confirmation.
ModeDB ValueBehaviour
Standard"standard"Immediate entry on strategy pass β€” no additional confirmation required
Context + Trigger"context_plus_trigger"Requires a context signal AND a separate trigger signal within the confirmation window. Higher conviction, fewer entries.
Hunter Loop Evaluation Cycle
Signal Poolsnapshot()
β†’
Strategy Listpriority order
β†’
Pattern Matchcall/put patterns in pool?
β†’
Veera Rulesmarket regime filter
β†’
Hunter Gatecontext + trigger confirm
β†’
Risk Preflightall 8 gates must pass
β†’
Execute βœ“strike pick β†’ submit
πŸ“
Section 09
Options Selection Pipeline
Delta-target based strike selection β€” not fixed strikes. The greek cache ensures real-time IV, theta, and delta coverage. Liquidity filtering prevents fills in thin contracts.
Options Selection Flow β€” Hunter Confirmed β†’ Contract Selected
Delta Targete.g. 0.30 calls Β· 0.25 puts
β†’
Chain LoaderIBKR chain request
β†’
Greek CacheIV Β· Ξ” Β· Θ Β· Ξ“ real-time
β†’
Liquidity Filterbid-ask Β· volume check
β†’
Delta Strike Pickerclosest delta to target
β†’
Contract βœ“symbol Β· expiry Β· strike
ModuleFilePurpose
DeltaStrikePickermodules/options/delta_strike_picker.pySelects strike closest to configured delta target
GreekCachemodules/options/greek_cache.pyReal-time IV, delta, theta, gamma β€” cached per tick
OptionChainLoadermodules/options/option_chain_loader.pyRequests full option chain from IBKR on demand
LiquidityFiltermodules/execution/liquidity_filter.pyFilters illiquid contracts β€” bid-ask spread + volume
ExpiryUtilsmodules/options/expiry_utils.py0DTE / weekly / monthly expiry calculation
ESConidResolvermodules/options/es_conid_resolver.pyResolves ES futures contract IDs for quarterly rolls
⚑
Section 10
Order Execution Engine
modules/execution/order_executor.py handles all placement, modification, and cancellation. Implements atomic cancel-replace, parallel multi-contract submission, and event-driven fill confirmation.
Python Β· Atomic Cancel-Replace (LP Shield modification)
# Step 1: Pre-validate price against IBKR tick rules # Step 2: Pre-validate position size from PortfolioCache (O(1)) # Step 3: Pre-build new order object β€” no broker call yet # Step 4: Cancel old SELL + place new β€” back-to-back, no sleep # Step 5: Event-driven cancel confirm via OrderStatusCache (max 100ms) new_order_id = loss_protection._atomic_replace_sell( contract, new_price=5.17, label="t1_target_replace" ) # Total atomic window: <150ms guaranteed by OrderStatusCache event
Service / ModulePurpose
OrderExecutorPlace, modify, cancel orders via ib_async β€” single entry point
OrderStatusCacheO(1) order status lookup β€” replaces slow ib.openTrades() scans in hot path
V2FillDispatcherRoutes IBKR fill events β†’ lifecycle bridge β†’ DB write
V2PositionWatchdogDaemon thread β€” monitors open position, breakeven modify, trail stops
V2OrderStateTrackerTracks order state transitions in memory for fast lookup
OrderCancelServiceSafe cancel with CancelCause classification (LP / manual / expire)
OrderCancelRegistryImmutable record of every cancel with cause and timestamp
OrderFailureTrackerClassifies and records all order failures β€” root cause + derived
StartupReconciliationReconciles open positions with lifecycle DB on engine restart
SafeLockAsync lock preventing concurrent entry/exit for same instrument
πŸ›‘οΈ
Section 11
Loss Protection β€” 6 Rules
modules/risk/loss_protection.py runs as a daemon thread from fill confirmation to position close. Implements 6 rules, each independently configurable from the operator console.
RuleNameAction TakenNotes
Rule 1Profit TargetLimit sell placed at entry; monitored by LP daemonT1 / T2 / T3 ladder, atomic replace on target adjust
Rule 2Grace Period GateProtects sell order from modification for N minutesDefault 15 min; V2PositionWatchdog handles breakeven after
Rule 3Unclosed AlertFires alert every N minutes if position remains openDefault 30-min interval on CRITICAL alert lane
Rule 43:30PM HandlingThree modes: modify_to_entry, alert_only, force_closeConfigurable per environment β€” default: modify_to_entry
Rule 5EOD Force CloseMarket sell at eod_close_time β€” non-negotiableDefault 15:55 ET β€” no exceptions, no overrides
Rule 6Price Feed EmergencyMarket sell after N consecutive zero price readingsDefault: 8 consecutive zeros β€” prevents stale-data hold

Polling Schedule

Fast Poll Phase (first 10 min)Every 5 seconds β€” danger zone for 0DTE gamma
Normal Poll Phase (after 10 min)Every 30 seconds β€” standard monitoring
Fill ConfirmationEvent-driven via OrderStatusCache β€” not timed
Grace Period Default15 minutes after entry fill
πŸ”’
Section 12
Shield Types β€” Per-Strategy Protection
Set the shield field in config_veera_strategies per strategy. Shields are enforced by V2PositionWatchdog alongside LP rules.
ShieldDB ValueBehaviourBest For
Rapid Shield"rapid_shield"Arms within seconds of fill. Triggers on intraday drawdown threshold (default 22% loss). Immediate market exit.Breakout strategies β€” fast adverse moves
Day Shield"day_shield"Session-level daily loss ceiling. Gates all new entries once daily drawdown is reached. Parks engine in observation mode.Multi-entry strategies per session
None (Global LP)nullFalls back to global LP rules in stoploss_config tableDefault for all strategies
βš–οΈ
Section 13
Risk Manager β€” Pre-Trade Validation
modules/risk/risk_manager.py validates every proposed trade before submission. ALL checks must pass or the trade is blocked with a classified reason code.
Position limitsDaily loss ceiling ($) Max open positionsGamma exposure bounds Staleness guardMarket gate state Existing position checkCapital sufficiency Instrument enabled checkOption viability (greeks loaded)
🚦
Section 14
Market Gate β€” Session Control
A runtime toggle β€” OPEN or CLOSED. All new entries are blocked when closed. Automatically closes on daily loss limit breach. Manually toggleable from the operator console.
State: OPENAll strategies can enter β€” normal operation
State: CLOSEDNo new entries β€” LP continues monitoring open positions
Auto-Close TriggerDaily loss limit hit β†’ gate auto-closes, alert dispatched
Manual ToggleDashboard β†’ Config β†’ Risk β†’ Market Gate toggle (5s TTL)
PersistenceState persists in config_meta table β€” survives restart
πŸ”€
Section 15
Trade State Machine β€” Deterministic Lifecycle
Every trade flows through a deterministic sequence of states. Each transition is atomic β€” written to the lifecycle DB before the next step begins. Crash-recoverable at any stage.
scanner fires
pool publishes
01SCANNER_SIGNALSignalPool.publish() β†’ Hunter wakes
↓ T+0ms
pattern match
Veera Rules Β· Hunter
02STRATEGY_PASSAll gates pass β†’ proceed to risk
↓ T+3ms
DeltaStrikePicker
GreekCache
03OPTION_SELECTEDStrike Β· expiry Β· contract confirmed
↓ T+8ms
WealthManager
ladder level
04WEALTH_SIZEDContract count determined for this session
↓ T+10ms
ib_async
market order
05BUY_SUBMITTEDOrder ID stored Β· lifecycle DB written Β· SafeLock held
↓ T+12ms
V2FillDispatcher
IBKR fill event
06BUY_FILLEDFill price Β· slippage recorded Β· LP daemon starts
↓ T+35ms avg
limit sell placed
LP armed
07SELL_SUBMITTEDT1 limit sell @ entry Γ— 1.23 Β· LP monitors
↓ T+36ms
V2FillDispatcher
exit fill event
08SELL_FILLEDExit fill confirmed Β· PnL calculated Β· LP stops
↓ variable
TradeCloseService
immutable audit
09CLOSEDLifecycle DB written Β· immutable audit record created
↓ +1ms
WealthManager
ws/wealth fires
10WEALTH_UPDATEDCapital Β· milestones Β· TradeDiary Β· dashboard WS
↓ +5ms
πŸ”„
Crash Recovery

Every state transition writes to the lifecycle DB before proceeding. On restart, StartupReconciliation reads the DB and resumes from the last committed state. No orphaned positions, no missed closes β€” the engine always knows where each trade is.

πŸ’Ύ
Section 16
Lifecycle Database Schema
backend/runtime/intellect_finlab_next.db β€” canonical trade truth. Every trade, every state transition, every fill event persisted here.
TablePurposeKey Columns
tradesOne row per trade β€” full lifecycletrade_id, symbol, direction, state, buy_fill_price, sell_fill_price, pnl, strategy_id
trade_eventsAudit trail β€” every state transitiontrade_id, event_type, timestamp, data_json
order_fillsRaw IBKR fill recordsorder_id, fill_price, fill_time, commission
position_snapshotsPoint-in-time greek snapshotstrade_id, snapshot_time, delta, theta, gamma, iv
cancel_registryEvery cancel with cause classificationorder_id, cancel_cause, timestamp, context
order_failuresAll order failures with root/derived causeorder_id, root_cause, derived_cause, context
πŸ’°
Section 17
Wealth Model Architecture
CSV-driven capital progression plans β€” WM235K, WM2310K, WM2320K. Each plan defines weekly capital milestones, trade sizing ladder levels (trade_start / T1 / T2 / T3), and target PnL per week.
ModelStarting CapitalAnnual TargetLadder Levels
WM235K$35,000~$500Ktrade_start β†’ T1 β†’ T2 β†’ T3 (weekly milestones)
WM2310K$10,000~$150KAggressive compounding for smaller accounts
WM2320K$20,000~$300KMid-tier β€” balance of growth and risk
Ladder Level: trade_startBase contract size β€” beginning of week
Ladder Level: T1Size up after first weekly target milestone hit
Ladder Level: T2Size up further after T2 milestone
Ladder Level: T3Maximum size β€” final weekly target range
Week AdvanceAuto-triggered when current capital reaches weekly target
πŸ“¦
Section 18
DI Container β€” build_container()
All 40+ services are instantiated once in build_container() in backend/app/main.py and stored in a Container dataclass. Routes receive services via FastAPI dependency injection.
Python Β· backend/app/main.py (simplified)
@dataclass class Container: lifecycle_repo: LifecycleRepository config_repo: ConfigRepository trade_lifecycle_svc: TradeLifecycleService runtime_control_svc: RuntimeControlService wealth_svc: WealthService scanner_svc: ScannerService analytics_svc: AnalyticsService # ... 35+ more services def build_container() -> Container: # Wire all dependencies once at startup # Never instantiate services directly in routes ...
πŸ”‘
Architecture Rule

Routes are thin β€” they receive services via FastAPI DI and delegate immediately. All business logic lives in services. Workers call services on a timer or event. This ensures testability, single responsibility, and no circular imports.

🌐
Section 19
API Routes β€” REST Endpoints
FastAPI routers in backend/app/api/routes/ β€” one file per domain. All routes use ORJSONResponse for high-performance serialization.
Route DomainFileKey Endpoints
Lifecycle / Tradesroutes/lifecycle.pyGET /trades, GET /trades/{id}, GET /trade-story/{id}
Configroutes/config.pyGET/PUT /config/:domain β€” all config domains
Wealthroutes/wealth.pyGET /wealth/state, GET /wealth/diary, GET /wealth/plan
Scannersroutes/scanners.pyGET /scanners, GET /scanners/status, PUT /scanners/{name}/toggle
Analyticsroutes/analytics.pyGET /analytics/session, GET /analytics/leaderboard
Portfolioroutes/portfolio.pyGET /portfolio/positions, GET /portfolio/risk
Backtestroutes/backtest.pyPOST /backtest/run, GET /backtest/results, POST /backtest/ai-discover
Systemroutes/system.pyGET /health, POST /system/start, POST /system/stop
Alertsroutes/alerts.pyGET /alerts/history, POST /alerts/test
πŸ“‘
Section 20
WebSocket Channels β€” Real-Time Feeds
Sub-second real-time event streams via FastAPI WebSocket. Each channel is purpose-scoped. The React frontend subscribes via dedicated hooks in frontend/src/live/.
ChannelURLEvents Pushed
Orders / Tradesws://host/ws/ordersBUY_SUBMITTED, BUY_FILLED, SELL_SUBMITTED, SELL_FILLED, CLOSED
Live Flowws://host/ws/flowSCANNER_FIRE, STRATEGY_PASS, RISK_BLOCK, HUNTER_CONFIRMED
Trade Centerws://host/ws/trade-centerFull trade story updates, position mark-to-market
Wealthws://host/ws/wealthCapital updates, milestone reached, ladder level change
System Eventsws://host/ws/systemHealth status, IBKR connection, gate state, engine status
Alertsws://host/ws/alertsTelegram/email dispatch events, alert delivery status
πŸ”§
Section 21
Background Workers β€” Daemon Threads
Background workers run on daemon threads, calling services on timer or event. Each worker has a single responsibility and a configurable run interval.
WorkerIntervalResponsibility
RuntimeSyncWorkerIBKR tick eventsHeartbeat β€” syncs IBKR state to RuntimeStore, fires notify_tick()
FlowWorker500msProcesses LiveFlow events, dispatches to ws/flow channel
DeltaLadderWorker60sPre-activates ES, SPX, NQ symbols for fast greek access
PromotionSyncWorkerStartup + 5minPromotes un-promoted legacy diary entries to lifecycle DB
BrokerTradeReconcilerStartup +8sReconciles TWS fills with lifecycle DB on startup
DBHygieneWorkerDailyPrunes stale order cache entries, compacts DBs
πŸ—„οΈ
Section 22
Database Schemas β€” All 3 SQLite DBs
Three isolated SQLite databases β€” config, lifecycle/trades, and wealth state. Paths resolved via Settings properties. Never hardcoded anywhere in the codebase.

Config DB β€” backend/data/config.db

TablePurpose
config_optionsPer-instrument settings (delta targets, entry windows, gamma bounds)
config_scannerPer-scanner settings (enabled, cooldown, email, telegram)
config_scanner_globalMaster scanner switches (email_all, telegram_all, es_only_mode)
config_veera_strategiesAll strategy definitions β€” patterns, rules, hunter mode, shield
config_metaSystem-level config (telegram tokens, environment, market gate)
stoploss_configGlobal LP settings (grace period, EOD time, poll intervals)
wealth_configActive wealth model name, current week, capital state

Lifecycle DB β€” backend/runtime/intellect_finlab_next.db

TablePurpose
tradesOne row per trade β€” full lifecycle state, fill prices, PnL
trade_eventsImmutable audit trail β€” every state transition with timestamp
order_fillsRaw IBKR fill records including commission

Wealth DB β€” runtime/paper/intellect.db or runtime/live/intellect.db

TablePurpose
wealth_stateCurrent capital, week number, ladder level, PnL to date
trade_diaryPer-trade record with greeks at entry, hold time, close reason
weekly_summaryWeek-over-week capital progression vs plan
βš™οΈ
Section 23
Config System β€” DB with TTL Cache
Config DB is the runtime source of truth. 5-second TTL cache ensures changes made via the operator console propagate within one cache expiry β€” no restart required.
Config Change Propagation Flow
Operator UIConfig Console
β†’
FastAPI RoutePUT /config/:domain
β†’
ConfigServiceWrite to config.db
β†’
TTL Expires5 seconds max lag
β†’
Services Re-readChange applied live
πŸ“²
Section 24
Alert Manager β€” Dual-Lane Dispatch
Two independent Telegram bots + email SMTP. All alerts dispatched on daemon threads β€” trading path is never blocked waiting for Telegram or email delivery.
LaneChannelEvents
Main BotTelegram Bot 1Trade fills (buy/sell), LP events, session summaries, market gate changes
Scanner BotTelegram Bot 2Scanner fire events β€” separate channel keeps main bot clean
EmailSMTPHTML emails: order_buy, order_sell templates with full greek table
In-AppWebSocket ws/alertsAll events immediately visible in dashboard Live Feed
πŸ”¬
Section 25
Backtest Engine β€” 2Y Historical Data
Vectorized backtester running against 2 years of 1-minute bar data. Scanner leaderboard, equity curves, wealth replay, and AI-discovered strategies via Ollama LLM integration.
ComponentPurpose
Scanner LeaderboardRuns all 80+ scanners against historical data β€” ranked by TQS (Trade Quality Score)
Rule BuilderCustom strategy builder β€” compose 15+ indicator rules (EMA, RSI, ADX, VWAP, MACD)
Equity CurveTrade-by-trade equity curve with drawdown overlay
Wealth ReplaySimulate full WM plan progression against backtest results
AI DiscoveryOllama LLM analyses signal combinations for high-conviction patterns
Onboard to PaperPromotes validated backtest config directly to config DB as live strategy