数据接入

EigenLedger 支持 A 股和港股吗?先把数据这关过掉

这个库的绩效与风险计算本身与市场无关,真正决定「能不能用在国内标的」的是数据层:默认走 yfinance 的复权收盘价,A 股与港股需要正确的代码后缀,数据缺失时会直接抛错而不是给警告。

本页把数据契约写清楚:它要什么格式、怎么换成自己的数据、以及哪六类数据质量问题会让报告失真。

ticker 代码
yfinance
Adj Close 矩阵
首日价格
份额 = 权重 ÷ 首日价
组合日收益
示意图:数据进入组合收益的四步。权重在这里被当作「买入时的资金分配」。
EigenLedger · 数据来源

EigenLedger 的数据从哪里来、算什么口径?

理解这一步,才能解释「为什么我的收益和账户不一样」。

环节源码行为含义注意点
数据源yfinance 下载历史行情免费、无需 Key,但受上游接口变更影响项目把 yfinance 锁在 0.1.96,上游接口已多次变动
价格字段["Adj Close"](复权收盘价)近似把分红与拆股计入没有单独的现金分红记录,无法统计股息收入
权重语义initial_alloc = wts ÷ 首日价权重是「买入时的资金分配」,之后不再自动平衡所以组合会自然漂移,不是每日再平衡
收益计算组合市值序列做 pct_change() 并丢掉第一行日频收益率序列首行被丢弃,区间起点实际晚一个交易日
单标的走单独分支,直接对价格序列求收益率单票也能算单标的时基准仍会另行取数
访问行情接口即使用 data= 传入本地数据,基准仍会走 yfinance 联网取数无外网或 Yahoo 不可达时,分析会在基准环节失败先确认基准能取到,再谈本地数据
本地数据仅覆盖组合发布版 2.1.6 中基准不受 data= 影响“完全离线”这一目标在发布版里实现不了基准问题需另行解决,详见下方说明
Pandas 版本项目未约束 pandas 上界会被解析到 pandas 3.x,导致绘图报错见「安装与运行时边界」页的实测记录

本机实测(Python 3.11.9 / yfinance 0.1.96):yf.download(["KO"], ...) 返回 0 行数据、无异常抛出,随后 portfolio_analysis()assets.iloc[0] 处抛出 IndexError: single positional indexer is out-of-bounds;把 pandas 降到 2.1 后,报错点前移到基准取数的 ValueError: attempt to get argmax of an empty sequence。两个报错都指向同一件事:本机取不到行情数据。能否取到与你所在网络能否访问 Yahoo 行情接口直接相关,官方 issue 中也记录了旧版 yfinance 无法下载数据的问题。

EigenLedger · 代码格式

A 股、港股、指数在 EigenLedger 里怎么写代码?

代码后缀写错不会报「代码不存在」,通常表现为取数失败或数据为空。

市场代码写法示例注意点
上交所 A 股6 位数字 + .SS600519.SS 贵州茅台后缀是 .SS(Shanghai),不是 .SH
深交所 A 股6 位数字 + .SZ000001.SZ 平安银行深市代码常以 0/3 开头,前后不要丢零
港股4 位数字 + .HK0700.HK 腾讯控股必须补足 4 位(700.HK 可能取不到)
美股直接写 tickerKOAMD大小写均可,建议统一大写
美股指数^ 开头^GSPC 标普 500、^IXIC 纳斯达克README 示例里就把 ^IXIC 当作组合成分使用
A 股指数指数代码 + 交易所后缀000001.SS 上证指数与平安银行的 000001.SZ 仅后缀之差,极易混淆
港股指数^HSI^HSI 恒生指数覆盖率与数据长度需自行验证
同一串数字在不同后缀下可能是完全不同的标的。写完代码后建议先单独下载一次并打印首尾日期与行数,确认取到的是你想的那个标的,再放进组合。
EigenLedger · 本地数据

