Skip to main content

actual risk management rules that work

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
#

Risk Management Improvements

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

Related

position sizing is killing me - fixing it with code
been up since 3am coding a proper position sizing module. my current approach (fixed 2% risk per trade) is bleeding me out. down another $8k this week. total drawdown now -$48k since january. at this rate i’ll be broke by august.