LangGraphAPSchedulerHuman-in-the-Loop

Orchestration & Agents

LangGraph StateGraph — a structured multi-agent debate before every trade. No signal reaches execution without surviving research, critique, adversarial review, and a sanity check.

Three-Layer Architecture

Layer 1SuperIntelOrchestrator— master controller, top-level wiring
└──Layer 2GraphOrchestrator— LangGraph StateGraph, 7-node decision flow
└──Layer 3PredictionOrchestrator— 22+ parallel ML models

LangGraph State Machine

GraphOrchestrator — StateGraph topology

LangGraph orchestration state machine

Router — After debate_agent

DEEP DIVE
dissent_score > 0.7 AND loop_count < 3

→ deep_research (loop_count++) → back to debate_agent

FAST PATH
dissent_score < 0.2

→ allocator_agent (high conviction, no deep dive needed)

TERMINATE
else (dissent 0.2–0.7, or loop_count ≥ 3)

→ END — uncertain_end, no trade submitted

The 7 Graph Nodes

1
research_agentresearch_node()

Calls Perplexity sonar-pro to fetch a real-time market narrative for the ticker. Synthesises news, social tone, macro context, and earnings expectations into a structured summary injected into AgentState.

fills:market_narrative
2
debate_agentdebate_node()

Runs a structured Bull / Bear / Neutral debate using ML ensemble signals and market_narrative. Computes dissent_score [0–1] — degree of disagreement. High dissent (>0.7) triggers deep_research re-entry. Low dissent (<0.2) fast-paths to allocator.

fills:dissent_score
3
deep_researchdeep_research_node()

Full Perplexity deep-dive triggered only when dissent_score > 0.7 AND loop_count < 3. Injects heavyweight context to break the deadlock. loop_count increments after each call; control returns to debate_agent.

fills:market_narrative (updated)
4
allocator_agentallocator_node()

Runs the PortfolioOptimizer (half-Kelly sizing, 4-constraint enforcement). Returns AllocationResult with approved flag, position_size_pct, stop_loss, take_profit. approved=False blocks all further execution.

fills:allocation_result
5
red_team_nodered_team_node()

Passes the full AgentState to adversarial GPT-3.5-turbo: 'Find every reason this trade should NOT be taken.' Returns veto=bool, kill_reason, risk_flags[]. Sets red_team_veto in AgentState.

fills:red_team_veto
6
sanity_guard_nodesanity_guard_node()

Hard reality check: if |LLM-referenced price − live price| / live price > 5%, veto='price_hallucination'. Also validates order size vs. current liquidity. Any failure sets sanity_veto=True — execution never proceeds.

fills:sanity_veto
7
execution_agentexecution_node()

Calls DecisionGateway.create_decision(). Confidence >0.85 → AUTO_EXECUTE. 0.65–0.85 → TRADER_REVIEW (5-min). <0.65 → SENIOR_REVIEW (10-min). Timeout always means auto-reject.

fills:final_decision

AgentState — TypedDict

Persists across all graph nodes. Key routing-critical fields:

FieldTypeSet ByUsed By
dissent_scorefloat [0–1]debate_agentRouter (deep dive decision)
allocation_resultAllocationResultallocator_agentRouter (approved flag)
red_team_vetoboolred_team_nodeExecution gate
sanity_vetoboolsanity_guard_nodeExecution gate
loop_countint (max 3)deep_researchRouter (infinite loop guard)
market_narrativestrresearch_agentdebate_agent, allocator_agent
final_decisiondictexecution_agentDecisionGateway output

Human-in-the-Loop Approval Tiers

Timeout always means auto-reject — the system never auto-approves a timed-out decision. Decisions unattended for 15+ minutes are invalidated before any broker call.
TierConfidenceApproverTimeoutDelivery
AUTO_EXECUTE> 0.85System (no human)Window-based override
TRADER_REVIEW0.65 – 0.85Trading desk trader5 minutesWebSocket + Telegram
SENIOR_REVIEW< 0.65Senior trader10 minutesWebSocket + Telegram

Circuit Breakers

BreakerTrigger ConditionReset
Drawdown BreakerDaily PnL drawdown > 5%Manual only (CIO/Risk)
Failure Breaker3+ execution failures in 5 minutesAuto-reset after cool-down
Latency BreakerConfigurable response time threshold exceededAuto-reset
Manual BreakerCIO/Risk manager command via APIManual only
When any circuit trips: all new signal processing halts. Open orders continue (live fills proceed). Telegram alert fires to Risk Manager role. System resumes only after manual or auto reset.

APScheduler — 20 Timed Jobs

AsyncIOScheduler in UTC timezone. Jobs are the heartbeat of the entire system — data ingestion, signal scans, EOD reconciliation, and weekly model retraining.

Job NameIntervalPurpose
crypto_ingestion5 minFetches latest crypto OHLCV from Binance CCXT
trade_lifecycle5 minChecks open order status; updates fills from broker
signal_generation5 minTriggers SuperIntel engine for autonomous signal scan
position_limits5 / 15 minEnforces max position size limits across portfolio
nav_scanning5 minScans NAV arbitrage opportunities (GBTC/BTC pairs)
pnl_snapshot15 minWrites portfolio PnL snapshot to TimescaleDB
model_health1 hourReviews model scoring; flags underperforming models
equity_ingestion1 hourFetches equity OHLCV from YFinance
eod_reconciliationEOD step 1Reconciles broker fills with internal position records
data_quality_gateEOD step 25-check quality validation sweep on all day's ingested data
feature_computationEOD step 3Computes all ML features from raw OHLCV data
eod_pipelineEOD step 4EOD data pipeline — aggregations, rolling statistics
arbitrage_discoveryEOD step 5Scans for intraday arbitrage opportunities
correlation_refreshEOD step 6Refreshes rolling cross-asset correlation matrix
cointegration_refreshEOD step 7Re-tests cointegration pairs with fresh data
intraday_pipeline09:00–16:00 UTCIntraday data ingestion and feature update (Mon-Fri)

Regime-Adaptive Thresholds

The RegimeAdaptiveOrchestrator maintains per-regime threshold profiles. On regime detection, thresholds switch live — no restart required.

RegimeConfidence ThresholdMax PositionConsensus Required
HIGH_VOLATILITY0.901% of NAV0.80 — near-unanimous
LOW_VOLATILITY0.703% of NAV0.65 — standard
TRENDING0.752% of NAV0.70 — allows trend-following pairs