Trading the Breaking

Trading the Breaking

Share this post

Trading the Breaking
Trading the Breaking
RiskOps: Traditional sizing methods
Alpha Lab

RiskOps: Traditional sizing methods

Why β€˜go big or go home’ is a lieβ€”and how to play the long game with surgical precision

πš€πšžπšŠπš—πš π™±πšŽπšŒπš”πš–πšŠπš—'s avatar
πš€πšžπšŠπš—πš π™±πšŽπšŒπš”πš–πšŠπš—
Mar 04, 2025
βˆ™ Paid
11

Share this post

Trading the Breaking
Trading the Breaking
RiskOps: Traditional sizing methods
2
3
Share

Table of contents:

  1. Introduction.

  2. Sizing based on fixed fractional.

  3. Sizing based on volatility targeting

  4. Sizing based on Monte Carlo simulations.

  5. Sizing based on Omega ratio.

  6. Bonus: Theoretical foundations of conformal prediction in contract sizing.


Introduction

Everyone knows the typical trader who is 99% sure that their algorithm will winβ€”until the account burns. They bet everything on that certainty. Then the market slips through his fingers like sand β€”hello, unexpected news!β€”and, poof, their money is gone.

Confidence is like a shiny balloon: fun until it pops, leaving you with a bunch of deflated dreams. Risk management, on the other hand, is the string that keeps the balloon from drifting away.

In trading, if you use mediocre models, it’s not enough to have a good prediction; you need to size your positions based on quantifiable risk. Now, if you drink from the Holy Grail, ahhh! Brother, equiponderate is God.

Let’s start with the simplest risk rule: fixed fractional sizing. Think of it as the β€œfuel gauge” methodβ€”where your trading algorithm only burns a measured amount of capital on each trade, ensuring you never run out of fuel on your journey, no matter how strong the signal.

Sizing based on fixed fractional

Imagine your algorithm is like a sophisticated trading system that generates signals for when to enter a trade. These signals might be as tempting as an all-in recommendation from your favorite robo-advisor. However, even if the algorithm is screaming, this stock is going to skyrocket!, your system must still follow a disciplined approach to avoid catastrophic losses.

Instead of diving in headfirst and allocating all your capital based solely on a strong signal, you treat your available capital like the fuel in your algorithm’s trading engine. You only commit a fixed fraction of that fuel per trade. This is analogous to a well-designed trading system that never burns through its reserves by risking only a predetermined percentage of capital on any single trade.

Assume your total capital is C dollars, and you decide to risk a fixed percentage rf​ on every trade. Then your risk per tradeβ€”in dollarsβ€”is:

\(\text{Risk Dollars} = C \times r_f. \)

Now, suppose you buy an asset at a price Pentry​​​ and set a stop loss at a relative distance Ξ΄β€”e.g., 10%. The potential loss per share is then:

\(\text{Loss per Share} = P_{\text{entry}} \times \delta. \)

If you buy N shares, the total loss if the stop is hit is:

\(\text{Total Loss} = N \times (P_{\text{entry}} \times \delta). \)

To ensure that your loss does not exceed your predetermined risk dollars, set:

\(N \times (P_{\text{entry}} \times \delta) = C \times r_f, \)

which rearranges to give:

\(N = \frac{C \times r_f}{P_{\text{entry}} \times \delta}. \)

This simple equation guarantees that you only risk a small, fixed percentage of your capital on each tradeβ€”regardless of your algorithm’s level of confidence.

Let’s implement it with a plot that shows how the number of shares changes as the stop-loss distance increases.

import numpy as np
import matplotlib.pyplot as plt

def fixed_fractional(capital, risk_percent=0.02, stop_loss=0.10, entry_price=100):
    """
    Calculate the number of shares to buy using fixed fractional sizing.
    
    Parameters:
        capital (float): Total capital available.
        risk_percent (float): Fraction of capital to risk per trade.
        stop_loss (float): Stop-loss distance as a fraction of the entry price.
        entry_price (float): Price at which the asset is bought.
        
    Returns:
        float: Number of shares to buy.
    """
    risk_dollars = capital * risk_percent
    return risk_dollars / (entry_price * stop_loss)

# Example usage:
capital = 1000
shares = fixed_fractional(capital, risk_percent=0.02, stop_loss=0.10, entry_price=50)
print(f"Buy {shares:.2f} shares.")

# Plot: Effect of stop_loss on the number of shares
stop_loss_range = np.linspace(0.01, 0.20, 100)
N_values = [fixed_fractional(capital, risk_percent=0.02, stop_loss=sl, entry_price=50) for sl in stop_loss_range]

