From 72e980e9562b6d1bd20e114368489ad5c4a1d370 Mon Sep 17 00:00:00 2001 From: aszerW Date: Thu, 14 May 2026 01:03:31 +0800 Subject: [PATCH] =?UTF-8?q?refactor(rotation):=20=E5=88=A9=E7=94=A8=20Flas?= =?UTF-8?q?k=20API=20=E5=86=85=E8=81=94=E7=9A=84=20ETF=20=E5=87=80?= =?UTF-8?q?=E5=80=BC=E5=92=8C=E6=BA=A2=E4=BB=B7=E7=8E=87=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除单独的 fetch_etf_nav 调用 - 从 ETF OHLCV DataFrame.attrs 中提取净值和溢价率 - 新增 etf_premium_data 字段存储溢价率详情 - 减少一次 API 请求,提高数据获取效率 --- strategies/rotation/strategy.py | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/strategies/rotation/strategy.py b/strategies/rotation/strategy.py index 5b1ca40..ac5f97b 100644 --- a/strategies/rotation/strategy.py +++ b/strategies/rotation/strategy.py @@ -180,7 +180,7 @@ class RotationStrategy(StrategyBase): valid_codes = [code for code, df in index_ohlcv_data.items() if df is not None and len(df) > 0] print(f"有效指数: {len(valid_codes)} 只") - # 获取 ETF 价格数据 + # 获取 ETF 价格数据(同时获取净值和溢价率) print(f"\n获取 ETF 数据 ({len(etf_codes)} 只)...") etf_ohlcv_data = api_source.fetch_batch( etf_codes, @@ -188,16 +188,34 @@ class RotationStrategy(StrategyBase): self.end_date ) - # 转换为宽格式 DataFrame + # 转换为宽格式 DataFrame,并提取净值/溢价率数据 etf_data = None + etf_nav_data = {} + etf_premium_data = {} + if etf_ohlcv_data: etf_close_dict = {} for etf_code, df in etf_ohlcv_data.items(): if df is not None and 'close' in df.columns: etf_close_dict[etf_code] = df['close'] + + # 从 DataFrame.attrs 中提取净值和溢价率数据 + # Flask API 已自动附加这些数据 + if 'nav' in df.attrs: + etf_nav_data[etf_code] = df.attrs['nav'] + if 'premium_series' in df.attrs: + etf_premium_data[etf_code] = { + 'series': df.attrs['premium_series'], + 'latest': df.attrs.get('latest_premium'), + 'date': df.attrs.get('premium_date'), + 'stats': df.attrs.get('premium_stats'), + } if etf_close_dict: etf_data = pd.DataFrame(etf_close_dict) + print(f"有效净值: {len(etf_nav_data)} 只") + print(f"有效溢价率: {len(etf_premium_data)} 只") + # 获取基准数据 print(f"\n获取基准数据 ({benchmark_code})...") benchmark_ohlcv = api_source.fetch(benchmark_code, self.start_date, self.end_date) @@ -213,20 +231,12 @@ class RotationStrategy(StrategyBase): index_close_dict[code] = df['close'] index_close = pd.DataFrame(index_close_dict) if index_close_dict else None - # 获取 ETF 净值数据(用于溢价率计算) - print(f"\n获取 ETF 净值数据...") - etf_nav_data = {} - for etf_code in etf_codes: - nav_df = api_source.fetch_etf_nav(etf_code, self.start_date, self.end_date) - if nav_df is not None: - etf_nav_data[etf_code] = nav_df - print(f"有效净值: {len(etf_nav_data)} 只") - return { 'index_data': index_ohlcv_data, # 原始 OHLCV 数据 {code: DataFrame} 'index_close': index_close, # 对齐后的收盘价(宽格式) 'etf_data': etf_data, # ETF 收盘价(宽格式) 'etf_nav_data': etf_nav_data, # ETF 净值数据 {code: DataFrame} + 'etf_premium_data': etf_premium_data, # ETF 溢价率数据 {code: dict} 'benchmark_data': benchmark_data, # 基准收盘价 Series 'valid_codes': valid_codes, # 有效指数代码列表 'etf_code_map': etf_code_map # {指数代码: ETF代码} 映射