TradingAgents/orchestrator/tests/test_live_mode.py

169 lines
6.3 KiB
Python

import asyncio
from datetime import datetime, timezone
from orchestrator.contracts.error_taxonomy import ReasonCode
from orchestrator.contracts.result_contract import CombinedSignalFailure, FinalSignal, Signal
from orchestrator.live_mode import LiveMode
def _signal(*, source: str, direction: int, confidence: float) -> Signal:
return Signal(
ticker="AAPL",
direction=direction,
confidence=confidence,
source=source,
timestamp=datetime(2026, 4, 11, 12, 0, tzinfo=timezone.utc),
)
class _StubOrchestrator:
def __init__(self, responses):
self._responses = responses
def get_combined_signal(self, ticker: str, date: str):
response = self._responses[(ticker, date)]
if isinstance(response, Exception):
raise response
return response
def test_live_mode_serializes_degraded_contract_shape():
live_mode = LiveMode(
_StubOrchestrator(
{
("AAPL", "2026-04-11"): FinalSignal(
ticker="AAPL",
direction=-1,
confidence=0.42,
quant_signal=None,
llm_signal=_signal(source="llm", direction=-1, confidence=0.6),
timestamp=datetime(2026, 4, 11, 12, 1, tzinfo=timezone.utc),
degrade_reason_codes=(ReasonCode.QUANT_SIGNAL_FAILED.value,),
metadata={
"contract_version": "v1alpha1",
"data_quality": {"state": "stale_data", "source": "quant"},
"research": {
"research_status": "degraded",
"research_mode": "degraded_synthesis",
"timed_out_nodes": ["Bull Researcher"],
"degraded_reason": "bull_researcher_timeout",
"covered_dimensions": ["market"],
"manager_confidence": None,
},
"source_diagnostics": {
"quant": {"reason_code": ReasonCode.STALE_DATA.value}
},
},
)
}
)
)
results = asyncio.run(live_mode.run_once(["AAPL"], "2026-04-11"))
assert results == [
{
"contract_version": "v1alpha1",
"ticker": "AAPL",
"date": "2026-04-11",
"status": "degraded_success",
"result": {
"direction": -1,
"confidence": 0.42,
"quant_direction": None,
"llm_direction": -1,
"timestamp": "2026-04-11T12:01:00+00:00",
},
"error": None,
"degradation": {
"degraded": True,
"reason_codes": [ReasonCode.QUANT_SIGNAL_FAILED.value],
"source_diagnostics": {
"quant": {"reason_code": ReasonCode.STALE_DATA.value}
},
},
"data_quality": {"state": "stale_data", "source": "quant"},
"research": {
"research_status": "degraded",
"research_mode": "degraded_synthesis",
"timed_out_nodes": ["Bull Researcher"],
"degraded_reason": "bull_researcher_timeout",
"covered_dimensions": ["market"],
"manager_confidence": None,
},
}
]
def test_live_mode_serializes_failure_contract_shape():
live_mode = LiveMode(
_StubOrchestrator(
{
("AAPL", "2026-04-11"): CombinedSignalFailure(
"both quant and llm signals are None",
reason_codes=(ReasonCode.BOTH_SIGNALS_UNAVAILABLE.value, ReasonCode.PROVIDER_MISMATCH.value),
source_diagnostics={
"llm": {
"reason_code": ReasonCode.PROVIDER_MISMATCH.value,
"research": {
"research_status": "failed",
"research_mode": "degraded_synthesis",
"timed_out_nodes": ["Bull Researcher"],
"degraded_reason": "bull_researcher_connectionerror",
"covered_dimensions": ["market"],
"manager_confidence": None,
},
}
},
data_quality={"state": "provider_mismatch", "source": "llm"},
)
}
)
)
results = asyncio.run(live_mode.run_once(["AAPL"], "2026-04-11"))
assert results == [
{
"contract_version": "v1alpha1",
"ticker": "AAPL",
"date": "2026-04-11",
"status": "failed",
"result": None,
"error": {
"code": "live_signal_failed",
"message": "both quant and llm signals are None",
"retryable": False,
},
"degradation": {
"degraded": True,
"reason_codes": [
ReasonCode.BOTH_SIGNALS_UNAVAILABLE.value,
ReasonCode.PROVIDER_MISMATCH.value,
],
"source_diagnostics": {
"llm": {
"reason_code": ReasonCode.PROVIDER_MISMATCH.value,
"research": {
"research_status": "failed",
"research_mode": "degraded_synthesis",
"timed_out_nodes": ["Bull Researcher"],
"degraded_reason": "bull_researcher_connectionerror",
"covered_dimensions": ["market"],
"manager_confidence": None,
},
},
},
},
"data_quality": {"state": "provider_mismatch", "source": "llm"},
"research": {
"research_status": "failed",
"research_mode": "degraded_synthesis",
"timed_out_nodes": ["Bull Researcher"],
"degraded_reason": "bull_researcher_connectionerror",
"covered_dimensions": ["market"],
"manager_confidence": None,
},
}
]