Free playbooks in your inbox
Hands-on tutorials for people who want to build with AI.

Why a 61% Win Rate Still Loses You $14K

Algorithmic trading for beginners in Python: the position-sizing rules and Kelly math that keep a real edge from blowing up your account on one bad trade.

From the youcanbuildthings catalog ▸ Build-tested 8 min read

Summary:

  1. A 61% win rate with no position sizing still lost a real trader $14,000 in two weeks.
  2. The Kelly Criterion sets the bet size; a 2% hard cap and a 6% daily stop keep it survivable.
  3. Five hard rules, coded so the bot, Claude, and you at 11 PM cannot override them.
  4. Copy-paste the Kelly sizing function and the integration snippet for any bot.

Search “algorithmic trading for beginners python” and almost every result teaches you a strategy. Almost none teach the thing that actually empties accounts: position sizing. A trader on r/algotrading posted a bot with a 61% win rate and a 1.4 Sharpe ratio. Average winner twice the average loser. On paper, a great system. He lost $14,000 in two weeks.

How? No sizing rules. The bot put 15% of the account into one TSLA trade. TSLA gapped down 8% on an earnings miss. That single position wiped out three months of gains. Then he revenge-traded to win it back. Account down 40% from peak. Bot off. Reddit post written.

The strategy was fine. The risk management did not exist. Position sizing is survival. Strategy is optional. A good strategy with bad sizing is account suicide. A mediocre strategy with good sizing survives long enough to compound.

Risk management comparison: a 61% win rate, 1.4 Sharpe strategy loses $14,000 in two weeks with no position sizing on a TSLA 8% earnings gap, versus the same strategy surviving with a small dip under the five hard rules

Same strategy, properly sized: the same TSLA earnings gap is a small survivable dip, and the account keeps compounding. Nothing about the signals changed. Only the size of the bet.

What are the five hard rules?

They are hard limits coded into the system, not advice. If the bot tries to break one, the trade is blocked and the violation is logged.

  1. Never risk more than 2% of the account on one trade. On $100K, max loss per position is $2,000. Your share count falls out of where the stop is.
  2. Never lose more than 6% of the account in one day. Hit that and all bots stop opening positions until the next session. This kills the revenge-trade spiral.
  3. Every position gets a stop-loss at entry. Default 3% below entry for longs. It can move closer (trailing), never wider.
  4. No single sector above 40% of portfolio value. Already 35% tech and the bot wants another chip name? It gets reduced or rejected.
  5. No trading within 3 days of earnings. Earnings are binary. Claude cannot predict the gap. The bot sits them out.

How much should you actually bet?

The 2% rule is a ceiling. Kelly tells you the right size underneath it. The formula:

Kelly % = W - (1 - W) / R

W is win rate as a decimal, R is average win divided by average loss. Run the screener’s real backtest numbers (53.7% win rate, profit factor 1.79):

Kelly % = 0.537 - (1 - 0.537) / 1.79
        = 0.537 - 0.259
        = 0.278   (27.8%)

Full Kelly says risk 27.8% per trade. That is stomach-churning. Every professional uses a fraction. Quarter-Kelly is 6.95%. Reasonable for a tested strategy. Then the 2% hard cap takes over: if Kelly says 6.95% and the cap says 2%, you bet 2%. If Kelly says 1.2%, you bet 1.2%. And if Kelly goes negative, you bet zero.

def position_size(account_value, entry_price, stop_loss_pct=0.03,
                  win_rate=0.537, profit_factor=1.79):
    risk_per_share = entry_price * stop_loss_pct
    cap_shares = int((account_value * 0.02) / risk_per_share)  # 2% cap
    kelly = win_rate - (1 - win_rate) / profit_factor
    kelly = max(0, kelly * 0.25)                               # quarter-Kelly
    kelly_shares = int((account_value * kelly) / risk_per_share)
    return max(0, min(cap_shares, kelly_shares))               # no floor

There is no minimum floor. Negative Kelly means no edge, and no edge means bet nothing. Rounding zero up to one share would defeat the entire point. A 48% win rate at 0.9 profit factor gives Kelly = -0.098. The function returns 0. The caller skips the trade. That is correct, not a bug.

What broke

The same way it always breaks: a human overriding the rules. The author of the book this comes from lost $800 on his first bot in 2019 to slippage and missing stops. That was technical. He lost another $2,400 the same month on manual overrides. A META position dropped 2.8%, he gave it room because “fundamentals are strong,” it dropped another 7%. A TSLA position was up 5%, he got nervous and sold, it ran another 12%. Two overrides, one fear, one greed, cost more than the bot’s own bugs.

The r/algotrading graveyard is full of these. One trader’s post-mortem:

TLDR: program crash made me 50k and I ordered a list the wrong way and the initial market crash and recovery from liberation day hid my stupidity until the 50k was lost.

Source: r/algotrading, “How my stupidity made and lost 50k this month” (100 upvotes). Different mechanism, same root cause: nothing hard-coded was stopping the damage.

That is why the risk module is a gatekeeper, not a suggestion. Every trade passes through evaluate_trade() before it reaches the broker:

risk_check = rm.evaluate_trade(ticker, entry_price)
if risk_check["verdict"] == "APPROVED":
    shares = risk_check["approved_shares"]
    # place the trade with 'shares'
else:
    # BLOCKED (rule violation) or REJECTED-NO-EDGE (Kelly returned 0)
    print(f"{risk_check['verdict']}: {risk_check['block_reason']}")

If the verdict is anything but APPROVED, the trade does not happen. Not after you argue with it. Not because this one feels different. The bot is not allowed to be wrong about risk. It can be wrong about direction, timing, which stock. It cannot be wrong about how much to risk and when to stop.

What should you actually do?

  • If your strategy has a great win rate → that is not the question. Ask what one bad gap on an oversized position does to the account. A 61% win rate did not save the $14,000.
  • If Kelly returns zero or negative → bet zero. Go fix the strategy in the backtest. Do not round up to one share to feel productive.
  • If a volatile name like TSLA triggers your 3% stop on normal noise → widen the stop to 5% and cut the share count so the dollar risk stays at 2%. Same risk, fewer shares.
  • If you feel the urge to override at 11 PM after a red day → that urge is the failure mode. Write it in a log instead of touching the bot. Nine times out of ten it looks foolish the next morning.

bottom_line

  • Win rate is vanity. Position sizing is survival. A 61% bot with no sizing lost $14,000 in two weeks.
  • Kelly sets the size, the 2% cap and 6% daily stop keep it alive, and negative Kelly means bet nothing.
  • Hard-code the rules so neither the bot nor you can override them. The override is always the thing that kills the account.
Why trust this? Every youcanbuildthings guide is pulled from a build-tested book: code that ran in production before it was written down.

Frequently Asked Questions

Can a trading strategy with a 61% win rate still lose money?+

Yes. A 61% win rate with a 1.4 Sharpe lost a real trader $14,000 in two weeks because one oversized position took a single 8% earnings gap. Win rate without position sizing is meaningless.

What is the Kelly Criterion for position sizing?+

Kelly % = W - (1-W)/R, where W is win rate and R is average win over average loss. It tells you the optimal bet size. Use quarter-Kelly capped by a 2% hard limit in real trading.

How much of my account should I risk per trade?+

Never more than 2% on a single trade, and never more than 6% in a single day. These are hard coded limits the bot cannot override, not guidelines you follow when you feel disciplined.