plt.figure(figsize=(8, 4))
plt.plot(stop_loss_range, N_values, label='Shares (N)', color='darkblue', linewidth=2)
plt.xlabel("Stop-Loss distance (Ξ΄)")
plt.ylabel("Number of shares (N)")
plt.title("Fixed fractional sizing: N vs. Stoploss distance")
plt.legend()
plt.grid(True)
plt.show()

This plot shows the amount of shares vs. stop-loss distance. Wider stops = fewer shares. It’s like filling fewer cups if you pour lemonade into bigger mugs.

With fixed fractional sizing locking down basic risk, we now move on to a method that adapts to market mood swingsβ€”volatility targeting.

Sizing based on volatility targeting

When the market is calm, prices move gently; when it’s wild, prices swing like needles. Volatility, denoted by Οƒ quantifies this unpredictability. Volatility targeting adjusts your position size based on market volatility to keep your risk constant.

Let’s say your risk budget for a trade is R dollars. High Οƒ = needles mode. To ensure that your exposure remains consistent, regardless of volatility, you set:

\(\text{Position Size} = \frac{R}{\sigma}. \)

For example, if your risk budget is $100 and the volatility is 5%β€”Οƒ=0.05β€”then your position size is:

\(\frac{100}{0.05} = 2000 \text{ dollars}. \)

If volatility doubles to 10%β€”Οƒ=0.10β€”the position size halves:

\(\frac{100}{0.10} = 1000 \text{ dollars}. \)

This inverse relationship ensures that when the market becomes more uncertain, you reduce your exposure, protecting your capital.

Let's get our hands on that code!

import numpy as np
import matplotlib.pyplot as plt

def volatility_target(risk_budget, volatility):
    """
    Compute the position size based on volatility targeting.
    
    Parameters:
        risk_budget (float): Dollar amount you are willing to risk.
        volatility (float): Standard deviation (Οƒ) of returns.
        
    Returns:
        float: Position size in dollars.
    """
    return risk_budget / volatility

# Example usage:
risk_budget = 100
vol_low = 0.05  # 5% volatility
vol_high = 0.10 # 10% volatility
pos_size_low = volatility_target(risk_budget, vol_low)
pos_size_high = volatility_target(risk_budget, vol_high)
print(f"Position size at 5% volatility: ${pos_size_low:.0f}")
print(f"Position size at 10% volatility: ${pos_size_high:.0f}")

# Plot: Position size vs. volatility
vol_range = np.linspace(0.01, 0.20, 100)
pos_sizes = [volatility_target(risk_budget, vol) for vol in vol_range]

plt.figure(figsize=(8, 4))
plt.plot(vol_range, pos_sizes, 'b-', label='Position size curve', linewidth=2)
# Superpose the specific points for vol_low and vol_high
plt.scatter([vol_low, vol_high], [pos_size_low, pos_size_high], color='red', s=100, label='Specific volatilities')
plt.xlabel("Volatility (Οƒ)")
plt.ylabel("Position size ($)")
plt.title("Volatility targeting: Position size vs. volatility")
plt.legend()
plt.grid(True)
plt.show()

Position size plunges as volatility spikesβ€”like shrinking your surfboard when waves get huge:

With volatility captured mathematically, we now turn our attention to simulation-based methodsβ€”Monte Carlo simulationsβ€”that help us prepare for extreme market events.

Sizing based on Monte Carlo simulations

The markets can be unpredictableβ€”sometimes behaving like a drunken robot with a PhD in uncertainty. Monte Carlo simulations allow us to model thousandsβ€”or even millionsβ€”of potential future scenarios using stochastic processes. A common model is the geometric Brownian motion, defined by the stochastic differential equation:

\(dP_t = \mu P_t \, dt + \sigma P_t \, dW_t, \)

where ΞΌ is the driftβ€”expected returnβ€”Οƒ is the volatility, and Wt​ is a Wiener process representing the random movement. When integrated, the solution is:

\(P_t = P_0 \exp \left[ \left( \mu - \frac{\sigma^2}{2} \right) t + \sigma W_t \right]. \)

By simulating many paths Pt​​, we estimate the distribution of future pricesβ€”and, importantly, the worst-case loss. If we choose a confidence level Ξ±β€”say, 95%β€”then we define Lworst ​as the loss corresponding to the (1βˆ’Ξ±) percentile. Our position size multiplier is then:

\(\text{Multiplier} = \frac{R}{L_{\text{worst}}}, \)

where R is the risk budget.

While GBM assumes normally distributed returns, real markets often show skewnessβ€”asymmetryβ€”and kurtosisβ€”fat tails. These properties mean that extreme events happen more frequently than a normal distribution predicts.

Mathematical considerations [In depth]

This post is for paid subscribers

Already a paid subscriber? Sign in
Β© 2025 Quant Beckman
Privacy βˆ™ Terms βˆ™ Collection notice
Start writingGet the app
Substack is the home for great culture

Share