after losing $60k in 4 months i finally built risk management that doesn’t suck.
what wasn’t working #
my “risk management” before:
- max 2% risk per trade (i’d override this constantly)
- stop losses at -20% (never hit because options expire worthless first)
- “diversify across strategies” (all strategies correlated anyway)
basically no real risk management. just guidelines i’d ignore when feeling confident.
new rules i can’t override #
hard-coded into my execution engine. can’t trade without following these:
1. daily loss limit: $2,000
def check_daily_limit():
today_pnl = get_todays_pnl()
if today_pnl < -2000:
disable_all_strategies()
send_alert("Daily limit hit: -$2000")
return False
return True
if i’m down $2k in a day, algo stops trading automatically. no override. done for the day.
2. max position size: $15k per strategy
doesn’t matter what my account size is. single strategy can’t have >$15k at risk.
forces diversification. can’t go all-in on one “sure thing” anymore.
3. max portfolio heat: 30%
“heat” = total capital at risk across all positions
if 30% of my account ($108k currently) is at risk, no new positions until something closes.
the impact #
Figure 1: Impact of new risk rules on losses (backtested on march 2023 data)
if i had these rules in january:
- average loss per trade: $3.2k → $1.8k
- max single loss: $8.5k → $3.5k
- losing days per month: 12 → 8
would’ve saved ~$25k over 4 months.
the hard part: following them #
built the code. now comes the hard part: not fucking disabling it when i “know better”
already caught myself wanting to override daily limit twice this week. algo said “no more trades” at -$2k, i wanted to trade more to “make it back”
resisted. logged out. went to the gym instead.
portfolio heat calculation #
this one’s tricky with options:
def calculate_portfolio_heat():
"""Calculate total capital at risk"""
total_heat = 0
for position in get_open_positions():
if position.type == 'option_spread':
# Risk = max loss on spread
heat = position.max_loss
elif position.type == 'naked_option':
# Risk = position value (could go to zero)
heat = position.market_value
else:
# Futures, stocks: use stop distance
heat = abs(position.entry_price - position.stop_price) * position.quantity
total_heat += heat
account_value = get_account_equity()
heat_percent = (total_heat / account_value) * 100
return heat_percent
why 30% max heat #
at 30% heat, if everything goes to zero simultaneously (unlikely), i lose 30% of account.
painful but not account-ending. still have $250k+ to rebuild.
at my old “no limit” approach, i had 70%+ heat during march. one bad day could’ve blown up the account.
the psychological benefit #
knowing i can’t lose more than $2k in a day helps me sleep.
before: would stay up until 2am worried about positions, checking markets now: hit $2k limit, algo stops, i can actually relax
worth the opportunity cost of “missed gains” from being risk-off.
2:58am. new risk rules deployed. let’s see if i can make it through may without hitting -$20k for the month.
-AK