aihf 2.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. aihf-2.2.0/LICENSE +21 -0
  2. aihf-2.2.0/PKG-INFO +132 -0
  3. aihf-2.2.0/README.md +98 -0
  4. aihf-2.2.0/hedge_fund/README.md +119 -0
  5. aihf-2.2.0/hedge_fund/__init__.py +7 -0
  6. aihf-2.2.0/hedge_fund/backtesting/__init__.py +25 -0
  7. aihf-2.2.0/hedge_fund/backtesting/__main__.py +190 -0
  8. aihf-2.2.0/hedge_fund/backtesting/engine.py +299 -0
  9. aihf-2.2.0/hedge_fund/backtesting/fund.py +204 -0
  10. aihf-2.2.0/hedge_fund/backtesting/models.py +47 -0
  11. aihf-2.2.0/hedge_fund/brokers/__init__.py +7 -0
  12. aihf-2.2.0/hedge_fund/brokers/models.py +39 -0
  13. aihf-2.2.0/hedge_fund/brokers/protocol.py +34 -0
  14. aihf-2.2.0/hedge_fund/brokers/sim.py +58 -0
  15. aihf-2.2.0/hedge_fund/data/__init__.py +32 -0
  16. aihf-2.2.0/hedge_fund/data/cached.py +158 -0
  17. aihf-2.2.0/hedge_fund/data/client.py +303 -0
  18. aihf-2.2.0/hedge_fund/data/models.py +275 -0
  19. aihf-2.2.0/hedge_fund/data/protocol.py +88 -0
  20. aihf-2.2.0/hedge_fund/event_study/__init__.py +33 -0
  21. aihf-2.2.0/hedge_fund/event_study/__main__.py +135 -0
  22. aihf-2.2.0/hedge_fund/event_study/engine.py +413 -0
  23. aihf-2.2.0/hedge_fund/event_study/models.py +103 -0
  24. aihf-2.2.0/hedge_fund/event_study/plot.py +190 -0
  25. aihf-2.2.0/hedge_fund/event_study/stats.py +119 -0
  26. aihf-2.2.0/hedge_fund/features/__init__.py +20 -0
  27. aihf-2.2.0/hedge_fund/features/snapshot.py +199 -0
  28. aihf-2.2.0/hedge_fund/fund/__init__.py +23 -0
  29. aihf-2.2.0/hedge_fund/fund/example.yaml +29 -0
  30. aihf-2.2.0/hedge_fund/fund/spec.py +210 -0
  31. aihf-2.2.0/hedge_fund/llm/__init__.py +40 -0
  32. aihf-2.2.0/hedge_fund/llm/api_models.json +42 -0
  33. aihf-2.2.0/hedge_fund/llm/cache.py +48 -0
  34. aihf-2.2.0/hedge_fund/llm/client.py +222 -0
  35. aihf-2.2.0/hedge_fund/llm/registry.py +66 -0
  36. aihf-2.2.0/hedge_fund/llm/watch.py +99 -0
  37. aihf-2.2.0/hedge_fund/models.py +36 -0
  38. aihf-2.2.0/hedge_fund/paths.py +32 -0
  39. aihf-2.2.0/hedge_fund/pipeline/__init__.py +8 -0
  40. aihf-2.2.0/hedge_fund/pipeline/execution.py +53 -0
  41. aihf-2.2.0/hedge_fund/pipeline/models.py +57 -0
  42. aihf-2.2.0/hedge_fund/pipeline/run_cycle.py +173 -0
  43. aihf-2.2.0/hedge_fund/portfolio/__init__.py +8 -0
  44. aihf-2.2.0/hedge_fund/portfolio/construction.py +89 -0
  45. aihf-2.2.0/hedge_fund/risk/__init__.py +8 -0
  46. aihf-2.2.0/hedge_fund/risk/limits.py +82 -0
  47. aihf-2.2.0/hedge_fund/run.py +171 -0
  48. aihf-2.2.0/hedge_fund/signals/__init__.py +42 -0
  49. aihf-2.2.0/hedge_fund/signals/base.py +105 -0
  50. aihf-2.2.0/hedge_fund/signals/buffett.py +54 -0
  51. aihf-2.2.0/hedge_fund/signals/druckenmiller.py +63 -0
  52. aihf-2.2.0/hedge_fund/signals/graham.py +59 -0
  53. aihf-2.2.0/hedge_fund/signals/llm_agent.py +172 -0
  54. aihf-2.2.0/hedge_fund/signals/lynch.py +59 -0
  55. aihf-2.2.0/hedge_fund/signals/munger.py +55 -0
  56. aihf-2.2.0/hedge_fund/signals/pead.py +138 -0
  57. aihf-2.2.0/hedge_fund/strategies/deep-value.yaml +13 -0
  58. aihf-2.2.0/hedge_fund/strategies/earnings-drift.yaml +10 -0
  59. aihf-2.2.0/hedge_fund/strategies/fundamental-ls.yaml +17 -0
  60. aihf-2.2.0/hedge_fund/strategies/inflections.yaml +11 -0
  61. aihf-2.2.0/hedge_fund/tui/__init__.py +18 -0
  62. aihf-2.2.0/hedge_fund/tui/__main__.py +11 -0
  63. aihf-2.2.0/hedge_fund/tui/app.py +2099 -0
  64. aihf-2.2.0/hedge_fund/tui/app.tcss +437 -0
  65. aihf-2.2.0/hedge_fund/tui/keys.py +92 -0
  66. aihf-2.2.0/hedge_fund/tui/shared.py +264 -0
  67. aihf-2.2.0/hedge_fund/validation/__init__.py +5 -0
  68. aihf-2.2.0/pyproject.toml +57 -0
