Home / Libraries / ML4T Live / Docs
ML4T Live
ML4T Live Documentation
Production trading with broker integrations
Skip to content

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 from ml4t-backtest. LiveEngine handles 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.Strategy and run it in LiveEngine
  • connect that strategy to Alpaca or Interactive Brokers
  • replay or stream data through a live-style feed interface
  • start in shadow_mode=True so 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=100 and max_order_value=5_000. SafeBroker rejects any single order that would exceed 100 shares or $5,000 notional.
  • Set max_position_value=25_000 and max_total_exposure=50_000. SafeBroker blocks 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 raises RiskLimitError.
  • 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=True during 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

uv add ml4t-live

Or:

pip install ml4t-live

Install databento separately if you want DataBentoFeed.

Documentation Map

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:

  1. develop and validate the strategy in the book workflow
  2. map the notebook to reusable APIs in the Book Guide
  3. port the strategy into LiveEngine
  4. start in shadow mode under SafeBroker
  5. promote only after paper-trading and operational checks pass

Part Of The ML4T Library Suite

ml4t-data -> ml4t-engineer -> ml4t-diagnostic -> ml4t-backtest -> ml4t-live

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.