refactor(rotation): 利用 Flask API 内联的 ETF 净值和溢价率数据
- 移除单独的 fetch_etf_nav 调用 - 从 ETF OHLCV DataFrame.attrs 中提取净值和溢价率 - 新增 etf_premium_data 字段存储溢价率详情 - 减少一次 API 请求,提高数据获取效率
This commit is contained in:
@@ -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代码} 映射
|
||||
|
||||
Reference in New Issue
Block a user