mirror of
https://github.com/ZhuLinsen/daily_stock_analysis
synced 2026-09-20 10:53:33 +08:00
fix: handle efinance index open column fallback (#1051)
* fix: handle efinance index open column fallback
This commit is contained in:
@@ -842,7 +842,7 @@ class EfinanceFetcher(BaseFetcher):
|
||||
price_col = '最新价' if '最新价' in df.columns else 'price'
|
||||
pct_col = '涨跌幅' if '涨跌幅' in df.columns else 'pct_chg'
|
||||
chg_col = '涨跌额' if '涨跌额' in df.columns else 'change'
|
||||
open_col = '开盘' if '开盘' in df.columns else 'open'
|
||||
open_cols = [column for column in ('今开', '开盘', 'open') if column in df.columns]
|
||||
high_col = '最高' if '最高' in df.columns else 'high'
|
||||
low_col = '最低' if '最低' in df.columns else 'low'
|
||||
vol_col = '成交量' if '成交量' in df.columns else 'volume'
|
||||
@@ -851,6 +851,14 @@ class EfinanceFetcher(BaseFetcher):
|
||||
|
||||
current = safe_float(item.get(price_col, 0))
|
||||
change_amount = safe_float(item.get(chg_col, 0))
|
||||
open_price = 0.0
|
||||
for column in open_cols:
|
||||
candidate = safe_float(item.get(column), default=None)
|
||||
if candidate not in (None, 0.0):
|
||||
open_price = candidate
|
||||
break
|
||||
if open_price == 0.0 and open_cols:
|
||||
open_price = safe_float(item.get(open_cols[0], 0), 0)
|
||||
|
||||
results.append({
|
||||
'code': full_code,
|
||||
@@ -858,7 +866,7 @@ class EfinanceFetcher(BaseFetcher):
|
||||
'current': current,
|
||||
'change': change_amount,
|
||||
'change_pct': safe_float(item.get(pct_col, 0)),
|
||||
'open': safe_float(item.get(open_col, 0)),
|
||||
'open': open_price,
|
||||
'high': safe_float(item.get(high_col, 0)),
|
||||
'low': safe_float(item.get(low_col, 0)),
|
||||
'prev_close': current - change_amount if current or change_amount else 0,
|
||||
|
||||
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
||||
<!-- 每条独立一行追加到本段末尾,无需分类标题,合并时冲突最小 -->
|
||||
|
||||
- [修复] 大盘复盘链路接入 `REPORT_LANGUAGE`:`REPORT_LANGUAGE=en` 时,A 股/合并复盘的 Prompt、章节标题、模板兜底文案与通知包装标题统一改为英文,避免出现英文正文外包中文标题的问题。
|
||||
- [修复] `EfinanceFetcher.get_main_indices()` 对东方财富指数实时行情的开盘价映射改为兼容 `今开 -> 开盘 -> open`,修复部分 `efinance` 版本下指数开盘价被读成缺失值的问题(fixes #1043)
|
||||
- [修复] `AGENT_MAX_STEPS` 在 orchestrator 多 Agent 模式下统一明确为“默认作为各子 Agent 的步数上限而非硬覆盖;TechnicalAgent 等高默认值 Agent 会被封顶、低默认值 Agent 保持原值;当用户主动调高(>10)时,再统一覆盖所有子 Agent 采用全局值”,同时修复用户设置 12 但 TechnicalAgent 仍以默认 6 步运行并报 "Agent exceeded max steps" 的问题(fixes #1026)
|
||||
- [修复] Specialist(Skill)Agent 失败不再中断整个分析管线,改为与 intel/risk 相同的优雅降级策略
|
||||
- [改进] Agent 超步数错误信息增加 AGENT_MAX_STEPS 调整提示,帮助用户自助排查
|
||||
|
||||
82
tests/test_efinance_main_indices.py
Normal file
82
tests/test_efinance_main_indices.py
Normal file
@@ -0,0 +1,82 @@
|
||||
import os
|
||||
import sys
|
||||
import types
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import pandas as pd
|
||||
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
||||
|
||||
from data_provider.efinance_fetcher import EfinanceFetcher
|
||||
|
||||
|
||||
class TestEfinanceMainIndices(unittest.TestCase):
|
||||
def test_get_main_indices_prefers_jinkai_column_for_open_price(self):
|
||||
fetcher = EfinanceFetcher()
|
||||
fake_df = pd.DataFrame(
|
||||
{
|
||||
"股票代码": ["000001"],
|
||||
"最新价": [3200.0],
|
||||
"涨跌幅": [0.63],
|
||||
"涨跌额": [20.0],
|
||||
"今开": [3188.0],
|
||||
"开盘": [0.0],
|
||||
"最高": [3215.0],
|
||||
"最低": [3170.0],
|
||||
"成交量": [123456789],
|
||||
"成交额": [9876543210.0],
|
||||
"振幅": [1.2],
|
||||
}
|
||||
)
|
||||
fake_efinance = types.SimpleNamespace(
|
||||
stock=types.SimpleNamespace(get_realtime_quotes=lambda *args, **kwargs: fake_df)
|
||||
)
|
||||
|
||||
with patch.dict(sys.modules, {"efinance": fake_efinance}):
|
||||
with patch.object(fetcher, "_set_random_user_agent", return_value=None), patch.object(
|
||||
fetcher, "_enforce_rate_limit", return_value=None
|
||||
):
|
||||
data = fetcher.get_main_indices(region="cn")
|
||||
|
||||
self.assertIsNotNone(data)
|
||||
self.assertEqual(len(data), 1)
|
||||
self.assertEqual(data[0]["code"], "sh000001")
|
||||
self.assertEqual(data[0]["name"], "上证指数")
|
||||
self.assertAlmostEqual(data[0]["open"], 3188.0)
|
||||
self.assertAlmostEqual(data[0]["current"], 3200.0)
|
||||
|
||||
def test_get_main_indices_falls_back_to_kaipan_when_jinkai_is_missing(self):
|
||||
fetcher = EfinanceFetcher()
|
||||
fake_df = pd.DataFrame(
|
||||
{
|
||||
"股票代码": ["000001"],
|
||||
"最新价": [3200.0],
|
||||
"涨跌幅": [0.63],
|
||||
"涨跌额": [20.0],
|
||||
"今开": [""],
|
||||
"开盘": [3186.0],
|
||||
"最高": [3215.0],
|
||||
"最低": [3170.0],
|
||||
"成交量": [123456789],
|
||||
"成交额": [9876543210.0],
|
||||
"振幅": [1.2],
|
||||
}
|
||||
)
|
||||
fake_efinance = types.SimpleNamespace(
|
||||
stock=types.SimpleNamespace(get_realtime_quotes=lambda *args, **kwargs: fake_df)
|
||||
)
|
||||
|
||||
with patch.dict(sys.modules, {"efinance": fake_efinance}):
|
||||
with patch.object(fetcher, "_set_random_user_agent", return_value=None), patch.object(
|
||||
fetcher, "_enforce_rate_limit", return_value=None
|
||||
):
|
||||
data = fetcher.get_main_indices(region="cn")
|
||||
|
||||
self.assertIsNotNone(data)
|
||||
self.assertEqual(len(data), 1)
|
||||
self.assertAlmostEqual(data[0]["open"], 3186.0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user