ML4T Live¶
Run the same Strategy class you validated in ml4t-backtest against real brokers and live market
data, with SafeBroker risk controls layered on top.
ml4t-live is the deployment layer in the ML4T stack. It sits after research and backtesting, where
the main problem is no longer "does this idea work?" but "can I run it safely against a broker without
rewriting the strategy or losing track of operational risk?" The library is built for staged rollout:
shadow mode first, then paper trading, then small live size under explicit limits.
-
Same Strategy, Live Execution --- Keep the same
Strategy.on_data(...)interface fromml4t-backtest.LiveEnginehandles the async broker and feed runtime around it. Quickstart -
SafeBroker Risk Controls --- Position caps, order limits, duplicate-order protection, and a persistent kill switch. Start in shadow mode before you route anything real. Risk Controls
-
Multiple Brokers And Feeds --- Alpaca and Interactive Brokers for execution, plus replay and crypto feed options. Change infrastructure without forking strategy logic. Brokers
-
From Book To Production --- The book develops strategies in research and backtest form. This library runs them live with the same surface and explicit deployment controls. Book Guide
What You Can Do With It Right Now¶
With ml4t-live, you can:
- take an existing
ml4t-backtest.Strategyand run it inLiveEngine - connect that strategy to Alpaca or Interactive Brokers
- replay or stream data through a live-style feed interface
- start in
shadow_mode=Trueso orders are tracked but not routed - add hard limits for order size, exposure, order rate, and drawdown before going live
If you do not yet have a validated strategy, start in ml4t-backtest. If you do have one, this is the
next layer.
Where It Fits In The ML4T Stack¶
| Stage | Primary library | Practical question |
|---|---|---|
| Data preparation | ml4t-data |
Do I trust the raw and canonical inputs? |
| Features and labels | ml4t-engineer |
Am I computing the right signals? |
| Diagnostics and validation | ml4t-diagnostic |
Are the signals robust and statistically defensible? |
| Simulation and cost realism | ml4t-backtest |
Does the strategy survive explicit execution assumptions? |
| Deployment and staged rollout | ml4t-live |
Can I run the validated strategy against a real broker safely? |
Strategy Portability¶
The headline feature is strategy portability. The strategy class stays the same. The engine and infrastructure change.
The Strategy Code Stays The Same¶
from ml4t.backtest import Strategy
from ml4t.backtest.types import OrderSide
class BuyOnceStrategy(Strategy):
def on_data(self, timestamp, data, context, broker):
bar = data.get("SPY")
if bar is None:
return
if broker.get_position("SPY") is None:
broker.submit_order("SPY", 10, side=OrderSide.BUY)
Backtest Run¶
from ml4t.backtest import DataFeed, Engine
feed = DataFeed(prices_df=prices)
engine = Engine(feed=feed, strategy=BuyOnceStrategy())
result = engine.run()
Live Run¶
from ml4t.live import AlpacaBroker, AlpacaDataFeed, LiveEngine, LiveRiskConfig, SafeBroker
raw_broker = AlpacaBroker(api_key="...", secret_key="...", paper=True)
safe_broker = SafeBroker(raw_broker, LiveRiskConfig(shadow_mode=True))
feed = AlpacaDataFeed(api_key="...", secret_key="...", symbols=["SPY"], data_type="bars")
engine = LiveEngine(BuyOnceStrategy(), safe_broker, feed)
await engine.connect()
await engine.run()
The point is not that backtest and live are identical systems. They are not. The point is that your decision logic survives the engine swap intact, so any later mismatch is easier to attribute to data, execution, or operations instead of to a second implementation of the strategy.
Staged Rollout¶
ml4t-live is designed for staged deployment, not instant promotion from notebook to production.
1. Start In Shadow Mode¶
The strategy runs, risk checks run, and VirtualPortfolio tracks fills, but no real order is sent.
safe_broker = SafeBroker(
raw_broker,
LiveRiskConfig(
shadow_mode=True,
max_position_value=25_000,
max_order_value=5_000,
max_orders_per_minute=5,
),
)
2. Graduate To Paper Trading¶
The key config change is turning shadow mode off while still using paper broker credentials.
safe_broker = SafeBroker(
raw_broker,
LiveRiskConfig(
shadow_mode=False,
max_position_value=25_000,
max_order_value=5_000,
max_orders_per_minute=5,
),
)
3. Go To Small Live Size¶
Keep limits tight enough that mistakes are survivable.
safe_broker = SafeBroker(
raw_broker,
LiveRiskConfig(
shadow_mode=False,
max_position_value=10_000,
max_total_exposure=25_000,
max_order_value=2_500,
max_drawdown_pct=0.03,
max_daily_loss=1_000,
),
)
4. Scale Only After Stable Monitoring¶
Promotion to larger live size should follow routine reconciliation, order-flow review, and operational checks, not just a passing backtest.
SafeBroker In Action¶
The safety model matters because this is a live trading library. SafeBroker is the main trust signal,
so it should be understood in concrete terms:
- Set
max_order_shares=100andmax_order_value=5_000.SafeBrokerrejects any single order that would exceed 100 shares or $5,000 notional. - Set
max_position_value=25_000andmax_total_exposure=50_000.SafeBrokerblocks orders that would push one position or the overall book beyond those limits. - Set
max_orders_per_minute=5. A runaway loop that tries to fire ten orders in a burst gets stopped at the broker wrapper. - Set
allowed_assets={"SPY", "QQQ"}. Any attempt to trade an asset outside that set raisesRiskLimitError. - Set
max_drawdown_pct=0.05. If portfolio equity drops 5% from the high-water mark, the kill switch activates and new orders are refused until you clear it. - Leave
shadow_mode=Trueduring the first rollout phase. Orders are recorded and reflected in the virtual portfolio, but the real broker never sees them.
Example Configuration¶
from ml4t.live import LiveRiskConfig
config = LiveRiskConfig(
max_position_value=25_000,
max_position_shares=1_000,
max_total_exposure=50_000,
max_positions=10,
max_order_value=5_000,
max_order_shares=100,
max_orders_per_minute=5,
max_daily_loss=2_000,
max_drawdown_pct=0.05,
dedup_window_seconds=1.0,
allowed_assets={"SPY", "QQQ"},
shadow_mode=True,
)
What A Breach Looks Like¶
from ml4t.live import RiskLimitError
try:
await safe_broker.submit_order_async("SPY", 1_000)
except RiskLimitError as exc:
print(f"order blocked: {exc}")
That failure mode is intentional. In live trading, "do nothing" is often the correct behavior when the request is unsafe.
Broker Comparison¶
| Broker | Asset Classes | Paper Trading | Live Trading | Best fit |
|---|---|---|---|---|
| Alpaca | US equities, ETFs, Alpaca-supported crypto | Yes | Yes | fast setup, developer-friendly paper workflow |
| Interactive Brokers | global equities, options, futures, multi-asset brokerage accounts | Yes | Yes | broader asset coverage and existing IBKR setups |
See Brokers for connection details and usage patterns.
Data Feed Comparison¶
| Data Feed | Source | Market Shape | Best for |
|---|---|---|---|
| AlpacaDataFeed | Alpaca API | bars, quotes, trades | US equities and Alpaca crypto |
| IBDataFeed | TWS / IB Gateway | real-time ticks | IB-driven multi-asset execution |
| DataBentoFeed | DataBento API or DBN replay | tick and bar schemas | replay, validation, institutional futures workflows |
| CryptoFeed | exchange WebSocket via CCXT | trades and candles | exchange-agnostic crypto streaming |
| OKXFundingFeed | OKX public APIs | OHLCV plus funding context | perpetual futures and funding-rate strategies |
Use Data Feeds for examples and feed-specific setup.
Installation¶
Or:
Install databento separately if you want DataBentoFeed.
Documentation Map¶
- Installation for environment setup and broker prerequisites
- Quickstart for the first shadow-mode run
- Backtest to Live for the migration workflow
- Risk Controls for
SafeBrokerand rollout policy - Brokers for Alpaca and IB paths
- Data Feeds for live and replay feed choices
- Book Guide for chapter, notebook, and case-study mapping
- API Reference for exact signatures and public types
From Book To Deployment¶
The book develops strategies through research, diagnostics, and backtesting. ml4t-live takes the
same strategy surface and runs it against real brokers with explicit deployment controls around it.
If you are reading Machine Learning for Trading, Third Edition, the practical sequence is:
- develop and validate the strategy in the book workflow
- map the notebook to reusable APIs in the Book Guide
- port the strategy into
LiveEngine - start in shadow mode under
SafeBroker - promote only after paper-trading and operational checks pass
Part Of The ML4T Library Suite¶
The same Strategy class sits at the handoff between ml4t-backtest and ml4t-live.
Disclaimer¶
This library reduces operational risk but does not remove it. Start in shadow mode, validate order flow and reconciliation carefully, and treat live deployment as a staged process rather than a single switch from backtest to production.