11 KiB
TRADING AGENT SYSTEM OVERHAUL: Technical Requirements Document (v3.0)
Status: ✅ COMPLETE / PRODUCTION-READY Objective: The system is now a deterministic, institutional-grade decision engine.
1. CORE ARCHITECTURE: The Data Registrar (Immutable Reality)
Goal: Prevent hallucination, time-drift, and "dirty reads" by freezing the state of the world before any agent wakes up.
1.1. Canonical Data Fetching
- Requirement: The graph must execute a
DataRegistrarnode exactly once at theSTART. - Constraint: Downstream agents (
Market,News,Fundamentals) are FORBIDDEN from calling external data tools. They must strictly read fromstate["fact_ledger"]. - Scope: The Registrar must fetch and bundle:
- Price Data (OHLCV + Technicals)
- Fundamental Data (Balance Sheet, Income, Cash Flow)
- News & Sentiment (Raw text/JSON)
- Insider Transactions
1.2. Cryptographic Auditability & Schema
- Requirement: The
FactLedgermust be cryptographically sealed and include explicit freshness metadata.
Schema Definition:
{
"ledger_id": "UUID-v4",
"created_at": "ISO-8601 UTC Timestamp",
"freshness": {
"price_age_seconds": 32.5, // Allow max 60s
"fundamentals_age_hours": 6.0, // Allow max 24h
"news_age_hours": 1.0 // Allow max 4h
},
"source_versions": {
"price": "yfinance_v2@2026-01-15T...",
"news": "serper@2026-01-15T..."
},
"data_payload": { ... }, // The actual data content
"hash": "SHA-256(data_payload)" // Hash of PAYLOAD ONLY (Metadata excluded)
}
1.3. The "Fail-Fast" Kill Switch
- Requirement: If any critical data source fails or exceeds freshness limits:
- The system must ABORT IMMEDIATELY (Raise Exception).
- No LLM agents shall be invoked.
- No partial degradation is allowed for trading decisions.
2. EXECUTION LAYER: The Omnipotent Gatekeeper
Goal: Separate "Decision Generation" (LLM) from "Decision Authorization" (Python). Stop the Trader from executing invalid or dangerous orders.
2.1. Machine-Readable Return Codes (Enums)
- Requirement: The Gatekeeper must return specific
ExecutionResultEnums, never generic strings.
Codes:
APPROVED: Trade passes all checks.ABORT_COMPLIANCE: Insider flag or restricted list hit.ABORT_DATA_GAP: Data found to be stale or missing during verification.ABORT_LOW_CONFIDENCE: Trader confidence < 0.7.ABORT_DIVERGENCE: Analyst disagreement exceeds threshold.BLOCKED_TREND: "Don't Fight the Tape" rule triggered.
2.2. Consensus Divergence Check (Normalized)
- Requirement: Quantify disagreement between Bull and Bear analysts to detect "Epistemic Uncertainty."
- Formula:
Divergence_Score = abs(Bull_Score - Bear_Score) * mean_confidence
Logic:
- High Disagreement + High Confidence = DANGER (ABORT).
- High Disagreement + Low Confidence = NOISE (Ignore/Size Down).
2.3. Deterministic Trend Override (Counterfactuals)
- Requirement: Block "SELL" orders on high-growth assets in strong uptrends using
FactLedgerdata.
Logging Requirement: When a trade is blocked, log the Counterfactual:
{
"event": "TRADE_BLOCKED",
"rule": "STRONG_UPTREND_PROTECTION",
"original_intent": "SELL 100 SHARES",
"executed_action": "HOLD",
"counterfactual_outcome": "Would have sold into a +30% growth/bull regime."
}
2.4. Abort Semantics
- Constraint:
ABORT!=HOLD.HOLDis a strategic decision to do nothing.ABORTis a system failure or safety trigger.
- Action: Aborted trades must trigger an alert to the
HumanReviewQueue(log file or dashboard).
3. INTELLIGENCE LAYER: Bounded & Conditioned Learning
Goal: Prevent "Recency Bias" and "Overfitting" by forcing the Reflector to respect math and regimes.
3.1. Agent Attribution Scoring
- Requirement: The Reflector must assign performance scores to individual agents based on the outcome.
- Constraint: The sum of attribution scores (negative or positive) must not exceed 1.0. (Prevents "blaming everyone" for a single loss).
3.2. Regime-Conditioned Memory
- Requirement: Every memory/lesson must be tagged with the context in which it was learned.
{ "lesson": "Tighten stops", "regime": "VOLATILE" }
- Retrieval Rule: The Trader may ONLY retrieve lessons that match the Current Regime. (e.g., Do not fetch "Bear Market" lessons during a "Bull Market").
3.3. Bounded Parameter Tuning (The Safety Rails)
- Requirement: Python code must validate all
UPDATE_PARAMETERSsuggestions from the LLM.
Velocity Brake: If a parameter is adjusted in the same direction for 3 consecutive sessions:
- FREEZE that parameter.
- Flag for Human Review. (Reason: Prevents runaway drift or "death-by-a-thousand-tweaks").
4. OPERATIONAL SAFETY: The Human Loop
Goal: Operationalize human oversight so it isn't just a theoretical concept.
4.1. The "Cold" Review Path
- Requirement: The system must produce a
human_review.jsonlog file after every run.
Content:
- Any
ABORT_*events. - Any
BLOCKED_TRENDoverrides. - Any Parameter updates flagged by the Velocity Brake.
- Any Drift > 20% from baseline defaults.
4.2. Hard Stop
- Requirement: If the
cash_balancedrops by > 15% in a single session (simulation or live), theDataRegistrarMUST refuse to run subsequent sessions until a manualreset_flagscommand is issued.
PHASE 1: THE FOUNDATION (Immutable Reality)
Objective: Eliminate hallucination and time-drift by implementing the Data Registrar and killing tool-usage downstream.
1.1. Core Schema & State
- Define Enums: Implement
ExecutionResult(APPROVED,ABORT_COMPLIANCE,ABORT_DATA_GAP, etc.) to ensure machine-readable logs. - Define Ledger: Implement
FactLedgerTypedDict withfreshness,source_versions, andcontent_hash. - Immutability Guard: Implement
write_once_enforcereducer to trigger a hard crash if any agent attempts to mutate the ledger after creation.
1.2. The Data Registrar Node
- Central Fetch: Move all data fetching logic (
get_stock_data,get_fundamentals,get_news,get_insider) intodata_registrar.py. - Poisoning Guard: Implement a check that raises a hard exception if
price_dataorfundamental_datais missing or empty (Partial Payload Protection). - Hashing: Implement SHA-256 hashing of the data payload (excluding metadata) for auditability.
- Freshness: Implement logic to calculate data age and raise an exception if data is stale (e.g., Price > 60s old).
1.3. Analyst Refactoring (The "Lobotomy")
- Market Analyst: Remove
get_stock_datatool binding. Update prompt to ingeststate["fact_ledger"]["price_data"]directly. - Fundamentals Analyst: Remove
get_fundamentalstool binding. Update prompt to ingeststate["fact_ledger"]["fundamental_data"]. - News/Social Analysts: Remove
get_newstool binding. Update prompt to ingeststate["fact_ledger"]["news_data"]. - Verification: Assert that no tools are passed to these agents during graph construction.
1.4. Graph Wiring
- Reroute: Update
setup.pyto routeSTART→DataRegistrar→Market Analyst. - Test: Execute a run. Verify that if the Registrar fails, the graph aborts immediately and no LLM tokens are consumed.
PHASE 2: THE GUARDRAILS (Execution Gatekeeper)
Objective: Separate "Decision Generation" from "Decision Authorization" using deterministic python logic.
2.1. Gatekeeper Logic Core
- Create Class: Implement
ExecutionGatekeeperin a new file. - Compliance Check: Scan
fact_ledger["insider_data"]for restricted flags. ReturnABORT_COMPLIANCEif found. - Data Re-Verification: Check
fact_ledger["freshness"]again at the moment of execution. ReturnABORT_DATA_GAPif expired.
2.2. Consensus & Directionality Rules
- Divergence Logic: Calculate
Divergence_Score = abs(Bull_Score - Bear_Score) * Confidence. Ifscore > Threshold, returnABORT_DIVERGENCE. - Direction Consistency: Compare Trader Direction (Buy/Sell) vs. Mean Analyst Direction.
- Rule: If Trader says "BUY" but Average Analyst says "SELL", return
ABORT_DIRECTION_MISMATCH.
- Rule: If Trader says "BUY" but Average Analyst says "SELL", return
2.3. Deterministic Trend Override
- Logic: Implement the "Don't Fight the Tape" rule:
IF (Regime == BULL) AND (Price > 200SMA) AND (Growth > 30%): BLOCK_SELL.
- Counterfactual Logging: If a trade is blocked, log the specific event:
{"event": "BLOCKED_TREND", "intent": "SELL", "action": "HOLD"}.
2.4. Integration
- Wire Node: Insert
ExecutionGatekeeperbetweenTraderandEND.
2.4 Phase 2.7: Institutional Safety (Hardening)
- Pulse Check: A pre-trade live market verify. Abort if drift > 3%.
- Market Hours: Trade only during NYSE sessions (9:30-16:00 EST).
- Split Check: Massive drift (>50%) triggers a corporate action abort.
- Deterministic Flow: Insider math is computed as a float in the Registrar, not sniffed in the Gatekeeper.
PHASE 2 STATUS: ✅ 100% VERIFIED via verify_logic_v2_7.py.
PHASE 3: THE INTELLIGENCE (Bounded Learning)
Objective: Implement safe, attributed parameter tuning that respects market regimes.
3.1. Attribution Scoring
- Reflector Update: Modify the reflection prompt to output a specific performance score (0.0 - 1.0) for each agent based on the trade outcome.
- Sparse Scoring: Enforce a rule that scores must be decisive (e.g., ≥ 0.7 or ≤ 0.3) to prevent "diffuse blame."
3.2. Parameter Validator
- Velocity Brake: Implement logic to track the last 3 updates for every parameter. If the direction is identical 3x in a row, return
REJECT_UPDATE(Freeze Parameter). - Rollback: Implement
revert_last_update()functionality to undo the previous parameter change if performance degrades.
3.3. Regime-Conditioned Memory
- Tagging: Update the memory saver to tag every lesson with
{"regime": current_regime}. - Retrieval: Update the Trader's memory retrieval to filter strictly by the
current_regime(e.g., do not fetch Bear Market lessons during a Bull Market).
PHASE 4: OPERATIONAL SAFETY (The Human Loop)
Objective: Make the system observable and manually stoppable.
4.1. The "Cold" Review Path
- Logger: Create
human_review_logger.py. - Event Hooks: Wire
ABORT_*,BLOCKED_TREND, andFREEZE_PARAMETERevents to write to an append-onlyhuman_review.jsonfile.
4.2. Circuit Breakers
- Sticky Breaker: Implement a lockfile mechanism.
- Rule: If
Cash_Balance< 85% of starting capital, write a lockfile to disk. - Enforcement:
DataRegistrarmust check for this file on startup and refuse to run until a human manually deletes it.