最近做了一个小工具,用来整理场外美股 QDII / 联接基金的公开数据,并生成一个 Excel 文件。
这个工具的目标不是做交易策略,也不是预测涨跌,而是解决一个很具体的问题:
```text
把分散的基金申购状态、单日限额、跟踪指数、底层持仓,整理成一张可读的 Excel。
```
最终输出大概是:
- 一个汇总页
- 每只基金一个明细页
- 汇总页展示申购状态和单日限额
- 明细页展示底层股票代码、名称和权重
一、为什么要做这个工具?
场外美股 QDII 基金经常会出现限购或暂停申购。
比如:
暂停申购
限额 100 元
限额 500 元
不限额
如果只关注一只基金,手动打开 App 看没问题。但如果想同时看多个纳斯达克 100、标普 500、标普信息科技方向的基金,手动维护就很麻烦。
另一个问题是底层持仓。
很多场外基金并不直接展示完整底层股票明细,尤其是联接基金。用户看到的是基金名称,但如果想知道它对应的底层股票权重,就需要进一步整理指数或代理 ETF 的公开持仓数据。
所以我把它拆成了两个任务:
- 整理场外基金列表和申购限额
- 整理底层指数持仓并写入 Excel
二、整体流程
整个脚本大概分成五步:
获取 QDII / 海外基金列表
筛选美股方向基金
匹配基金对应的跟踪指数
获取指数或代理 ETF 的底层持仓
生成 Excel 汇总页和基金明细页
在代码结构上,我把它拆成了几类文件:
config.py # 基金和指数映射配置
data_fetcher.py # 数据获取逻辑
purchase_limit.py # 申购限额格式化和排序
main.py # 主流程和 Excel 输出
tencent_docs_uploader.py # 可选:上传在线表格
三、基金和指数映射
核心配置是一个映射关系:
FUND_INDEX_MAP = {
"006479": "纳斯达克100",
"270042": "纳斯达克100",
"050025": "标普500",
"161125": "标普500",
"007874": "标普科技",
"160140": "道琼斯工业",
}
实际运行时不会只依赖手工配置,也会根据基金名称做关键词匹配。
例如:
AUTO_MATCH_RULES = [
("标普科技", ["标普科技", "标普信息科技"]),
("标普500", ["标普500", "标普 500"]),
("纳斯达克100", ["纳斯达克100", "纳指100", "纳指ETF"]),
("道琼斯工业", ["道琼斯美国精选"]),
]
这样可以覆盖一部分新增基金或命名相近的基金。
四、申购限额怎么处理?
申购限额字段的麻烦点在于,它不是单纯的数字。
可能出现:
暂停申购
0
100
500
空值
超大数值表示不限
所以我单独写了格式化逻辑,把它变成更适合展示和排序的形式。
示例逻辑:
def format_purchase_limit(purchase_status, purchase_limit):
if "暂停" in str(purchase_status):
return "暂停申购"
if purchase_limit is None:
return "不限"
value = float(purchase_limit)
if value <= 0:
return "暂停申购"
if value >= 1e10:
return "不限"
return f"{value:,.0f} 元"
汇总页里会优先把还能申购、限额更高的基金排在前面,把暂停申购的放到后面。
五、底层持仓怎么整理?
底层持仓这块,我使用“指数代理”的思路。
比如:
纳斯达克100 -> QQQ / Nasdaq-100 成分股
标普500 -> SPY
标普科技 -> XLK
道琼斯工业 -> DIA
配置大概长这样:
INDEX_PROXY = {
"纳斯达克100": {
"proxy_etf": "QQQ",
"source": "invesco",
"position_ratio": 0.93,
},
"标普500": {
"proxy_etf": "SPY",
"source": "ssga",
"position_ratio": 0.93,
},
}
最终整理出来的明细页包含:
排名
股票代码
股票名称
权重(%)
这一步的重点不是“精确预测”,而是把公开持仓数据结构化,方便在 Excel 里查看。
六、Excel 输出结构
生成的 Excel 主要分两层。
第一层是汇总页:
基金代码
基金名称
跟踪指数
最新净值
基金规模
申购状态
单日申购限额
成分股数量
第二层是基金明细页:
基金名称
基金代码
跟踪指数
最新净值
基金规模
申购状态
单日申购限额
仓位系数
数据日期
排名
股票代码
股票名称
权重(%)
这样既可以快速扫汇总,也可以点进单只基金看底层明细。
七、一个主流程示意
简化后的主流程大概是:
def main():
qdii_df = get_qdii_fund_list()
us_funds = filter_us_stock_funds(qdii_df, FUND_INDEX_MAP, AUTO_MATCH_RULES)
us_funds = sort_funds_by_purchase_limit(us_funds)
index_holdings_cache = {}
for index_name in us_funds["跟踪指数"].unique():
proxy_config = INDEX_PROXY[index_name]
index_holdings_cache[index_name] = get_index_holdings(index_name, proxy_config)
all_funds_data = []
for _, row in us_funds.iterrows():
code = row["基金代码"]
name = row["基金简称"]
index_name = row["跟踪指数"]
holdings = index_holdings_cache[index_name]
info, detail = build_fund_sheet_v2(
fund_code=code,
fund_name=name,
index_name=index_name,
purchase_limit=row.get("日累计限定金额"),
purchase_status=row.get("申购状态"),
holdings_df=holdings,
position_ratio=INDEX_PROXY[index_name]["position_ratio"],
)
all_funds_data.append((f"{code}_{name[:12]}", info, detail))
write_excel(all_funds_data, OUTPUT_EXCEL)
实际项目里还会做异常处理、列宽调整、在线表格同步等细节。
八、这个工具适合谁?
我觉得它适合这几类人:
- 想学习 Python 数据抓取和 Excel 自动化的人
- 想整理 QDII 基金公开数据的人
- 想维护个人复盘表格的人
- 想把分散信息统一到一个 Excel 文件里的人
它不适合用来做什么:
- 不适合当成投资建议
- 不适合预测涨跌
- 不适合替代基金公告和官方披露
九、后续可以怎么扩展?
这个工具后续还可以继续扩展:
- 增加更多指数方向,比如日经、印度、德国等
- 保存历史限额变化,做时间序列
- 增加邮件或飞书通知
- 生成在线文档,方便手机查看
- 做一个轻量 Web 页面展示汇总结果
十、结尾
这个项目本质上是一个公开数据整理和自动化报表生成工具。
对我来说,它比较有意思的地方不在“金融判断”,而在于如何把分散、格式不统一、需要每天查看的信息,变成一个稳定可复用的 Excel 工作流。
如果你也对这个方向感兴趣,可以私信关键词:
QDII脚本
说明:本文只做技术实现和公开数据整理方法分享,不提供任何投资建议,不承诺收益,不指导买卖。