Loading data¶
A Backtest accepts any pd.DataFrame (single-asset) or
dict[str, pd.DataFrame] (multi-asset) as long as the index is a
DatetimeIndex and the columns include Open, High, Low, Close (Volume is
nice-to-have). You can build that yourself from a CSV / database / API,
but for the common cases QTrade ships two loaders.
US markets — from_yfinance¶
Install the [data] extra:
pip install "qtrade-lib[data]"
from qtrade.data import from_yfinance
data = from_yfinance(
["AAPL", "MSFT", "GC=F"], # one ticker or a list
start="2023-01-01",
end="2024-12-31",
interval="1d", # "1h", "5m", etc. all supported
auto_adjust=True, # split / dividend adjusted closes
)
# data is a dict[str, DataFrame] aligned on the intersection of indexes
# — pass straight to Backtest.
What the helper does for you:
Loops over symbols, raises a clean
ValueErrorif any returned empty.Drops
NaNrows from each frame (yfinance occasionally returns them on early-listing dates).Aligns every frame on the intersection of their
DatetimeIndexsoBacktestaccepts them as a multi-asset input.
Aligning external data¶
If you've assembled dict[str, DataFrame] yourself (e.g. from a CSV folder)
and the indexes don't perfectly match, run:
from qtrade.data import align_indexes
data = align_indexes(data)
align_indexes reindexes every frame on the intersection of their indexes
— a no-op when they already match, a one-liner when they don't.
Other data sources¶
The two helpers here are convenience wrappers, not framework constraints.
For Tushare, JoinQuant, IB, or your own pipeline, just produce a
dict[str, DataFrame] (each indexed by datetime, OHLC capitalized) and
hand it to Backtest. If the indexes aren't aligned, align_indexes
takes care of it.