title: Sizer API description: Complete Sizer class API reference for position sizing
Sizer API¶
Position Sizers determine the size of orders placed during trading. They calculate position sizes based on available cash, risk parameters, and other factors. Backtrader provides several built-in sizers and allows custom sizer development.
Class Definition¶
class backtrader.Sizer:
"""Base class for position sizers."""
```bash
## Parameters
### `params`
Tuple of parameter definitions for the sizer (legacy format).
```python
class MySizer(bt.Sizer):
params = (
('stake', 1),
('percents', 10),
)
```bash
### Modern Parameter Descriptors
New sizers use `ParameterDescriptor` for type-safe parameter definitions:
```python
from backtrader.parameters import Int, ParameterDescriptor
class MySizer(bt.Sizer):
stake = ParameterDescriptor(
default=1,
type_=int,
validator=Int(min_val=1),
doc="Fixed stake size for operations"
)
```bash
## Core Methods
### `__init__(self, **kwargs)`
Initialize the Sizer with parameters.
```python
def __init__(self, **kwargs):
super().__init__(**kwargs)
```bash
### `getsizing(self, data, isbuy)`
Get the position size for an order. This method retrieves commission info and available cash before calling `_getsizing`.
```python
def getsizing(self, data, isbuy):
"""Get the position size for an order.
Args:
data: The target data for the order.
isbuy: True for buy operations, False for sell operations.
Returns:
int: The position size to use for the order.
"""
```bash
### `_getsizing(self, comminfo, cash, data, isbuy)`
Override this method to implement custom sizing logic. This is the main method that determines position size.
```python
def _getsizing(self, comminfo, cash, data, isbuy):
"""Calculate position size for an order.
Args:
comminfo: CommissionInfo instance with commission and margin info
cash: Current available cash in the broker
data: Target data feed for the operation
isbuy: True for buy operations, False for sell operations
Returns:
int: The position size to execute. Returns 0 for no action.
"""
raise NotImplementedError
```bash
### `set(self, strategy, broker)`
Set the strategy and broker references for this sizer.
```python
def set(self, strategy, broker):
"""Set the strategy and broker references.
Args:
strategy: The strategy instance using this sizer.
broker: The broker instance for portfolio information.
"""
```bash
## Built-in Sizers
### FixedSize
Returns a fixed stake size for any operation. Supports tranches for scaling into positions.
```python
import backtrader as bt
cerebro.addsizer(bt.sizers.FixedSize, stake=100)
```bash
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `stake` | int | 1 | Fixed stake size for operations |
| `tranches` | int | 1 | Number of tranches to divide stake into |
```python
# Fixed size of 100 shares
sizer = bt.sizers.FixedSize(stake=100)
# Scale in using 3 tranches
sizer = bt.sizers.FixedSize(stake=300, tranches=3)
# Each order will be 100 shares (300/3)
```bash
### FixedReverser
Returns the fixed size needed to reverse an open position or open a new one.
```python
cerebro.addsizer(bt.sizers.FixedReverser, stake=50)
```bash
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `stake` | int | 1 | Fixed stake size for operations |
Behavior:
- To open a position: returns `stake`
- To reverse a position: returns `2 * stake`
```python
# If current position is 0: returns 50
# If current position is 50 (long): returns 100 (to close 50 and short 50)
sizer = bt.sizers.FixedReverser(stake=50)
```bash
### FixedSizeTarget
Returns a fixed target position size, useful with Target Orders.
```python
cerebro.addsizer(bt.sizers.FixedSizeTarget, stake=100)
```bash
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `stake` | int | 1 | Fixed target stake size |
| `tranches` | int | 1 | Number of tranches for scaling |
### PercentSizer
Uses a percentage of available cash for position sizing.
```python
cerebro.addsizer(bt.sizers.PercentSizer, percents=20)
```bash
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `percents` | float | 20 | Percentage of available cash to use (0-100) |
| `retint` | bool | False | Return int size or float value |
```python
# Use 30% of available cash
sizer = bt.sizers.PercentSizer(percents=30)
# Use 10% of cash, return integer
sizer = bt.sizers.PercentSizer(percents=10, retint=True)
```bash
### AllInSizer
Uses 100% of available cash for each order.
```python
cerebro.addsizer(bt.sizers.AllInSizer)
```bash
This is a `PercentSizer` with `percents=100`.
### PercentSizerInt
Percentage-based sizer that returns integer values.
```python
cerebro.addsizer(bt.sizers.PercentSizerInt, percents=15)
```bash
This is a `PercentSizer` with `retint=True` by default.
### AllInSizerInt
Uses 100% of available cash and returns integer values.
```python
cerebro.addsizer(bt.sizers.AllInSizerInt)
```bash
Combines `percents=100` with `retint=True`.
## Integration with Cerebro
### Adding a Default Sizer
Use `addsizer()` to set the default sizer for all strategies:
```python
cerebro = bt.Cerebro()
cerebro.addsizer(bt.sizers.FixedSize, stake=100)
```bash
### Adding a Strategy-Specific Sizer
Use `addsizer_byidx()` to assign a sizer to a specific strategy:
```python
# Add strategies and get their indices
idx1 = cerebro.addstrategy(MyStrategy1)
idx2 = cerebro.addstrategy(MyStrategy2)
# Assign different sizers to each strategy
cerebro.addsizer_byidx(idx1, bt.sizers.PercentSizer, percents=10)
cerebro.addsizer_byidx(idx2, bt.sizers.FixedSize, stake=50)
```bash
## Integration with Strategy
### Setting Sizer in Strategy
```python
class MyStrategy(bt.Strategy):
def __init__(self):
super().__init__()
# Set a custom sizer
self.setsizer(bt.sizers.PercentSizer(percents=20))
def next(self):
# buy() and sell() will use the sizer automatically
if self.data.close[0] > self.sma[0]:
self.buy() # Uses sizer to determine size
```bash
### Getting Sizer from Strategy
```python
# Get the current sizer
sizer = self.getsizer()
# Or via property
sizer = self.sizer
```bash
### Manual Sizing
```python
def next(self):
# Get size manually from sizer
size = self.getsizing(self.data, isbuy=True)
self.buy(size=size)
```bash
## Custom Sizer Development
### Basic Custom Sizer
```python
import backtrader as bt
class VolatilitySizer(bt.Sizer):
"""Size positions based on volatility."""
params = (
('risk_pct', 0.02), # 2% risk per trade
('atr_period', 14),
)
def __init__(self, **kwargs):
super().__init__(**kwargs)
def _getsizing(self, comminfo, cash, data, isbuy):
# Calculate position size based on ATR
atr = bt.indicators.ATR(data, period=self.p.atr_period)
risk_amount = cash *self.p.risk_pct
# Avoid division by zero
if atr[0] == 0:
return 0
# Size = Risk Amount / ATR
size = risk_amount / atr[0]
return int(size)
```bash
### Using Custom Sizer
```python
cerebro = bt.Cerebro()
cerebro.addsizer(VolatilitySizer, risk_pct=0.03, atr_period=20)
```bash
### Kelly Criterion Sizer
```python
class KellySizer(bt.Sizer):
"""Size positions using Kelly Criterion."""
params = (
('win_rate', 0.55),
('avg_win', 100),
('avg_loss', 80),
('capital_pct', 0.25), # Fraction of Kelly to use
)
def _getsizing(self, comminfo, cash, data, isbuy):
# Kelly % = (W - (1-W)) / R
# where W = win rate, R = win/loss ratio
win_loss_ratio = self.p.avg_win / self.p.avg_loss
kelly_pct = (self.p.win_rate - (1 - self.p.win_rate)) / win_loss_ratio
# Use fraction of Kelly for safety
safe_pct = kelly_pct*self.p.capital_pct
# Calculate position size
size = (cash* safe_pct) / data.close[0]
return int(size)
```bash
### Risk Parity Sizer
```python
class RiskParitySizer(bt.Sizer):
"""Allocate capital based on risk parity."""
params = (
('target_vol', 0.15), # Target portfolio volatility
('lookback', 20),
)
def _getsizing(self, comminfo, cash, data, isbuy):
# Calculate recent volatility
returns = [data.close[-i] / data.close[-i-1] - 1
for i in range(1, self.p.lookback)]
volatility = (sum(r*r for r in returns) / len(returns)) ** 0.5
if volatility == 0:
return 0
# Scale position inversely to volatility
scale = self.p.target_vol / volatility
size = (cash * scale) / data.close[0]
return int(size)
```bash
## Sizer Reference by Strategy
When a strategy calls `buy()` or `sell()` without specifying size:
1. The strategy uses its assigned sizer
2. The sizer's `getsizing()` method is called
3. `_getsizing()` computes the position size
4. The order is placed with the computed size
```python
class MyStrategy(bt.Strategy):
def next(self):
# All these use the sizer automatically
self.buy() # Sizer determines size
self.sell() # Sizer determines size
self.close() # Sizer determines size
# Override with explicit size
self.buy(size=100) # Ignores sizer
```bash
## CommissionInfo Object
The `comminfo` parameter passed to `_getsizing()` provides:
```python
def _getsizing(self, comminfo, cash, data, isbuy):
# Get margin information
margin = comminfo.getmargin(data)
# Get commission for a hypothetical order
commission = comminfo.getcommission(size, price)
# Check if leveraged
leverage = comminfo.getleveragemargin()
return size
```bash
## Full Example
```python
import backtrader as bt
import datetime
class TestStrategy(bt.Strategy):
params = (('period', 20),)
def __init__(self):
super().__init__()
self.sma = bt.indicators.SMA(self.data.close, period=self.p.period)
self.crossover = bt.indicators.CrossOver(self.data.close, self.sma)
def next(self):
if self.crossover > 0:
self.buy() # Size determined by sizer
elif self.crossover < 0:
self.sell() # Size determined by sizer
# Create cerebro
cerebro = bt.Cerebro()
# Add data
data = bt.feeds.YahooFinanceData(
dataname='AAPL',
fromdate=datetime.datetime(2020, 1, 1),
todate=datetime.datetime(2021, 12, 31)
)
cerebro.adddata(data)
# Add strategy
cerebro.addstrategy(TestStrategy)
# Add sizer - use 10% of available cash
cerebro.addsizer(bt.sizers.PercentSizer, percents=10)
# Set initial cash
cerebro.broker.setcash(10000)
# Run
results = cerebro.run()
```bash
## Available Aliases
| Sizer | Alias |
|-------|-------|
| `FixedSize` | `SizerFix` |
## Next Steps
- [Strategy API](strategy.md) - Strategy development
- [Broker API](broker.md) - Order execution
- [Indicator API](indicator.md) - Technical indicators
- [Analyzer API](analyzer.md) - Performance analysis