Lumibot: backtestable AI trading agents and Python strategies
Backtestable AI trading agents and Python algorithmic trading strategies for stocks, options, crypto, futures, forex, SEC filings, FRED macro data, and real brokers.
At a glance
- What is it?
- Lumibot is a Python framework that runs the same strategy class in a Yahoo-data backtest, an Alpaca paper account, or an AI agent loop. The docs are strong on the happy path and quiet on the parts that decide whether you can ship.
- Who is it for?
- Adopt Lumibot if you already write Python and want one Strategy class that survives the trip from a YahooDataBacktesting run to an Alpaca paper account, with optional LLM agents layered on top.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Lumibot solves, and who it is actually for
Most retail trading code dies at the boundary between research and execution. You write a pandas script that looks fine on a CSV, then rewrite it as a broker adapter, then discover the two versions disagree about fill timing, position sizing and order state. Lumibot's answer is to make the strategy class the unit of work. The README states that the same strategy code is reused for backtests, paper trading and live trading, and the quick start demonstrates exactly that: a MyStrategy class is defined once, backtested against Yahoo data, and then handed to an Alpaca broker runner with only the runner block changed.
The intended audience is a Python developer who already understands orders and indicators, not someone looking for a no-code bot. The requirements file pulls in pandas, numpy, polars, scipy, pandas-ta-classic, quantstats-lumi, ccxt, alpaca-py, ibapi, polygon-api-client, databento and duckdb. That is a quant workstation expressed as a dependency list. If you are not comfortable reading a stack trace out of a broker adapter, the abstraction will cost you more than it saves.
The second audience is newer and more contested: people who want an LLM in the loop. The README describes a built-in AI agent runtime where agents inspect market data, read filings, query indicators, search memory and submit orders through the same strategy loop. That is a much harder promise than a backtest runner, because agent behaviour is not reproducible in the way a moving-average crossover is.
The Strategy loop and the broker abstraction underneath it
The mechanism visible in the README is a lifecycle method. A Strategy subclass implements on_trading_iteration, and the framework calls it repeatedly. Inside that method you call self.create_order(symbol, quantity, side) and self.submit_order(order). The README's example uses self.first_iteration as a guard so the order is placed once rather than on every iteration, which tells you the loop runs far more often than the trade logic does.
The same class is then constructed with a broker object. In the paper-trading example, Alpaca is instantiated with a config dict containing API_KEY, API_SECRET and PAPER, the strategy is built as MyStrategy(broker=broker), and a Trader object collects strategies via add_strategy and runs them via run_all. That is the whole live path: strategy, broker, trader. Data sources and brokers are pluggable behind those interfaces, which is why the dependency list can carry Yahoo, Alpaca, Interactive Brokers, Polygon, Databento, Tradier, Schwab and ccxt at once.
The AI layer sits on top rather than beside it. The README describes agents as having tools: market and account state, order inspection, DuckDB queries, documentation search, Alpaca news when credentials exist, technical indicators, SEC fundamentals and filings, FRED macro data, local memory and Telegram notifications. A multi-agent pattern is described as a research agent building an evidence pack, bull and bear agents arguing, and a trader agent checking cash, positions, open orders and risk limits before deciding. The README calls the hybrid case out explicitly: Python handles hard gates, agents reason through evidence. That framing is the honest one, and it is also a warning. An agent that reasons is not an agent that is testable.
How to install Lumibot and run a first backtest
The README gives a two-step quick start. Install from PyPI, then save a strategy file and run it. The install is a single package; the dependency tree that comes with it is large, so expect a slow first resolution.
pip install lumibotThe strategy file below is the README's own example. It buys 10 shares of AAPL on the first iteration and backtests from 2023-01-01 to 2024-01-01 using YahooDataBacktesting.
from datetime import datetime
from lumibot.strategies import Strategy
from lumibot.backtesting import YahooDataBacktesting
class MyStrategy(Strategy):
def on_trading_iteration(self):
if self.first_iteration:
aapl = self.create_order("AAPL", 10, "buy")
self.submit_order(aapl)
MyStrategy.backtest(
YahooDataBacktesting,
datetime(2023, 1, 1),
datetime(2024, 1, 1),
)Run it with python my_strategy.py. What you should see is a backtest run that prints performance output; the README does not specify the exact report format, so treat the console output as something to read rather than something to parse.
Moving to paper trading keeps the class and replaces the final backtest call with a broker runner. The README sets credentials as environment variables and reads them back through os.environ, which keeps keys out of the source file.
export ALPACA_API_KEY='your-alpaca-key'
export ALPACA_API_SECRET='your-alpaca-secret'
export ALPACA_IS_PAPER=true
python my_strategy.pyimport os
from lumibot.brokers import Alpaca
from lumibot.traders import Trader
ALPACA_CONFIG = {
"API_KEY": os.environ["ALPACA_API_KEY"],
"API_SECRET": os.environ["ALPACA_API_SECRET"],
"PAPER": os.environ.get("ALPACA_IS_PAPER", "true").lower() != "false",
}
broker = Alpaca(ALPACA_CONFIG)
strategy = MyStrategy(broker=broker)
trader = Trader()
trader.add_strategy(strategy)
trader.run_all()The README is explicit that you should start with paper trading and switch the account configuration intentionally when going live. There is no separate live-trading code path to write, which is the point of the design and also the risk: a config flag is the only thing between a backtest-shaped strategy and real money.
Where the AI agent runtime changes the testing story
The AI trading team example is the part of the repository that will draw the most attention and deserves the most scepticism. The README describes a research agent, a bull agent, a bear agent and a trader agent, and gives a runnable file, ai_trading_team_bull_bear_leveraged_etf.py, driven by a GEMINI_API_KEY plus the Alpaca credentials. The README notes the example uses Gemini Flash Lite because it is fast and inexpensive for experiments, and that flipping IS_BACKTESTING from False to True runs the same strategy as a backtest.
That flip is the interesting claim. A deterministic strategy backtest is reproducible: same data, same code, same result. An agent that reasons over an evidence pack introduces model nondeterminism, prompt sensitivity and API latency into the trading loop. The repository does carry agent_eval_baselines, agent_eval_cases and agent_eval_fixtures directories at the top level, which suggests the maintainers treat agent behaviour as something to evaluate rather than eyeball. The README itself does not describe how those evaluations are scored or what a passing baseline looks like, so you cannot conclude from the file layout alone that agent outputs are stable across runs.
Practically, the hybrid framing is the one to adopt. Put deterministic gates in Python: position size limits, maximum daily loss, symbol allowlists, order-type restrictions. Let agents produce evidence and argument, and let the Python gate decide whether the trade is permitted. An agent that both argues and executes has no independent check on itself.
Limitations, failure modes, and the licence mismatch
Three things stand out as real constraints rather than caveats.
First, the licence is not clean. The repository metadata and the LICENSE file point to GPL-3.0, while the README's own badge reads License: MIT and links to the LICENSE file. Those cannot both be right. If you plan to embed Lumibot in a closed-source product, resolve that before you write code, because the two answers imply very different obligations. This article is not legal advice; the point is that the primary source contradicts itself and you should read the actual LICENSE file rather than the badge.
Second, the interpreter floor is old and the ceiling is unstated. pyproject.toml sets target-version = "py38" for type annotations, and requirements.txt pins setuptools<81 and numpy>=1.20.0,<2.5.0. A project that supports 3.8 in 2026 is carrying compatibility weight, and the README does not state which Python versions are actually tested in CI. If your environment is on a recent interpreter, verify before assuming.
Third, the upgrade path is undocumented. Releases arrive frequently (v4.5.91 on 2026-09-06, v4.5.90 on 2026-09-04, v4.5.88 on 2026-09-01), and a fast patch cadence on a library that touches broker APIs means behaviour can shift between minor versions. The README does not document rollback, deprecation policy or version pinning strategy, and CHANGELOG.md exists in the repository but its contents are not shown here. Pin the version you deploy and read the changelog yourself.
The wrong-tool case is equally clear. If you want a hosted bot with a web dashboard and no code, Lumibot is the wrong layer; the README points to a managed cloud product for that. If you need tick-level microstructure simulation with queue position modelling, the README does not claim that level of fidelity. And if your strategy depends on a data source outside the documented tool list, you are writing the adapter.
Lumibot compared with Backtrader and vectorbt
The closest comparison in the Python world is Backtrader, and the difference is architectural rather than cosmetic. Backtrader is a backtesting engine with a broker simulation at its centre; live trading is bolted on through separate stores and feeds, and each broker needs its own integration. Lumibot inverts that: the broker is a first-class object passed into the strategy constructor, and backtesting is one implementation among several. The README's quick start makes the inversion visible, because the same MyStrategy is constructed with an Alpaca broker without touching the class body.
vectorbt takes a third position. It is built around vectorised array computation over pandas and numpy, which makes parameter sweeps across thousands of configurations practical, but it is not a live-trading framework and does not model an order lifecycle against a broker. If your question is which of ten thousand parameter sets survived 2015 to 2024, vectorbt is the better tool. If your question is whether the code you just validated can place an order at Alpaca tomorrow morning, that is Lumibot's problem to solve.
The honest summary is that Lumibot trades simulation depth for deployment continuity. You get one code path from backtest to broker, and you pay for it with an abstraction layer between you and the order book, plus a dependency list that includes ibapi, ccxt, alpaca-py and databento simultaneously.
Maintenance, upgrade cost, and what the repository shows
The repository is not archived, and the last push was on 2026-09-09, nine days before this writing. Releases are frequent: v4.5.88 on 2026-09-01, v4.5.90 on 2026-09-04, v4.5.91 on 2026-09-06. A CI workflow exists at .github/workflows/cicd.yaml and the README carries CI and coverage badges, so there is automated testing in place, though the README does not state what the coverage threshold is.
The upgrade cost is the practical concern. A library whose dependencies include a pinned ibapi==9.81.1.post1, a bounded litellm>=1.83.7,<=1.83.14, and google-adk[extensions]>=2.1.0,<3.0.0 will occasionally be held back by one of those pins rather than by Lumibot itself. When a broker changes an API, you wait for Lumibot to ship, and the release cadence suggests that happens quickly, but the README documents no support window or deprecation schedule.
On licence implications: the GPL-3.0 identifier in the repository metadata and the MIT badge in the README point in different directions, and the README does not explain the discrepancy. GPL-3.0 carries copyleft obligations that matter if you distribute a derivative work; MIT does not. Read the LICENSE file at the repository root and get your own answer before you build a product on top of this.
Editorial conclusion
Adopt Lumibot if you already write Python and want one Strategy class that survives the trip from a YahooDataBacktesting run to an Alpaca paper account, with optional LLM agents layered on top. Do not adopt it if you need a documented upgrade or rollback procedure, an officially supported Python 3.13 interpreter, or a permissive licence for a closed-source product; the README documents none of those, the pyproject targets py38, and the LICENSE file and the README badge disagree on GPL-3.0 versus MIT. Before writing strategy logic, install it, run the README's MyStrategy backtest, and confirm the fill prices and commissions your backtest produces against a broker statement for the same period.
Frequently asked questions
How do I install Lumibot?
The README's quick start installs it from PyPI with pip install lumibot, then has you save a strategy file and run it with python. The full documentation at lumibot.lumiwealth.com covers broker setup and deployment notes.
How do I use Lumibot to backtest a strategy?
Subclass Strategy, implement on_trading_iteration, and call MyStrategy.backtest(YahooDataBacktesting, start, end) with two datetime bounds. The README's example places a single AAPL buy order on self.first_iteration.
Is Lumibot free?
The source is published under GPL-3.0 according to the repository metadata, so you can install it from PyPI at no cost. The README also links to a separate managed cloud product, BotSpot.trade, which is a distinct offering from the open-source library.
What are alternatives to Lumibot?
Backtrader centres on a backtesting engine with broker simulation and adds live trading through separate integrations, while vectorbt is built for vectorised parameter sweeps and does not model a live order lifecycle. Lumibot's difference is that the broker is passed into the strategy constructor, so the same class runs in backtest and live.
Do AI trading bots really work?
The README does not make a performance claim about agent strategies, and no results are reported. It describes the agent runtime as a way to reason over evidence, and recommends a hybrid where Python handles hard gates and agents reason through evidence.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/lumiwealth-lumibot)