trading-platform-core 1.0.0rc2__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 (46) hide show
  1. trading_platform_core-1.0.0rc2/.gitignore +60 -0
  2. trading_platform_core-1.0.0rc2/LICENSE +106 -0
  3. trading_platform_core-1.0.0rc2/PKG-INFO +302 -0
  4. trading_platform_core-1.0.0rc2/README.md +266 -0
  5. trading_platform_core-1.0.0rc2/alembic.ini +51 -0
  6. trading_platform_core-1.0.0rc2/migrations/__init__.py +0 -0
  7. trading_platform_core-1.0.0rc2/migrations/env.py +87 -0
  8. trading_platform_core-1.0.0rc2/migrations/script.py.mako +27 -0
  9. trading_platform_core-1.0.0rc2/migrations/versions/.gitkeep +0 -0
  10. trading_platform_core-1.0.0rc2/migrations/versions/001_data_quality_log.py +143 -0
  11. trading_platform_core-1.0.0rc2/migrations/versions/002_execution_quality_log.py +128 -0
  12. trading_platform_core-1.0.0rc2/migrations/versions/003_aar_events.py +203 -0
  13. trading_platform_core-1.0.0rc2/migrations/versions/004_parity_drift_log.py +127 -0
  14. trading_platform_core-1.0.0rc2/migrations/versions/005_add_dq_provenance_columns.py +93 -0
  15. trading_platform_core-1.0.0rc2/migrations/versions/006_rls_policies.py +200 -0
  16. trading_platform_core-1.0.0rc2/pyproject.toml +94 -0
  17. trading_platform_core-1.0.0rc2/tests/__init__.py +0 -0
  18. trading_platform_core-1.0.0rc2/tests/conftest.py +28 -0
  19. trading_platform_core-1.0.0rc2/tests/integration/__init__.py +0 -0
  20. trading_platform_core-1.0.0rc2/tests/integration/test_alpaca_readiness_gate.py +888 -0
  21. trading_platform_core-1.0.0rc2/tests/unit/__init__.py +0 -0
  22. trading_platform_core-1.0.0rc2/tests/unit/test_no_stdlib_shadow.py +31 -0
  23. trading_platform_core-1.0.0rc2/tpcore/__init__.py +17 -0
  24. trading_platform_core-1.0.0rc2/tpcore/aar/__init__.py +12 -0
  25. trading_platform_core-1.0.0rc2/tpcore/aar/models.py +95 -0
  26. trading_platform_core-1.0.0rc2/tpcore/aar/writer.py +342 -0
  27. trading_platform_core-1.0.0rc2/tpcore/alerts/__init__.py +9 -0
  28. trading_platform_core-1.0.0rc2/tpcore/alerts/discord.py +341 -0
  29. trading_platform_core-1.0.0rc2/tpcore/alpaca/__init__.py +10 -0
  30. trading_platform_core-1.0.0rc2/tpcore/alpaca/broker_adapter.py +1189 -0
  31. trading_platform_core-1.0.0rc2/tpcore/alpaca/data_adapter.py +808 -0
  32. trading_platform_core-1.0.0rc2/tpcore/backtest/__init__.py +47 -0
  33. trading_platform_core-1.0.0rc2/tpcore/backtest/costs.py +549 -0
  34. trading_platform_core-1.0.0rc2/tpcore/backtest/credibility.py +752 -0
  35. trading_platform_core-1.0.0rc2/tpcore/backtest/harness.py +1039 -0
  36. trading_platform_core-1.0.0rc2/tpcore/backtest/types.py +415 -0
  37. trading_platform_core-1.0.0rc2/tpcore/interfaces/__init__.py +72 -0
  38. trading_platform_core-1.0.0rc2/tpcore/interfaces/broker_execution.py +869 -0
  39. trading_platform_core-1.0.0rc2/tpcore/interfaces/data_provider.py +843 -0
  40. trading_platform_core-1.0.0rc2/tpcore/parity/__init__.py +13 -0
  41. trading_platform_core-1.0.0rc2/tpcore/parity/live_paper_harness.py +767 -0
  42. trading_platform_core-1.0.0rc2/tpcore/quality/__init__.py +18 -0
  43. trading_platform_core-1.0.0rc2/tpcore/quality/data_quality.py +344 -0
  44. trading_platform_core-1.0.0rc2/tpcore/quality/execution_quality.py +445 -0
  45. trading_platform_core-1.0.0rc2/tpcore/risk/__init__.py +9 -0
  46. trading_platform_core-1.0.0rc2/tpcore/risk/governor.py +760 -0
