Signal Pipeline — Detector → Advisor → Inspector execution flow
End-to-end signal pipeline: 115 technical indicators, 8-stage LLM decision, Signal Fusion Engine, risk governor with 17 block reasons, bracket orders, and TWAP execution.
Overview
The signal pipeline is the core trading logic of the Barfinex platform. A market data event enters at Provider, becomes a signal in Detector, passes through an 8-stage AI decision pipeline in Advisor, is validated by Inspector's risk governor, and finally results in an executed order on the exchange.
Exchange candle close
│
▼
Provider (8081)
publishes PROVIDER_MARKETDATA_CANDLE → Redis
│
▼
Detector (8101)
FollowTrendService.onCandleClose()
115 indicators computed → signal scored
publishes DETECTOR_SIGNAL_GENERATED → Redis
│
▼
Advisor (8009) — 8-stage LLM pipeline
Stage 1: Fetch context (Provider MCP)
Stage 2: Market quality gate
Stage 3: Signal engine (rules + ML)
Stage 4: Conviction scoring [0,1]
Stage 5: Calibration (logistic regression)
Stage 6: LLM synthesis (Claude/GPT)
Stage 7: Execution validation (spread/R:R)
Stage 8: Publish ADVISOR_EXECUTION_INTENT_OPEN → Redis
│
▼
Inspector (8008)
RiskEngine → RiskGovernor → PortfolioEngine
ALLOW → ProviderExecutionService (REST order)
BLOCK/THROTTLE → audit log, no execution
│
▼
Provider (8081) → Exchange (Binance/Bybit/…)
Exchange fills → real fill via account WS ORDER_TRADE_UPDATE
Provider publishes PROVIDER_ORDER_FILL → Redis
│
▼
Inspector: INSPECTOR_TRADE_OUTCOME → Redis
Advisor: updates calibration weights (INSPECTOR_TRADE_OUTCOME)
Stage 1: Detector — Strategy runtime
Detector is a configurable rule engine with 115 technical indicators. Each Detector instance is a typed TypeScript configuration specifying:
- Which symbols and intervals to watch
- Which indicators to compute (
rsi14,adx14,macd,ema20,bands20,atr14,dc20,stoch,cci20,mfi14,obv,vwap, etc.) - Which rules to evaluate and their numeric weights
- Conviction threshold for signal emission
Indicator computation:
IndicatorEnginecomputes in DAG order — indicators with dependencies compute after their inputs- Every indicator result is published via
IndicatorSnapshotStoreServiceto the indicator publisher (REST + WebSocket) - Feature vectors extracted from raw indicator values for ML and LLM context
Signal scoring:
- Each rule produces a sub-score weighted by its configured weight
- Combined score compared to
signalThreshold - Signal carries: symbol, side (BUY/SELL), confidence [0,1], strategyId, rule attribution
Multiple instances:
- Multiple Detector configurations run simultaneously, each isolated
DecisionWindowServicein Advisor is keyed bysymbol + strategyId— two detectors on the same symbol each get an independent decision cycle with full provenance
Capital efficiency:
- Detector tracks per-strategy capital utilization, suppression, and reservation analytics
GlobalCapitalAllocatorEngineevaluates each signal against per-symbol and total exposure limits before publishing
Stage 2: Advisor — 8-Stage LLM Pipeline
Stage 1: ProviderMcpContextService
Fetches live market context via Provider MCP tools:
- Current price, recent candles, orderbook depth
- Open positions, account balance, equity
- Any active Inspector risk state
Stage 2: MarketReadinessGateService
Validates market data quality via MarketQualityEngine:
- Orderbook freshness and depth
- Trade stream continuity
- Candle OHLC validity
- Returns
healthScore [0,1]andhealthState: HEALTHY/DEGRADED/BAD - Block threshold:
DATA_QUALITY_BLOCK_HEALTH_SCORE=0.3
Also runs DataQualityGateService (Phase 14):
- Feature NaN count check (
DATA_QUALITY_BLOCK_NAN_COUNT=5) - Orderbook staleness check (
DATA_QUALITY_BLOCK_STALENESS_MS=120000ms) - Rolling feature drift — 100-sample baseline per feature, flags >2σ for ≥3 consecutive snapshots
- Regime instability — >3 regime changes in 30 minutes
- Performance drift — recent-20 win rate vs historical-100 win rate
Stage 3: SignalEngineIntegrationService
Runs rule engine + ML signal scorer in parallel:
- Rule engine: evaluates signal conditions against live data
- ML signal scorer (Stage 3.5): optional PyTorch MLP inference via
ML_TRADING_ADVISOR_URL(port 8019)- Currently DISABLED (
ML_TRADING_ADVISOR_ENABLED=false) — no robust edge, insufficient training data - Head 1: direction (UP/DOWN/NEUTRAL)
- Head 2: expected return (%)
- Latency target: <5ms
- Currently DISABLED (
Stage 4: ConvictionEngineService
Scores conviction [0,1] from:
- Signal engine confidence
- ML agreement/disagreement adjustment (when enabled)
- Quantitative runtime truth: account active, margin sufficient, kill-switch state, data freshness
- Hard
NO_TRADEon explicit kill switch, insufficient margin, or stale feed
Stage 5: CalibrationEngineService
Calibrates raw conviction via:
- Logistic regression (Platt scaling) with per-regime scaling
- Isotonic regression as alternative
ConvictionLogisticModelreturns: win probability, capital multiplier,ALLOW/DAMPEN/BLOCK- Calibration weights updated from
INSPECTOR_TRADE_OUTCOMEfeedback loop
Stage 6: GptService — LLM Synthesis
Calls the configured LLM with full structured context:
- Market data snapshot, indicator values, orderbook depth
- Account state, open positions, risk status
- Breaking market intelligence (from
PROVIDER_MARKET_INTELLIGENCE_EVENT— critical/high events only) - Conviction score and calibration result
LLM catalog (config.advisor.json — not env vars):
| Profile | Provider | Model |
|---|---|---|
claude-opus (default) | claude-cli | opus, effort=high, budget=$0.50 |
claude-sonnet | claude-cli | sonnet, effort=medium |
openai-4.1 | openai | gpt-4.1 |
openai-4.1-mini | openai | gpt-4.1-mini |
glm-5 | glm | glm-5 |
Role assignments: decision=claude-opus, advisory=claude-opus, temperature decision=0.2, advisory=0.5.
Stage 7: ExecutionAgentService
Final validation before Redis emit:
- Spread < 0.4% (or MICRO_GATE_SPREAD_BLOCK_PCT)
- Risk/Reward ≥ 1.2 (MIN_RR_FULL=2.0 from TuningRegistry)
- Direction strength > 0.25 (MIN_DIRECTION_STRENGTH)
- Consistency score > 0.5 (MIN_CONSISTENCY)
- Edge score > 0.4 (MIN_EDGE)
- Execution quality > 0.4 (MIN_EXECUTION_QUALITY)
Decision policy modes:
CONSERVATIVE(default) — tight thresholds, fewer tradesBALANCED— moderateAGGRESSIVE— looser thresholds, higher frequency
Stage 8: Redis emit
Publishes ADVISOR_EXECUTION_INTENT_OPEN/CLOSE/REDUCE/FLIP and ADVISOR_DECISION_MADE to Redis. Execution intents are dual-written to Redis Streams for bounded replay.
Signal Fusion Engine (SHADOW mode)
An optional upstream layer that pre-aggregates multi-detector signals across domains before the 8-stage pipeline runs.
Domains: LIQUIDITY, FLOW, NEWS, MICROSTRUCTURE, LEGACY (weights configurable via env vars)
Pipeline:
SignalIntakeServicesubscribes toDETECTOR_SIGNAL_GENERATED- Stale filter (>45s) + per-symbol storm protection (10/sec)
SignalBufferrolling 90-second window per symbolDebounceCoordinatorleading-edge 350ms timer- Domain-weighted consensus with multi-domain boost (×1.25), conflict veto (ratio ≥0.85), per-domain cap (0.55)
- Single-domain override: LIQUIDITY ≥0.75 strength + ≥0.9 reliability bypasses consensus
Status: Currently in SHADOW mode — logs and counters only. Active pipeline drive deferred behind ADVISOR_SIGNAL_FUSION_DRIVE_PIPELINE=true.
Intel Detectors
Lightweight services that bypass the heavy DetectorService DI chain. Subscribe to PROVIDER_MARKET_INTELLIGENCE_EVENT and publish DETECTOR_SIGNAL_GENERATED.
| Service | Domain | Description |
|---|---|---|
whale-alert-intel | FLOW | Whale transactions >$50M. Redis SETNX dedup (6h TTL), amount-aware boost ($50M/$200M) |
news-intelligence-intel | NEWS | Breaking news signals. Headline hash dedup, clickbait filter, cross-source boost |
Feature flags: INTEL_DETECTORS_WHALE_ALERT_ENABLED, INTEL_DETECTORS_NEWS_ENABLED (default OFF).
Stage 3: Inspector — Risk Governor
Execution flow
ADVISOR_EXECUTION_INTENT_* received
│
▼
RiskEngine.evaluate() -- compute proper position size
│ ATR stop, Kelly, regime multiplier, vol scaling
│
▼
PortfolioEngine.evaluate() -- cross-symbol correlation check
│ covariance matrix, vol budget, correlation soft-cap 0.6
│
▼
RiskGovernor.evaluate() -- 17 block reasons, 5 actions
│
├── ALLOW → ProviderExecutionService.submitOrder()
├── BLOCK → audit log, no execution
├── THROTTLE → reduce position size
├── STAND_DOWN → block all new opens
└── CLOSE_ALL → emergency exit all positions
5 RiskGovernor actions
| Action | Meaning |
|---|---|
ALLOW | Intent approved — proceed to execution |
BLOCK | Intent blocked — do not execute |
THROTTLE | Intent throttled — reduce position size |
STAND_DOWN | System stand-down — halt new positions |
CLOSE_ALL | Emergency — close all positions immediately |
17 block reasons
EXPOSURE_CAP_BREACH, DRAWDOWN_LIMIT_BREACH, DAILY_LOSS_LIMIT_BREACH, CONSECUTIVE_LOSSES_LIMIT, MARGIN_INSUFFICIENT, LEVERAGE_EXCEEDED, COOLDOWN_ACTIVE, CIRCUIT_BREAKER_OPEN, STANDDOWN_POLICY, THROTTLE_POLICY, CLOSE_ALL_POLICY, HEALTH_DISALLOW, DATA_NOT_MATURE, ACCOUNT_INACTIVE, INVALID_QUANTITY, EXPOSURE_ESTIMATED_BREACH, ALLOW_DEFAULT
Post-execution
After successful OPEN:
- Inspector immediately places bracket orders (STOP_MARKET + TAKE_PROFIT_MARKET) via Provider REST
- Binance protection orders use rate-limiter
protectionpriority — bypass local client-side freeze, Binance response still authoritative INSPECTOR_TRADE_OUTCOMEpublished to Redis → Advisor updates calibration weightsPostTradeAuditServicerecords: slippage bps, latency ms, fee tiers, partial fill detection- Equity curve updated in
inspector_equity_curve(QuestDB, every account sync)
Scale-out and TWAP
- Scale-out: configurable
riskManagement.scaleOutLevels[]—{pnlPct, closePct}pairs. Processed sequentially. - TWAP:
TwapExecutionServicesplits large orders into configurable slices at intervals. Idempotent sub-orders tracked (active/completed/failed/cancelled).
Key env vars
| Variable | Default | Service |
|---|---|---|
ADVISOR_TRIGGER_MODE | detector | Advisor — detector (signal-driven) or self (autonomous) |
ADVISOR_EXECUTION_MODE | inspector-gated | Advisor — inspector-gated or direct-provider |
DATA_QUALITY_BLOCK_HEALTH_SCORE | 0.3 | Advisor — market quality block threshold |
INSPECTOR_RISK_GOVERNOR_ENABLED | true | Inspector — enable risk governor |
INSPECTOR_MAX_DRAWDOWN_PCT | 10 | Inspector — max portfolio drawdown % |
INSPECTOR_MAX_DAILY_LOSS_PCT | 5 | Inspector — max daily loss % |
INSPECTOR_MAX_CONSECUTIVE_LOSSES | 5 | Inspector — max consecutive losses |
INSPECTOR_MAX_LEVERAGE | 20 | Inspector — maximum allowed leverage |
INSPECTOR_STRATEGY_ISOLATION_ENABLED | true | Inspector — per-strategy budget isolation |
INSPECTOR_STRATEGY_DEFAULT_BUDGET_PCT | 25 | Inspector — equity fraction per strategy |
INSPECTOR_ADAPTIVE_RISK_ENABLED | false | Inspector — adaptive position sizing |
ML_TRADING_ADVISOR_ENABLED | false | Advisor — ML signal scorer (disabled, no edge) |