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.
Files changed (60) hide show
  1. ml4t_live-0.1.0a2/.gitignore +36 -0
  2. ml4t_live-0.1.0a2/AGENT.md +170 -0
  3. ml4t_live-0.1.0a2/DESIGN.md +1843 -0
  4. ml4t_live-0.1.0a2/LICENSE +21 -0
  5. ml4t_live-0.1.0a2/PKG-INFO +18 -0
  6. ml4t_live-0.1.0a2/README.md +246 -0
  7. ml4t_live-0.1.0a2/api.yaml +191 -0
  8. ml4t_live-0.1.0a2/docs/api/index.md +45 -0
  9. ml4t_live-0.1.0a2/docs/getting-started/installation.md +62 -0
  10. ml4t_live-0.1.0a2/docs/getting-started/quickstart.md +107 -0
  11. ml4t_live-0.1.0a2/docs/index.md +87 -0
  12. ml4t_live-0.1.0a2/docs/stylesheets/ml4t-theme.css +290 -0
  13. ml4t_live-0.1.0a2/docs/user-guide/brokers.md +127 -0
  14. ml4t_live-0.1.0a2/docs/user-guide/feeds.md +115 -0
  15. ml4t_live-0.1.0a2/docs/user-guide/risk.md +138 -0
  16. ml4t_live-0.1.0a2/examples/live_ib_example.py +256 -0
  17. ml4t_live-0.1.0a2/mkdocs.yml +137 -0
  18. ml4t_live-0.1.0a2/pyproject.toml +62 -0
  19. ml4t_live-0.1.0a2/src/ml4t/live/__init__.py +42 -0
  20. ml4t_live-0.1.0a2/src/ml4t/live/_version.py +34 -0
  21. ml4t_live-0.1.0a2/src/ml4t/live/brokers/__init__.py +6 -0
  22. ml4t_live-0.1.0a2/src/ml4t/live/brokers/alpaca.py +653 -0
  23. ml4t_live-0.1.0a2/src/ml4t/live/brokers/ib.py +525 -0
  24. ml4t_live-0.1.0a2/src/ml4t/live/engine.py +271 -0
  25. ml4t_live-0.1.0a2/src/ml4t/live/feeds/__init__.py +18 -0
  26. ml4t_live-0.1.0a2/src/ml4t/live/feeds/aggregator.py +250 -0
  27. ml4t_live-0.1.0a2/src/ml4t/live/feeds/alpaca_feed.py +518 -0
  28. ml4t_live-0.1.0a2/src/ml4t/live/feeds/crypto_feed.py +363 -0
  29. ml4t_live-0.1.0a2/src/ml4t/live/feeds/databento_feed.py +329 -0
  30. ml4t_live-0.1.0a2/src/ml4t/live/feeds/ib_feed.py +250 -0
  31. ml4t_live-0.1.0a2/src/ml4t/live/feeds/okx_feed.py +304 -0
  32. ml4t_live-0.1.0a2/src/ml4t/live/protocols.py +300 -0
  33. ml4t_live-0.1.0a2/src/ml4t/live/safety.py +1066 -0
  34. ml4t_live-0.1.0a2/src/ml4t/live/wrappers.py +238 -0
  35. ml4t_live-0.1.0a2/tests/conftest.py +17 -0
  36. ml4t_live-0.1.0a2/tests/integration/README.md +88 -0
  37. ml4t_live-0.1.0a2/tests/integration/__init__.py +1 -0
  38. ml4t_live-0.1.0a2/tests/integration/conftest.py +54 -0
  39. ml4t_live-0.1.0a2/tests/integration/test_alpaca_integration.py +248 -0
  40. ml4t_live-0.1.0a2/tests/integration/test_backtest_to_live.py +531 -0
  41. ml4t_live-0.1.0a2/tests/integration/test_ib_integration.py +296 -0
  42. ml4t_live-0.1.0a2/tests/integration/test_shadow_mode.py +418 -0
  43. ml4t_live-0.1.0a2/tests/stress/__init__.py +0 -0
  44. ml4t_live-0.1.0a2/tests/stress/test_memory_leak.py +365 -0
  45. ml4t_live-0.1.0a2/tests/unit/__init__.py +1 -0
  46. ml4t_live-0.1.0a2/tests/unit/test_alpaca_broker.py +905 -0
  47. ml4t_live-0.1.0a2/tests/unit/test_alpaca_feed.py +616 -0
  48. ml4t_live-0.1.0a2/tests/unit/test_bar_aggregator.py +409 -0
  49. ml4t_live-0.1.0a2/tests/unit/test_bar_buffer.py +263 -0
  50. ml4t_live-0.1.0a2/tests/unit/test_crypto_feed.py +519 -0
  51. ml4t_live-0.1.0a2/tests/unit/test_databento_feed.py +350 -0
  52. ml4t_live-0.1.0a2/tests/unit/test_engine.py +503 -0
  53. ml4t_live-0.1.0a2/tests/unit/test_ib_broker.py +1257 -0
  54. ml4t_live-0.1.0a2/tests/unit/test_ib_feed.py +355 -0
  55. ml4t_live-0.1.0a2/tests/unit/test_okx_feed.py +581 -0
  56. ml4t_live-0.1.0a2/tests/unit/test_protocols.py +468 -0
  57. ml4t_live-0.1.0a2/tests/unit/test_safe_broker.py +784 -0
  58. ml4t_live-0.1.0a2/tests/unit/test_safety_config.py +366 -0
  59. ml4t_live-0.1.0a2/tests/unit/test_virtual_portfolio.py +470 -0
  60. 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)