Position sizing calculations for trading systems.
Pure functions for calculating position sizes based on risk parameters, account size, and volatility. Supports multiple sizing strategies.
Example
# Fixed fractional sizing (risk 1% of account)
ZenQuant.Sizing.fixed_fractional(100_000, 0.01, 500)
# => 2.0 (2 units where each unit has $500 max loss)
# Kelly criterion
ZenQuant.Sizing.kelly(0.55, 1.5)
# => 0.183 (18.3% of bankroll)API Functions
| Function | Arity | Description | Param Kinds |
|---|---|---|---|
optimal_f | 1 | Calculate Ralph Vince's optimal fixed fraction from trade history. | trades: value |
anti_martingale | 4 | Calculate anti-martingale position adjustment. | base_size: value, consecutive_wins: value |
volatility_scaled | 4 | Calculate position size scaled by volatility. | account_size: value, risk_percent: value, current_volatility: value, target_volatility: value |
kelly | 3 | Calculate optimal position size using Kelly criterion. | win_rate: value, win_loss_ratio: value |
max_loss | 2 | Calculate position size based on maximum loss amount. | max_loss_amount: value, stop_distance: value |
fixed_fractional | 3 | Calculate position size using fixed fractional method. | account_size: value, risk_percent: value, stop_distance: value |
Summary
Functions
Calculate anti-martingale position adjustment.
Calculate position size using fixed fractional method.
Calculate optimal position size using Kelly criterion.
Calculate position size based on maximum loss amount.
Calculate Ralph Vince's optimal fixed fraction from trade history.
Calculate position size scaled by volatility.
Types
Functions
@spec anti_martingale(number(), integer(), fraction(), float()) :: position_size()
Calculate anti-martingale position adjustment.
Parameters
base_size- Starting position size (value)consecutive_wins- Number of consecutive wins (negative for losses) (value)
Options
scale_factor- Adjustment per win/loss (0.25 = 25%) (default:0.25)max_scale- Maximum multiplier cap (default:2.0)
Returns
Adjusted position size (float)
Example
0.1095# descripex:contract
%{
opts: %{
scale_factor: %{
default: 0.25,
type: :float,
description: "Adjustment per win/loss (0.25 = 25%)"
},
max_scale: %{
default: 2.0,
type: :float,
description: "Maximum multiplier cap"
}
},
params: %{
base_size: %{description: "Starting position size", kind: :value},
consecutive_wins: %{
description: "Number of consecutive wins (negative for losses)",
kind: :value
}
},
returns: %{type: :float, description: "Adjusted position size"},
returns_example: 0.1095
}
@spec fixed_fractional(number(), fraction(), number()) :: position_size()
Calculate position size using fixed fractional method.
Parameters
account_size- Total account equity (value)risk_percent- Risk per trade as decimal (e.g., 0.01 = 1%) (value)stop_distance- Distance to stop loss in account currency per unit (value)
Returns
Position size in units (e.g., contracts) (float)
Example
0.1095# descripex:contract
%{
params: %{
account_size: %{description: "Total account equity", kind: :value},
risk_percent: %{
description: "Risk per trade as decimal (e.g., 0.01 = 1%)",
kind: :value
},
stop_distance: %{
description: "Distance to stop loss in account currency per unit",
kind: :value
}
},
returns: %{
type: :float,
description: "Position size in units (e.g., contracts)"
},
returns_example: 0.1095
}
Calculate optimal position size using Kelly criterion.
Parameters
win_rate- Probability of winning (0.0 to 1.0) (value)win_loss_ratio- Average win divided by average loss (value)
Options
kelly_fraction- Fraction of Kelly to use (0.5 = half Kelly) (default:0.5)
Returns
Optimal bet size as fraction of bankroll, 0.0 if negative EV (float)
Example
0.1095# descripex:contract
%{
opts: %{
kelly_fraction: %{
default: 0.5,
type: :float,
description: "Fraction of Kelly to use (0.5 = half Kelly)"
}
},
params: %{
win_rate: %{
description: "Probability of winning (0.0 to 1.0)",
kind: :value
},
win_loss_ratio: %{
description: "Average win divided by average loss",
kind: :value
}
},
returns: %{
type: :float,
description: "Optimal bet size as fraction of bankroll, 0.0 if negative EV"
},
returns_example: 0.1095
}
@spec max_loss(number(), number()) :: position_size()
Calculate position size based on maximum loss amount.
Parameters
max_loss_amount- Maximum acceptable loss in account currency (value)stop_distance- Distance to stop loss per unit (value)
Returns
Position size in units (float)
Example
0.1095# descripex:contract
%{
params: %{
stop_distance: %{
description: "Distance to stop loss per unit",
kind: :value
},
max_loss_amount: %{
description: "Maximum acceptable loss in account currency",
kind: :value
}
},
returns: %{type: :float, description: "Position size in units"},
returns_example: 0.1095
}
Calculate Ralph Vince's optimal fixed fraction from trade history.
Parameters
trades- List of trade results (positive for wins, negative for losses) (value)
Returns
Optimal fraction of account to risk per trade, or nil if insufficient data (float)
Example
0.1095# descripex:contract
%{
params: %{
trades: %{
description: "List of trade results (positive for wins, negative for losses)",
kind: :value
}
},
returns: %{
type: :float,
description: "Optimal fraction of account to risk per trade, or nil if insufficient data"
},
returns_example: 0.1095
}
@spec volatility_scaled(number(), fraction(), number(), number()) :: position_size()
Calculate position size scaled by volatility.
Parameters
account_size- Total account equity (value)risk_percent- Base risk per trade as decimal (value)current_volatility- Current volatility measure (e.g., ATR, std dev) (value)target_volatility- Target/baseline volatility for normal sizing (value)
Returns
Volatility-adjusted risk amount in account currency (float)
Example
0.1095# descripex:contract
%{
params: %{
account_size: %{description: "Total account equity", kind: :value},
risk_percent: %{description: "Base risk per trade as decimal", kind: :value},
current_volatility: %{
description: "Current volatility measure (e.g., ATR, std dev)",
kind: :value
},
target_volatility: %{
description: "Target/baseline volatility for normal sizing",
kind: :value
}
},
returns: %{
type: :float,
description: "Volatility-adjusted risk amount in account currency"
},
returns_example: 0.1095
}