From 13be83965bb257077234f834b847144573ea73cd Mon Sep 17 00:00:00 2001 From: aszerW Date: Sat, 16 May 2026 08:57:20 +0800 Subject: [PATCH] =?UTF-8?q?fix(datasource):=20QDII=E6=BA=A2=E4=BB=B7?= =?UTF-8?q?=E7=8E=87=E8=AE=A1=E7=AE=97=E4=BF=AE=E5=A4=8D=E5=87=80=E5=80=BC?= =?UTF-8?q?=E6=97=A5=E6=9C=9F=E6=BB=9E=E5=90=8E=E4=B8=80=E5=A4=A9=E5=AF=B9?= =?UTF-8?q?=E9=BD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题: 溢价率计算使用同一天收盘价+净值,但QDII净值T+1披露 修复: 将净值索引后移一天,T日收盘价配T-1日净值 参考: 集思录做法(价格日期配前一日净值) 验证数据(513100.SH): - 2026-05-15: 收盘价2.100, 净值(5/14)2.0200, 溢价率3.96% ✓ --- datasource/universal_fetcher.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/datasource/universal_fetcher.py b/datasource/universal_fetcher.py index 0400d58..b25bb24 100644 --- a/datasource/universal_fetcher.py +++ b/datasource/universal_fetcher.py @@ -236,15 +236,15 @@ class UniversalDataFetcher: 溢价率 = (ETF收盘价 - ETF净值) / ETF净值 - 注意:净值数据通常T+1公布,只计算有净值日期的溢价率 - 不使用 ffill,只保留当天有净值数据的日期 + 关键:QDII基金净值T+1披露,需要用T日收盘价配T-1日净值 + 集思录做法:价格日期配前一日净值(净值日期滞后一天) Args: price_df: ETF价格数据(索引为日期) nav_df: ETF净值数据(索引为日期) Returns: - 溢价率Series(索引为净值日期,值为溢价率) + 溢价率Series(索引为价格日期,值为溢价率) """ # 去除重复日期 price_index = price_df.index @@ -255,15 +255,20 @@ class UniversalDataFetcher: if nav_index.has_duplicates: nav_df = nav_df[~nav_df.index.duplicated(keep='last')] - # 找到共同的日期(只有当天有净值数据才计算溢价率) - common_dates = price_df.index.intersection(nav_df.index) + # QDII净值T+1披露:T日收盘价配T-1日净值 + # 将净值索引后移一天,使价格日期与前一日净值对齐 + nav_df_shifted = nav_df.copy() + nav_df_shifted.index = nav_df_shifted.index + pd.Timedelta(days=1) + + # 找到对齐后的共同日期(价格日期) + common_dates = price_df.index.intersection(nav_df_shifted.index) if len(common_dates) == 0: return None - # 只计算共同日期的溢价率 + # 计算溢价率:T日收盘价 / T-1日净值(已后移到T日索引) close_prices = price_df.loc[common_dates, 'close'] - nav_values = nav_df.loc[common_dates, 'nav'] + nav_values = nav_df_shifted.loc[common_dates, 'nav'] premium = (close_prices - nav_values) / nav_values premium = premium.dropna()