ml4t-live 0.1.0a2__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.
- ml4t_live-0.1.0a2/.gitignore +36 -0
- ml4t_live-0.1.0a2/AGENT.md +170 -0
- ml4t_live-0.1.0a2/DESIGN.md +1843 -0
- ml4t_live-0.1.0a2/LICENSE +21 -0
- ml4t_live-0.1.0a2/PKG-INFO +18 -0
- ml4t_live-0.1.0a2/README.md +246 -0
- ml4t_live-0.1.0a2/api.yaml +191 -0
- ml4t_live-0.1.0a2/docs/api/index.md +45 -0
- ml4t_live-0.1.0a2/docs/getting-started/installation.md +62 -0
- ml4t_live-0.1.0a2/docs/getting-started/quickstart.md +107 -0
- ml4t_live-0.1.0a2/docs/index.md +87 -0
- ml4t_live-0.1.0a2/docs/stylesheets/ml4t-theme.css +290 -0
- ml4t_live-0.1.0a2/docs/user-guide/brokers.md +127 -0
- ml4t_live-0.1.0a2/docs/user-guide/feeds.md +115 -0
- ml4t_live-0.1.0a2/docs/user-guide/risk.md +138 -0
- ml4t_live-0.1.0a2/examples/live_ib_example.py +256 -0
- ml4t_live-0.1.0a2/mkdocs.yml +137 -0
- ml4t_live-0.1.0a2/pyproject.toml +62 -0
- ml4t_live-0.1.0a2/src/ml4t/live/__init__.py +42 -0
- ml4t_live-0.1.0a2/src/ml4t/live/_version.py +34 -0
- ml4t_live-0.1.0a2/src/ml4t/live/brokers/__init__.py +6 -0
- ml4t_live-0.1.0a2/src/ml4t/live/brokers/alpaca.py +653 -0
- ml4t_live-0.1.0a2/src/ml4t/live/brokers/ib.py +525 -0
- ml4t_live-0.1.0a2/src/ml4t/live/engine.py +271 -0
- ml4t_live-0.1.0a2/src/ml4t/live/feeds/__init__.py +18 -0
- ml4t_live-0.1.0a2/src/ml4t/live/feeds/aggregator.py +250 -0
- ml4t_live-0.1.0a2/src/ml4t/live/feeds/alpaca_feed.py +518 -0
- ml4t_live-0.1.0a2/src/ml4t/live/feeds/crypto_feed.py +363 -0
- ml4t_live-0.1.0a2/src/ml4t/live/feeds/databento_feed.py +329 -0
- ml4t_live-0.1.0a2/src/ml4t/live/feeds/ib_feed.py +250 -0
- ml4t_live-0.1.0a2/src/ml4t/live/feeds/okx_feed.py +304 -0
- ml4t_live-0.1.0a2/src/ml4t/live/protocols.py +300 -0
- ml4t_live-0.1.0a2/src/ml4t/live/safety.py +1066 -0
- ml4t_live-0.1.0a2/src/ml4t/live/wrappers.py +238 -0
- ml4t_live-0.1.0a2/tests/conftest.py +17 -0
- ml4t_live-0.1.0a2/tests/integration/README.md +88 -0
- ml4t_live-0.1.0a2/tests/integration/__init__.py +1 -0
- ml4t_live-0.1.0a2/tests/integration/conftest.py +54 -0
- ml4t_live-0.1.0a2/tests/integration/test_alpaca_integration.py +248 -0
- ml4t_live-0.1.0a2/tests/integration/test_backtest_to_live.py +531 -0
- ml4t_live-0.1.0a2/tests/integration/test_ib_integration.py +296 -0
- ml4t_live-0.1.0a2/tests/integration/test_shadow_mode.py +418 -0
- ml4t_live-0.1.0a2/tests/stress/__init__.py +0 -0
- ml4t_live-0.1.0a2/tests/stress/test_memory_leak.py +365 -0
- ml4t_live-0.1.0a2/tests/unit/__init__.py +1 -0
- ml4t_live-0.1.0a2/tests/unit/test_alpaca_broker.py +905 -0
- ml4t_live-0.1.0a2/tests/unit/test_alpaca_feed.py +616 -0
- ml4t_live-0.1.0a2/tests/unit/test_bar_aggregator.py +409 -0
- ml4t_live-0.1.0a2/tests/unit/test_bar_buffer.py +263 -0
- ml4t_live-0.1.0a2/tests/unit/test_crypto_feed.py +519 -0
- ml4t_live-0.1.0a2/tests/unit/test_databento_feed.py +350 -0
- ml4t_live-0.1.0a2/tests/unit/test_engine.py +503 -0
- ml4t_live-0.1.0a2/tests/unit/test_ib_broker.py +1257 -0
- ml4t_live-0.1.0a2/tests/unit/test_ib_feed.py +355 -0
- ml4t_live-0.1.0a2/tests/unit/test_okx_feed.py +581 -0
- ml4t_live-0.1.0a2/tests/unit/test_protocols.py +468 -0
- ml4t_live-0.1.0a2/tests/unit/test_safe_broker.py +784 -0
- ml4t_live-0.1.0a2/tests/unit/test_safety_config.py +366 -0
- ml4t_live-0.1.0a2/tests/unit/test_virtual_portfolio.py +470 -0
- ml4t_live-0.1.0a2/tests/unit/test_wrappers.py +411 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*$py.class
|
|
4
|
+
*.so
|
|
5
|
+
.Python
|
|
6
|
+
build/
|
|
7
|
+
develop-eggs/
|
|
8
|
+
dist/
|
|
9
|
+
downloads/
|
|
10
|
+
eggs/
|
|
11
|
+
.eggs/
|
|
12
|
+
lib/
|
|
13
|
+
lib64/
|
|
14
|
+
parts/
|
|
15
|
+
sdist/
|
|
16
|
+
var/
|
|
17
|
+
wheels/
|
|
18
|
+
*.egg-info/
|
|
19
|
+
.installed.cfg
|
|
20
|
+
*.egg
|
|
21
|
+
.env
|
|
22
|
+
.venv/
|
|
23
|
+
venv/
|
|
24
|
+
ENV/
|
|
25
|
+
.mypy_cache/
|
|
26
|
+
.ruff_cache/
|
|
27
|
+
.pytest_cache/
|
|
28
|
+
.coverage
|
|
29
|
+
htmlcov/
|
|
30
|
+
*.log
|
|
31
|
+
.DS_Store
|
|
32
|
+
*.tmp
|
|
33
|
+
/data/
|
|
34
|
+
logs/
|
|
35
|
+
site/
|
|
36
|
+
src/ml4t/live/_version.py
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# ML4T Live - Agent Reference
|
|
2
|
+
|
|
3
|
+
> **Quick Start**: `from ml4t.live import LiveEngine, SafeBroker, LiveRiskConfig`
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
Live trading platform enabling zero-code migration from backtesting. Copy-paste your Strategy class from ml4t-backtest to live trading with no changes.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
```bash
|
|
10
|
+
pip install ml4t-live ml4t-backtest
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Core Architecture
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
LiveEngine (async orchestration)
|
|
17
|
+
│
|
|
18
|
+
├── ThreadSafeBrokerWrapper (sync/async bridge)
|
|
19
|
+
│ └── Strategy.on_data() (sync, matches backtest API)
|
|
20
|
+
│
|
|
21
|
+
├── SafeBroker (risk layer)
|
|
22
|
+
│ └── IBBroker / AlpacaBroker (async broker)
|
|
23
|
+
│
|
|
24
|
+
└── DataFeed (market data)
|
|
25
|
+
└── IBFeed / DatabentoFeed / CryptoFeed
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Key Concept: Zero-Code Migration
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
# This exact Strategy class works in BOTH backtest and live:
|
|
32
|
+
class MyStrategy(Strategy):
|
|
33
|
+
def on_data(self, timestamp, data, context, broker):
|
|
34
|
+
if data["close"] > data["sma_20"]:
|
|
35
|
+
broker.submit_order("AAPL", 100)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Basic Usage
|
|
39
|
+
|
|
40
|
+
### Shadow Mode (Recommended First)
|
|
41
|
+
```python
|
|
42
|
+
from ml4t.live import LiveEngine, IBBroker, IBDataFeed, SafeBroker, LiveRiskConfig
|
|
43
|
+
|
|
44
|
+
# Always start in shadow mode (no real orders!)
|
|
45
|
+
config = LiveRiskConfig(shadow_mode=True)
|
|
46
|
+
broker = SafeBroker(IBBroker(), config)
|
|
47
|
+
feed = IBDataFeed(symbols=["AAPL", "MSFT"])
|
|
48
|
+
|
|
49
|
+
engine = LiveEngine(my_strategy, broker, feed)
|
|
50
|
+
await engine.connect()
|
|
51
|
+
await engine.run()
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Paper Trading
|
|
55
|
+
```python
|
|
56
|
+
config = LiveRiskConfig(
|
|
57
|
+
shadow_mode=False, # Real orders to paper account
|
|
58
|
+
max_position_value=25_000,
|
|
59
|
+
max_daily_loss=2_000,
|
|
60
|
+
)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Live Trading (Careful!)
|
|
64
|
+
```python
|
|
65
|
+
config = LiveRiskConfig(
|
|
66
|
+
shadow_mode=False,
|
|
67
|
+
max_position_value=10_000,
|
|
68
|
+
max_order_value=5_000,
|
|
69
|
+
max_daily_loss=1_000,
|
|
70
|
+
kill_switch_enabled=False, # Enable if emergency stop needed
|
|
71
|
+
)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Available Brokers
|
|
75
|
+
|
|
76
|
+
| Broker | Class | Notes |
|
|
77
|
+
|--------|-------|-------|
|
|
78
|
+
| Interactive Brokers | `IBBroker` | Via ib_async, requires TWS/Gateway |
|
|
79
|
+
| Alpaca | `AlpacaBroker` | Paper + live, easy API keys |
|
|
80
|
+
|
|
81
|
+
## Available Data Feeds
|
|
82
|
+
|
|
83
|
+
| Feed | Class | Notes |
|
|
84
|
+
|------|-------|-------|
|
|
85
|
+
| Interactive Brokers | `IBDataFeed` | Real-time quotes via IB |
|
|
86
|
+
| Databento | `DatabentoFeed` | Institutional-grade streaming |
|
|
87
|
+
| Crypto | `CryptoFeed` | Exchange WebSocket feeds |
|
|
88
|
+
| Alpaca | `AlpacaFeed` | Alpaca market data |
|
|
89
|
+
| OKX | `OKXFeed` | OKX exchange data |
|
|
90
|
+
|
|
91
|
+
## Risk Controls (LiveRiskConfig)
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
config = LiveRiskConfig(
|
|
95
|
+
# Mode
|
|
96
|
+
shadow_mode=True, # Log but don't execute
|
|
97
|
+
|
|
98
|
+
# Position Limits
|
|
99
|
+
max_position_value=25_000, # Max value per position
|
|
100
|
+
max_shares=1000, # Max shares per position
|
|
101
|
+
max_positions=10, # Max concurrent positions
|
|
102
|
+
|
|
103
|
+
# Order Limits
|
|
104
|
+
max_order_value=10_000, # Max single order value
|
|
105
|
+
|
|
106
|
+
# Loss Limits
|
|
107
|
+
max_daily_loss=2_000, # Daily loss limit
|
|
108
|
+
max_drawdown_pct=0.10, # 10% max drawdown
|
|
109
|
+
|
|
110
|
+
# Safety Checks
|
|
111
|
+
max_price_deviation_pct=0.05, # 5% fat finger protection
|
|
112
|
+
max_data_staleness_seconds=60, # Reject stale data
|
|
113
|
+
dedup_window_seconds=5, # Prevent duplicate orders
|
|
114
|
+
|
|
115
|
+
# Emergency
|
|
116
|
+
kill_switch_enabled=False, # Halt all trading
|
|
117
|
+
)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Key Classes
|
|
121
|
+
|
|
122
|
+
### LiveEngine
|
|
123
|
+
- Async orchestration of strategy, broker, and data feed
|
|
124
|
+
- Handles signal interrupts (SIGINT, SIGTERM)
|
|
125
|
+
- Error recovery and reconnection
|
|
126
|
+
|
|
127
|
+
### SafeBroker
|
|
128
|
+
- Wraps broker with risk checks
|
|
129
|
+
- Enforces all LiveRiskConfig limits
|
|
130
|
+
- Logs all order attempts
|
|
131
|
+
|
|
132
|
+
### ThreadSafeBrokerWrapper
|
|
133
|
+
- Bridges sync Strategy.on_data() to async broker
|
|
134
|
+
- Uses `run_coroutine_threadsafe()` internally
|
|
135
|
+
|
|
136
|
+
### VirtualPortfolio
|
|
137
|
+
- Tracks shadow positions when shadow_mode=True
|
|
138
|
+
- Prevents infinite buy loops
|
|
139
|
+
- State persisted to JSON
|
|
140
|
+
|
|
141
|
+
### BarAggregator
|
|
142
|
+
- Converts ticks to OHLCV bars
|
|
143
|
+
- Timeout-based flush for market close
|
|
144
|
+
- BarBuffer for multi-asset sync
|
|
145
|
+
|
|
146
|
+
## Safety Guidelines
|
|
147
|
+
|
|
148
|
+
1. **Always start with shadow_mode=True**
|
|
149
|
+
2. **Graduate to paper trading before live**
|
|
150
|
+
3. **Use conservative risk limits**
|
|
151
|
+
4. **Set max_daily_loss to limit damage**
|
|
152
|
+
5. **Test signal handling (Ctrl+C)**
|
|
153
|
+
6. **This is NOT a substitute for professional trading systems**
|
|
154
|
+
|
|
155
|
+
## Error Handling
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
try:
|
|
159
|
+
await engine.run()
|
|
160
|
+
except BrokerConnectionError:
|
|
161
|
+
# Handle connection issues
|
|
162
|
+
except RiskLimitExceeded as e:
|
|
163
|
+
# Handle risk violations
|
|
164
|
+
print(f"Risk limit: {e}")
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Dependencies
|
|
168
|
+
- ml4t-backtest (Strategy, Order, Position)
|
|
169
|
+
- ib-async (Interactive Brokers API)
|
|
170
|
+
- asyncio (async/await infrastructure)
|