aihf-2.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Virat Singh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
aihf-2.2.0/PKG-INFO ADDED
@@ -0,0 +1,132 @@
1
+ Metadata-Version: 2.1
2
+ Name: aihf
3
+ Version: 2.2.0
4
+ Summary: An AI-powered hedge fund: LLM investor agents and quant alpha models you can build, backtest, and run from your terminal
5
+ Home-page: https://github.com/virattt/ai-hedge-fund
6
+ License: MIT
7
+ Keywords: ai,hedge-fund,trading,llm,backtesting,agents
8
+ Author: Virat Singh
9
+ Author-email: virat.dot@gmail.com
10
+ Requires-Python: >=3.11,<4.0
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Requires-Dist: langchain-anthropic (==0.3.5)
17
+ Requires-Dist: langchain-deepseek (>=0.1.2,<0.2.0)
18
+ Requires-Dist: langchain-google-genai (>=2.0.11,<3.0.0)
19
+ Requires-Dist: langchain-openai (>=0.3.5,<0.4.0)
20
+ Requires-Dist: langchain-xai (>=0.2.5,<0.3.0)
21
+ Requires-Dist: matplotlib (>=3.9.2,<4.0.0)
22
+ Requires-Dist: numpy (>=1.24.0,<2.0.0)
23
+ Requires-Dist: pandas (>=2.1.0,<3.0.0)
24
+ Requires-Dist: pydantic (>=2.4.2,<3.0.0)
25
+ Requires-Dist: python-dotenv (==1.0.0)
26
+ Requires-Dist: pyyaml (>=6.0.3,<7.0.0)
27
+ Requires-Dist: requests (>=2.32.0,<3.0.0)
28
+ Requires-Dist: rich (>=14.2.0,<15.0.0)
29
+ Requires-Dist: scipy (>=1.11.0,<2.0.0)
30
+ Requires-Dist: textual (>=8.2.8,<9.0.0)
31
+ Project-URL: Repository, https://github.com/virattt/ai-hedge-fund
32
+ Description-Content-Type: text/markdown
33
+
34
+ # AI Hedge Fund
35
+
36
+ This is a proof of concept for an AI-powered hedge fund. The goal of this project is to explore the use of AI to make trading decisions. This project is for **educational** purposes only and is not intended for real trading or investment.
37
+
38
+ > **🚧 The project is evolving.** We're rebuilding it into a persistent, always-on AI hedge fund — a *fund* as a first-class entity you can backtest, paper-trade, and (opt-in) run live, with the investor agents reimagined as pluggable, backtestable "alpha models." Read the **[Vision →](VISION.md)** and the **[Roadmap →](ROADMAP.md)**.
39
+
40
+ Note: the system does not actually make any trades.
41
+
42
+ [![Twitter Follow](https://img.shields.io/twitter/follow/virattt?style=social)](https://twitter.com/virattt)
43
+
44
+ ## Disclaimer
45
+
46
+ This project is for **educational and research purposes only**.
47
+
48
+ - Not intended for real trading or investment
49
+ - No investment advice or guarantees provided
50
+ - Creator assumes no liability for financial losses
51
+ - Consult a financial advisor for investment decisions
52
+ - Past performance does not indicate future results
53
+
54
+ By using this software, you agree to use it solely for learning purposes.
55
+
56
+ ## How to Install
57
+
58
+ ```bash
59
+ pipx install aihf
60
+ ```
61
+
62
+ (or `uv tool install aihf`, or `pip install aihf` into an environment of your choice)
63
+
64
+ Then run it from anywhere:
65
+
66
+ ```bash
67
+ aihf
68
+ ```
69
+
70
+ ### API keys
71
+
72
+ The app asks for keys the first time it needs them and saves them to `~/.hedge-fund/.env` — nothing to configure up front. It needs:
73
+
74
+ - A [Financial Datasets](https://financialdatasets.ai) API key, for prices, fundamentals, and earnings.
75
+ - One LLM API key for the LLM-powered alpha models. Supported providers: Anthropic, OpenAI, DeepSeek, Google, xAI, Kimi.
76
+
77
+ Keys exported in your shell always win over the saved file.
78
+
79
+ ## How to Run
80
+
81
+ ### Interactive app
82
+
83
+ ```bash
84
+ aihf
85
+ ```
86
+
87
+ With no arguments, this launches the interactive terminal app. Build a fund — pick stocks, strategies, rebalance cadence — or backtest a saved fund and watch its equity curve draw against its benchmark. Funds you build are saved as mandate files in `~/.hedge-fund/mandates/`.
88
+
89
+ ### Non-interactive
90
+
91
+ Run one fund cycle from a mandate file. The full cycle record prints to stdout as JSON; a short human summary goes to stderr:
92
+
93
+ ```bash
94
+ aihf ~/.hedge-fund/mandates/example.yaml --tickers AAPL,MSFT
95
+ ```
96
+
97
+ Backtest the mandate over history at its rebalance cadence:
98
+
99
+ ```bash
100
+ aihf ~/.hedge-fund/mandates/example.yaml --tickers AAPL,MSFT --backtest
101
+ ```
102
+
103
+ A mandate is the desk — strategies, staff, risk, capital, cadence — and never names tickers; `--tickers` says what to point it at for this run.
104
+
105
+ ## Development
106
+
107
+ ```bash
108
+ git clone https://github.com/virattt/ai-hedge-fund.git
109
+ cd ai-hedge-fund
110
+ poetry install
111
+ poetry run aihf
112
+ poetry run pytest hedge_fund
113
+ ```
114
+
115
+ ## How to Contribute
116
+
117
+ 1. Fork the repository
118
+ 2. Create a feature branch
119
+ 3. Commit your changes
120
+ 4. Push to the branch
121
+ 5. Create a Pull Request
122
+
123
+ **Important**: Please keep your pull requests small and focused. This will make it easier to review and merge.
124
+
125
+ ## Feature Requests
126
+
127
+ If you have a feature request, please open an [issue](https://github.com/virattt/ai-hedge-fund/issues) and make sure it is tagged with `enhancement`.
128
+
129
+ ## License
130
+
131
+ This project is licensed under the MIT License - see the LICENSE file for details.
132
+
aihf-2.2.0/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # AI Hedge Fund
2
+
3
+ This is a proof of concept for an AI-powered hedge fund. The goal of this project is to explore the use of AI to make trading decisions. This project is for **educational** purposes only and is not intended for real trading or investment.
4
+
5
+ > **🚧 The project is evolving.** We're rebuilding it into a persistent, always-on AI hedge fund — a *fund* as a first-class entity you can backtest, paper-trade, and (opt-in) run live, with the investor agents reimagined as pluggable, backtestable "alpha models." Read the **[Vision →](VISION.md)** and the **[Roadmap →](ROADMAP.md)**.
6
+
7
+ Note: the system does not actually make any trades.
8
+
9
+ [![Twitter Follow](https://img.shields.io/twitter/follow/virattt?style=social)](https://twitter.com/virattt)
10
+
11
+ ## Disclaimer
12
+
13
+ This project is for **educational and research purposes only**.
14
+
15
+ - Not intended for real trading or investment
16
+ - No investment advice or guarantees provided
17
+ - Creator assumes no liability for financial losses
18
+ - Consult a financial advisor for investment decisions
19
+ - Past performance does not indicate future results
20
+
21
+ By using this software, you agree to use it solely for learning purposes.
22
+
23
+ ## How to Install
24
+
25
+ ```bash
26
+ pipx install aihf
27
+ ```
28
+
29
+ (or `uv tool install aihf`, or `pip install aihf` into an environment of your choice)
30
+
31
+ Then run it from anywhere:
32
+
33
+ ```bash
34
+ aihf
35
+ ```
36
+
37
+ ### API keys
38
+
39
+ The app asks for keys the first time it needs them and saves them to `~/.hedge-fund/.env` — nothing to configure up front. It needs:
40
+
41
+ - A [Financial Datasets](https://financialdatasets.ai) API key, for prices, fundamentals, and earnings.
42
+ - One LLM API key for the LLM-powered alpha models. Supported providers: Anthropic, OpenAI, DeepSeek, Google, xAI, Kimi.
43
+
44
+ Keys exported in your shell always win over the saved file.
45
+
46
+ ## How to Run
47
+
48
+ ### Interactive app
49
+
50
+ ```bash
51
+ aihf
52
+ ```
53
+
54
+ With no arguments, this launches the interactive terminal app. Build a fund — pick stocks, strategies, rebalance cadence — or backtest a saved fund and watch its equity curve draw against its benchmark. Funds you build are saved as mandate files in `~/.hedge-fund/mandates/`.
55
+
56
+ ### Non-interactive
57
+
58
+ Run one fund cycle from a mandate file. The full cycle record prints to stdout as JSON; a short human summary goes to stderr:
59
+
60
+ ```bash
61
+ aihf ~/.hedge-fund/mandates/example.yaml --tickers AAPL,MSFT
62
+ ```
63
+
64
+ Backtest the mandate over history at its rebalance cadence:
65
+
66
+ ```bash
67
+ aihf ~/.hedge-fund/mandates/example.yaml --tickers AAPL,MSFT --backtest
68
+ ```
69
+
70
+ A mandate is the desk — strategies, staff, risk, capital, cadence — and never names tickers; `--tickers` says what to point it at for this run.
71
+
72
+ ## Development
73
+
74
+ ```bash
75
+ git clone https://github.com/virattt/ai-hedge-fund.git
76
+ cd ai-hedge-fund
77
+ poetry install
78
+ poetry run aihf
79
+ poetry run pytest hedge_fund
80
+ ```
81
+
82
+ ## How to Contribute
83
+
84
+ 1. Fork the repository
85
+ 2. Create a feature branch
86
+ 3. Commit your changes
87
+ 4. Push to the branch
88
+ 5. Create a Pull Request
89
+
90
+ **Important**: Please keep your pull requests small and focused. This will make it easier to review and merge.
91
+
92
+ ## Feature Requests
93
+
94
+ If you have a feature request, please open an [issue](https://github.com/virattt/ai-hedge-fund/issues) and make sure it is tagged with `enhancement`.
95
+
96
+ ## License
97
+
98
+ This project is licensed under the MIT License - see the LICENSE file for details.
@@ -0,0 +1,119 @@
1
+ # v2 — AI Hedge Fund core
2
+
3
+ > **Status: Work in progress.** A ground-up rebuild of the engine, developed
4
+ > alongside the shipped v1 app (`src/`, `app/`) but not yet wired into it.
5
+ > See [`../VISION.md`](../VISION.md) and [`../ROADMAP.md`](../ROADMAP.md) for
6
+ > where this is headed.
7
+
8
+ v2 rebuilds the fund as a persistent, point-in-time-honest system, mirroring a
9
+ real shop's hierarchy:
10
+
11
+ ```
12
+ FUND = capital slices over STRATEGIES (master risk on the netted book)
13
+ STRATEGY = a blend policy over MODELS (a "pod")
14
+ MODEL = an alpha model → a Signal (conviction in [-1,+1] + thesis)
15
+ ```
16
+
17
+ A fund is the **desk**, not a watchlist: the mandate names no tickers. Which
18
+ names to trade is supplied per run (`--tickers`, or the app's ticker prompt)
19
+ and recorded on every `CycleRecord` — so one fund can be pointed at anything,
20
+ and every run remembers what it traded.
21
+
22
+ A fund runs two kinds of pods, like a real shop. **Discretionary** strategies
23
+ are staffed by **agents** — LLM investor personas (Warren Buffett, Charlie
24
+ Munger, Benjamin Graham, Peter Lynch, Stanley Druckenmiller) whose judgment
25
+ is the edge; blend them long-biased or market-neutral. **Systematic**
26
+ strategies are powered by quant models (post-earnings drift) — the model *is*
27
+ the strategy, no persona attached. Both kinds implement one interface and
28
+ plug into the same engine unchanged.
29
+
30
+ Run a fund two ways: **one cycle** (today's data → today's target book) or a
31
+ **backtest** — the same cycle looped over history at the mandate's rebalance
32
+ cadence, producing an equity curve against your benchmark and a full
33
+ `CycleRecord` for every tick. Same code path, so a backtest is honest by
34
+ construction: it's the fund, replayed, not a separate simulator.
35
+
36
+ ## Quickstart
37
+
38
+ ```bash
39
+ poetry install # dependencies
40
+
41
+ # .env needs (at repo root):
42
+ # FINANCIAL_DATASETS_API_KEY=... # market/fundamentals data
43
+ # ANTHROPIC_API_KEY=... # only for LLM agents (Buffett)
44
+
45
+ # THE command. No arguments: launch the interactive app (a Textual TUI).
46
+ # Build a fund — pick stocks, strategies, rebalance cadence — or backtest a
47
+ # saved fund and watch its equity curve draw against its benchmark.
48
+ poetry run aihf # or, equivalently: python -m hedge_fund.tui
49
+
50
+ # With a mandate: run one cycle non-interactively (data → strategies →
51
+ # netting → risk → execution), full CycleRecord as JSON on stdout. A mandate
52
+ # carries no tickers — --tickers says what to point the fund at this run.
53
+ poetry run aihf ~/.hedge-fund/mandates/example.yaml --tickers AAPL,MSFT,NVDA
54
+
55
+ # Backtest a mandate: the same run_cycle looped over history at the
56
+ # mandate's rebalance cadence, full result JSON (every CycleRecord) on stdout.
57
+ poetry run aihf ~/.hedge-fund/mandates/example.yaml --tickers AAPL,MSFT --backtest
58
+
59
+ # Tests
60
+ poetry run pytest hedge_fund/
61
+ ```
62
+
63
+ All API responses cache to disk (`~/.hedge-fund/cache/`), so reruns are fast,
64
+ free, and work offline once warmed.
65
+
66
+ ## Architecture
67
+
68
+ ```
69
+ Data (point-in-time) → Alpha models → Portfolio → Risk → Execution → Ledger
70
+ ```
71
+
72
+ | Module | What | Status |
73
+ |--------|------|--------|
74
+ | `data/` | `DataClient` protocol, Financial Datasets client, disk cache | ✅ |
75
+ | `signals/` | `AlphaModel` interface, PEAD, `LLMAgent` + 5 investor personas | ✅ |
76
+ | `llm/` | LLM provider protocol, Anthropic client, prompt cache | ✅ |
77
+ | `features/` | Point-in-time fundamentals snapshot (more features planned) | ◐ |
78
+ | `fund/` | `FundSpec`/`StrategySpec` — mandates as YAML data — and the `Fund` object | ✅ |
79
+ | `strategies/` | Strategy library (fundamental-ls, deep-value, inflections, earnings-drift) — add yours as a YAML | ✅ |
80
+ | `portfolio/` | View blending → target weights (conviction-weighted, optional market-neutral) | ✅ |
81
+ | `risk/` | Hard limits — per-position and gross-exposure clamps | ✅ |
82
+ | `brokers/` | `Broker` protocol + `SimBroker` (paper/live brokers planned) | ◐ |
83
+ | `pipeline/` | `run_cycle` — one code path for backtest/paper/live; `CycleRecord` | ✅ |
84
+ | `backtesting/` | `backtest_fund` — the whole fund over history on `run_cycle` — plus the per-model engine | ✅ |
85
+ | `event_study/` | Market-model abnormal returns (CARs) | ✅ |
86
+ | `validation/` | Combinatorial purged CV (CPCV), backtest-overfitting prob (PBO) | ⬜ |
87
+ | `tui/` | The interactive app (Textual): fund builder + live backtest board | ✅ |
88
+
89
+ ✅ built · ◐ partial · ⬜ planned
90
+
91
+ ## Principles (non-negotiable)
92
+
93
+ - **Point-in-time by construction.** On any simulated date, only data actually
94
+ filed by then is visible — the data layer filters on filing date, not report
95
+ period. No lookahead, ever.
96
+ - **Fail loud.** Infrastructure failures raise; only genuine "no data" returns
97
+ empty. A silent empty would poison a backtest as a fake "no signal."
98
+ - **The LLM never touches the trade.** Agents form *views* and *narrate*;
99
+ deterministic code sizes and places orders; risk limits are hard gates.
100
+ - **One interface for every analyst.** Implement `AlphaModel.predict(ticker,
101
+ date, data_client) -> Signal` and it plugs into the engine unchanged.
102
+
103
+ ## Data contracts (`models.py`)
104
+
105
+ - `Signal` — an alpha model's output: `value` in `[-1, +1]`, plus `reasoning`,
106
+ `components`, and `metadata`.
107
+ - `QuantSignals` — all signals for a ticker on a date.
108
+
109
+ ## Contributing
110
+
111
+ Two high-leverage contributions:
112
+
113
+ - **A new agent or quant model** (code): read `signals/base.py` for the
114
+ `AlphaModel` interface, use `signals/buffett.py` (an agent is just a system
115
+ prompt) or `signals/pead.py` (quant) as a template, register it, add a test.
116
+ - **A new strategy** (no code): drop a YAML in `strategies/` bundling existing
117
+ models with a blend policy — the fund builder picks it up automatically.
118
+
119
+ See [`../ROADMAP.md`](../ROADMAP.md) for the open list.
@@ -0,0 +1,7 @@
1
+ """AI Hedge Fund v2 — quantitative trading stack.
2
+
3
+ A clean-room rebuild focused on quant fundamentals:
4
+ data pipelines, event studies, backtesting, validation,
5
+ feature engineering, portfolio construction, risk management,
6
+ and execution simulation.
7
+ """
@@ -0,0 +1,25 @@
1
+ """v2 backtesting — simulate a fund (or a single alpha model) over history."""
2
+
3
+ from hedge_fund.backtesting.engine import BacktestEngine
4
+ from hedge_fund.backtesting.fund import (
5
+ FundBacktestMetrics,
6
+ FundBacktestResult,
7
+ backtest_fund,
8
+ rebalance_grid,
9
+ )
10
+ from hedge_fund.backtesting.models import (
11
+ BacktestResult,
12
+ PerformanceMetrics,
13
+ Trade,
14
+ )
15
+
16
+ __all__ = [
17
+ "BacktestEngine",
18
+ "BacktestResult",
19
+ "FundBacktestMetrics",
20
+ "FundBacktestResult",
21
+ "PerformanceMetrics",
22
+ "Trade",
23
+ "backtest_fund",
24
+ "rebalance_grid",
25
+ ]
@@ -0,0 +1,190 @@
1
+ """Run the PEAD backtester. Screen-record friendly output.
2
+
3
+ Usage: poetry run python -m hedge_fund.backtesting
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import os
9
+ import sys
10
+ import time
11
+ from datetime import date
12
+
13
+ from hedge_fund.data import FDClient
14
+ from hedge_fund.backtesting import BacktestEngine
15
+ from hedge_fund.signals import PEADModel
16
+
17
+ TICKERS = [
18
+ # Tech (21)
19
+ "AAPL", "MSFT", "AMZN", "GOOGL", "META", "NVDA", "TSLA", "NFLX", "CRM", "ADBE",
20
+ "ORCL", "INTC", "AMD", "CSCO", "IBM", "UBER", "SHOP", "SNOW", "PLTR", "PANW", "CRWD",
21
+ # Financials (15)
22
+ "JPM", "GS", "BAC", "WFC", "MS", "C", "BLK", "SCHW", "AXP", "COF",
23
+ "USB", "PNC", "TFC", "BK", "CME",
24
+ # Healthcare (15)
25
+ "JNJ", "PFE", "UNH", "MRK", "LLY", "ABBV", "TMO", "ABT", "BMY", "AMGN",
26
+ "GILD", "ISRG", "VRTX", "REGN", "MDT",
27
+ # Energy (7)
28
+ "XOM", "CVX", "COP", "SLB", "EOG", "MPC", "PSX",
29
+ # Consumer / Retail (15)
30
+ "HD", "LOW", "COST", "WMT", "KO", "PEP", "MCD", "SBUX", "NKE", "TGT",
31
+ "TJX", "ROST", "DG", "DLTR", "YUM",
32
+ # Industrials (10)
33
+ "CAT", "DE", "HON", "UPS", "RTX", "BA", "LMT", "GE", "MMM", "UNP",
34
+ # Media / Telecom (7)
35
+ "DIS", "CMCSA", "T", "VZ", "TMUS", "CHTR", "WBD",
36
+ # Other (10)
37
+ "V", "MA", "PYPL", "NEE", "D", "SO", "DUK", "ABNB", "COIN", "NOW",
38
+ ]
39
+
40
+ HOLDING_DAYS = 5
41
+ CAPITAL = 100_000.0
42
+ PER_TRADE = 10_000.0
43
+ START_DATE = "2024-06-01"
44
+ END_DATE = date.today().isoformat()
45
+
46
+ # Colors
47
+ GREEN = "\033[32m"
48
+ RED = "\033[31m"
49
+ YELLOW = "\033[33m"
50
+ CYAN = "\033[36m"
51
+ DIM = "\033[90m"
52
+ BOLD = "\033[1m"
53
+ RESET = "\033[0m"
54
+
55
+
56
+ def clear():
57
+ os.system("clear")
58
+
59
+
60
+ def color_pnl(v: float) -> str:
61
+ c = GREEN if v >= 0 else RED
62
+ return f"{c}${v:>+10,.2f}{RESET}"
63
+
64
+
65
+ def color_pct(v: float) -> str:
66
+ c = GREEN if v >= 0 else RED
67
+ return f"{c}{v:>+7.2%}{RESET}"
68
+
69
+
70
+ def color_direction(d: str) -> str:
71
+ return f"{GREEN}LONG {RESET}" if d == "long" else f"{RED}SHORT{RESET}"
72
+
73
+
74
+ def color_eps(s: str | None) -> str:
75
+ if s == "BEAT":
76
+ return f"{GREEN}BEAT{RESET}"
77
+ if s == "MISS":
78
+ return f"{RED}MISS{RESET}"
79
+ return f"{DIM} - {RESET}"
80
+
81
+
82
+ def print_header(metrics, equity: float):
83
+ """Print the portfolio summary dashboard."""
84
+ m = metrics
85
+ ret_color = GREEN if m.total_return_pct >= 0 else RED
86
+ sharpe_color = GREEN if m.sharpe_ratio > 1.0 else YELLOW if m.sharpe_ratio > 0 else RED
87
+
88
+ print(f" {BOLD}PEAD Backtest — Long BEATs, Short MISSes, {HOLDING_DAYS}-day hold{RESET}")
89
+ print(f" {DIM}{'─' * 70}{RESET}")
90
+ print(
91
+ f" Portfolio: {CYAN}${equity:>12,.2f}{RESET}"
92
+ f" Return: {ret_color}{m.total_return_pct:>+7.2%}{RESET}"
93
+ f" Sharpe: {sharpe_color}{m.sharpe_ratio:>5.2f}{RESET}"
94
+ f" Max DD: {RED}{m.max_drawdown_pct:>6.2%}{RESET}"
95
+ )
96
+ print(
97
+ f" Trades: {m.n_trades}"
98
+ f" ({GREEN}{m.n_long} long{RESET}, {RED}{m.n_short} short{RESET})"
99
+ f" Win Rate: {m.win_rate:.0%}"
100
+ f" Avg Return: {color_pct(m.avg_return_pct)}"
101
+ )
102
+ print(f" {DIM}{'─' * 70}{RESET}")
103
+ print()
104
+
105
+
106
+ def print_table_header():
107
+ print(
108
+ f" {DIM}{'Date':<12} {'Ticker':<6} {'Action':<6} {'EPS':<5}"
109
+ f" {'Entry':>9} {'Exit':>9} {'Shares':>7}"
110
+ f" {'P&L':>12} {'Return':>8}{RESET}"
111
+ )
112
+ print(f" {DIM}{'─' * 78}{RESET}")
113
+
114
+
115
+ def print_trade_row(t):
116
+ print(
117
+ f" {t.entry_date:<12} {CYAN}{t.ticker:<6}{RESET}"
118
+ f" {color_direction(t.direction)} {color_eps(t.metadata.get('eps_surprise'))}"
119
+ f" ${t.entry_price:>8.2f} ${t.exit_price:>8.2f} {t.shares:>7.1f}"
120
+ f" {color_pnl(t.pnl)} {color_pct(t.return_pct)}"
121
+ )
122
+
123
+
124
+ def main() -> None:
125
+ import logging
126
+ logging.getLogger("hedge_fund.data.client").setLevel(logging.ERROR)
127
+
128
+ n = len(TICKERS)
129
+ engine = BacktestEngine(capital=CAPITAL, per_trade=PER_TRADE)
130
+ model = PEADModel()
131
+
132
+ # Phase 1: Backtest the PEAD alpha model, ticker by ticker, with progress
133
+ sys.stdout.write(f" Backtesting PEAD alpha... [0/{n}]")
134
+ sys.stdout.flush()
135
+
136
+ trades = []
137
+ with FDClient() as fd:
138
+ for i, ticker in enumerate(TICKERS):
139
+ sys.stdout.write(f"\r Backtesting PEAD alpha... [{i + 1}/{n}] {ticker:<6}")
140
+ sys.stdout.flush()
141
+ r = engine.run_alpha(
142
+ model, [ticker], fd, START_DATE, END_DATE, holding_days=HOLDING_DAYS,
143
+ )
144
+ trades.extend(r.trades)
145
+
146
+ sys.stdout.write(f"\r Backtesting PEAD alpha... {len(trades)} trades" + " " * 20 + "\n")
147
+ sys.stdout.flush()
148
+ time.sleep(0.5)
149
+
150
+ if not trades:
151
+ print(" No trades generated.")
152
+ return
153
+
154
+ trades.sort(key=lambda t: t.entry_date)
155
+
156
+ # Phase 2: Replay trades one by one with running metrics
157
+ clear()
158
+ equity = CAPITAL
159
+ displayed: list = []
160
+
161
+ for trade in trades:
162
+ equity += trade.pnl
163
+ displayed.append(trade)
164
+
165
+ # Rebuild display each trade (like v1's clear-and-reprint)
166
+ clear()
167
+
168
+ # Compute running metrics over the trades shown so far
169
+ running_curve = engine._build_equity_curve(displayed)
170
+ running_metrics = engine._compute_metrics(displayed, running_curve)
171
+
172
+ print_header(running_metrics, equity)
173
+ print_table_header()
174
+
175
+ # Print all trades so far (newest first)
176
+ for t in reversed(displayed):
177
+ print_trade_row(t)
178
+
179
+ print()
180
+ time.sleep(0.4)
181
+
182
+ # Final summary
183
+ time.sleep(0.5)
184
+ print(f" {BOLD}Done.{RESET} {len(trades)} trades executed.\n")
185
+
186
+
187
+ if __name__ == "__main__":
188
+ from hedge_fund.tui.keys import apply_credentials
189
+ apply_credentials()
190
+ main()