Skip to content

contango.strategy.rule_based.position_sizers.volatility_position_sizer

contango.strategy.rule_based.position_sizers.volatility_position_sizer

VolatilityPositionSizer

VolatilityPositionSizer(vol_indicator: AverageTrueRange, target_vol: float, periods_per_year: int = 252)

Bases: PositionSizer[TradingContext]

Sizes positions inversely to volatility.

Initializes VolatilityPositionSizer.

Parameters:

Name Type Description Default
vol_indicator AverageTrueRange

An indicator producing the periodic return volatility.

required
target_vol float

The desired annualized volatility contribution of a full position.

required
periods_per_year int

The number of periods per year, used to annualize the indicator's per-period volatility.

252
Source code in src\contango\strategy\rule_based\position_sizers\volatility_position_sizer.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def __init__(
    self,
    vol_indicator: AverageTrueRange,
    target_vol: float,
    periods_per_year: int = 252,
) -> None:
    """
    Initializes `VolatilityPositionSizer`.

    Args:
        vol_indicator: An indicator producing the periodic return volatility.
        target_vol: The desired annualized volatility contribution of a full position.
        periods_per_year: The number of periods per year, used to annualize the indicator's per-period volatility.
    """
    self._vol_indicator = vol_indicator
    self._target_vol = target_vol
    self._periods_per_year = periods_per_year

size

size(context: TradingContext) -> int

Returns units sized so the position's annualized volatility = target_vol.

Source code in src\contango\strategy\rule_based\position_sizers\volatility_position_sizer.py
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def size(self, context: TradingContext) -> int:
    """
    Returns units sized so the position's annualized volatility = target_vol.
    """
    atr = self._vol_indicator.value
    price = context.event.close

    if atr is None or atr <= 0 or price <= 0:
        return 0

    periodic_vol = atr / price
    annualized_vol = periodic_vol * math.sqrt(self._periods_per_year)
    equity = context.portfolio.equity

    if equity is None:
        return 0

    dollar_exposure = (self._target_vol / annualized_vol) * equity
    return int(dollar_exposure / price)