summaryrefslogtreecommitdiff
path: root/services/strategy-engine/tests/test_stock_selector.py
diff options
context:
space:
mode:
authorTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-04-02 15:42:23 +0900
committerTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-04-02 15:42:23 +0900
commit8da5fb843856bb6585c6753f44d422beaa4a8204 (patch)
tree198c0e6b44ddb0981a48332effaad1276e643886 /services/strategy-engine/tests/test_stock_selector.py
parent0e177eafbed026445e50da6a5992177521fb8212 (diff)
fix: deduplicate LLM JSON parsing and reuse aiohttp sessions in stock selector
Extract _extract_json_array() to eliminate duplicate JSON parsing logic between _parse_llm_selections() and LLMCandidateSource._parse_candidates(). Add session reuse in StockSelector via _ensure_session()/close() methods instead of creating new aiohttp.ClientSession per HTTP call. Pass shared session to LLMCandidateSource.get_candidates().
Diffstat (limited to 'services/strategy-engine/tests/test_stock_selector.py')
-rw-r--r--services/strategy-engine/tests/test_stock_selector.py32
1 files changed, 32 insertions, 0 deletions
diff --git a/services/strategy-engine/tests/test_stock_selector.py b/services/strategy-engine/tests/test_stock_selector.py
index ff9d09c..fa15f66 100644
--- a/services/strategy-engine/tests/test_stock_selector.py
+++ b/services/strategy-engine/tests/test_stock_selector.py
@@ -7,6 +7,7 @@ from datetime import datetime, timezone
from strategy_engine.stock_selector import (
SentimentCandidateSource,
StockSelector,
+ _extract_json_array,
_parse_llm_selections,
)
@@ -60,6 +61,37 @@ def test_parse_llm_selections_with_markdown():
assert selections[0].symbol == "TSLA"
+def test_extract_json_array_from_markdown():
+ text = '```json\n[{"symbol": "AAPL", "score": 0.9}]\n```'
+ result = _extract_json_array(text)
+ assert result == [{"symbol": "AAPL", "score": 0.9}]
+
+
+def test_extract_json_array_bare():
+ text = '[{"symbol": "TSLA"}]'
+ result = _extract_json_array(text)
+ assert result == [{"symbol": "TSLA"}]
+
+
+def test_extract_json_array_invalid():
+ assert _extract_json_array("not json") is None
+
+
+def test_extract_json_array_filters_non_dicts():
+ text = '[{"symbol": "AAPL"}, "bad", 42]'
+ result = _extract_json_array(text)
+ assert result == [{"symbol": "AAPL"}]
+
+
+async def test_selector_close():
+ selector = StockSelector(
+ db=MagicMock(), broker=MagicMock(), alpaca=MagicMock(), anthropic_api_key="test"
+ )
+ # No session yet - close should be safe
+ await selector.close()
+ assert selector._http_session is None
+
+
async def test_selector_blocks_on_risk_off():
mock_db = MagicMock()
mock_db.get_latest_market_sentiment = AsyncMock(