docs: rewrite README for beta release - #1
Conversation
There was a problem hiding this comment.
Pull request overview
This PR rewrites README.md to align the project’s public docs with the beta release feature set (Alpaca integration, expanded feed options, and the safety/risk system), and updates the Quick Start and documentation links accordingly.
Changes:
- Updates the Quick Start to use
AlpacaBroker+SafeBrokerand adds an Alpaca integration section. - Adds a data feeds table and expands documentation of
LiveRiskConfig/safety concepts (kill switch,VirtualPortfolio, state persistence). - Adds links to the docs site pages and fixes the repository clone URL.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - Thread-safe bridging between sync strategies and async brokers | ||
| - The same Strategy class used in ml4t-backtest works unchanged in production | ||
| - Two broker integrations: Interactive Brokers (TWS/Gateway) and Alpaca (stocks + crypto) | ||
| - Six data feeds: Alpaca, IB, Databento, CCXT (100+ crypto exchanges), OKX |
There was a problem hiding this comment.
The intro bullet claims "Six data feeds" but only lists five (Alpaca, IB, Databento, CCXT, OKX). Either add the 6th item (e.g., BarAggregator) to the list or change the count to match the items listed.
| - Six data feeds: Alpaca, IB, Databento, CCXT (100+ crypto exchanges), OKX | |
| - Five data feeds: Alpaca, IB, Databento, CCXT (100+ crypto exchanges), OKX |
| - Two broker integrations: Interactive Brokers (TWS/Gateway) and Alpaca (stocks + crypto) | ||
| - Six data feeds: Alpaca, IB, Databento, CCXT (100+ crypto exchanges), OKX | ||
| - Shadow mode for testing without placing real orders (VirtualPortfolio tracking) | ||
| - 16-parameter risk configuration: position limits, order limits, loss limits, price protection |
There was a problem hiding this comment.
The README states this is a "16-parameter" risk configuration, but LiveRiskConfig currently has 17 fields (including blocked_assets and state_file). Please update the count (or clarify what is/isn't counted) to avoid drifting from the actual API.
| - 16-parameter risk configuration: position limits, order limits, loss limits, price protection | |
| - Multi-parameter risk configuration: position limits, order limits, loss limits, price protection |
| config = LiveRiskConfig( | ||
| kill_switch_enabled=True, | ||
| max_drawdown_pct=0.05, | ||
| state_file=".ml4t_risk_state.json", # Atomic JSON writes | ||
| ) |
There was a problem hiding this comment.
This example sets kill_switch_enabled=True, but SafeBroker.submit_order_async() treats kill_switch_enabled as an active kill switch and will immediately reject all orders. To document crash-safe persistence for drawdown-triggered kills, the example should not pre-enable the kill switch (instead configure max_drawdown_pct/state_file, and mention SafeBroker.enable_kill_switch() for manual activation).
| config = LiveRiskConfig( | |
| kill_switch_enabled=True, | |
| max_drawdown_pct=0.05, | |
| state_file=".ml4t_risk_state.json", # Atomic JSON writes | |
| ) | |
| # Configure crash-safe kill switch persistence | |
| config = LiveRiskConfig( | |
| max_drawdown_pct=0.05, | |
| state_file=".ml4t_risk_state.json", # Atomic JSON writes | |
| ) | |
| # Create a SafeBroker with this risk config | |
| safe_broker = SafeBroker(broker, config) | |
| # Optional: manually activate the kill switch (e.g., from an ops tool) | |
| safe_broker.enable_kill_switch() |
| # Live | ||
| from ml4t.live import LiveEngine | ||
| await LiveEngine(broker, MyStrategy(), risk_config).run() | ||
| await LiveEngine(MyStrategy(), safe_broker, live_feed).run() |
There was a problem hiding this comment.
In the live snippet, calling LiveEngine(...).run() without await engine.connect() will raise RuntimeError("Call connect() before run()"). Update this example to show the required connect/run/stop lifecycle (similar to the Quick Start section).
| await LiveEngine(MyStrategy(), safe_broker, live_feed).run() | |
| engine = LiveEngine(MyStrategy(), safe_broker, live_feed) | |
| await engine.connect() | |
| try: | |
| await engine.run() | |
| finally: | |
| await engine.stop() |
| - Always start with shadow_mode=True | ||
| - Always start with `shadow_mode=True` | ||
| - Set conservative position and order limits | ||
| - Enable `kill_switch_enabled=True` with a reasonable `max_drawdown_pct` |
There was a problem hiding this comment.
The Safety Notice suggests setting kill_switch_enabled=True, but that flag makes the kill switch immediately active and will block all new orders. Consider recommending leaving it False initially (and relying on max_drawdown_pct activation), or calling SafeBroker.enable_kill_switch() when you actually want to halt trading.
| - Enable `kill_switch_enabled=True` with a reasonable `max_drawdown_pct` | |
| - Configure a reasonable `max_drawdown_pct` for the kill switch, and only enable it (for example via `SafeBroker.enable_kill_switch()`) when you explicitly intend to halt trading |
Summary
AlpacaBrokerintegration sectionLiveRiskConfigwith all 16 parameters documentedVirtualPortfolio, atomic state persistence)SafeBrokerwrapper usageAlpacaBroker+SafeBrokerapplied-ai→ml4t)Test plan