金融 AI Skills · 项目研究站

EigenLedger:一份可复现的投资组合体检报告,从绩效指标到组合优化

EigenLedger(原名 Empyrial)是一个 Python 库,把 QuantStats 的绩效与风险指标和 PyPortfolioOpt 的组合优化器收进一个 Engine 对象里:填好起止日期、股票代码和权重,调一次 portfolio_analysis(),就得到 17 项指标表格、收益与回撤图和可选 PDF 报告。

本站不复述官方 README,而是回答中文用户真正会卡住的问题:装得上吗、跑得通吗、报告里的数字怎么来的、哪些结果不能当真。全部结论来自仓库源码、issue 记录与本机隔离环境实测,可逐条复核。

  • GitHub 约 1,084 Star / 134 Fork(2026-09-23 采集)
  • PyPI 最新 2.1.6(2024-10-28),新包名仅 2 个版本
  • 许可证口径 四份文件互相矛盾,见下文如实说明
  • 主线最近一次推送 2025-09-14,社区 issue 仍在开

项目来源

santoshlite/EigenLedger(原 ssantoshp/Empyrial)

santoshlite/EigenLedger GitHub 仓库页面截图
GitHub 仓库页截图(2026-09-23 抓取):描述为「面向所有人的开源投资组合回测引擎」,Apache-2.0,Python,主题标签含 portfolio-optimization、backtesting。截图仅为项目来源证明,本站与该项目维护者无关联。
打开仓库 ↗
问题

EigenLedger 想解决什么?做一次组合复盘通常卡在哪几步?

把「算收益率、算回撤、画图、优化权重」分开做,代码要写几百行,而且每次换参数都得重来。EigenLedger 想解决的正是这段重复劳动。

多库拼接

行情用 yfinance、绩效用 QuantStats、优化用 PyPortfolioOpt,三个库各有各的数据结构,粘合代码本身就是 bug 来源。

数据清洗

停牌、退市、上市时间不一致会让合并后的价格矩阵出现 NaN,处理方式不同,回测结论就不同。

指标口径

年化按 252 还是 365 天、无风险利率取 0 还是国债收益率,同一组数据能算出两个夏普。

结果复用

参数散落在脚本里,三个月后想复现同一份报告,已经说不清当时用的是哪段区间、什么权重。

常见痛点EigenLedger 的做法适用场景注意点
绩效指标要自己一项项算portfolio_analysis() 一次返回 17 项指标表月度/季度组合复盘、给客户或同事看的报告指标口径写在源码里而非文档里,换版本可能变
回撤、收益曲线要自己画内置收益柱状图、组合权重饼图,并可直接调 QuantStats 出图需要一页纸讲清「赚了还是亏了、怎么亏的」图表样式固定在源码中,改样式要改代码
不知道该配多少权重EF / MEANVAR / HRP / MINVAR 四种优化器,一行参数切换多标的组合,希望有一个可对比的权重起点优化结果强烈依赖历史区间,不等于未来最优
再平衡要靠手工维护日期rebalance 支持周期字符串或自定义日期权重表定投、季度调仓、策略跟踪周期按「天」近似折算,不是自然月
报告交付格式不统一report=True 输出 PDF(依赖 fpdf)需要发一份带图的静态报告中文字体不会自动嵌入,需另行配置
换数据源要改一遍代码data= / benchmark_data= 可传入本地 DataFrame用本地 CSV、内部行情、非美股标的列名与基准列有硬性约定,见「数据接入」页
想复现别人报告里的数字Engine 把全部参数固化为一个对象研究记录、策略评审、课程作业还需记录库版本与数据截止日,否则仍不可复现

EigenLedger 的定位是「把一次组合分析固化成可重跑的对象」,不是数据源,也不是交易系统。行情仍由 yfinance 拉取,优化仍由 PyPortfolioOpt 计算。

工作方式

EigenLedger 内部怎么把一次分析跑完?

