Skip to content

Commit 3b1daa4

Browse files
authored
fix: handle result-only market phases in history summaries (#1732)
1 parent 16b511b commit 3b1daa4

3 files changed

Lines changed: 48 additions & 2 deletions

File tree

docs/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
1212
<!-- 新条目格式:- [类型] 描述(类型取值:新功能/改进/修复/文档/测试/chore)-->
1313
<!-- 每条独立一行追加到本段末尾,无需分类标题,合并时冲突最小 -->
1414

15+
- [修复] 修复日股/韩股历史列表重建市场阶段摘要时将 non_trading 等结果阶段误传为 analysis_phase 导致列表查询失败的问题。
16+
1517
## [3.23.0] - 2026-06-20
1618

1719
### 发布亮点

src/market_phase_summary.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
"webhook",
3535
)
3636
_INTRADAY_BUCKET_PHASES = {"intraday", "lunch_break", "closing_auction"}
37+
_SUPPORTED_MANUAL_ANALYSIS_PHASES = {"premarket", "intraday", "postmarket"}
38+
_SUPPORTED_ANALYSIS_INTENTS = {"auto", *_SUPPORTED_MANUAL_ANALYSIS_PHASES}
3739
_PUBLIC_SOURCE_LABELS_ZH = {
3840
"alert_trigger_market_context": "告警触发上下文",
3941
"analysis_history_snapshot": "最近分析快照",
@@ -142,9 +144,9 @@ def rebuild_market_phase_summary_for_stock_code(
142144
return dict(summary)
143145

144146
phase = str(summary.get("phase", "")).strip()
145-
analysis_phase = phase if phase in _ALLOWED_PHASES else "auto"
147+
analysis_phase = phase if phase in _SUPPORTED_MANUAL_ANALYSIS_PHASES else "auto"
146148
analysis_intent = str(summary.get("analysis_intent") or "auto").strip()
147-
if not analysis_intent:
149+
if analysis_intent not in _SUPPORTED_ANALYSIS_INTENTS:
148150
analysis_intent = "auto"
149151

150152
rebuilt = build_market_phase_context(

tests/test_market_phase_summary.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
format_public_market_status_line,
1010
format_public_phase_pack_excerpt,
1111
normalize_analysis_phase_bucket,
12+
rebuild_market_phase_summary_for_stock_code,
1213
render_market_phase_summary,
1314
)
1415

@@ -125,6 +126,47 @@ def test_normalize_analysis_phase_bucket_maps_public_statistics_buckets() -> Non
125126
assert normalize_analysis_phase_bucket("bad_phase") == "unknown"
126127

127128

129+
def test_rebuild_market_phase_summary_uses_auto_for_result_only_phases(monkeypatch) -> None:
130+
calls = []
131+
132+
class FakeContext:
133+
def to_dict(self) -> dict:
134+
return {
135+
**_phase_context(),
136+
"market": "jp",
137+
"phase": "non_trading",
138+
"analysis_intent": "auto",
139+
"warnings": [],
140+
}
141+
142+
def fake_build_market_phase_context(**kwargs):
143+
calls.append(kwargs)
144+
return FakeContext()
145+
146+
monkeypatch.setattr(
147+
"src.market_phase_summary.build_market_phase_context",
148+
fake_build_market_phase_context,
149+
)
150+
151+
summary = {
152+
**_phase_context(),
153+
"market": "cn",
154+
"phase": "non_trading",
155+
"analysis_intent": "non_trading",
156+
}
157+
158+
rebuilt = rebuild_market_phase_summary_for_stock_code(
159+
"7203.T",
160+
{MARKET_PHASE_SUMMARY_KEY: summary},
161+
)
162+
163+
assert rebuilt is not None
164+
assert rebuilt["phase"] == "non_trading"
165+
assert calls[0]["market"] == "jp"
166+
assert calls[0]["analysis_phase"] == "auto"
167+
assert calls[0]["analysis_intent"] == "auto"
168+
169+
128170
def test_format_public_phase_pack_excerpt_limits_and_redacts_public_fields() -> None:
129171
excerpt = format_public_phase_pack_excerpt(
130172
{

0 commit comments

Comments
 (0)