bounce12340/investment-engine
GitHub: bounce12340/investment-engine
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)**
A lightweight framework for tracking high-conviction equity theses with
**triangulation valuation**, **kill-switch monitoring**, an **adversarial
Red/Blue thesis stress test**, and **Obsidian-integrated weekly reports**.
The workflow is simple: you maintain one JSON file (your _monitor registry_)
with a thesis per ticker. The engine computes three independent price targets,
checks falsification triggers, scores the thesis 0–10, and writes a Markdown
memo into your Obsidian vault. Optionally, a macOS launchd schedule runs it on
a cadence.
## 内容
- [Features](#features)
- [Install](#install)
- [Quickstart](#quickstart)
- [CLI reference](#cli-reference)
- [Scheduling (macOS)](#scheduling-macos)
- [Registry format](#registry-format)
- [Sample output](#sample-output)
- [Project layout](#project-layout)
- [Scope](#scope)
- [Development](#development)
- [License](#license)
## 功能
**1. Monitor registry.** One JSON file (`data/monitor-registry.json`) holds a
thesis per ticker — narrative across short/medium/long horizons, leading
indicators (manually maintained), kill-switches, Red/Blue arguments, and
valuation inputs.
**2. Triangulation valuation.** Three independent price targets per ticker,
averaged into a single triangulated estimate:
- **Two-Stage DCF** — high-growth period then terminal growth (Gordon growth).
- **Probabilistic scenarios** — probability-weighted Bull / Base / Bear targets
(probabilities must sum to 1.0).
- **Relative multiples** — ticker metric × peer-median multiple.
**3. Kill-switches.** Threshold-based falsification checks. Each has a
direction (`below` / `above`) and a current value; crossing the threshold fires
the trigger, flagging thesis violation.
**4. Thesis stress test.** Every report includes a **conviction score (0–10)**
and a list of process-hygiene flags. Scoring is deterministic and transparent:
| Factor | Effect |
|--------|--------|
| Safe kill-switch | +1 each (capped at +3) |
| Triggered kill-switch | −2 each |
| Bull/bear ratio ∈ [0.5, 2.0] | +1 (balanced) |
| Bear points ≥ 3 / ≥ 5 | +1 / +2 (red-team strength) |
Flags (ℹ️ info / ⚠️ warning / 🔴 alert):
- `No red team — confirmation bias risk` (no bear points)
- `Thin red team — only N bear point(s)` (< 2 bear)
- `No blue team — negative thesis only` (no bull)
- `Bull-biased: N.N× bull-to-bear ratio` (> 3×)
- `N kill-switch(es) triggered — thesis violation`
- `No red flags — thesis well-balanced` (only when no other flags)
**5. Obsidian reports.** Markdown memos written to
`{vault}/Weekly_Reports/{TICKER}_{YYYY}-W{WW}.md`, suitable for your knowledge
base. ISO week numbering.
**6. Historical performance.** For every ticker, the engine pulls 3 years of
daily closes from Yahoo Finance and computes **Sharpe, Sortino, max drawdown,
annualized volatility, and Jensen's α / β vs VOO** over 1y and 3y windows
(risk-free rate = 4.0%). Adds a `## Historical Performance` section to every
report and a Rich table in `analyze`.
**7. Technical snapshot.** From the same 3-year close series the engine
computes **RSI(14), MACD (12/26/9), 50-day and 200-day moving averages**,
plus distance-from-MA percentages. RSI ≥ 70 and ≤ 30 get annotated as
overbought / oversold. Pure-pandas implementation — no new dependencies.
**8. Fundamentals reality-check.** Each ticker's registry assumptions
(DCF FCF, shares outstanding) are compared against live yfinance data.
Also surfaces **trailing/forward P/E, market cap, live β, analyst consensus
target, analyst recommendation (1=strongBuy … 5=strongSell), and
dividend yield**. Flags fire when FCF drifts more than 25% or shares
outstanding drift more than 5%, so stale registry entries stand out.
**9. Live prices.** Current price fetched from Yahoo Finance via `yfinance`,
with graceful fallback when offline.
**10. Scheduling.** Daily / weekly / monthly recurring runs via macOS
`launchd`. Interactive prompts or flags.
## 安装
```
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
```
Requires Python 3.10+. Scheduling requires macOS.
## 快速开始
```
# NVDA 控制台摘要
investment-engine analyze NVDA
# 每周 Markdown 报告到您的 Obsidian 保险库
investment-engine weekly NVDA --vault /Users/chunghsutsai/Vault
```
Works offline with `--no-price` (skips the yfinance call).
## CLI 参考
### `analyze TICKER`
Prints a console summary: triangulated valuation, kill-switch status,
historical performance, technical snapshot, fundamentals reality-check,
and thesis stress test.
| Flag | Default | Description |
|------|---------|-------------|
| `--registry PATH` | `data/monitor-registry.json` | Custom registry file |
| `--no-price` | off | Skip fetching live price from yfinance |
| `--no-performance` | off | Skip fetching 3y history for Sharpe/α/β stats |
| `--no-technicals` | off | Skip technical indicators (RSI/MACD/MA) |
| `--no-fundamentals` | off | Skip fundamentals reality-check |
### `weekly TICKER`
Generates a Markdown report and writes it into the Obsidian vault.
| Flag | Default | Description |
|------|---------|-------------|
| `--registry PATH` | `data/monitor-registry.json` | Custom registry file |
| `--vault PATH` | `$OBSIDIAN_VAULT` or `/Users/chunghsutsai/Vault` | Target vault |
| `--no-price` | off | Skip fetching live price from yfinance |
| `--no-performance` | off | Skip fetching 3y history for Sharpe/α/β stats |
| `--no-technicals` | off | Skip technical indicators (RSI/MACD/MA) |
| `--no-fundamentals` | off | Skip fundamentals reality-check |
Output path: `{vault}/Weekly_Reports/{TICKER}_{YYYY}-W{WW}.md`.
### `schedule create` / `list` / `show` / `remove`
See [Scheduling](#scheduling-macos) below.
## 调度(macOS)
Recurring runs via `launchd`. Interactive by default — run
`investment-engine schedule create` and you'll be prompted for frequency,
time, and tickers. Each schedule creates one plist + wrapper script + log file.
```
# 交互式
investment-engine schedule create
# 每日上午 09:00 针对注册表中的所有股票代码
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
```
**Flags for `schedule create`:**
| Flag | Description |
|------|-------------|
| `--name SLUG` | Short lowercase-hyphen name |
| `--frequency daily\|weekly\|monthly` | |
| `--time HH:MM` | 24-hour clock |
| `--weekday 0..6` | 0=Sun … 6=Sat (weekly only, launchd convention) |
| `--day 1..31` | (monthly only) |
| `--tickers A,B,C` | Subset of registry; blank = all |
| `--command weekly\|analyze` | Default `weekly` |
| `--vault PATH` | Vault override |
| `--yes` / `-y` | Skip confirmation before loading into launchd |
**Generated artifacts:**
- Wrapper: `~/Library/Application Support/investment-engine/.sh`
- Plist: `~/Library/LaunchAgents/com.investment-engine..plist`
- Log: `~/Library/Logs/investment-engine-.log`
The wrapper loops all tickers with `|| echo "[warn] X failed"` so one
ticker's yfinance blip won't abort the rest.
## 注册表格式
See `data/monitor-registry.json` for the NVDA sample and 9 other tickers
(PLTR, GOOGL, MP, NU, RCAT, TSLA, TSM, UUUU, VOO). Top-level keys are ticker
symbols; each entry matches this schema:
| Field | Description |
|-------|-------------|
| `ticker` | Ticker symbol (must match the key) |
| `name` | Display name (e.g. `NVIDIA Corporation`) |
| `sector` | Free-form sector tag |
| `thesis.short_term` / `medium_term` / `long_term` | Narrative per horizon |
| `leading_indicators[].{name,value,unit,description}` | Manually maintained values |
| `kill_switches[].{name,metric,threshold,direction,current_value}` | `direction`: `below` or `above` |
| `bull_points[]` / `bear_points[]` | Red/Blue team arguments (strings) |
| `valuation_inputs.dcf` | `fcf`, `growth_high`, `growth_terminal`, `years_high`, `wacc`, `shares` |
| `valuation_inputs.scenarios[]` | `name`, `price`, `probability` — probabilities must sum to 1.0 |
| `valuation_inputs.relative` | `ticker_metric`, `peer_median`, `target_metric` (e.g. `EPS × peer P/E`) |
Pydantic validates every entry at load time. Probability sums, DCF convergence
(WACC > terminal growth), and direction enum are all enforced.
## 示例输出
```
$ 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
```
The `weekly` Markdown output includes the same information plus a
Leading-Indicators table, Red/Blue team points, and the Thesis Stress Test
flags, ready to be indexed and linked inside an Obsidian vault.
## 项目布局
```
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
```
## 范围
**In scope:**
- Triangulation valuation (DCF + Probabilistic + Relative)
- Static kill-switch checks
- Deterministic Red/Blue thesis stress test with conviction score
- Historical performance (Sharpe / Sortino / max drawdown / α-β vs VOO)
- Technical snapshot (RSI(14), MACD(12/26/9), 50-day and 200-day MA)
- Fundamentals reality-check (registry vs live FCF/shares; analyst consensus)
- Obsidian Markdown output
- Live prices via yfinance
- macOS launchd scheduling
**Out of scope (future work):**
- LLM-driven qualitative analysis (generating bull/bear arguments)
- Live scraping of strategic indicators (CUDA share, NdPr price, etc.)
- Margin stress testing (leverage / maintenance-margin simulations)
- Conviction-score history tracking over time
- Windows/Linux scheduling (launchd is macOS-only)
## 开发
```
pip install -e ".[dev]"
pytest tests/ # 36 tests
```
Tests use mocked yfinance and never touch the real vault or launchd, so the
full suite runs in under a second with no side effects.
## 许可证
MIT — see [LICENSE](LICENSE).
标签:AI基础设施, ASM汇编, DCF, JSON监控注册表, macOS定时任务, Markdown报告, MIT许可, Obsidian自动化报告, Python, SEO: AI基础设施, SEO: Obsidian报告, SEO: 压力测试, SEO: 投资平台, SEO: 概率估值, SEO: 红蓝队, SEO: 量化框架, SEO: 领先指标, 保证金压力测试, 压力测试, 基本面分析, 多因子验证, 对抗性分析, 开源投资, 情景分析, 技术分析, 投资引擎, 投资组合管理, 数据驱动决策, 无后门, 概率估值, 混合智能, 熔断机制, 盯市监控, 相对估值, 红蓝队分析, 轻量级框架, 量化投资, 领先指标, 颠覆性技术