从源码看,一次完整分析会依次经过取数、算收益、算指标、画图四段逻辑。

  1. 构造 Engine,固定参数

    Engine(start_date="2023-01-02", portfolio=["KO","AMD"], weights=[0.5,0.5], benchmark=["SPY"])。权重省略时默认等权,基准省略时默认 ["SPY"],结束日期省略时取运行当天。

  2. 调 portfolio_analysis,触发取数

    内部先调 get_returns(),用 yf.download(..., auto_adjust=True)["Adj Close"] 拉复权收盘价再算日收益;缺数据的标的会抛 ValueError 并列出缺失代码。

  3. 算指标、出图表

    用 QuantStats 与内置 empyrical 计算年化、波动、夏普、Calmar、信息比率、最大回撤、Sortino、偏度、峰度、尾部比率、VaR、Alpha、Beta 等 17 项,并绘制收益柱状图与权重饼图。

  4. 可选落盘为 PDF

    portfolio_analysis(pf, report=True, filename="report.pdf") 会走 fpdf 分支生成静态 PDF,适合归档与发送。

关键函数作用适用场景注意点
Engine(...)承载全部输入参数与结果对象任何一次分析的第一步构造时不一定联网,真正取数在分析时
portfolio_analysis(pf)主入口,返回指标与图表对象日常出报告会打印大量中间结果,Notebook 外运行注意日志量
optimize_portfolio(pf)optimizer 求权重并对比优化前后想知道「优化到底有没有用」未设置优化器会直接抛异常
make_rebalance(...)生成再平衡日期与各期权重表定期调仓、定投生成出的权重需要自己保存,否则下次要重跑
get_returns(...)拉取并加权计算组合日收益只想拿收益序列时直接用权重与标的数量必须一致
源码中 TODAY = dt.date.today()BENCHMARK = ["SPY"]DAYS_IN_YEAR = 365 是模块级常量:这意味着「不写结束日期」的报告每次重跑结果都可能不同,严谨复盘应显式写死起止日期。
核心速览

EigenLedger 报告里有什么?17 项指标、4 个优化器、1 个数据源

先看这三张表,就能判断它是不是你要的工具。

17 项指标

覆盖收益类(年化、累计)、风险类(年化波动、最大回撤、VaR)、风险调整类(夏普、Calmar、Sortino、信息比率)与分布类(偏度、峰度、尾部比率)。不含交易次数、胜率、盈亏比。

4 个优化器

EF(最大夏普)、MEANVAR(给定波动上限求最大收益)、HRP(层次风险平价)、MINVAR(最小波动)。也支持传入自定义函数返回权重列表。

1 个默认数据源

yfinance 复权收盘价。A 股用 .SS/.SZ、港股用 .HK 后缀;本地数据可用 data= 传入。

报告指标源码口径适用场景注意点
Annual return 年化收益CAGR,按日频年化快速对比不同组合的收益水平区间越短越不稳定,三年以下的年化参考价值有限
Cumulative return 累计收益期末累计净值 − 1判断区间内总盈亏与起始日期强绑定,必须写明区间
Annual volatility 年化波动QuantStats 年化波动衡量组合整体抖动与优化器的 max_vol 是两套口径,别直接对照
Winning day ratio 上涨日占比收益 > 0 的天数 ÷ 总天数看胜率感受日频胜率高不代表最终赚钱
Sharpe / Sortino / CalmarQuantStats 实现,rf 默认 0风险调整后绩效对比默认无风险利率为 0,会系统性抬高夏普
Max Drawdown 最大回撤内置 empyrical 实现评估最坏持有体验它只给「跌了多少」,不给「多久修复」
Alpha / Beta对指定基准回归判断收益是否只是跟着大盘基准不同结论不同;默认 SPY 对 A 股组合不适用
Skew / Kurtosis / Tail Ratio分布形态统计识别肥尾与极端行情暴露样本少时统计量噪声大
Daily value at risk默认 sigma=1, confidence=0.95估日常极端亏损量级参数可调,报告里要注明用的置信度
优化器求的是什么适用场景注意点
EF给定预期收益与协方差,求最大夏普权重想做「性价比最高」的配置默认用历史均值估收益,容易把过去涨幅当成未来预期
MEANVAR在年化波动不超过 max_vol 的前提下求最优有明确波动预算的产品或账户max_vol 默认 0.15,含义与报告里的年化波动口径不同
HRP层次风险平价,按相关性聚类分配风险标的较多、相关性结构复杂不使用预期收益,天然更分散,但也不追求收益最优
MINVAR最小化组合波动把风险控制放在第一位低波动组合的收益通常也更低
自定义函数自己返回权重列表接入内部打分、等风险贡献等自有逻辑权重数量与顺序必须和 portfolio 完全一致
上手路径

