DEV Community

Timevolt
Timevolt

Posted on

Neo's Guide to Position Sizing and Stops in Algo Trading

The Quest Begins (The "Why")

Honestly, I remember the first time I watched my algo blow up a simulated account because I’d sized a trade like I was betting my lunch money on a coin flip. I was thrilled the strategy had a 60 % win rate, but after a few losing streaks the equity curve looked like a rollercoaster designed by a sadist. I kept asking myself: Why does a seemingly solid edge keep biting me in the tail?

The dragon I was trying to slay wasn’t the market itself—it was my own ignorance of risk management. I’d spent weeks tweaking indicators, optimizing entry signals, and yet I kept ignoring the two most basic levers: how much to put on each trade and when to get out if things go south. It felt like showing up to a boss fight in Dark Souls with a wooden sword and no armor—sure, I could swing, but I’d get one‑shot every time.

That frustration pushed me to dig into the math behind position sizing and stop‑loss placement. What I discovered felt like unlocking a hidden cheat code, and I’m excited to share it with you.

The Revelation (The Insight)

The big “aha!” moment came when I realized that position sizing isn’t about guessing how much you feel comfortable risking; it’s a deterministic calculation that protects your capital while letting your edge work. And stops aren’t arbitrary price levels you slap on a chart—they’re the distance you need to survive the inevitable adverse moves that any strategy will face.

Here’s the core insight in plain English:

  • Risk per trade = (Account equity) × (risk percent you’re willing to lose on a single trade).
  • Position size = (Risk per trade) ÷ (distance from entry to stop‑loss in price units).

If you know how much you’re willing to lose (say 1 % of equity) and you can measure how far your stop is from your entry (in ticks, pips, or dollars), the math tells you exactly how many contracts/shares to trade. No more “I’ll just go with 0.5 lots because it feels right.”

The second revelation? Stops should be based on market volatility, not hope. Using a fixed number of points ignores the fact that a volatile Forex pair can swing 100 points in an hour while a steady blue‑chip might only move 5. I started using the Average True Range (ATR) to size my stops:

  • Stop distance = ATR × multiplier (commonly 1.5–2).

This makes the stop adapt to current market conditions, giving your trade room to breathe while still capping loss.

When I combined these two ideas, my equity curve went from a jagged nightmare to a smooth, upward‑sloping line. It was like finally getting the right gear for that Dark Souls boss—suddenly the fight felt fair, and I could focus on executing my strategy instead of praying for luck.

Wielding the Power (Code & Examples)

Let’s see the before and after. First, the naive approach I used to code:

# BEFORE: Fixed fraction, no volatility awareness
account_equity = 100_000          # USD
risk_per_trade_pct = 0.02        # 2% of equity (too high!)
entry_price = 150.0
stop_price = 148.0               # arbitrary 2‑point stop
position_size = (account_equity * risk_per_trade_pct) / abs(entry_price - stop_price)
print(f"Position size: {position_size:.2f} contracts")
Enter fullscreen mode Exit fullscreen mode

Output:

Position size: 1000.00 contracts
Enter fullscreen mode Exit fullscreen mode

Whoa—risking 2 % on a 2‑point stop means I’m putting $4,000 at stake per trade! If the market gaps against me, I could blow a huge chunk of the account in a single tick.

Now, the after—the version that uses ATR‑based stops and a sane risk percent:

# AFTER: Volatility‑aware stop, 1% risk per trade
import pandas as pd

# Assume we have a DataFrame `df` with OHLC data
df['atr'] = df['high'].rolling(14).max() - df['low'].rolling(14).min()  # simple ATR proxy
latest_atr = df['atr'].iloc[-1]   # most recent ATR value

account_equity = 100_000
risk_per_trade_pct = 0.01        # 1% risk – far more conservative
entry_price = df['close'].iloc[-1]

# Stop distance = 1.5 * ATR (you can tune the multiplier)
stop_multiplier = 1.5
stop_distance = latest_atr * stop_multiplier
stop_price = entry_price - stop_distance  # for a long position

position_size = (account_equity * risk_per_trade_pct) / stop_distance
print(f"ATR: {latest_atr:.4f}, Stop distance: {stop_distance:.4f}")
print(f"Stop price: {stop_price:.2f}")
print(f"Position size: {position_size:.2f} contracts")
Enter fullscreen mode Exit fullscreen mode

Sample output (with a hypothetical ATR of 0.75):

ATR: 0.7500, Stop distance: 1.1250
Stop price: 148.88
Position size: 888.89 contracts
Enter fullscreen mode Exit fullscreen mode

Now we’re risking $1,000 (1 % of $100k) per trade, and the stop adapts to market turbulence. If volatility spikes, the stop widens and the position shrinks; if things calm down, we can take a slightly larger bite.

Common Traps to Avoid

  1. Using a fixed dollar amount for stops – This ignores changing volatility and can leave you either overexposed or prematurely stopped out.
  2. Risking too much per trade – Even a 2 % risk per trade can ruin you after a string of losses; 1 % (or even 0.5 %) is a safer baseline for most retail accounts.

When I first ignored these traps, I’d get stopped out on normal market noise, then overleap on the next trade trying to “make it back.” The ATR‑sized stop kept me in the game, and the disciplined position sizing kept my equity curve smooth.

Why This New Power Matters

With these two tools in your belt, you’re no longer gambling on each trade; you’re engineering it.

  • Consistency – Your risk per trade stays constant, so the law of large numbers works for you, not against you.
  • Adaptability – Stops that breathe with the market reduce false exits during choppy periods and give you room during trends.
  • Peace of mind – Knowing exactly how much you stand to lose on any given signal lets you focus on strategy execution, not emotional panic‑selling.

Imagine you’re backtesting a mean‑reversion strategy on EUR/USD. Before, you’d see wild equity swings that made you doubt the edge. After applying ATR stops and 1 % risk, the same strategy shows a steady 12 % annual return with a max drawdown of under 8 %. That’s the kind of result that makes you want to share it at the next meetup over coffee (or whatever your dev fuel is).

Your Turn – The Challenge

I dare you to take one of your existing algos (or even a simple moving‑average crossover) and rewrite the risk block using the formulas above.

  1. Measure the ATR of your instrument over the last 14 periods.
  2. Set your stop distance to ATR * 1.5.
  3. Risk exactly 1 % of your account equity per trade.

Run a quick back‑test and compare the equity curve to your old fixed‑stop, fixed‑size version. Did the curve smooth out? Did the max drop shrink?

Drop your findings in the comments—let’s geek out over the numbers together!

Happy coding, and may your stops always be just wide enough to let your winners run. 🚀

Top comments (0)