alpha-engine-lib 0.32.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.
- alpha_engine_lib-0.32.0/PKG-INFO +217 -0
- alpha_engine_lib-0.32.0/README.md +188 -0
- alpha_engine_lib-0.32.0/pyproject.toml +61 -0
- alpha_engine_lib-0.32.0/setup.cfg +4 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/__init__.py +3 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/agent_schemas.py +663 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/alerts.py +576 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/arcticdb.py +340 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/collector_results.py +69 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/cost.py +665 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/dates.py +273 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/decision_capture.py +462 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/ec2_spot.py +363 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/email_sender.py +206 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/eval_artifacts.py +361 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/logging.py +303 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/model_pricing.yaml +73 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/pillars.py +756 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/pipeline_status/__init__.py +70 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/pipeline_status/read.py +541 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/pipeline_status/registry.py +368 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/pipeline_status/templates.py +120 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/preflight.py +444 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/rag/__init__.py +39 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/rag/db.py +96 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/rag/embeddings.py +63 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/rag/migrations/0001_content_tsv.sql +39 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/rag/rerank.py +377 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/rag/retrieval.py +465 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/rag/schema.sql +65 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/reconcile.py +203 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/secrets.py +186 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/sources/__init__.py +35 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/sources/protocols.py +227 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/ssm_log_capture.py +274 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/telegram.py +165 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/trading_calendar.py +236 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/transparency.py +746 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/transparency_inventory.yaml +260 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib/universe.py +83 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib.egg-info/PKG-INFO +217 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib.egg-info/SOURCES.txt +71 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib.egg-info/dependency_links.txt +1 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib.egg-info/requires.txt +27 -0
- alpha_engine_lib-0.32.0/src/alpha_engine_lib.egg-info/top_level.txt +1 -0
- alpha_engine_lib-0.32.0/tests/test_agent_schemas.py +549 -0
- alpha_engine_lib-0.32.0/tests/test_alerts.py +720 -0
- alpha_engine_lib-0.32.0/tests/test_arcticdb.py +374 -0
- alpha_engine_lib-0.32.0/tests/test_collector_results.py +110 -0
- alpha_engine_lib-0.32.0/tests/test_cost.py +743 -0
- alpha_engine_lib-0.32.0/tests/test_dates.py +276 -0
- alpha_engine_lib-0.32.0/tests/test_decision_capture.py +743 -0
- alpha_engine_lib-0.32.0/tests/test_ec2_spot.py +434 -0
- alpha_engine_lib-0.32.0/tests/test_email_sender.py +184 -0
- alpha_engine_lib-0.32.0/tests/test_eval_artifacts.py +301 -0
- alpha_engine_lib-0.32.0/tests/test_logging.py +528 -0
- alpha_engine_lib-0.32.0/tests/test_pillars.py +741 -0
- alpha_engine_lib-0.32.0/tests/test_pipeline_status_read.py +442 -0
- alpha_engine_lib-0.32.0/tests/test_pipeline_status_registry.py +180 -0
- alpha_engine_lib-0.32.0/tests/test_pipeline_status_templates.py +123 -0
- alpha_engine_lib-0.32.0/tests/test_preflight.py +502 -0
- alpha_engine_lib-0.32.0/tests/test_rag.py +147 -0
- alpha_engine_lib-0.32.0/tests/test_rag_rerank.py +322 -0
- alpha_engine_lib-0.32.0/tests/test_rag_retrieval_hybrid.py +286 -0
- alpha_engine_lib-0.32.0/tests/test_reconcile.py +119 -0
- alpha_engine_lib-0.32.0/tests/test_secrets.py +236 -0
- alpha_engine_lib-0.32.0/tests/test_sources_protocols.py +233 -0
- alpha_engine_lib-0.32.0/tests/test_ssm_log_capture.py +297 -0
- alpha_engine_lib-0.32.0/tests/test_telegram.py +213 -0
- alpha_engine_lib-0.32.0/tests/test_trading_calendar.py +143 -0
- alpha_engine_lib-0.32.0/tests/test_transparency.py +957 -0
- alpha_engine_lib-0.32.0/tests/test_universe.py +189 -0
- alpha_engine_lib-0.32.0/tests/test_version_pin.py +58 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: alpha-engine-lib
|
|
3
|
+
Version: 0.32.0
|
|
4
|
+
Summary: Shared utilities for the Alpha Engine modules: preflight, structured logging with secret-redaction, ArcticDB universe access, NYSE-calendar dates + freshness predicates, decision capture, cost telemetry, RAG, agent output schemas, SSM-backed secrets, Telegram alerts + SNS fan-out, EC2 spot-launch resilience, SSM log-capture chokepoint, and Step-Functions execution-state projection. Full surface documented in README.
|
|
5
|
+
Author: Brian McMahon
|
|
6
|
+
License: Proprietary
|
|
7
|
+
Requires-Python: >=3.9
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: boto3>=1.34
|
|
10
|
+
Requires-Dist: pydantic>=2.0
|
|
11
|
+
Requires-Dist: pyyaml>=6.0
|
|
12
|
+
Requires-Dist: requests>=2.31
|
|
13
|
+
Requires-Dist: eval_type_backport>=0.2.0; python_version < "3.10"
|
|
14
|
+
Provides-Extra: arcticdb
|
|
15
|
+
Requires-Dist: arcticdb>=6.11; extra == "arcticdb"
|
|
16
|
+
Requires-Dist: pandas>=2.0; extra == "arcticdb"
|
|
17
|
+
Provides-Extra: flow-doctor
|
|
18
|
+
Requires-Dist: flow-doctor[diagnosis,s3]<0.5.0,>=0.4.0; extra == "flow-doctor"
|
|
19
|
+
Provides-Extra: rag
|
|
20
|
+
Requires-Dist: psycopg2-binary>=2.9; extra == "rag"
|
|
21
|
+
Requires-Dist: pgvector>=0.2; extra == "rag"
|
|
22
|
+
Requires-Dist: numpy>=1.24; extra == "rag"
|
|
23
|
+
Provides-Extra: rerank
|
|
24
|
+
Requires-Dist: sentence-transformers>=3.0; extra == "rerank"
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
27
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
28
|
+
Requires-Dist: moto>=5.0; extra == "dev"
|
|
29
|
+
|
|
30
|
+
# alpha-engine-lib
|
|
31
|
+
|
|
32
|
+
> Part of [**Nous Ergon**](https://nousergon.ai) — Autonomous Multi-Agent Trading System. Repo and S3 names use the underlying project name `alpha-engine`.
|
|
33
|
+
|
|
34
|
+
[](https://nousergon.ai)
|
|
35
|
+
[](https://www.python.org/)
|
|
36
|
+
[](LICENSE)
|
|
37
|
+
[](https://github.com/cipher813/alpha-engine-docs#phase-trajectory)
|
|
38
|
+
|
|
39
|
+
Shared utility library used by all 6 modules of Nous Ergon. Cross-cutting concerns only — logging, freshness checks, trading-calendar arithmetic, ArcticDB helpers, agent-decision capture, LLM cost tracking. No proprietary trading logic, no model weights, no agent prompts.
|
|
40
|
+
|
|
41
|
+
The lib's job is to keep the same code from being maintained six times.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Install
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
# requirements.txt
|
|
49
|
+
alpha-engine-lib @ git+https://github.com/cipher813/alpha-engine-lib@v0.4.0
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Tagged releases: `v0.1.0`, `v0.2.0`, `v0.3.0`, `v0.4.0`, etc. Consumers pin to a specific tag. Breaking changes bump the minor version while Alpha Engine is in pre-1.0.
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# With optional extras
|
|
56
|
+
pip install "alpha-engine-lib[arcticdb] @ git+https://github.com/cipher813/alpha-engine-lib@v0.4.0"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
| Extra | Pulls in | When you need it |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| `[arcticdb]` | `arcticdb`, `pandas` | Anything that calls `check_arcticdb_fresh` or the ArcticDB read/write helpers |
|
|
62
|
+
| `[flow_doctor]` | `flow-doctor` | Logging integration that escalates ERROR-level events to flow-doctor |
|
|
63
|
+
| `[rag]` | `psycopg2-binary`, `pgvector`, `numpy` | The `rag` submodule — Neon pgvector RAG retrieval/ingestion |
|
|
64
|
+
| `[dev]` | `pytest`, lint tooling | Local development |
|
|
65
|
+
|
|
66
|
+
## Modules
|
|
67
|
+
|
|
68
|
+
### `logging` — structured logging + flow-doctor attach
|
|
69
|
+
|
|
70
|
+
Replaces the near-identical `log_config.py` copies that used to live in alpha-engine-data and alpha-engine-executor. Consumers call `setup_logging` once at process startup:
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from alpha_engine_lib.logging import setup_logging
|
|
74
|
+
|
|
75
|
+
setup_logging("data-collector", flow_doctor_yaml="/path/to/flow-doctor.yaml")
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
- Text mode by default; JSON via `ALPHA_ENGINE_JSON_LOGS=1`
|
|
79
|
+
- Flow-doctor attaches as an ERROR-level handler when `FLOW_DOCTOR_ENABLED=1` (requires `[flow_doctor]` extra)
|
|
80
|
+
|
|
81
|
+
### `preflight` — fail-fast connectivity + freshness checks
|
|
82
|
+
|
|
83
|
+
Runs at the top of every entrypoint, before any real work starts. Primitives live on `BasePreflight`; each consumer subclasses and overrides `run()`:
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from alpha_engine_lib.preflight import BasePreflight
|
|
87
|
+
|
|
88
|
+
class DataPreflight(BasePreflight):
|
|
89
|
+
def __init__(self, bucket, mode):
|
|
90
|
+
super().__init__(bucket)
|
|
91
|
+
self.mode = mode
|
|
92
|
+
|
|
93
|
+
def run(self):
|
|
94
|
+
self.check_env_vars("AWS_REGION")
|
|
95
|
+
if self.mode == "phase1":
|
|
96
|
+
self.check_env_vars("FRED_API_KEY", "POLYGON_API_KEY")
|
|
97
|
+
self.check_s3_bucket()
|
|
98
|
+
if self.mode == "daily":
|
|
99
|
+
self.check_arcticdb_fresh("universe", "SPY", max_stale_days=4)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Failed checks raise `RuntimeError` with an explanatory message. Consumers catch nothing — the raise propagates up through `main()` → non-zero exit → Step Function `HandleFailure` → flow-doctor notification. The point is to fail before paying for any LLM calls or downstream work.
|
|
103
|
+
|
|
104
|
+
### `arcticdb` — read/write helpers + symbol enumeration
|
|
105
|
+
|
|
106
|
+
Wrappers around the ArcticDB Python client. Standardizes the URI format, library naming, and read paths so each consumer doesn't reinvent the connection logic.
|
|
107
|
+
|
|
108
|
+
### `dates` — trading-day arithmetic
|
|
109
|
+
|
|
110
|
+
`now_dual()` returns a `(calendar_date, trading_day)` pair following the rule `trading_day = last_closed_trading_day(now)`. Strictly backward-looking; never ahead. `session_for_timestamp(ts)` resolves any timestamp to its trading session. Used at every artifact-write site to prevent calendar/trading-day drift between modules.
|
|
111
|
+
|
|
112
|
+
### `trading_calendar` — NYSE holiday detection
|
|
113
|
+
|
|
114
|
+
Pure-Python NYSE calendar through 2030. No `pandas-market-calendars` dependency.
|
|
115
|
+
|
|
116
|
+
### `decision_capture` — agent decision audit logger
|
|
117
|
+
|
|
118
|
+
Captures every agent decision as a structured artifact: prompt metadata (id + version), input snapshot, agent output, and cost. Each decision becomes replayable, auditable, and attributable to a specific prompt revision. Backbone of the Phase 2 measurement substrate.
|
|
119
|
+
|
|
120
|
+
### `cost` — LLM cost tracking
|
|
121
|
+
|
|
122
|
+
Token-aware cost computation following Anthropic's prompt-caching semantics (cache-write vs cache-read pricing). Used by every LLM call site to attach a `cost_usd` to its output.
|
|
123
|
+
|
|
124
|
+
### `agent_schemas` — canonical LLM-output Pydantic schemas
|
|
125
|
+
|
|
126
|
+
Shared contract surface for the 14 LLM-output classes used in `with_structured_output(...)` calls across the research pipeline (sector quant + qual + peer review, macro economist + critic, held-stock thesis update, CIO, eval-judge rubric). Lives here so downstream tooling — replay harness in alpha-engine-backtester, future cheap-model-concordance signals — can validate against the canonical contract without a heavy cross-repo dep on research.
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
from alpha_engine_lib.agent_schemas import (
|
|
130
|
+
QuantAnalystOutput,
|
|
131
|
+
JointFinalizationOutput,
|
|
132
|
+
CIORawOutput,
|
|
133
|
+
HeldThesisUpdateLLMOutput,
|
|
134
|
+
resolve_schema_for_agent,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
# Dispatch by captured agent_id (e.g. "sector_quant:technology" → QuantAnalystOutput)
|
|
138
|
+
schema = resolve_schema_for_agent(agent_id)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
`SCHEMA_BY_AGENT_ID_BASE` covers the 6 canonical agent families: `sector_quant`, `sector_qual`, `sector_peer_review`, `macro_economist`, `ic_cio`, `thesis_update`. Validators that defend observed LLM failure modes (sector-modifier clamp, JSON-string-as-list parser, `min_length=1` on CIO decisions) move with their classes.
|
|
142
|
+
|
|
143
|
+
### `pillars` — canonical 6-pillar attractiveness scoring shapes
|
|
144
|
+
|
|
145
|
+
Pydantic shapes for the institutional / SOTA refactor of research-module composite scoring — replaces the opaque `quant_score + qual_score` two-bucket model with a canonical 6-pillar decomposition: **Quality / Value / Momentum / Growth / Stewardship / Defensiveness**. Pillar set is the AQR Style Premia / Morningstar Economic Moat / Greenblatt / Piotroski / Fama-French / Asness "QMJ" consensus.
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
from alpha_engine_lib.pillars import (
|
|
149
|
+
PILLARS,
|
|
150
|
+
MoatAssessment,
|
|
151
|
+
PillarSubscore,
|
|
152
|
+
QualitativePillarAssessment,
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Qual Analyst emits via with_structured_output(QualitativePillarAssessment).
|
|
156
|
+
# Each of the 6 PillarSubscore fields carries 0-100 + confidence + evidence;
|
|
157
|
+
# the Quality pillar additionally carries a structured MoatAssessment
|
|
158
|
+
# (Morningstar wide/narrow/none + 6-archetype primary moat type + trend) —
|
|
159
|
+
# the qualitative core of Quality, persisted per ticker for time-series
|
|
160
|
+
# trend tracking.
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Each `PillarSubscore` decomposes into optional `quant_component` (from the factor substrate) + `qual_component` (from the agent rubric) for traceability through the composite scoring layer. Catalyst is preserved as an orthogonal `catalyst_horizon_modulation: int ∈ [-20, 20]` (a horizon shift on near-term attractiveness), not a 7th pillar weight.
|
|
164
|
+
|
|
165
|
+
Origin: 2026-05-20 attractiveness-pillars-260520 plan-doc arc. Phase 1 (this module) ships the schema layer; Phases 2-7 wire it through alpha-engine-research, alpha-engine-data, alpha-engine-backtester, and alpha-engine-dashboard.
|
|
166
|
+
|
|
167
|
+
### `rag` — semantic retrieval over SEC filings, transcripts, and theses
|
|
168
|
+
|
|
169
|
+
Neon pgvector backbone shared by `alpha-engine-research` (qual analyst's `query_filings` tool) and `alpha-engine-data` (weekly RAGIngestion step). Re-exports a small surface — `retrieve`, `ingest_document`, `document_exists`, `embed_texts`, `get_connection`, `is_available` — and ships the canonical `schema.sql` as package data.
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
from alpha_engine_lib.rag import retrieve
|
|
173
|
+
|
|
174
|
+
results = retrieve(
|
|
175
|
+
query="competitive risks and market position",
|
|
176
|
+
tickers=["AAPL"],
|
|
177
|
+
doc_types=["10-K", "10-Q", "earnings_transcript"],
|
|
178
|
+
top_k=8,
|
|
179
|
+
)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Requires the `[rag]` extra. Embeddings are Voyage `voyage-3-lite` (512d); the database backend is Neon Postgres with pgvector + HNSW indexes.
|
|
183
|
+
|
|
184
|
+
## How it's used
|
|
185
|
+
|
|
186
|
+
All six Nous Ergon module repos depend on this lib:
|
|
187
|
+
|
|
188
|
+
| Module | Repo | What it imports from here |
|
|
189
|
+
|---|---|---|
|
|
190
|
+
| Data | [`alpha-engine-data`](https://github.com/cipher813/alpha-engine-data) | `logging`, `preflight`, `arcticdb`, `dates`, `trading_calendar`, `rag` (ingestion) |
|
|
191
|
+
| Research | [`alpha-engine-research`](https://github.com/cipher813/alpha-engine-research) | `logging`, `decision_capture`, `cost`, `dates`, `rag` (retrieval), `agent_schemas` (canonical LLM-output contracts) |
|
|
192
|
+
| Predictor | [`alpha-engine-predictor`](https://github.com/cipher813/alpha-engine-predictor) | `logging`, `preflight`, `arcticdb`, `dates` |
|
|
193
|
+
| Executor | [`alpha-engine`](https://github.com/cipher813/alpha-engine) | `logging`, `preflight`, `arcticdb`, `dates`, `trading_calendar` |
|
|
194
|
+
| Backtester | [`alpha-engine-backtester`](https://github.com/cipher813/alpha-engine-backtester) | `logging`, `preflight`, `arcticdb`, `dates`, `agent_schemas` (replay-harness Pydantic validation) |
|
|
195
|
+
| Dashboard | [`alpha-engine-dashboard`](https://github.com/cipher813/alpha-engine-dashboard) | `logging`, `arcticdb`, `dates` |
|
|
196
|
+
|
|
197
|
+
## Development
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
git clone https://github.com/cipher813/alpha-engine-lib.git
|
|
201
|
+
cd alpha-engine-lib
|
|
202
|
+
pip install -e ".[dev,arcticdb,flow_doctor]"
|
|
203
|
+
pytest
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Scope discipline
|
|
207
|
+
|
|
208
|
+
This repo is intentionally narrow. Code lands here when **at least two consumers would otherwise maintain their own copy**. New modules land as their own minor release with per-consumer adoption — no lockstep updates.
|
|
209
|
+
|
|
210
|
+
Code that **does not** belong here:
|
|
211
|
+
- Anything tunable (scoring weights, risk thresholds, sizing parameters) → `alpha-engine-config` (private)
|
|
212
|
+
- Agent prompts → `alpha-engine-config` (private)
|
|
213
|
+
- Module-specific business logic → that module's repo
|
|
214
|
+
|
|
215
|
+
## License
|
|
216
|
+
|
|
217
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# alpha-engine-lib
|
|
2
|
+
|
|
3
|
+
> Part of [**Nous Ergon**](https://nousergon.ai) — Autonomous Multi-Agent Trading System. Repo and S3 names use the underlying project name `alpha-engine`.
|
|
4
|
+
|
|
5
|
+
[](https://nousergon.ai)
|
|
6
|
+
[](https://www.python.org/)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
[](https://github.com/cipher813/alpha-engine-docs#phase-trajectory)
|
|
9
|
+
|
|
10
|
+
Shared utility library used by all 6 modules of Nous Ergon. Cross-cutting concerns only — logging, freshness checks, trading-calendar arithmetic, ArcticDB helpers, agent-decision capture, LLM cost tracking. No proprietary trading logic, no model weights, no agent prompts.
|
|
11
|
+
|
|
12
|
+
The lib's job is to keep the same code from being maintained six times.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
# requirements.txt
|
|
20
|
+
alpha-engine-lib @ git+https://github.com/cipher813/alpha-engine-lib@v0.4.0
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Tagged releases: `v0.1.0`, `v0.2.0`, `v0.3.0`, `v0.4.0`, etc. Consumers pin to a specific tag. Breaking changes bump the minor version while Alpha Engine is in pre-1.0.
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# With optional extras
|
|
27
|
+
pip install "alpha-engine-lib[arcticdb] @ git+https://github.com/cipher813/alpha-engine-lib@v0.4.0"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
| Extra | Pulls in | When you need it |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| `[arcticdb]` | `arcticdb`, `pandas` | Anything that calls `check_arcticdb_fresh` or the ArcticDB read/write helpers |
|
|
33
|
+
| `[flow_doctor]` | `flow-doctor` | Logging integration that escalates ERROR-level events to flow-doctor |
|
|
34
|
+
| `[rag]` | `psycopg2-binary`, `pgvector`, `numpy` | The `rag` submodule — Neon pgvector RAG retrieval/ingestion |
|
|
35
|
+
| `[dev]` | `pytest`, lint tooling | Local development |
|
|
36
|
+
|
|
37
|
+
## Modules
|
|
38
|
+
|
|
39
|
+
### `logging` — structured logging + flow-doctor attach
|
|
40
|
+
|
|
41
|
+
Replaces the near-identical `log_config.py` copies that used to live in alpha-engine-data and alpha-engine-executor. Consumers call `setup_logging` once at process startup:
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from alpha_engine_lib.logging import setup_logging
|
|
45
|
+
|
|
46
|
+
setup_logging("data-collector", flow_doctor_yaml="/path/to/flow-doctor.yaml")
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- Text mode by default; JSON via `ALPHA_ENGINE_JSON_LOGS=1`
|
|
50
|
+
- Flow-doctor attaches as an ERROR-level handler when `FLOW_DOCTOR_ENABLED=1` (requires `[flow_doctor]` extra)
|
|
51
|
+
|
|
52
|
+
### `preflight` — fail-fast connectivity + freshness checks
|
|
53
|
+
|
|
54
|
+
Runs at the top of every entrypoint, before any real work starts. Primitives live on `BasePreflight`; each consumer subclasses and overrides `run()`:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from alpha_engine_lib.preflight import BasePreflight
|
|
58
|
+
|
|
59
|
+
class DataPreflight(BasePreflight):
|
|
60
|
+
def __init__(self, bucket, mode):
|
|
61
|
+
super().__init__(bucket)
|
|
62
|
+
self.mode = mode
|
|
63
|
+
|
|
64
|
+
def run(self):
|
|
65
|
+
self.check_env_vars("AWS_REGION")
|
|
66
|
+
if self.mode == "phase1":
|
|
67
|
+
self.check_env_vars("FRED_API_KEY", "POLYGON_API_KEY")
|
|
68
|
+
self.check_s3_bucket()
|
|
69
|
+
if self.mode == "daily":
|
|
70
|
+
self.check_arcticdb_fresh("universe", "SPY", max_stale_days=4)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Failed checks raise `RuntimeError` with an explanatory message. Consumers catch nothing — the raise propagates up through `main()` → non-zero exit → Step Function `HandleFailure` → flow-doctor notification. The point is to fail before paying for any LLM calls or downstream work.
|
|
74
|
+
|
|
75
|
+
### `arcticdb` — read/write helpers + symbol enumeration
|
|
76
|
+
|
|
77
|
+
Wrappers around the ArcticDB Python client. Standardizes the URI format, library naming, and read paths so each consumer doesn't reinvent the connection logic.
|
|
78
|
+
|
|
79
|
+
### `dates` — trading-day arithmetic
|
|
80
|
+
|
|
81
|
+
`now_dual()` returns a `(calendar_date, trading_day)` pair following the rule `trading_day = last_closed_trading_day(now)`. Strictly backward-looking; never ahead. `session_for_timestamp(ts)` resolves any timestamp to its trading session. Used at every artifact-write site to prevent calendar/trading-day drift between modules.
|
|
82
|
+
|
|
83
|
+
### `trading_calendar` — NYSE holiday detection
|
|
84
|
+
|
|
85
|
+
Pure-Python NYSE calendar through 2030. No `pandas-market-calendars` dependency.
|
|
86
|
+
|
|
87
|
+
### `decision_capture` — agent decision audit logger
|
|
88
|
+
|
|
89
|
+
Captures every agent decision as a structured artifact: prompt metadata (id + version), input snapshot, agent output, and cost. Each decision becomes replayable, auditable, and attributable to a specific prompt revision. Backbone of the Phase 2 measurement substrate.
|
|
90
|
+
|
|
91
|
+
### `cost` — LLM cost tracking
|
|
92
|
+
|
|
93
|
+
Token-aware cost computation following Anthropic's prompt-caching semantics (cache-write vs cache-read pricing). Used by every LLM call site to attach a `cost_usd` to its output.
|
|
94
|
+
|
|
95
|
+
### `agent_schemas` — canonical LLM-output Pydantic schemas
|
|
96
|
+
|
|
97
|
+
Shared contract surface for the 14 LLM-output classes used in `with_structured_output(...)` calls across the research pipeline (sector quant + qual + peer review, macro economist + critic, held-stock thesis update, CIO, eval-judge rubric). Lives here so downstream tooling — replay harness in alpha-engine-backtester, future cheap-model-concordance signals — can validate against the canonical contract without a heavy cross-repo dep on research.
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
from alpha_engine_lib.agent_schemas import (
|
|
101
|
+
QuantAnalystOutput,
|
|
102
|
+
JointFinalizationOutput,
|
|
103
|
+
CIORawOutput,
|
|
104
|
+
HeldThesisUpdateLLMOutput,
|
|
105
|
+
resolve_schema_for_agent,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# Dispatch by captured agent_id (e.g. "sector_quant:technology" → QuantAnalystOutput)
|
|
109
|
+
schema = resolve_schema_for_agent(agent_id)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`SCHEMA_BY_AGENT_ID_BASE` covers the 6 canonical agent families: `sector_quant`, `sector_qual`, `sector_peer_review`, `macro_economist`, `ic_cio`, `thesis_update`. Validators that defend observed LLM failure modes (sector-modifier clamp, JSON-string-as-list parser, `min_length=1` on CIO decisions) move with their classes.
|
|
113
|
+
|
|
114
|
+
### `pillars` — canonical 6-pillar attractiveness scoring shapes
|
|
115
|
+
|
|
116
|
+
Pydantic shapes for the institutional / SOTA refactor of research-module composite scoring — replaces the opaque `quant_score + qual_score` two-bucket model with a canonical 6-pillar decomposition: **Quality / Value / Momentum / Growth / Stewardship / Defensiveness**. Pillar set is the AQR Style Premia / Morningstar Economic Moat / Greenblatt / Piotroski / Fama-French / Asness "QMJ" consensus.
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from alpha_engine_lib.pillars import (
|
|
120
|
+
PILLARS,
|
|
121
|
+
MoatAssessment,
|
|
122
|
+
PillarSubscore,
|
|
123
|
+
QualitativePillarAssessment,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
# Qual Analyst emits via with_structured_output(QualitativePillarAssessment).
|
|
127
|
+
# Each of the 6 PillarSubscore fields carries 0-100 + confidence + evidence;
|
|
128
|
+
# the Quality pillar additionally carries a structured MoatAssessment
|
|
129
|
+
# (Morningstar wide/narrow/none + 6-archetype primary moat type + trend) —
|
|
130
|
+
# the qualitative core of Quality, persisted per ticker for time-series
|
|
131
|
+
# trend tracking.
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Each `PillarSubscore` decomposes into optional `quant_component` (from the factor substrate) + `qual_component` (from the agent rubric) for traceability through the composite scoring layer. Catalyst is preserved as an orthogonal `catalyst_horizon_modulation: int ∈ [-20, 20]` (a horizon shift on near-term attractiveness), not a 7th pillar weight.
|
|
135
|
+
|
|
136
|
+
Origin: 2026-05-20 attractiveness-pillars-260520 plan-doc arc. Phase 1 (this module) ships the schema layer; Phases 2-7 wire it through alpha-engine-research, alpha-engine-data, alpha-engine-backtester, and alpha-engine-dashboard.
|
|
137
|
+
|
|
138
|
+
### `rag` — semantic retrieval over SEC filings, transcripts, and theses
|
|
139
|
+
|
|
140
|
+
Neon pgvector backbone shared by `alpha-engine-research` (qual analyst's `query_filings` tool) and `alpha-engine-data` (weekly RAGIngestion step). Re-exports a small surface — `retrieve`, `ingest_document`, `document_exists`, `embed_texts`, `get_connection`, `is_available` — and ships the canonical `schema.sql` as package data.
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
from alpha_engine_lib.rag import retrieve
|
|
144
|
+
|
|
145
|
+
results = retrieve(
|
|
146
|
+
query="competitive risks and market position",
|
|
147
|
+
tickers=["AAPL"],
|
|
148
|
+
doc_types=["10-K", "10-Q", "earnings_transcript"],
|
|
149
|
+
top_k=8,
|
|
150
|
+
)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Requires the `[rag]` extra. Embeddings are Voyage `voyage-3-lite` (512d); the database backend is Neon Postgres with pgvector + HNSW indexes.
|
|
154
|
+
|
|
155
|
+
## How it's used
|
|
156
|
+
|
|
157
|
+
All six Nous Ergon module repos depend on this lib:
|
|
158
|
+
|
|
159
|
+
| Module | Repo | What it imports from here |
|
|
160
|
+
|---|---|---|
|
|
161
|
+
| Data | [`alpha-engine-data`](https://github.com/cipher813/alpha-engine-data) | `logging`, `preflight`, `arcticdb`, `dates`, `trading_calendar`, `rag` (ingestion) |
|
|
162
|
+
| Research | [`alpha-engine-research`](https://github.com/cipher813/alpha-engine-research) | `logging`, `decision_capture`, `cost`, `dates`, `rag` (retrieval), `agent_schemas` (canonical LLM-output contracts) |
|
|
163
|
+
| Predictor | [`alpha-engine-predictor`](https://github.com/cipher813/alpha-engine-predictor) | `logging`, `preflight`, `arcticdb`, `dates` |
|
|
164
|
+
| Executor | [`alpha-engine`](https://github.com/cipher813/alpha-engine) | `logging`, `preflight`, `arcticdb`, `dates`, `trading_calendar` |
|
|
165
|
+
| Backtester | [`alpha-engine-backtester`](https://github.com/cipher813/alpha-engine-backtester) | `logging`, `preflight`, `arcticdb`, `dates`, `agent_schemas` (replay-harness Pydantic validation) |
|
|
166
|
+
| Dashboard | [`alpha-engine-dashboard`](https://github.com/cipher813/alpha-engine-dashboard) | `logging`, `arcticdb`, `dates` |
|
|
167
|
+
|
|
168
|
+
## Development
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
git clone https://github.com/cipher813/alpha-engine-lib.git
|
|
172
|
+
cd alpha-engine-lib
|
|
173
|
+
pip install -e ".[dev,arcticdb,flow_doctor]"
|
|
174
|
+
pytest
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Scope discipline
|
|
178
|
+
|
|
179
|
+
This repo is intentionally narrow. Code lands here when **at least two consumers would otherwise maintain their own copy**. New modules land as their own minor release with per-consumer adoption — no lockstep updates.
|
|
180
|
+
|
|
181
|
+
Code that **does not** belong here:
|
|
182
|
+
- Anything tunable (scoring weights, risk thresholds, sizing parameters) → `alpha-engine-config` (private)
|
|
183
|
+
- Agent prompts → `alpha-engine-config` (private)
|
|
184
|
+
- Module-specific business logic → that module's repo
|
|
185
|
+
|
|
186
|
+
## License
|
|
187
|
+
|
|
188
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "alpha-engine-lib"
|
|
7
|
+
version = "0.32.0"
|
|
8
|
+
description = "Shared utilities for the Alpha Engine modules: preflight, structured logging with secret-redaction, ArcticDB universe access, NYSE-calendar dates + freshness predicates, decision capture, cost telemetry, RAG, agent output schemas, SSM-backed secrets, Telegram alerts + SNS fan-out, EC2 spot-launch resilience, SSM log-capture chokepoint, and Step-Functions execution-state projection. Full surface documented in README."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
# EC2 still runs Python 3.9 on the always-on micro instance (boto3 drops
|
|
11
|
+
# 3.9 support 2026-04-29, so upgrade is on the near-term roadmap). All
|
|
12
|
+
# modules in this package use ``from __future__ import annotations``, so
|
|
13
|
+
# PEP 604 union syntax (``str | None``) is deferred and works on 3.9.
|
|
14
|
+
requires-python = ">=3.9"
|
|
15
|
+
authors = [{ name = "Brian McMahon" }]
|
|
16
|
+
license = { text = "Proprietary" }
|
|
17
|
+
dependencies = [
|
|
18
|
+
"boto3>=1.34",
|
|
19
|
+
"pydantic>=2.0",
|
|
20
|
+
"pyyaml>=6.0",
|
|
21
|
+
"requests>=2.31",
|
|
22
|
+
# Pydantic V2 evaluates field annotations at class-construction time
|
|
23
|
+
# via get_type_hints, which on Python 3.9 cannot eval PEP 604 union
|
|
24
|
+
# syntax (``str | None``) even when guarded by
|
|
25
|
+
# ``from __future__ import annotations``. eval_type_backport is the
|
|
26
|
+
# backport Pydantic's own error message points to. 3.10+ has the
|
|
27
|
+
# syntax natively, so the dep is conditional on 3.9.
|
|
28
|
+
"eval_type_backport>=0.2.0; python_version < '3.10'",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.optional-dependencies]
|
|
32
|
+
arcticdb = ["arcticdb>=6.11", "pandas>=2.0"]
|
|
33
|
+
flow_doctor = ["flow-doctor[diagnosis,s3]>=0.4.0,<0.5.0"]
|
|
34
|
+
rag = [
|
|
35
|
+
"psycopg2-binary>=2.9",
|
|
36
|
+
"pgvector>=0.2",
|
|
37
|
+
"numpy>=1.24",
|
|
38
|
+
]
|
|
39
|
+
# Cross-encoder rerank dependency. Pulls torch + transformers + the
|
|
40
|
+
# ~600MB BAAI bge-reranker-v2-m3 model on first use. Kept as a
|
|
41
|
+
# separate extra so vector/hybrid-only consumers don't pay the install
|
|
42
|
+
# cost.
|
|
43
|
+
rerank = [
|
|
44
|
+
"sentence-transformers>=3.0",
|
|
45
|
+
]
|
|
46
|
+
dev = [
|
|
47
|
+
"pytest>=7.0",
|
|
48
|
+
"pytest-cov>=4.0",
|
|
49
|
+
"moto>=5.0",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
[tool.setuptools.packages.find]
|
|
53
|
+
where = ["src"]
|
|
54
|
+
|
|
55
|
+
[tool.setuptools.package-data]
|
|
56
|
+
"alpha_engine_lib" = ["transparency_inventory.yaml", "model_pricing.yaml"]
|
|
57
|
+
"alpha_engine_lib.rag" = ["schema.sql", "migrations/*.sql"]
|
|
58
|
+
|
|
59
|
+
[tool.pytest.ini_options]
|
|
60
|
+
testpaths = ["tests"]
|
|
61
|
+
pythonpath = ["src"]
|