The Quest Begins (The "Why")
I still remember the first time I watched my algorithm go berserk on a back‑test. It was like watching a dragon breathe fire on a village I’d spent weeks building. The strategy looked solid on paper — entry signals were crisp, the win‑rate hovered around 55 % — but the equity curve looked like a roller coaster designed by a mad scientist. After a few nasty drawdowns I realized I wasn’t fighting a bad signal; I was fighting poor risk management. My position sizes were all over the place, and my stop‑losses were either too tight (getting whipped out by noise) or too wide (letting losses run like a rogue Wookiee). Honestly, I felt like a Padawan trying to swing a lightsaber without knowing how to grip it.
That moment was my “aha!”: if I could tame position sizing and stops, the dragon would become a loyal mount instead of a menace. The quest was on.
The Revelation (The Insight)
The treasure I uncovered wasn’t some secret sauce; it was a simple, repeatable framework:
- Risk per trade – decide how much of your capital you’re willing to lose on any single transaction (commonly 1 %–2 %).
- Position size – back‑calculate the number of contracts/shares so that, if the stop is hit, you lose exactly that amount.
- Stop placement – base the stop on market structure (e.g., ATR, recent swing low/high) rather than an arbitrary percentage.
When you lock these three together, every trade carries the same expected dollar risk, no matter how volatile the instrument is. It’s like giving each lightsaber swing the same force — consistency breeds survivability.
I’ll admit, the first time I coded this I felt like I’d just unlocked a new Force ability. The equity curve smoothed out, drawdowns shrank, and I could finally sleep through the night without checking my P&L every five minutes.
Wielding the Power (Code & Examples)
The Struggle – Fixed Fraction Position Sizing (the “trap”)
A common beginner mistake is to use a fixed fraction of equity without accounting for the stop distance. Here’s what that looks like in Python:
# ❌ Naive fixed fraction – ignores stop size
def naive_position_size(equity, risk_per_trade, price):
# risk 1% of equity, but we just buy a set number of shares
risk_amount = equity * risk_per_trade
shares = risk_amount / price # <-- WRONG! assumes stop = 0
return shares
If you plug this into a back‑test, you’ll quickly see that a volatile stock can wipe out your risk budget in a single tick, while a sleepy barely‑moving asset barely touches it. The result? Uneven risk exposure and a false sense of safety.
The Victory – Proper Position Sizing with ATR‑Based Stops
Now for the real spell. We’ll compute the stop distance using the Average True Range (ATR), then size the position so that hitting the stop loses exactly our predefined risk amount.
import pandas as pd
def atr(df, period=14):
"""Calculate ATR using Wilder's smoothing."""
high_low = df['high'] - df['low']
high_close = np.abs(df['high'] - df['close'].shift())
low_close = np.abs(df['low'] - df['close'].shift())
tr = pd.concat([high_low, high_close, low_close], axis=1).max(axis=1)
return tr.ewm(alpha=1/period, adjust=False).mean()
def position_size(equity, risk_per_trade, entry_price, atr_value, atr_multiplier=1.5):
"""
Returns the number of shares/contracts to trade.
- equity: current account equity
- risk_per_trade: fraction of equity to risk (e.g., 0.01 for 1%)
- entry_price: price at which we enter the trade
- atr_value: latest ATR
- atr_multiplier: how many ATRs we place the stop away from entry
"""
risk_amount = equity * risk_per_trade # dollars we are willing to lose
stop_distance = atr_multiplier * atr_value # price distance to stop
if stop_distance == 0:
raise ValueError("ATR is zero – check your data")
size = risk_amount / stop_distance # shares/contracts
return size
# Example usage
equity = 100_000
risk_per_trade = 0.01 # 1% risk per trade
entry = 150.0
data = pd.read_csv('AAPL_daily.csv')
data['atr'] = atr(data)
latest_atr = data['atr'].iloc[-1]
shares = position_size(equity, risk_per_trade, entry, latest_atr, atr_multiplier=2.0)
print(f"Buy {shares:,.2f} shares (~{shares * entry:,.0f} USD)")
Why this works:
-
risk_amountis fixed (e.g., $1,000 on a $100k account). -
stop_distancescales with volatility — high ATR → wider stop, low ATR → tighter stop. - Dividing the fixed dollar risk by the volatility‑adjusted stop distance yields a position size that always risks the same amount.
Common Traps to Avoid
| Trap | What it looks like | Why it hurts |
|---|---|---|
| Using a fixed stop‑loss percent (e.g., always 2 % below entry) | Ignores that a 2 % move is noise for a volatile crypto but a huge move for a blue‑chip stock. | Leads to over‑risking in calm markets and under‑risking in turbulent ones. |
| Risking more than your defined % per trade | Accidentally adding leverage after the size calculation (e.g., multiplying by margin). | Can blow past your risk target on a single loss, wrecking the whole plan. |
| Not updating ATR regularly | Using a stale ATR from weeks ago while the market regime has changed. | Stop distance becomes mis‑aligned with current volatility, causing premature exits or excessive drawdowns. |
Treat each of these like a boss fight in a RPG — learn the pattern, dodge the attack, and strike back with the correct move.
Why This New Power Matters
With this framework in your toolbox, you’re no longer gambling on each trade’s outcome; you’re managing the process. The equity curve starts to look like a steady climb rather than a chaotic scribble. You can:
- Scale confidently – add more strategies or instruments knowing each respects the same risk budget.
- Sleep easier – you know the worst‑case loss per trade is bounded, so portfolio‑level drawdowns stay predictable.
- Focus on edge – because risk is constant, you can spend energy refining entry/exit logic instead of constantly re‑sizing positions.
It’s the difference between swinging a lightsaber blindly and wielding it with precise, measured strikes — each hit counts, each miss is controlled.
Your Turn – A Quick Challenge
Grab a dataset of any instrument you like (forex pair, futures, equities). Code the ATR‑based position sizing above, run a simple moving‑average crossover strategy, and compare the equity curve to the same strategy using a naïve fixed‑fraction size. Post your results in the comments — let’s see whose curve looks smoother!
May the Force be with your stops. 🚀
Top comments (0)