EigenLedger 的三条入口,你是哪一种用户?

先选路线,再进对应页面,可以省掉大部分试错。

只想复现一份报告

目标:半小时内跑出第一份组合报告。
路径:安装与运行时边界 → 报告解剖。
你要接受的前提:装依赖时大概率要额外装 wheel,见安装页实测记录。

想知道数字可不可信

目标:判断报告里的夏普、Alpha、回撤能不能用于决策。
路径:结果审计 → 数据接入。
重点:收益来源拆解、区间敏感性、优化过拟合。

想接自己的数据

目标:用本地 CSV、A 股或港股数据跑同一套分析。
路径:数据接入 → 四种优化器。
重点:列名约定、代码后缀、复权口径与基准对齐。

你的场景建议先用理由下一步
第一次接触,不确定能不能装上安装与运行时边界实测记录里已经写明失败原因与可复现的绕行方案装完后进「报告解剖」
手上有一组美股代码,想快速出报告报告解剖把 17 项指标逐项讲清,避免看着表格发懵再用「结果审计」检查结论
想定投或季度调仓再平衡机制周期字符串与自定义日期表两种写法差异很大用「四种优化器」选权重
主仓在 A 股或港股数据接入yfinance 对 A 股港股有覆盖与复权限制,先确认再分析必要时改用本地数据
报告要交给别人看结果审计先自查结论边界,再交付补「可复现清单」
已经报错卡住了报错排查按真实 issue 归类,多数是依赖版本问题修完回到对应页面
免代码路线

不写 Python 能得到同样的组合结论吗?EigenLedger 与本机技能的分工

下面两张截图来自 EasyClaw 的实际对话界面(用户实拍,2026-09-23),用自然语言完成「区间行情统计」与「技术指标解读」两类任务。它们不是 EigenLedger 的运行结果,标的、数据源与口径都不同,仅用于说明另一种可选路径。

你想做的事EigenLedger 路线本机技能路线怎么选
跑一份含 17 项指标的组合报告Engine + portfolio_analysisquant-analyst 可做风险指标与组合优化,但输出形态不同需要固定格式的批量报告,选前者
查一只票或一段区间的指标要自己拼代码a-stock-analysis、a-share-metrics-card 等技能直接对话取数一次性查询,选后者更快
把结论画成图内置图表 + QuantStats 出图chart-image 生成折线/柱状/K 线等图要嵌进报告选前者,要单张图选后者
组合优化权重EF / MEANVAR / HRP / MINVARquant-analyst 声明支持组合优化两套结果都建议交叉验证
不写代码也能问不支持支持,自然语言即可这是两条路线最大的差别

披露:本站核验的是本机技能目录(29 个技能)中的公开描述,EigenLedger 与 EasyClaw 之间没有已证实的集成关系;上表仅为能力对照,不代表两者可以互相调用。

选型

什么情况下不该用 EigenLedger?

把这个项目放回真实工作流里,边界比功能更重要。

适合

投资组合绩效复盘、投研报告配图、量化课程演示、把 QuantStats + PyPortfolioOpt 的组合流程固化成可重跑的脚本。

勉强可用

