How do I load my own data?
How do I load my own data?
Pass a Column names are case-sensitive. The index must be a
pandas.DataFrame with a DatetimeIndex and columns named Open, High, Low, and Close. A Volume column is optional.DatetimeIndex sorted in ascending order. Any extra columns are accessible inside your strategy via self.data.df.Why does my strategy start trading late?
Why does my strategy start trading late?
Indicators computed over a lookback window produce This is intentional — it prevents look-ahead bias caused by acting on incomplete indicator values. If you have multiple indicators, the warmup period equals the longest one.
NaN values for the first N−1 bars. backtesting.py skips those bars automatically, so next() is only called once all indicators have a valid (non-NaN) value.For example, if you declare an SMA with period 200, next() won’t be called until bar 201:What commission formats are supported?
What commission formats are supported?
The Tuple (fixed + relative): A two-element tuple Callable: A function that receives
commission= parameter of Backtest accepts three formats:Float (relative): A fraction of the trade value applied at both entry and exit.(fixed, relative) where the fixed amount is in cash units.(order_size: int, price: float) and returns the commission in cash units. order_size is negative for short orders.Since version 0.6.0, commission is applied twice per trade — once at entry and once at exit. For a cost applied only at entry (e.g., spread/slippage), use the
spread= parameter instead.How do I trade fractional shares or Bitcoin?
How do I trade fractional shares or Bitcoin?
How do I close only part of a position?
How do I close only part of a position?
Pass a fraction between 0 and 1 to A fraction of
Trade.close() or Position.close().1.0 (the default) closes the full trade or position. You can call close() multiple times to scale out of a position incrementally.How do I avoid look-ahead bias?
How do I avoid look-ahead bias?
Follow the two-method pattern strictly:Never compute indicators directly in
init()— precompute all indicators over the full dataset. This is safe because the framework controls what is visible innext().next()— make all trading decisions. Data arrays grow bar-by-bar here;self.data.Close[-1]is always the current bar’s close, and future data is not accessible.
next() using the full self.data.df — that exposes future values. Always use self.I() in init().Can I use multiple time frames?
Can I use multiple time frames?
Yes. Use The resampled indicator is forward-filled so it has the same length as the base series and is accessible in
backtesting.lib.resample_apply() to compute an indicator on a higher time frame and align it back to the base data. Call it directly inside init() — when called from within a Strategy.init(), it automatically wraps the result in self.I().next() without look-ahead bias.How does commission work?
How does commission work?
Starting in version 0.6.0, commission is applied at both entry and exit. This means a round-trip trade incurs the commission cost twice.Total commissions paid are reported in
stats['Commissions [$]'] and per-trade in the Commission column of stats._trades.If you want to model a spread (cost applied only once at entry), use the spread= parameter:Why is my optimization slow?
Why is my optimization slow?
A few techniques can dramatically speed up Limit tries with Use model-based (SAMBO) optimization for large search spaces:Grid optimization runs in parallel by default using Python’s
Backtest.optimize():Use ranges instead of explicit lists to reduce the parameter space:max_tries=:multiprocessing pool. On Windows, make sure your script has a if __name__ == '__main__': guard to avoid multiprocessing issues:How do I use stop-loss and take-profit?
How do I use stop-loss and take-profit?
Pass You can also set or update them on an existing trade:
sl= (stop-loss) and tp= (take-profit) directly in buy() or sell(). Both are price levels, not distances.When both SL and TP are hit in the same bar, the stop-loss always executes first (as of version 0.6.3).
Does backtesting.py support short selling?
Does backtesting.py support short selling?
Yes. Call Short positions show negative
self.sell() to open a short position. The full Order/Trade/Position API applies equally to short trades.size in stats._trades. P&L is calculated correctly for both long and short sides.What does exclusive_orders=True do?
What does exclusive_orders=True do?
When With this setting, calling
exclusive_orders=True, placing a new buy or sell order automatically closes any open trade in the opposite direction before filling the new order. This simplifies trend-following strategies that should never hold both long and short simultaneously.self.buy() when a short trade is open will close the short and open a long in one step. This matches the behavior of many live trading platforms.Without exclusive_orders=True, you must manage closing existing trades manually before opening new ones in the opposite direction.How do I save the plot without opening a browser?
How do I save the plot without opening a browser?
Pass The output is a self-contained HTML file with the interactive Bokeh chart. This is useful in headless environments, CI pipelines, or when generating reports programmatically.
open_browser=False to Backtest.plot(). You can also specify a custom output file path with filename=.What does hedging=True do?
What does hedging=True do?
By default, backtesting.py closes trades in FIFO (first-in, first-out) order. Setting With hedging enabled, opening a short does not automatically offset an existing long. Both positions are tracked independently, which is useful for strategies that genuinely hold opposing positions at the same time.
hedging=True disables this behavior and allows simultaneous long and short positions.hedging=True and exclusive_orders=True are mutually exclusive — enable only one at a time.What's the difference between spread and commission?
What's the difference between spread and commission?
They model different real-world costs:
Use
| Parameter | Applied at | Typical use |
|---|---|---|
spread= | Entry only | Bid-ask spread, slippage |
commission= | Entry and exit | Broker fee, exchange fee |
spread= for costs that are embedded in the price (you “pay” by crossing the spread), and commission= for explicit fees charged per trade by your broker.