EigenLedger 怎么用自己的 CSV 或 DataFrame 跑分析?

这是让 A 股与港股分析可复现的最稳做法:把取数环节从库里挪到你自己手上。

  1. 准备一张价格表

    行是交易日(按日期升序),列是标的代码。data.filter(stocks) 会按你传入的 portfolio 挑列,因此列名必须与代码字符串完全一致。

  2. 把基准问题单独解决

    发布版 2.1.6 的基准总是联网取数,data= 不会改变这一点(仓库主分支新增了「基准列存在则用本地数据」的判断,但该版本尚未发布)。因此:本地数据能让组合链路可复现,但无法让它完全离线。

  3. 传入 data= 并显式写死区间

    Engine(start_date=..., end_date=..., portfolio=[...], weights=[...], benchmark=[...], data=df)。区间要落在这张表的日期范围内。

  4. 核对首日是否有值

    首日缺价会直接抛 ValueError: Some stock is not available at initial state!。数据表应从所有标的都有价格的第一个交易日开始。

Python · 本地数据接入示意(本站未在本机跑通该路径,仅作格式说明) import pandas as pd from EigenLedger import Engine, portfolio_analysis # 行=交易日,列=标的与基准代码,值=复权收盘价 df = pd.read_csv("prices.csv", index_col=0, parse_dates=True).sort_index() pf = Engine( start_date="2022-01-04", end_date="2024-12-31", portfolio=["600519.SS", "000001.SZ", "0700.HK"], weights=[0.4, 0.3, 0.3], benchmark=["000300.SS"], # 注意:发布版仍会联网取基准,此处仅作代码示例 data=df, ) portfolio_analysis(pf)
数据要求具体规定违反了会怎样自查方式
列名portfolio 中的代码字符串完全一致该标的被静默丢弃,收益按剩余标的计算打印 df.filter(portfolio).columns 逐项核对
索引日期索引,升序且唯一排序错误会让首日价变成尾部价格,权重完全错位打印 df.index[[0, -1]]
首日值所有标的首日都不能为空ValueError: Some stock is not available at initial state!检查 df.iloc[0].isna().any()
价格口径统一复权方式(建议后复权)混用复权口径会让收益被低估或虚高记录数据来源的复权说明
基准列代码里可以带上,但发布版不会使用它库仍会为基准联网取数,离线环境直接失败确认基准代码能联网取到,或自行改造代码
数据截止日覆盖到 end_date末尾交易日被截断,区间与实际不符打印 df.index[-1]
EigenLedger · 数据质量

哪六类数据问题会让 EigenLedger 报告失真?

它们都不会让程序报错,只会让结论悄悄偏掉。

问题现象对报告的影响处理建议
上市时间晚于起点该标的早期无价格优化器会把缺失价填成 1,早期出现人为低价区,污染收益与协方差把区间起点挪到所有标的都有数据之后
停牌出现连续空值或价格不变波动被低估,回撤被平滑剔除长期停牌标的,或改用可交易样本
拆股与复权前后价格量级突变未复权数据会产生跳变式收益统一使用复权价并记录复权方式
代码变更或退市取数直接失败或历史被截断组合里静默少一只标的核对标的数量与 pf.portfolio
时区不一致不同市场交易日错位跨市场组合在非共同交易日出现虚假收益先按共同交易日对齐再分析
币种不一致A 股人民币、港股港币、美股美元收益率被汇率波动混入,收益归因失真统一本币口径,或明确说明未做汇率处理
本库不做数据质量校验,也不会在收益率里剔除异常值。数据对不对,责任在使用者——这也是「可复现」必须把数据快照一起留档的原因。
EigenLedger · 核对流程

用 EigenLedger 本地数据前要核对哪五步?

顺序固定,可以避免大部分「数字对不上」的返工。