A 股与港股分析:需要自行确认 yfinance 的代码后缀与数据缺失情况,并用本地数据兜底。

不适合

实时交易、下单与风控执行;逐笔或分钟级高频研究;需要交易次数、胜率、盈亏比等策略统计的报告;对长期维护有硬性要求的生产系统。

判断维度现状对你的影响建议
维护活跃度主线最近推送 2025-09-14,最新发布 2024-10-28新依赖兼容问题可能长期不修小范围使用,别放进核心生产链路
依赖约束硬钉 numpy<2、yfinance<0.2、quantstats 锁 0.0.62与其它库同环境时容易冲突用独立虚拟环境
数据源默认 yfinanceA 股港股覆盖不稳定用本地数据接口,见数据接入页
指标完整性17 项绩效与风险指标没有交易层面的统计策略类评估另配工具
许可证仓库 Apache-2.0,README 与 PyPI 口径不一致商用前需自行确认授权以仓库 LICENSE 文件为准并留存证据
中文支持仓库有 README_CN.md(机翻),官方文档站只有英文报错与文档需要读英文配合本站的中文排查页使用
FAQ

关于 EigenLedger 的常见问题

EigenLedger 和 Empyrial 是同一个项目吗?

是。该项目 2021 年以 Empyrial 之名发布,2024-10-27 的 v2.1.5 发布说明写着「Empyrial becomes EigenLedger」。同一功能现在有两个包名:旧名 empyrial 最新为 2.1.4(2024-02-08),新名 EigenLedger 只有 2.1.5 与 2.1.6 两个版本。README 里不少链接仍指向旧账号地址,属改名遗留,以官方仓库为准。

它是免费开源的吗?许可证到底是什么?

仓库 LICENSE 文件是 Apache License 2.0,GitHub 也标注 Apache-2.0;但 README 徽章写 MIT,PyPI 的 license 字段是「LICENSE」、分类器写着「Other/Proprietary License」,README 正文末尾又写「Apache 许可证 2.0」。四份口径互相矛盾,商用前请自行确认授权范围,并以仓库中的 LICENSE 文件原文为准。

它自己算指标吗?还是调别的库?

混合方案。项目自述是 QuantStats 与 PyPortfolioOpt 的封装器:绩效与风险指标一部分调用 QuantStats,一部分调用内置的 empyrical 副本(位于 EigenLedger/modules/empyrical/),组合优化全部交给 PyPortfolioOpt。因此 QuantStats 或 PyPortfolioOpt 的行为变化会直接影响报告数字。

报告里的数字我能直接引用吗?

可以作为研究参考,但引用时必须同时给出区间、标的、权重、基准、复权方式与所用版本。默认参数下无风险利率为 0、基准为 SPY、结束日期取运行当天,这三项都会让「同一份报告」在不同时间或不同人手里算出不同结果,以官方实现与你的实际输入为准。

支持 A 股和港股吗?

数据层走 yfinance,因此可以用 600519.SS000001.SZ0700.HK 这类后缀代码,但这取决于 yfinance 对相应市场的覆盖情况,缺失标的会直接抛错。更稳的做法是把本地行情整理成 DataFrame 后通过 data= 传入,细节见「数据接入」页。

它能帮我决定买什么吗?

不能。它只对给定的标的与权重做历史统计与组合优化,不做选股,也不预测未来。优化器给出的权重是历史区间的数学解,换一段区间结果可能完全不同,因此不能当作投资建议;本页内容仅供项目研究与技术评估。

为什么不推荐在报告里用它自带的 PDF 输出?

PDF 分支依赖 fpdf 1.7.2(一个 2015 年前后定版的旧库),不嵌入中文字体,中文标的名称与说明会出现乱码或方块;同时这个包只提供源码包,是安装失败的常见原因。要交付中文报告,建议先出图再自行排版,具体以官方实现为准。

装不上就不用谈分析,先过安装这一关

本站记录了本机隔离环境里的真实安装失败与可复现的绕行步骤,先确认依赖再往下走。