algorithmic trading · python · live execution
// no more wait
.. just await
How the Zipline ecosystem evolved toward asynchronous live trading — and why a single keyword in front of every function call turns out to be the answer we were all circling around.
I spent several years on Quantopian. Writing strategies, running backtests, staring at equity curves — convincing myself I was ready for the real market. When the platform shut down in 2020, like many others I went looking for what came next. What I found was a rich, earnest, sometimes frustrating ecosystem of forks, each one trying to answer the same question: how do you keep the Quantopian-style API and actually trade live with it?
I worked through most of them. Each taught me something. And each one, in its own way, kept running into the same wall.
The ecosystem
The history of Zipline forks is one of the better illustrations of how genuinely hard it is to bridge backtesting and live execution in a single framework. Each project found its own angle, and each one contributed something real to the community.
zipline-live archived
One of the earliest forks to seriously pursue live trading — connecting Zipline to Interactive Brokers via the TWS API. A genuine pioneer: it proved the concept was workable and gave the community its first real taste of Zipline-compatible live execution. The authors worked within the existing synchronous core, bridging real-time broker data through threading. The project is no longer maintained, but as a proof of concept for its time it pointed the way for everything that came after.
zipline-reloaded maintained
Perhaps the most honest project in this list — and I mean that as a genuine compliment.
zipline-reloaded staked out a clear lane: keep the original Zipline alive and
working on modern Python, with up-to-date dependencies. No live trading promises, no overreach. If you need
reliable backtesting with a familiar API, this is a strong, well-maintained choice. It knows exactly what it is.
zipline-trader low activity
A meaningful step forward: Python 3, Alpaca support, extended calendars for crypto markets. The authors did real work modernising the stack and gave the community a usable tool for getting first live strategies off the ground. Broker integration relied on polling in a separate thread — a pragmatic choice within the constraints of the existing architecture. Activity has quieted down since, but the project left a visible mark and likely helped many people execute their first live trade.
zipline-live
open source · archived
The original pioneer. Proved live trading was possible in a Zipline-compatible API. IB via TWS.
zipline-reloaded
open source · active
Backtesting only, done well. Modern Python, active maintenance, honest scope.
zipline-trader
open source · low activity
Python 3, Alpaca, crypto calendars. Got people to their first live execution.
Ziplime
open source · active
async core. await everywhere. The broker
is part of the architecture from day one.
→ github
These projects form a lineage, not a competition. Ziplime stands on the shoulders of the work done before it —
without zipline-live and
zipline-trader mapping the terrain, it would have been much harder to see
exactly where the architectural ceiling was.
Where the ceiling is
Every fork up to Ziplime worked with the same synchronous Zipline core — and that was a reasonable choice. Rewriting the foundation is expensive, breaks backward compatibility, and changes the public contract of every function people had been using for years. Adding a threading wrapper on top is far more practical.
But there is a ceiling to that approach. In production, every familiar call is a network request:
# looks instant in backtest — blocks the thread in live trading df = data.history(assets=[asset], fields=["close"], bar_count=context.long_window) context.asset = context.symbol("AAPL") order_buy = context.order_target_percent(asset=asset, target=1.0, style=MarketOrder())
In a backtest, data comes from disk — everything is instant. In live trading each of these calls can take 50–500 ms waiting on a broker or data provider. Synchronous code blocks the entire thread for that time. With a multi-asset strategy the delays compound on every tick.
Threading addresses part of the problem but introduces its own: shared mutable state, subtle race conditions,
hard-to-reproduce bugs under load. That is the ceiling zipline-live and
zipline-trader ran into — not for lack of effort, but because the constraint
was architectural.
What Ziplime changes
Ziplime took the step the other forks reasonably avoided: it rewrote the core engine for an asynchronous model. Every function that touches I/O became a coroutine — and that is visible directly in the API:
async def handle_data(context, data): # non-blocking — event loop stays free while we wait for the broker df = await data.history( assets=[asset], fields=["close"], bar_count=context.long_window ) context.asset = await context.symbol("AAPL") order_buy = await context.order_target_percent( asset=asset, target=1.0, style=MarketOrder() )
Behind each await is a hand-off to Python's
asyncio event loop. While one coroutine waits for the broker to respond, the
loop can handle other work — processing another asset, listening on a WebSocket feed, writing to a log. No
threading, no shared state, fully deterministic.
In a backtest, await resolves instantly from local storage. In live trading,
the exact same await makes a real network request without blocking anything
else. One strategy file, two execution modes.
Synchronous core
Delays compound across calls. Threading as a workaround. The broker is an external layer grafted onto the engine.
Ziplime: async core
Event loop owns all I/O. Parallel requests via asyncio.gather(). The
broker is a first-class citizen from day one.
For multi-asset strategies this matters significantly. Instead of fetching history for ten instruments
sequentially, you can dispatch all ten requests concurrently with
asyncio.gather() and wait for the slowest one — not the sum of all of them.
Closing
Looking at the Zipline fork ecosystem as a single arc, you see a community steadily working toward something.
zipline-reloaded keeps the original alive.
zipline-live and zipline-trader mapped out
what live trading in this API space looks like — and where it strains.
Ziplime took that accumulated knowledge and asked a different question: what if instead of adapting a synchronous engine to the real market, we designed the engine so the real market felt native to it?
For years we waited for live trading to work properly in Zipline-land. Turns out the
answer was just await.
Open source, actively maintained. Drop a star if the idea resonates — and check the docs to get your first async strategy running.