@@ -0,0 +1,60 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Distribution / packaging
7
+ build/
8
+ dist/
9
+ *.egg-info/
10
+ *.egg
11
+ wheels/
12
+ .eggs/
13
+
14
+ # Virtual environments
15
+ .venv/
16
+ venv/
17
+ env/
18
+ ENV/
19
+ .python-version
20
+
21
+ # Testing / coverage
22
+ .pytest_cache/
23
+ .coverage
24
+ .coverage.*
25
+ htmlcov/
26
+ coverage.xml
27
+ .tox/
28
+ .nox/
29
+
30
+ # Type checking
31
+ .mypy_cache/
32
+ .pyright/
33
+ .ruff_cache/
34
+
35
+ # IDEs / editors
36
+ .vscode/
37
+ .idea/
38
+ *.swp
39
+ *.swo
40
+ .DS_Store
41
+
42
+ # Secrets / local config (CLAUDE.md: env vars only; .env never committed)
43
+ .env
44
+ .env.local
45
+ .env.*.local
46
+ *.pem
47
+ *.key
48
+
49
+ # Local DB / Alembic (versions/ is tracked; only local state is ignored)
50
+ *.db
51
+ *.sqlite
52
+ *.sqlite3
53
+
54
+ # Logs
55
+ *.log
56
+ logs/
57
+
58
+ # Build artifacts from docs (Sphinx/MkDocs setup deferred to Sprint 2)
59
+ docs/_build/
60
+ site/
@@ -0,0 +1,106 @@
1
+ trading-platform-core License — Proprietary, Personal Use Only
2
+ ================================================================
3
+
4
+ Copyright (c) 2026 Michael Easterly. All rights reserved.
5
+
6
+ This software, including all source code, documentation, configuration,
7
+ schemas, and associated materials in this repository (the "Library"), is
8
+ proprietary and confidential. The Library is licensed, not sold, to the
9
+ licensee.
10
+
11
+
12
+ 1. PERMITTED USE
13
+
14
+ Personal, non-commercial use by the copyright holder and by any natural
15
+ person expressly authorized in writing by the copyright holder.
16
+ Permitted uses include personal algorithmic-trading research, personal
17
+ backtesting against historical data, and personal use of derived
18
+ signals for self-directed brokerage-account activity belonging to the
19
+ licensee.
20
+
21
+
22
+ 2. PROHIBITED USE
23
+
24
+ Without the prior written consent of the copyright holder, you MUST
25
+ NOT:
26
+
27
+ (a) Use the Library for any commercial purpose, including managing
28
+ capital on behalf of any third party (whether for compensation or
29
+ otherwise), offering trading-related services, operating a
30
+ capital-pool, or any activity involving third-party funds.
31
+
32
+ (b) Distribute, sublicense, sell, rent, lease, publish, or transfer
33
+ the Library or any derivative work, in whole or in part, to any
34
+ third party.
35
+
36
+ (c) Reverse engineer, decompile, or disassemble the Library beyond
37
+ what is expressly permitted by applicable law.
38
+
39
+ (d) Remove, obscure, or alter any proprietary notices, copyright
40
+ statements, license text, or scope-guard references contained in
41
+ the Library.
42
+
43
+ Commercial deployment is BLOCKED without explicit Legal-Hat
44
+ ratification per the upstream scope guard (creeper decision D-096
45
+ Sub-decision 6, mirrored in this repository's `CLAUDE.md` "Project
46
+ Identity" section).
47
+
48
+
49
+ 3. NO WARRANTY
50
+
51
+ THE LIBRARY IS PROVIDED "AS IS" AND "AS AVAILABLE", WITHOUT WARRANTY
52
+ OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
53
+ IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
54
+ PURPOSE, AND NON-INFRINGEMENT. ALGORITHMIC TRADING INVOLVES SUBSTANTIAL
55
+ RISK OF LOSS. PAST PERFORMANCE OF ANY STRATEGY, BACKTEST, OR SIGNAL IS
56
+ NOT INDICATIVE OF FUTURE RESULTS.
57
+
58
+
59
+ 4. LIMITATION OF LIABILITY
60
+
61
+ TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
62
+ THE COPYRIGHT HOLDER BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
63
+ CONSEQUENTIAL, OR PUNITIVE DAMAGES, OR FOR ANY LOSS OF PROFITS,
64
+ REVENUE, DATA, OR USE, ARISING OUT OF OR IN CONNECTION WITH USE OF
65
+ THE LIBRARY, WHETHER IN CONTRACT, TORT, OR OTHERWISE, EVEN IF ADVISED
66
+ OF THE POSSIBILITY OF SUCH DAMAGES.
67
+
68
+
69
+ 5. TERMINATION
70
+
71
+ This license terminates automatically upon any breach of its terms.
72
+ Upon termination, the licensee must cease all use of the Library and
73
+ destroy all copies in their possession or control.
74
+
75
+
76
+ 6. GOVERNING LAW AND VENUE
77
+
78
+ This License, and all claims and causes of action (whether sounding in
79
+ contract, tort, or statute) arising out of or relating to it, including
80
+ all related disputes and the validity, enforceability, and
81
+ interpretation hereof, shall be governed by and construed in accordance
82
+ with the laws of the State of Florida, United States of America,
83
+ including its statutes of limitations, without regard to its conflict
84
+ of laws principles. The parties consent to the exclusive jurisdiction
85
+ and venue of the state and federal courts located in Duval County,
86
+ Florida, for any action arising out of or relating to this License.
87
+
88
+
89
+ 7. CONTACT
90
+
91
+ Inquiries regarding licensing, commercial-use ratification, or any
92
+ other matter should be directed to the copyright holder via either
93
+ (a) the GitHub repository at
94
+ https://github.com/michaeleasterly-cpu/trading-platform-core, or
95
+ (b) packetvoidlabs@aol.com. Formal notices required under this License
96
+ (including breach or termination notices) shall be sent to the email
97
+ address above.
98
+
99
+ ---
100
+
101
+ NOTE: This license text reflects the personal-use-only scope ratified in
102
+ upstream creeper decision D-096 (Sub-decision 6). It is intentionally
103
+ terse and intended to prevent unauthorized commercial use during the
104
+ project's pre-public phase. It has not been reviewed by counsel; the
105
+ copyright holder is advised to obtain legal review prior to any
106
+ commercial-use exposure of this Library.
@@ -0,0 +1,302 @@
1
+ Metadata-Version: 2.4
2
+ Name: trading-platform-core
3
+ Version: 1.0.0rc2
4
+ Summary: Engine-agnostic Python library providing shared infrastructure for algorithmic trading engines (Swinger, Creeper, future engines).
5
+ Project-URL: Homepage, https://github.com/michaeleasterly-cpu/trading-platform-core
6
+ Project-URL: Repository, https://github.com/michaeleasterly-cpu/trading-platform-core
7
+ Author: Michael Easterly
8
+ License-Expression: LicenseRef-Proprietary
9
+ License-File: LICENSE
10
+ Keywords: alpaca,backtest,broker,risk-governor,trading
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Office/Business :: Financial :: Investment
17
+ Requires-Python: >=3.11
18
+ Requires-Dist: alembic>=1.13
19
+ Requires-Dist: alpaca-py>=0.30.0
20
+ Requires-Dist: psycopg2-binary>=2.9
21
+ Requires-Dist: pydantic<3.0,>=2.0
22
+ Requires-Dist: requests>=2.31
23
+ Requires-Dist: sqlalchemy<3.0,>=2.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: mypy>=1.8; extra == 'dev'
26
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
27
+ Requires-Dist: pytest-cov>=4.1; extra == 'dev'
28
+ Requires-Dist: pytest>=8.0; extra == 'dev'
29
+ Requires-Dist: ruff>=0.3; extra == 'dev'
30
+ Requires-Dist: types-requests>=2.31; extra == 'dev'
31
+ Provides-Extra: docs
32
+ Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
33
+ Requires-Dist: mkdocs>=1.5; extra == 'docs'
34
+ Requires-Dist: mkdocstrings[python]>=0.24; extra == 'docs'
35
+ Description-Content-Type: text/markdown
36
+
37
+ > **PROPRIETARY — PERSONAL USE ONLY.** This software is licensed under a proprietary, personal-use-only license. See [LICENSE](LICENSE) for full terms. Commercial deployment is BLOCKED without explicit Legal-Hat ratification per upstream creeper D-096 Sub-decision 6.
38
+
39
+ # trading-platform-core
40
+
41
+ Engine-agnostic Python library providing shared infrastructure for algorithmic trading engines (Swinger, Creeper, future engines).
42
+
43
+ ---
44
+
45
+ ## What it is
46
+
47
+ `trading-platform-core` is a **library**, not a service. Engines import it as a pinned dependency; it does not run as a standalone process, has no webhook listeners, no cron deployments, and no service runtime. There is no Railway / Vercel / Fly footprint.
48
+
49
+ It provides:
50
+
51
+ - Provider-abstraction ABCs (`DataProviderInterface`, `BrokerExecutionInterface`)
52
+ - Concrete Alpaca adapters (data, broker, paper-account readiness gate)
53
+ - Quality-scoring Pydantic models + DB writers (`DataQualityScore`, `ExecutionQualityScore`)
54
+ - `RiskGovernor` state machine (per-engine instance, hard-limit enforcement)
55
+ - AAR (After-Action Report) Pydantic models + writer to `platform.aar_events`
56
+ - Live-vs-paper parity harness (drift detection)
57
+ - Generic Discord alerting (engine-agnostic)
58
+ - Callback-driven backtest harness with 14-dimension `BacktestCredibilityScore` rubric
59
+
60
+ It does **not** contain engine-specific trading logic, hardcoded strategy parameters, or any signal-generation code. Engines inject those via the public API (e.g., `SignalGenerator` callback into the backtest harness).
61
+
62
+ See [`MASTER_PLAN.md`](MASTER_PLAN.md) for the full architecture, decision log, and component contracts.
63
+
64
+ ## Mission and scope
65
+
66
+ > **PERSONAL USE ONLY.** This library is licensed Proprietary per the [`LICENSE`](LICENSE) file (declared in [`pyproject.toml`](pyproject.toml) `project.license`). Commercial deployment is BLOCKED without explicit Legal-Hat ratification. See [`CLAUDE.md`](CLAUDE.md) "Project Identity" for the upstream scope guard (creeper D-096 Sub-decision 6).
67
+
68
+ The library exists to ensure that every engine in the family shares a single source of truth for provider abstraction, point-in-time (PIT) data discipline, risk governance, AAR auditability, and backtest credibility — so engine-side code stays focused on signal generation, not infrastructure plumbing.
69
+
70
+ ## Component overview
71
+
72
+ | Component | Module | Purpose |
73
+ |-----------|--------|---------|
74
+ | ABCs | `tpcore.interfaces.data_provider`, `tpcore.interfaces.broker_execution` | `DataProviderInterface` + `BrokerExecutionInterface` — every engine talks to providers exclusively through these. No direct vendor SDK calls in engine code. |
75
+ | Alpaca adapters | `tpcore.alpaca.data_adapter`, `tpcore.alpaca.broker_adapter`, `tpcore.alpaca.readiness_gate` | `AlpacaDataAdapter` (Market Data API v2), `AlpacaBrokerAdapter` (Trading API; paper/live via `ALPACA_PAPER`; stop→stop-limit conversion; `client_order_id` idempotency; `emergency_flatten` with limit-widening), `AlpacaReadinessGate` (pytest suite, must pass before any engine goes live). |
76
+ | Quality models | `tpcore.quality.data_quality`, `tpcore.quality.execution_quality` | `DataQualityScore` + `ExecutionQualityScore` Pydantic models + DB writers to `platform.data_quality_log` / `platform.execution_quality_log`. Bitemporal (`valid_at` + `recorded_at`) for PIT safety. |
77
+ | AAR pipeline | `tpcore.aar.models`, `tpcore.aar.writer` | Engine-agnostic AAR Pydantic models + `AARWriter` to `platform.aar_events` (canonical schema per D-139 — adopts upstream creeper D-140 framework-portable schema; 18 typed columns + UNIQUE on `(engine_id, trade_table, trade_id)` + 7 CHECK constraints + 4 indexes + RLS). Auto-normalises `setup_confidence` to 0-100; embeds `_schema_version` in JSONB; writes `engine_version`. |
78
+ | RiskGovernor | `tpcore.risk.governor` | Per-engine state machine; tracks daily/weekly P&L + open positions; `check_trade()` gate; `record_loss()` / `record_win()` accumulators; hard limits (`max_daily_loss_percent` 2%, `max_weekly_loss_percent` 4%, `max_open_positions` 8 — defaults; configurable per engine); `emergency_kill()` flag. No engine ships live without governor ratification of every trade. |
79
+ | ParityHarness | `tpcore.parity.live_paper_harness` | `LivePaperParityHarness` — submits identical orders to paper + live (when both enabled), compares fill prices / timestamps / slippage, logs to `platform.parity_drift_log`, alerts on drift threshold breach (default 0.2% per order, 1% cumulative weekly). |
80
+ | Discord alerts | `tpcore.alerts.discord` | Generic `send_discord_alert(webhook_url, title, fields, color)`. Engine-supplied webhook URL via env. No engine-specific formatting in the library. HTTP via `requests` (declared dep; `httpx` swap is one-line forward change — see [`MASTER_PLAN.md`](MASTER_PLAN.md) §3.7). |
81
+ | Backtest harness | `tpcore.backtest.harness` | Callback-driven, provider-agnostic. Accepts `DataProviderInterface` instance + `SignalGenerator: Callable[[date, DataSnapshot], List[Signal]]` callback (signature FROZEN at v1.0.0 per MP §3.8 design decision A) + slippage/spread/commission `Protocol`s. Returns full report with PIT verification, survivorship check, configurable walk-forward (calendar days), and 14-dimension `BacktestCredibilityScore` rubric (graduation threshold ≥70 default, configurable per engine). |
82
+
83
+ Full per-component specifications: [`MASTER_PLAN.md`](MASTER_PLAN.md) §3.1-§3.8.
84
+
85
+ ## Installation
86
+
87
+ ### From PyPI (engines, production)
88
+
89
+ Engines pin to the current major version, allowing additive minor / patch upgrades:
90
+
91
+ ```bash
92
+ pip install "trading-platform-core>=1.0,<2.0"
93
+ ```
94
+
95
+ > **Note:** The PyPI distribution name is `trading-platform-core`; the Python import name is `tpcore`. This split is intentional — see [`MASTER_PLAN.md`](MASTER_PLAN.md) §2 Naming note. Importing as `tpcore` avoids shadowing the Python stdlib `platform` module (which `setuptools`, `pip`, and many CLI tools depend on via `platform.system()`).
96
+
97
+ ### Editable install (development)
98
+
99
+ For library development, including the `dev` optional-dependency block (pytest, mypy, ruff, etc., per [`pyproject.toml`](pyproject.toml) `project.optional-dependencies.dev`):
100
+
101
+ ```bash
102
+ git clone git@github.com:michaeleasterly-cpu/trading-platform-core.git
103
+ cd trading-platform-core
104
+ pip install -e ".[dev]"
105
+ ```
106
+
107
+ Minimum Python version: **3.11** (declared in `pyproject.toml` `requires-python`). Tested on 3.11 and 3.12.
108
+
109
+ ## Quick start
110
+
111
+ ```python
112
+ import os
113
+ from tpcore.alpaca.data_adapter import AlpacaDataAdapter
114
+ from tpcore.alpaca.broker_adapter import AlpacaBrokerAdapter
115
+
116
+ # Engines parse ALPACA_PAPER themselves and pass it to the adapter constructors.
117
+ # `ALPACA_PAPER=true` (default) → paper endpoint; `ALPACA_PAPER=false` → live endpoint.
118
+ paper = os.environ.get("ALPACA_PAPER", "true").lower() == "true"
119
+
120
+ data = AlpacaDataAdapter(
121
+ api_key=os.environ["ALPACA_API_KEY"],
122
+ api_secret=os.environ["ALPACA_API_SECRET"],
123
+ paper=paper,
124
+ )
125
+
126
+ broker = AlpacaBrokerAdapter(
127
+ api_key=os.environ["ALPACA_API_KEY"],
128
+ api_secret=os.environ["ALPACA_API_SECRET"],
129
+ paper=paper,
130
+ )
131
+
132
+ # Both adapters implement the engine-agnostic ABCs:
133
+ # tpcore.interfaces.data_provider.DataProviderInterface
134
+ # tpcore.interfaces.broker_execution.BrokerExecutionInterface
135
+ # Engine code should type-annotate against the ABCs, never the concrete class.
136
+
137
+ bars = data.get_daily_bars(symbol="SPY", start="2025-01-01", end="2025-12-31")
138
+ account = broker.get_account()
139
+ assert account.is_paper is True # paper account confirmed
140
+ ```
141
+
142
+ A typical engine wires the adapters into a `RiskGovernor`, `AARWriter`, and (for backtests) the harness with an engine-specific `SignalGenerator` callback. See [`MASTER_PLAN.md`](MASTER_PLAN.md) §6 for the full integration pattern.
143
+
144
+ ### Required environment variables
145
+
146
+ | Variable | Purpose |
147
+ |----------|---------|
148
+ | `ALPACA_API_KEY` | Alpaca API key (paper or live, matching `ALPACA_PAPER`) |
149
+ | `ALPACA_API_SECRET` | Alpaca API secret (paper or live, matching `ALPACA_PAPER`) |
150
+ | `ALPACA_PAPER` | `true` (default) routes to the paper endpoint; `false` routes to the live endpoint. Engines parse this and pass `paper=` to the adapter constructors. |
151
+ | `TPCORE_DATABASE_URL` | Postgres connection string for `platform.*` tables (engine-supplied; consumed by `migrations/env.py`) |
152
+
153
+ ## Postgres setup
154
+
155
+ The library ships Alembic migrations under [`migrations/versions/`](migrations/versions/). Engines provide the connection (the library does not own credentials or pool config). Today there are five migrations:
156
+
157
+ | Migration | Table |
158
+ |-----------|-------|
159
+ | `001_data_quality_log.py` | `platform.data_quality_log` |
160
+ | `002_execution_quality_log.py` | `platform.execution_quality_log` |
161
+ | `003_aar_events.py` | `platform.aar_events` (per D-139 / upstream D-140) |
162
+ | `004_parity_drift_log.py` | `platform.parity_drift_log` |
163
+ | `005_add_dq_provenance_columns.py` | additive: `data_quality_log` provenance columns |
164
+
165
+ To apply migrations against an engine-provided database:
166
+
167
+ ```bash
168
+ export TPCORE_DATABASE_URL="postgresql+psycopg2://user:pass@host:5432/db"
169
+ alembic upgrade head
170
+ ```
171
+
172
+ Every `platform.*` table includes:
173
+
174
+ - `engine` column (`'creeper'`, `'swinger'`, etc.) — for engine-scoped writes / RLS
175
+ - `valid_at` + `recorded_at` — bitemporal columns for point-in-time (PIT) historical queries
176
+
177
+ PIT-safe historical reads use the canonical pattern:
178
+
179
+ ```sql
180
+ WHERE valid_at <= :date AND recorded_at <= :date
181
+ ```
182
+
183
+ For Alembic conventions (revision ordering, downgrade discipline, schema-version embedding in JSONB columns), see [`MIGRATION.md`](MIGRATION.md).
184
+
185
+ ## Engine integration
186
+
187
+ Swinger and Creeper are the two reference consumers; both follow the integration pattern documented in [`MASTER_PLAN.md`](MASTER_PLAN.md) §6:
188
+
189
+ 1. Pin `trading-platform-core>=1.0,<2.0` in the engine's dependency manifest.
190
+ 2. Import providers + governor + writer through the ABC-typed entrypoints (`from tpcore.interfaces.data_provider import DataProviderInterface`, etc.).
191
+ 3. Instantiate **one `RiskGovernor` per engine** (separate state files; never share an instance across engines).
192
+ 4. Provide an engine-specific `SignalGenerator` callback to the backtest harness (the harness has zero awareness of squeeze / swing / any other strategy semantics).
193
+ 5. Write AARs through `AARWriter` (the writer auto-attaches `engine` + `engine_version`).
194
+
195
+ Canonical engine wiring snippet:
196
+
197
+ ```python
198
+ from tpcore.interfaces.data_provider import DataProviderInterface
199
+ from tpcore.interfaces.broker_execution import BrokerExecutionInterface
200
+ from tpcore.alpaca.data_adapter import AlpacaDataAdapter
201
+ from tpcore.alpaca.broker_adapter import AlpacaBrokerAdapter
202
+ from tpcore.risk.governor import RiskGovernor
203
+ from tpcore.aar.writer import AARWriter
204
+
205
+ # Engine code annotates against the ABCs, not the concrete adapter classes.
206
+ data: DataProviderInterface = AlpacaDataAdapter(...)
207
+ broker: BrokerExecutionInterface = AlpacaBrokerAdapter(...)
208
+
209
+ # Per-engine governor instance — never share across engines.
210
+ governor = RiskGovernor(
211
+ engine="swinger",
212
+ max_daily_loss_percent=2.0,
213
+ max_weekly_loss_percent=4.0,
214
+ max_open_positions=8,
215
+ )
216
+
217
+ aar_writer = AARWriter(engine=os.environ["TPCORE_DATABASE_URL"])
218
+
219
+ # Pre-trade gate
220
+ allowed, reason = governor.check_trade(symbol="AAPL", proposed_size_usd=2500)
221
+ if not allowed:
222
+ logger.info("trade rejected: %s", reason)
223
+ ```
224
+
225
+ Engine repositories must NOT contain:
226
+
227
+ - Direct Alpaca SDK calls (use the ABCs)
228
+ - Hardcoded provider credentials (env vars only)
229
+ - Duplicate quality / risk / AAR logic (import from `tpcore`)
230
+
231
+ See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the contributor workflow (adding new adapters, modifying ABCs, writing tests, opening PRs).
232
+
233
+ ## Design discipline
234
+
235
+ Three non-negotiables enforced by the library and verified in CI:
236
+
237
+ 1. **Provider abstraction is mandatory.** Every Alpaca SDK call lives behind an ABC method. Engines depending on `alpaca-py` directly is a process violation. The ABCs are versioned with the library and frozen at v1.0.0 (additive-only after that).
238
+ 2. **Point-in-time (PIT) safety.** Historical reads always carry `valid_at` + `recorded_at` predicates. Bitemporal columns are required on every `platform.*` table; backtest harness verification fails the run if a snapshot includes data with `recorded_at > backtest_date`.
239
+ 3. **Risk governor before live capital.** No engine ships live without `RiskGovernor.check_trade()` ratifying every order. The governor's `emergency_kill()` flag is engine-callable and blocks all new orders until explicitly reset.
240
+
241
+ Component-level design decisions (e.g., `SignalGenerator` signature freeze, `DataSnapshot` representation, slippage/spread/commission as `Protocol` rather than ABC, walk-forward window semantics, `BacktestCredibilityScore` graduation threshold) are locked in [`MASTER_PLAN.md`](MASTER_PLAN.md) §3.8 design-decisions A–E. The MASTER_PLAN is canonical for design — never re-litigate decisions in code comments.
242
+
243
+ ## Versioning
244
+
245
+ Semantic versioning per [`MASTER_PLAN.md`](MASTER_PLAN.md) §7:
246
+
247
+ | Bump | Trigger |
248
+ |------|---------|
249
+ | **MAJOR** | Breaking changes to public ABCs or `platform.*` database schemas |
250
+ | **MINOR** | New optional ABC methods, new adapters, additive schema columns, non-breaking enhancements |
251
+ | **PATCH** | Bug fixes, documentation, internal refactors with zero API surface impact |
252
+
253
+ Pre-release tags follow PEP 440 (`v1.0.0-rc.1`, etc.). Engines pin to the current major (`>=1.0,<2.0`); new majors require a coordinated migration across consuming engines.
254
+
255
+ **Backward-compatibility commitment after v1.0.0:** zero breaking changes to public ABCs or schemas without a major bump.
256
+
257
+ ## Testing
258
+
259
+ ```bash
260
+ # All unit tests (mocked external APIs)
261
+ pytest tests/unit/
262
+
263
+ # Integration tests (requires Alpaca paper credentials in env + Postgres connection)
264
+ pytest -m integration tests/integration/
265
+
266
+ # Coverage report
267
+ pytest --cov=tpcore --cov-report=term-missing
268
+ ```
269
+
270
+ Coverage target: **≥80%** for `tpcore.*` per `MASTER_PLAN.md` §8 / §10. Integration runtime target: **<2 minutes** per the success-metrics table in `MASTER_PLAN.md` §10.
271
+
272
+ ## Repository layout
273
+
274
+ ```
275
+ trading-platform-core/
276
+ ├── tpcore/ # Importable library code
277
+ │ ├── interfaces/ # DataProviderInterface, BrokerExecutionInterface ABCs
278
+ │ ├── alpaca/ # AlpacaDataAdapter, AlpacaBrokerAdapter, AlpacaReadinessGate
279
+ │ ├── quality/ # DataQualityScore, ExecutionQualityScore
280
+ │ ├── risk/ # RiskGovernor
281
+ │ ├── aar/ # AAR models + AARWriter
282
+ │ ├── parity/ # LivePaperParityHarness
283
+ │ ├── alerts/ # Discord webhook sender
284
+ │ └── backtest/ # Callback-driven backtest harness
285
+ ├── migrations/ # Alembic migrations for platform.* schema
286
+ ├── tests/
287
+ │ ├── unit/ # Mocked-API unit tests
288
+ │ └── integration/ # Alpaca paper + Postgres integration tests
289
+ ├── pyproject.toml # PyPI metadata, deps, dev extras
290
+ ├── alembic.ini
291
+ ├── README.md # This file
292
+ ├── CONTRIBUTING.md # Contributor workflow
293
+ ├── MIGRATION.md # Schema-migration guide
294
+ ├── MASTER_PLAN.md # Architecture + decision log
295
+ └── LICENSE # Proprietary — personal use only
296
+ ```
297
+
298
+ Full structural reference: [`MASTER_PLAN.md`](MASTER_PLAN.md) §2.
299
+
300
+ ## License
301
+
302
+ Proprietary — personal use only. See [`LICENSE`](LICENSE) for the full text and [`pyproject.toml`](pyproject.toml) `project.license` for the declarative metadata. Commercial deployment is BLOCKED without explicit Legal-Hat ratification per the upstream scope guard (creeper D-096 Sub-decision 6, mirrored in [`CLAUDE.md`](CLAUDE.md) "Project Identity").