backtrader.strategy module¶
Strategy module - Base class for user-defined trading strategies.
This module provides the Strategy class which serves as the foundation for all user-defined trading strategies in Backtrader. It handles order management, position tracking, indicator integration, and the event-driven execution model.
- Key Features:
Order creation and management (buy, sell, close, cancel)
Position tracking per data feed
Integration with indicators and analyzers
Event notifications (order, trade, data, timer)
Support for multiple data feeds and timeframes
Signal-based trading via SignalStrategy
Example
Basic strategy implementation:
import backtrader as bt
class MyStrategy(bt.Strategy):
params = (('period', 20),)
def __init__(self):
self.sma = bt.indicators.SMA(period=self.p.period)
def next(self):
if self.data.close[0] > self.sma[0]:
self.buy()
elif self.data.close[0] < self.sma[0]:
self.sell()
- Classes:
Strategy: Main base class for trading strategies. SignalStrategy: Strategy subclass that responds to signal indicators.
- class backtrader.strategy.Strategy[source]¶
Bases:
StrategyBaseBase class for user-defined trading strategies.
This class provides the core functionality for implementing trading strategies including order management, position tracking, and event handling. Users should subclass this to create custom strategies.
- env¶
Reference to the Cerebro environment.
- cerebro¶
Alias for env.
- broker¶
Reference to the broker for order execution.
- datas¶
List of data feeds available to the strategy.
- data¶
Shortcut to the first data feed (datas[0]).
- position¶
Current position for the main data feed.
- stats¶
Collection of observer instances.
- analyzers¶
Collection of analyzer instances.
- Methods to Override:
__init__: Initialize indicators and strategy state. start: Called when the strategy starts running. prenext: Called before minimum period is reached. nextstart: Called once when minimum period is first reached. next: Main strategy logic, called on each bar. stop: Called when the strategy stops running. notify_order: Receive order status notifications. notify_trade: Receive trade notifications. notify_data: Receive data feed notifications. notify_timer: Receive timer notifications.
Example
- class MyStrategy(bt.Strategy):
params = ((‘period’, 20),)
- def __init__(self):
self.sma = bt.indicators.SMA(period=self.p.period)
- def next(self):
- if not self.position:
- if self.data.close[0] > self.sma[0]:
self.buy()
- else:
- if self.data.close[0] < self.sma[0]:
self.close()
- static __new__(cls, *args, **kwargs)[source]¶
Override __new__ to handle method renaming that was done in MetaStrategy
- __init__(*args, **kwargs)¶
- csv = True¶
- log(txt, dt=None, level='info')[source]¶
Log a message with optional datetime.
This method provides basic logging functionality. For comprehensive logging including orders, trades, positions, indicators, and signals, use the TradeLogger observer.
- Parameters:
txt – The message text to log.
dt – Optional datetime. If None, uses current bar datetime.
level – Log level (‘info’, ‘warning’, ‘error’, ‘debug’).
Example
>>> self.log(f'Close price: {self.data.close[0]:.2f}') >>> self.log('Warning message', level='warning')
- qbuffer(savemem=0, replaying=False)[source]¶
Enable the memory saving schemes. Possible values for
savemem:0: No savings. Each line object keeps in memory all values
1: All lines objects save memory, using the strict minimum needed
Negative values are meant to be used when plotting is required:
- -1: Indicators at Strategy Level and Observers do not enable memory
savings (but anything declared below it does)
- -2: Same as -1 plus activation of memory saving for any indicators
which has declared plotinfo.plot as False (will not be plotted)
- prenext_open()[source]¶
Called before next() during prenext phase.
This is a hook for strategies to take action at the open of each bar before minimum period is reached.
- nextstart_open()[source]¶
Called at the open of the first bar where minimum period is satisfied.
This is called only once, transitioning from prenext to next phase.
- next_open()[source]¶
Called at the open of each bar during normal execution.
This is a hook for strategies to take action at the open of each bar.
- start()[source]¶
Called right before the backtesting is about to be started.
This is a hook for strategies to perform initialization before the backtesting loop begins.
- getwriterheaders()[source]¶
Get the CSV headers for writer output.
- Returns:
Headers including indicator/observer names and line aliases
- Return type:
- getwritervalues()[source]¶
Get current values for writer output.
- Returns:
Current values from indicators and observers
- Return type:
- getwriterinfo()[source]¶
Get comprehensive writer information including params and analysis.
- Returns:
- Nested structure containing params, indicators,
observers, and analyzer results
- Return type:
- stop()[source]¶
Called right before the backtesting is about to be stopped.
This is a hook for strategies to perform cleanup or final logging.
- set_tradehistory(onoff=True)[source]¶
Enable or disable trade history tracking.
- Parameters:
onoff – If True, keep full trade history; if False, only track current trade
- clear()[source]¶
Clear pending orders and trades.
Moves pending orders to _orders list and clears pending trades.
- add_timer(when, offset=datetime.timedelta(0), repeat=datetime.timedelta(0), weekdays=[], weekcarry=False, monthdays=[], monthcarry=True, allow=None, tzdata=None, cheat=False, *args, **kwargs)[source]¶
Schedule a timer to invoke notify_timer or a callback.
Note: Can be called during __init__ or start
Schedules a timer to invoke either a specified callback or the notify_timer of one or more strategies.
- Parameters:
when – Can be: - datetime.time instance (see tzdata below) - bt.timer.SESSION_START to reference session start - bt.timer.SESSION_END to reference session end
offset (datetime.timedelta) – Offset the when value. Used with SESSION_START/SESSION_END to trigger after session start/end.
repeat (datetime.timedelta) – If set, timer repeats at this interval within the same session. Resets to original when after session end.
weekdays (list) – Sorted iterable with integers (Monday=1, Sunday=7) indicating which days the timer can be invoked. Empty = all days.
weekcarry (bool) – If True and weekday not seen (e.g., holiday), execute on next day (even if in new week).
monthdays (list) – Sorted iterable with integers (1-31) indicating which days of month to execute. Empty = all days.
monthcarry (bool) – If True and day not seen (weekend, holiday), execute on next available day.
allow (callable) – Callback receiving datetime.date, returns True if date is allowed for timer execution.
tzdata – Timezone data - None, pytz instance, or data feed instance. If None and when is SESSION_START/END, uses first data feed.
cheat (bool) – If True, timer called before broker evaluates orders, allowing orders based on opening price.
*args – Additional args passed to notify_timer
**kwargs – Additional kwargs passed to notify_timer
- Returns:
The created timer instance
- notify_timer(timer, when, *args, **kwargs)[source]¶
Receive timer notifications.
Receives a timer notification where
timeris the timer instance returned byadd_timer, andwhenis the calling time.argsandkwargsare any additional arguments passed toadd_timer.The actual
whentime can be later than expected, as the system may not have been able to call the timer before. This value is the timer’s scheduled time, not the actual system time.- Parameters:
timer – The timer instance created by add_timer
when – The scheduled time when the timer was triggered
*args – Additional positional arguments passed to add_timer
**kwargs – Additional keyword arguments passed to add_timer
- notify_cashvalue(cash, value)[source]¶
Notify the current cash and value of the strategy’s broker.
- Parameters:
cash – Current cash amount
value – Current portfolio value
- notify_fund(cash, value, fundvalue, shares)[source]¶
Notify the current cash, value, fund value, and fund shares.
- Parameters:
cash – Current cash amount
value – Current portfolio value
fundvalue – Current fund value
shares – Current fund shares
- notify_order(order)[source]¶
Receive notification when an order status changes.
- Parameters:
order – The order with changed status
- notify_trade(trade)[source]¶
Receive notification when a trade status changes.
- Parameters:
trade – The trade with changed status
- notify_store(msg, *args, **kwargs)[source]¶
Receive notification from a store provider.
- Parameters:
msg – Message from the store
*args – Additional positional arguments
**kwargs – Additional keyword arguments
- notify_data(data, status, *args, **kwargs)[source]¶
Receive notification from a data feed.
- Parameters:
data – The data feed sending the notification
status – Status code
*args – Additional positional arguments
**kwargs – Additional keyword arguments
- notify_tick(tick)[source]¶
Called when a new tick event arrives.
Override this method to implement tick-level trading logic.
- Parameters:
tick – TickEvent instance with price, volume, direction, etc.
- notify_orderbook(orderbook)[source]¶
Called when a new order book snapshot arrives.
Override this method to implement orderbook-based trading logic.
- Parameters:
orderbook – OrderBookSnapshot instance with bids, asks, spread, etc.
- notify_funding(funding)[source]¶
Called when a new funding rate event arrives.
Override this method to implement funding rate arbitrage or position management.
- Parameters:
funding – FundingEvent instance with rate, mark_price, etc.
- notify_bar(bar)[source]¶
Called when a bar event arrives from the channel system.
This is different from the standard next() method which processes bars from LineSeries data feeds. This callback handles BarEvents from the channel/queue system.
- Parameters:
bar – BarEvent instance with open, high, low, close, volume.
- get_last_tick(symbol=None)[source]¶
Get the last tick for a symbol.
- Parameters:
symbol – Symbol name. If None, returns first available.
- Returns:
TickEvent or None.
- get_last_orderbook(symbol=None)[source]¶
Get the last order book for a symbol.
- Parameters:
symbol – Symbol name. If None, returns first available.
- Returns:
OrderBookSnapshot or None.
- get_last_funding(symbol=None)[source]¶
Get the last funding rate for a symbol.
- Parameters:
symbol – Symbol name. If None, returns first available.
- Returns:
FundingEvent or None.
- getdatanames()[source]¶
Get a list of all data names in the system.
- Returns:
Names of all data feeds
- Return type:
- getdatabyname(name)[source]¶
Get a data feed by its name.
- Parameters:
name – Name of the data feed
- Returns:
The data feed with the given name
- buy(data=None, size=None, price=None, plimit=None, exectype=None, valid=None, tradeid=0, oco=None, trailamount=None, trailpercent=None, parent=None, transmit=True, **kwargs)[source]¶
Create a buy (long) order and send it to the broker.
- Parameters:
data – The data feed for the order. If None, uses the first data feed (self.data).
size – Size to use (positive) for the order. If None, the sizer instance retrieved via getsizer will determine the size.
price – Price to use. None is valid for Market and Close orders. For Limit, Stop and StopLimit orders this determines the trigger point.
plimit – Only applicable to StopLimit orders. This is the price at which to set the implicit Limit order, once the Stop has been triggered.
trailamount – For StopTrail/StopTrailLimit orders, an absolute amount which determines the distance to the price to keep the trailing stop.
trailpercent – For StopTrail/StopTrailLimit orders, a percentage amount which determines the distance to the price to keep the trailing stop.
exectype – Execution type. Possible values: - Order.Market or None: Market order - Order.Limit: Limit order - Order.Stop: Stop order - Order.StopLimit: Stop-limit order - Order.Close: Close order - Order.StopTrail: Stop-trail order - Order.StopTrailLimit: Stop-trail-limit order
valid – Order validity. Possible values: - None: Good till cancel - datetime.datetime/date: Good till date - Order.DAY: Day order
tradeid – Internal value to track overlapping trades.
oco – Another order instance for OCO (Order Cancel Others) group.
parent – Controls the relationship of a group of orders (e.g., bracket orders).
transmit – If True, transmit the order to the broker. Used for controlling bracket orders.
**kwargs – Additional broker-specific parameters.
- Returns:
The submitted order, or None if size is 0.
Example
Create a market buy order: >>> order = self.buy()
Create a limit buy order: >>> order = self.buy(price=100.0, exectype=Order.Limit)
- sell(data=None, size=None, price=None, plimit=None, exectype=None, valid=None, tradeid=0, oco=None, trailamount=None, trailpercent=None, parent=None, transmit=True, **kwargs)[source]¶
Create a sell (short) order and send it to the broker.
See the documentation for
buyfor an explanation of the parameters.- Returns:
The submitted order, or None if no order was created
- close(data=None, size=None, **kwargs)[source]¶
Close a long or short position.
Creates an order that counters the existing position to close it.
- Parameters:
data – The data feed for which to close the position. If None, uses the default data feed.
size – The size to close. If None, closes the entire position.
**kwargs – Additional keyword arguments passed to the order.
Note
If size is not provided, it is automatically calculated from the existing position to fully close it.
- Returns:
The submitted order, or None if no position exists
- buy_bracket(data=None, size=None, price=None, plimit=None, exectype=2, valid=None, tradeid=0, trailamount=None, trailpercent=None, oargs={}, stopprice=None, stopexec=3, stopargs={}, limitprice=None, limitexec=2, limitargs={}, **kwargs)[source]¶
Create a bracket order group (buy order with stop-loss and take-profit).
- Creates a bracket order group consisting of:
A main buy order with the specified execution type (default: Limit)
A low side bracket sell stop-loss order
A high side bracket sell take-profit order
- Parameters:
(default (- limitargs) –
None): The data feed for the order. If None, uses the first data feed (self.data).(default –
None): Size for the order. If None, the sizer determines the size. The same size is applied to all three orders.(default –
None): Price for the main buy order. None is valid for Market and Close orders.(default –
None): Price limit for StopLimit orders.(default –
None): Absolute trailing amount for StopTrail/StopTrailLimit orders.(default –
None): Percentage trailing amount for StopTrail/StopTrailLimit orders.(default –
bt.Order.Limit): Execution type for the main order. See buy() documentation for possible values.(default –
None): Order validity period. See buy() documentation for possible values.(default –
0): Trade ID for tracking overlapping trades.(default –
{}): Specific keyword arguments (dict) for the main side order. Applied before **kwargs.**kwargs (-) – Additional keyword arguments applied to all three orders. See buy() documentation for possible values.
(default –
None): Specific price for the stop-loss order.(default –
bt.Order.Stop): Execution type for the stop-loss order.(default –
{}): Specific keyword arguments (dict) for the stop-loss order.(default –
None): Specific price for the take-profit order.(default –
bt.Order.Limit): Execution type for the take-profit order.(default –
{}): Specific keyword arguments (dict) for the take-profit order.
- Returns:
A list containing the three orders [main_order, stop_order, limit_order]. Suppressed orders are represented as None.
Note
High/Low side orders can be suppressed by setting limitexec=None or stopexec=None.
- sell_bracket(data=None, size=None, price=None, plimit=None, exectype=2, valid=None, tradeid=0, trailamount=None, trailpercent=None, oargs={}, stopprice=None, stopexec=3, stopargs={}, limitprice=None, limitexec=2, limitargs={}, **kwargs)[source]¶
Create a sell bracket order group (sell order with stop-loss and take-profit).
- Creates a bracket order group consisting of:
A main sell order with the specified execution type (default: Limit)
A high side bracket buy stop-loss order
A low side bracket buy take-profit order
- Parameters:
documentation. (See buy_bracket() for parameter)
- Returns:
A list containing the three orders [main_order, stop_order, limit_order]. Suppressed orders are represented as None.
Note
High/Low side orders can be suppressed by setting limitexec=None or stopexec=None.
- order_target_size(data=None, target=0, **kwargs)[source]¶
Place an order to achieve a target position size.
Rebalances the current position to reach the specified target size.
- Parameters:
data – The data feed for the order. If None, uses the default data feed.
target – Target position size. - If target > pos.size: buy (target - pos.size) - If target < pos.size: sell (pos.size - target) - If target == 0: close the entire position
**kwargs – Additional keyword arguments passed to buy/sell.
- Returns:
The generated order, or None if target == current position size.
- order_target_value(data=None, target=0.0, price=None, **kwargs)[source]¶
Place an order to achieve a target position value.
Rebalances the position to reach the specified target value.
- Parameters:
data – The data feed for the order. If None, uses the default data feed.
target – Target position value in currency units. - If target is 0: close position - If target > value: buy to increase value - If target < value: sell to decrease value
price – Price for size calculation. If None, uses data.close[0].
**kwargs – Additional keyword arguments passed to buy/sell.
- Returns:
The generated order, or None if no order was issued.
- order_target_percent(data=None, target=0.0, **kwargs)[source]¶
Place an order to achieve a target percentage of portfolio value.
Rebalances the position so its value equals the target percentage of the total portfolio value.
- Parameters:
data – The data feed for the order. If None, uses the default data feed.
target – Target percentage as a decimal (e.g., 0.05 for 5%).
**kwargs – Additional keyword arguments passed to order_target_value.
- Returns:
The generated order, or None if no order was issued.
Example
With target=0.05 and portfolio value of 100: - Target value = 0.05 * 100 = 5 - Orders are placed through order_target_value
Note
Position direction (long/short) is considered: - If target > value: buy if pos.size >= 0, sell if pos.size < 0 - If target < value: sell if pos.size >= 0, buy if pos.size < 0
- getposition(data=None, broker=None)[source]¶
Get the current position for a data feed.
- Parameters:
data – The data feed to get position for. If None, uses the first data feed.
broker – The broker to query. If None, uses the default broker.
- Returns:
The current Position object.
Note
A property
positionis also available as a shortcut.
- property position¶
Get the current position for a data feed.
- Parameters:
data – The data feed to get position for. If None, uses the first data feed.
broker – The broker to query. If None, uses the default broker.
- Returns:
The current Position object.
Note
A property
positionis also available as a shortcut.
- getpositionbyname(name=None, broker=None)[source]¶
Get the current position for a data feed by name.
- Parameters:
name – Name of the data feed. If None, uses the first data feed.
broker – The broker to query. If None, uses the default broker.
- Returns:
The current Position object.
Note
A property
positionbynameis also available as a shortcut.
- property positionbyname¶
Get the current position for a data feed by name.
- Parameters:
name – Name of the data feed. If None, uses the first data feed.
broker – The broker to query. If None, uses the default broker.
- Returns:
The current Position object.
Note
A property
positionbynameis also available as a shortcut.
- getpositions(broker=None)[source]¶
Get all positions from the broker.
- Parameters:
broker – The broker to query. If None, uses the default broker.
- Returns:
Dictionary mapping data feeds to Position objects.
Note
A property
positionsis also available as a shortcut.
- property positions¶
Get all positions from the broker.
- Parameters:
broker – The broker to query. If None, uses the default broker.
- Returns:
Dictionary mapping data feeds to Position objects.
Note
A property
positionsis also available as a shortcut.
- getpositionsbyname(broker=None)[source]¶
Get all positions from the broker indexed by data name.
- Parameters:
broker – The broker to query. If None, uses the default broker.
- Returns:
OrderedDict mapping data names to Position objects.
Note
A property
positionsbynameis also available as a shortcut.
- property positionsbyname¶
Get all positions from the broker indexed by data name.
- Parameters:
broker – The broker to query. If None, uses the default broker.
- Returns:
OrderedDict mapping data names to Position objects.
Note
A property
positionsbynameis also available as a shortcut.
- setsizer(sizer)[source]¶
Set the sizer for automatic stake calculation.
- Parameters:
sizer – The sizer instance to use
- Returns:
The sizer instance
- getsizer()[source]¶
Get the current sizer for automatic stake calculation.
- Returns:
The current sizer instance
Note
Also available as the
sizerproperty.
- property sizer¶
Get the current sizer for automatic stake calculation.
- Returns:
The current sizer instance
Note
Also available as the
sizerproperty.
- getsizing(data=None, isbuy=True)[source]¶
Get the order size from the sizer.
Uses the configured sizer to calculate the appropriate stake size for the next order.
- Parameters:
data – The data feed for the order. If None, uses the default data.
isbuy – True for buy orders, False for sell orders.
- Returns:
The calculated stake size.
- frompackages = ()¶
- packages = ()¶
- class backtrader.strategy.SignalStrategy[source]¶
Bases:
StrategyA strategy subclass that automatically operates using signals.
This strategy subclass responds to signal indicators to automatically enter and exit positions based on signal values.
- Signal values:
> 0indicates a long (buy) signal< 0indicates a short (sell) signal
There are five types of signals, broken into two groups:
Main Group:
LONGSHORT: Both long and short indications from this signal are taken. The strategy will go long or short based on the sign.LONG: - Positive (long) indications: Go long - Negative (short) indications: Close long positionIf
LONGEXITexists, it is used to exit longsIf
SHORTsignal exists and noLONGEXIT, it will close longs before opening a short
SHORT: - Negative (short) indications: Go short - Positive (long) indications: Close short positionIf
SHORTEXITexists, it is used to exit shortsIf
LONGsignal exists and noSHORTEXIT, it will close shorts before opening a long
- Exit Group:
These signals override others to provide explicit exit criteria:
LONGEXIT: Negative indications are taken to exit long positionsSHORTEXIT: Positive indications are taken to exit short positions
Order Issuing
Orders are placed with Market execution type and Good-Until-Canceled validity.
Params:
signals(default:[]): A list/tuple of lists/tuples for signal instantiation and type allocation. This parameter is typically managed throughcerebro.add_signal._accumulate(default:False): Allow entering the market even if already in a position (accumulate positions)._concurrent(default:False): Allow issuing orders even when orders are already pending execution._data(default:None): If multiple datas are present in the system which is the target for orders. This can beNone: The first data in the system will be usedAn
int: indicating the data that was inserted at that positionAn
str: name given to the data when creating it (parametername) or when adding it cerebro withcerebro.adddata(..., name=)A
datainstance
- static __new__(cls, *args, **kwargs)[source]¶
Override __new__ to handle next method remapping that was done in MetaSigStrategy
- __init__(*args, **kwargs)¶
- signal_add(sigtype, signal)[source]¶
Add a signal indicator to the strategy.
- Parameters:
sigtype – Type of signal (e.g., SIGNAL_LONG, SIGNAL_SHORT)
signal – The signal indicator instance
- frompackages = ()¶
- packages = ()¶
- class backtrader.strategy.BtApiStrategy[source]¶
Bases:
StrategyA Strategy subclass with built-in logging capabilities.
This strategy class extends the base Strategy class with automatic logger initialization using the SpdLogManager. It provides a default log() method for logging messages and custom notification handling.
- logger¶
The configured logger instance from SpdLogManager.
- Params:
- log_file_name: Optional custom log file name. If not provided,
defaults to “{ClassName}.log”.
Example
- class MyStrategy(bt.BtApiStrategy):
params = ((‘log_file_name’, ‘my_strategy.log’),)
- def next(self):
self.log(f’Close price: {self.data.close[0]:.2f}’)
- frompackages = ()¶
- packages = ()¶
- __init__(*args, **kwargs)¶
- init_logger(log_file_name=None)[source]¶
Initialize and return a logger instance.
Creates a logger using SpdLogManager with the specified or default log file name.
- Parameters:
log_file_name – Optional custom log file name. If None, uses “{ClassName}.log” as the default.
- Returns:
A configured logger instance.