步骤做什么合格标准不合格怎么办
1打印价格表的行列数与首末日首末日覆盖你设定的区间补数据或缩短区间
2核对列名与组合代码逐一匹配集合完全一致,无遗漏统一命名后重新导出
3检查首行有无空值全不为空把起点后移到所有标的都有价的第一天
4用等权跑一次基线报告能算出指标且无异常先解决报错再谈优化
5换一段区间重跑结论方向一致(不一定数值相同)若完全相反,说明结论对区间高度敏感,需要标注
EigenLedger · 取数对照

同样是拿 A 股数据,EigenLedger 与本机技能有什么差别?

本机技能目录里有多个面向国内市场的取数技能,和 yfinance 的分工很不一样。

取数需求EigenLedger 路线本机技能路线建议
A 股日线行情yfinance + .SS/.SZ 后缀,覆盖面与稳定性需实测akshare-finance、tushare-finance、mx-data 等技能面向国内数据源对稳定性有要求时优先本地数据源
港股行情yfinance + .HK 后缀部分技能覆盖港股,需逐个确认先做小样本验证再批量
指数作为基准需找到对应指数代码(如 000300.SS可通过技能直接查询指数行情基准代码务必先验证可取
基本面与财务数据不支持,只做价格序列分析fp-dcf、a-share-metrics-card 等技能覆盖财务与估值基本面分析走技能路线
数据可复现导出快照后用 data= 固化取数过程依对话,留痕需自行记录正式研究统一导出快照

披露:本机技能目录已核验(29 个技能),但 EigenLedger 与 EasyClaw 无已证实集成;上表是取数能力的对照,不代表可以互相调用,也不表示数据口径一致。

FAQ

关于数据接入的常见问题

能直接分析加密货币或期货吗?

只有 yfinance 覆盖并返回复权收盘价的品种才可能走下去。库本身不区分资产类别,它只处理「价格矩阵 → 收益序列」;期货的展期、保证金、合约切换都不在范围内,不要用它做期货绩效评估,以官方实现为准。

为什么我的 A 股代码取不到数据?

按可能性排序:后缀写错(.SH 应为 .SS)、港股代码未补足 4 位、该标的在 yfinance 覆盖范围内缺失、当前网络无法访问 Yahoo 行情接口。先单独下载一次该代码并打印行数,可以快速区分是代码问题还是网络问题。

可以用 baostock 或 akshare 的数据吗?

可以,只要你把它们整理成「日期索引 + 标的列」的价格表,再通过 data= 传入即可。库关心的是列名与索引,不关心数据最初来自哪里。建议统一使用同一复权口径,并在报告里注明来源。

权重是每日再平衡的吗?

不是。源码按「权重 ÷ 首日价格」计算份额,之后价格变化会让实际权重自然漂移,相当于买入并持有。需要定期再平衡必须显式传 rebalance 参数,否则报告描述的是 buy-and-hold 结果,以官方实现为准。

基准要写在 portfolio 里吗?

不要。基准通过 benchmark 参数单独指定,写进 portfolio 会被当作组合成分参与权重计算。另需注意:发布版 2.1.6 中基准无论如何都会联网取数,本地数据只覆盖组合部分,所以「想让整条链路离线」在发布版里做不到,需要改造代码或等待仓库主分支的逻辑发布,以官方实现为准。

跨市场组合(A 股 + 美股)要注意什么?

至少要处理两件事:交易日对齐(不同市场假期不同,直接用会造成虚假收益)与币种统一(否则收益里混入汇率波动)。库不做这两件事,所以跨市场组合的结论需要额外说明处理方式,以官方实现与你的数据口径为准。

数据要保存成什么格式才能长期复现?

建议存成 CSV 或 Parquet,包含日期索引与全部标的列,并在旁边记录:来源、复权方式、导出时间、覆盖区间、单位与币种。只保存最终图片或指标表,无法在依赖升级后重算,等于放弃了复现能力。

数据接上了,为什么 EigenLedger 报告结论仍可能站不住?

收益来源、区间敏感性、集中度、过拟合——四个必须在交付前过一遍的检查。