bounce12340/investment-engine
GitHub: bounce12340/investment-engine
一个用于追踪高确信度股票逻辑的量化基本面投资框架,提供三角估值、熔断监控、逻辑压力测试及 Obsidian 自动周报生成。
Stars: 0 | Forks: 0
# Investment-Engine
[](LICENSE)
[](https://www.python.org/)
**English** | **[繁體中文](docs/README.zh-TW.md)** | **[日本語](docs/README.ja.md)** | **[한국어](docs/README.ko.md)**
一个轻量级框架,用于追踪高确信度股票逻辑,具备
**三角估值**、**熔断监控**、**对抗性红蓝逻辑压力测试**,
以及**集成 Obsidian 的周报**。
工作流非常简单:你只需维护一个 JSON 文件(你的 _监控注册表_),
其中包含每支股票的逻辑。引擎会计算三个独立的目标价,
检查证伪触发条件,对逻辑进行 0-10 分的评分,并将 Markdown
备忘录写入你的 Obsidian 库。可选地,可以通过 macOS launchd 定时任务按周期运行。
## 目录
- [功能](#features)
- [安装](#install)
- [快速开始](#quickstart)
- [CLI 参考](#cli-reference)
- [定时任务](#scheduling-macos)
- [注册表格式](#registry-format)
- [输出示例](#sample-output)
- [项目结构](#project-layout)
- [范围](#scope)
- [开发](#development)
- [许可协议](#license)
## 功能
**1. 监控注册表。** 一个 JSON 文件 (`data/monitor-registry.json`) 为每支股票
保存一个逻辑 —— 涵盖短/中/长周期的叙事、前瞻性指标(手动维护)、
熔断条件、红蓝方论点以及估值输入。
**2. 三角估值。** 每支股票有三个独立的目标价,
取平均值后得出一个单一的三角估值:
- **两阶段 DCF** —— 高增长期随后是终值增长(戈登增长模型)。
- **概率情景** —— 概率加权的牛市 / 基准 / 熊市目标价
(概率总和必须为 1.0)。
- **相对倍数** —— 股票指标 × 同行中位数倍数。
**3. 熔断条件。** 基于阈值的证伪检查。每个条件都有一个
方向(`below` / `above`)和一个当前值;一旦越过阈值即会
触发,标记逻辑失效。
**4. 逻辑压力测试。** 每份报告都包含一个 **确信度评分 (0–10)**
以及一系列流程规范警告标识。评分是确定且透明的:
| 因素 | 影响 |
|--------|--------|
| 安全的熔断条件 | 每个 +1(上限 +3) |
| 触发的熔断条件 | 每个 −2 |
| 牛/熊比率 ∈ [0.5, 2.0] | +1(平衡) |
| 熊市论点 ≥ 3 / ≥ 5 | +1 / +2(红队强度) |
标识(ℹ️ 信息 / ⚠️ 警告 / 🔴 警报):
- `无红队 —— 存在确认偏误风险` (无熊市论点)
- `红队力量薄弱 —— 仅有 N 个熊市论点` (< 2 个熊市)
- `无蓝队 —— 仅有负面逻辑` (无牛市论点)
- `偏多头:N.N× 牛/熊比率` (> 3×)
- `N 个熔断条件已触发 —— 逻辑失效`
- `无红警标识 —— 逻辑平衡良好` (仅在没有其他标识时出现)
**5. Obsidian 报告。** Markdown 备忘录被写入到
`{vault}/Weekly_Reports/{TICKER}_{YYYY}-W{WW}.md`,适合纳入你的知识
库。采用 ISO 周数编号。
**6. 历史表现。** 对于每支股票,引擎会从 Yahoo Finance 获取 3 年的
每日收盘价,并计算 **Sharpe, Sortino, 最大回撤、
年化波动率,以及 Jensen's α / β vs VOO**,涵盖 1 年和 3 年时间窗口
(无风险利率 = 4.0%)。会在每份报告中添加 `## Historical Performance` 部分,并在 `analyze` 中显示 Rich 表格。
**7. 技术面快照。** 根据相同的 3 年收盘价序列,引擎会
计算 **RSI(14), MACD (12/26/9), 50 日和 200 日移动平均线**,
以及距离 MA 的百分比。RSI ≥ 70 和 ≤ 30 会分别被标注为
超买 / 超卖。纯 pandas 实现 —— 无需引入新依赖。
**8. 基本面校验。** 每支股票的注册表假设
(DCF FCF、流通股本)都会与实时的 yfinance 数据进行比对。
同时还会显示 **trailing/forward P/E, 市值, 实时 β, 分析师共识
目标价, 分析师推荐评级 (1=强力买入 … 5=强力卖出),以及
股息率**。当 FCF 偏移超过 25% 或流通股本偏移超过 5% 时,会触发警告标识,从而让过时的注册表条目凸显出来。
**9. 实时价格。** 通过 `yfinance` 从 Yahoo Finance 获取当前价格,
在离线状态下可平滑回退。
**10. 定时任务。** 通过 macOS 的
`launchd` 进行每日 / 每周 / 每月的循环运行。支持交互式提示或标志参数。
## 安装
```
git clone https://github.com/bounce12340/investment-engine
cd investment-engine
python -m venv .venv && source .venv/bin/activate
pip install -e .
cp .env.example .env # edit OBSIDIAN_VAULT if different
```
需要 Python 3.10+。定时任务需要 macOS。
## 快速开始
```
# NVDA 的 Console 摘要
investment-engine analyze NVDA
# 导出到你的 Obsidian vault 的每周 Markdown 报告
investment-engine weekly NVDA --vault /Users/chunghsutsai/Vault
```
使用 `--no-price` 可在离线状态下运行 (跳过 yfinance 调用)。
## CLI 参考
### `analyze TICKER`
在控制台打印摘要:三角估值、熔断状态、
历史表现、技术面快照、基本面校验
以及逻辑压力测试。
| 标志 | 默认值 | 描述 |
|------|---------|-------------|
| `--registry PATH` | `data/monitor-registry.json` | 自定义注册表文件 |
| `--no-price` | off | 跳过从 yfinance 获取实时价格 |
| `--no-performance` | off | 跳过获取 3 年历史数据以计算 Sharpe/α/β 统计信息 |
| `--no-technicals` | off | 跳过技术指标计算 (RSI/MACD/MA) |
| `--no-fundamentals` | off | 跳过基本面校验 |
### `weekly TICKER`
生成 Markdown 报告并将其写入 Obsidian 库。
| 标志 | 默认值 | 描述 |
|------|---------|-------------|
| `--registry PATH` | `data/monitor-registry.json` | 自定义注册表文件 |
| `--vault PATH` | `$OBSIDIAN_VAULT` 或 `/Users/chunghsutsai/Vault` | 目标库 |
| `--no-price` | off | 跳过从 yfinance 获取实时价格 |
| `--no-performance` | off | 跳过获取 3 年历史数据以计算 Sharpe/α/β 统计信息 |
| `--no-technicals` | off | 跳过技术指标计算 (RSI/MACD/MA) |
| `--no-fundamentals` | off | 跳过基本面校验 |
输出路径: `{vault}/Weekly_Reports/{TICKER}_{YYYY}-W{WW}.md`。
### `schedule create` / `list` / `show` / `remove`
请参阅下方的 [定时任务](#scheduling-macos)。
## 定时任务
通过 `launchd` 进行循环运行。默认为交互式 —— 运行
`investment-engine schedule create`,系统会提示你输入频率、
时间以及股票代码。每个定时计划都会生成一个 plist + 包装脚本 + 日志文件。
```
# 交互式
investment-engine schedule create
# 每天 09:00 对 registry 中的所有 tickers 执行
investment-engine schedule create --name morning --frequency daily \
--time 09:00 --yes
# 每周一 08:30 对一个子集执行
investment-engine schedule create --name mon-brief --frequency weekly \
--time 08:30 --weekday 1 --tickers NVDA,TSM,GOOGL --yes
# 每月 1 号 07:00 执行
investment-engine schedule create --name month-end --frequency monthly \
--time 07:00 --day 1 --yes
# 管理
investment-engine schedule list
investment-engine schedule show morning
investment-engine schedule remove morning
```
**`schedule create` 的标志:**
| 标志 | 描述 |
|------|-------------|
| `--name SLUG` | 简短的小写连字符名称 |
| `--frequency daily\|weekly\|monthly` | |
| `--time HH:MM` | 24 小时制 |
| `--weekday 0..6` | 0=周日 … 6=周六 (仅限每周,launchd 约定) |
| `--day 1..31` | (仅限每月) |
| `--tickers A,B,C` | 注册表的子集;留空 = 全部 |
| `--command weekly\|analyze` | 默认为 `weekly` |
| `--vault PATH` | 覆盖库路径 |
| `--yes` / `-y` | 在加载到 launchd 之前跳过确认 |
**生成的产物:**
- 包装脚本: `~/Library/Application Support/investment-engine/.sh`
- Plist: `~/Library/LaunchAgents/com.investment-engine..plist`
- 日志: `~/Library/Logs/investment-engine-.log`
包装脚本会使用 `|| echo "[warn] X failed"` 循环遍历所有股票代码,因此单个
股票的 yfinance 波动不会中止其余股票的运行。
## 注册表格式
请参阅 `data/monitor-registry.json` 查看 NVDA 示例及其他 9 支股票
(PLTR, GOOGL, MP, NU, RCAT, TSLA, TSM, UUUU, VOO)。顶层键是股票
代码;每个条目都符合以下结构:
| 字段 | 描述 |
|-------|-------------|
| `ticker` | 股票代码 (必须与键名匹配) |
| `name` | 显示名称 (例如 `NVIDIA Corporation`) |
| `sector` | 自由格式的行业标签 |
| `thesis.short_term` / `medium_term` / `long_term` | 每个周期的叙事 |
| `leading_indicators[].{name,value,unit,description}` | 手动维护的数值 |
| `kill_switches[].{name,metric,threshold,direction,current_value}` | `direction`: `below` 或 `above` |
| `bull_points[]` / `bear_points[]` | 红蓝方论点 (字符串) |
| `valuation_inputs.dcf` | `fcf`, `growth_high`, `growth_terminal`, `years_high`, `wacc`, `shares` |
| `valuation_inputs.scenarios[]` | `name`, `price`, `probability` — 概率总和必须为 1.0 |
| `valuation_inputs.relative` | `ticker_metric`, `peer_median`, `target_metric` (例如 `EPS × 同行 P/E`) |
Pydantic 会在加载时验证每个条目。概率总和、DCF 收敛条件
(WACC > 终值增长率) 以及方向枚举均会被强制检查。
## 输出示例
```
$ investment-engine analyze NVDA
NVDA — NVIDIA Corporation (2026-W17) | price $202.06
Valuation Triangulation
┏━━━━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Model ┃ Target ┃
┡━━━━━━━━━━━━━━━╇━━━━━━━━━━┩
│ Two-Stage DCF │ $101.79 │
│ Probabilistic │ $1074.00 │
│ Relative │ $969.00 │
│ Triangulated │ $714.93 │
└───────────────┴──────────┘
Upside vs current price: +253.8%
Historical Performance
┏━━━━━━━━┳━━━━━━━━━┳━━━━━━━┳━━━━━━━━┳━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━┳━━━━━━┓
┃ Period ┃ Return ┃ Vol ┃ Sharpe ┃ Sortino ┃ Max DD ┃ α vs VOO ┃ β ┃
┡━━━━━━━━╇━━━━━━━━━╇━━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━╇━━━━━━┩
│ 1y │ +121.9% │ 33.7% │ 3.50 │ 5.71 │ -20.2% │ +52.9% │ 1.75 │
│ 3y │ +120.8% │ 48.8% │ 2.39 │ 3.72 │ -36.9% │ +76.2% │ 2.13 │
└────────┴─────────┴───────┴────────┴─────────┴────────┴──────────┴──────┘
Technical Snapshot
┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃ Indicator ┃ Value ┃
┡━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ Price │ $202.06 │
│ RSI(14) │ 71.6 (overbought) │
│ MACD │ 5.344 │
│ MACD signal │ 2.437 │
│ MACD histogram │ +2.907 │
│ 50-day MA │ $183.90 (+9.9%) │
│ 200-day MA │ $181.98 (+11.0%) │
└────────────────┴───────────────────┘
Fundamentals Reality-Check
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Metric ┃ Value ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ Trailing P/E │ 41.24 │
│ Forward P/E │ 17.98 │
│ Market Cap │ $4911.1B │
│ Live β (yfinance) │ 2.33 │
│ Analyst target (mean) │ $268.61 │
│ Analyst rec (1=SB/5=SS) │ 1.29 │
│ FCF registry / live / Δ │ $60.0B / $58.1B / -3.1% │
│ Shares registry / live / Δ │ 24.60B / 24.30B / -1.2% │
└────────────────────────────┴─────────────────────────┘
ℹ️ Analyst consensus: $268.61 (+32.9% vs current, 56 analysts)
Thesis Stress Test
┏━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Metric ┃ Value ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ Conviction score │ 10.0 / 10 │
│ Bull / Bear │ 5 / 5 │
│ Kill-switches triggered │ 0 / 4 │
│ Bull/Bear ratio │ 1.00 │
└─────────────────────────┴───────────┘
ℹ️ No red flags — thesis well-balanced
```
`weekly` 的 Markdown 输出包含相同的信息,另外还有
前瞻性指标表格、红蓝方论点以及逻辑压力测试
标识,可直接在 Obsidian 库中进行索引和链接。
## 项目结构
```
investment-engine/
├── investment_engine/
│ ├── valuation/ # DCF, probabilistic, relative
│ ├── data_sources/ # yfinance wrapper + registry loader
│ ├── analysis/ # kill_switches, leading_indicators, red_blue_team
│ ├── reports/ # Markdown template + Obsidian writer
│ ├── models.py # pydantic: Thesis, KillSwitch, StressTest, …
│ ├── watcher.py # InvestmentWatcher orchestrator
│ ├── scheduler.py # launchd plist / wrapper generation
│ └── cli.py # typer entry point
├── data/monitor-registry.json # sample: 10 tickers
└── tests/ # 36 tests covering each module
```
## 范围
**在范围内:**
- 三角估值 (DCF + 概率 + 相对估值)
- 静态熔断条件检查
- 具有确信度评分的确定性红蓝逻辑压力测试
- 历史表现 (Sharpe / Sortino / 最大回撤 / α-β vs VOO)
- 技术面快照 (RSI(14), MACD(12/26/9), 50 日和 200 日 MA)
- 基本面校验 (注册表 vs 实时 FCF/股本;分析师共识)
- Obsidian Markdown 输出
- 通过 yfinance 获取实时价格
- macOS launchd 定时任务
**不在范围内(未来工作):**
- LLM 驱动的定性分析 (生成牛/熊方论点)
- 实时抓取战略指标 (CUDA 份额、NdPr 价格等)
- 利润率压力测试 (杠杆 / 维持保证金模拟)
- 长期跟踪的确信度评分历史记录
- Windows/Linux 定时任务 (launchd 仅限 macOS)
## 开发
```
pip install -e ".[dev]"
pytest tests/ # 36 tests
```
测试使用了模拟的 yfinance,并且永远不会触碰真实的库或 launchd,因此
完整的测试套件能在不到一秒的时间内运行完毕,且没有任何副作用。
## 许可协议
MIT — 请参阅 [LICENSE](LICENSE)。
标签:Python, 估值模型, 无后门, 自动化报告, 逆向工具, 量化投资, 金融分析