◈   ∿ algotrading · Intermediate

Kelly Criterion Python: Size Crypto Trades Like a Pro

Master the Kelly Criterion in Python to calculate optimal position sizes for your crypto trades on Binance and Bybit, reduce drawdowns, and grow your portfolio consistently over time.

Uncle Solieditor · voc · 06.05.2026 ·views 19
◈   Contents
  1. → What Is the Kelly Criterion and Why Crypto Traders Use It
  2. → The Kelly Formula: Simple Math, Powerful Results
  3. → Implementing the Kelly Criterion in Python
  4. → Pulling Real Trade Data from Binance and Bybit
  5. → Combining Kelly with Real-Time Signals from VoiceOfChain
  6. → Common Mistakes When Applying Kelly to Crypto
  7. → Frequently Asked Questions
  8. → Conclusion

Most traders blow up not because they pick bad trades — but because they size them wrong. A strategy with a 60% win rate can still destroy your account if you bet too much on every trade. The Kelly Criterion is a mathematical formula that tells you exactly how much of your capital to risk on each trade, based on your historical win rate and reward-to-risk ratio. With Python, you can automate this calculation across your entire crypto portfolio in seconds.

What Is the Kelly Criterion and Why Crypto Traders Use It

The Kelly Criterion was developed by John L. Kelly Jr. in 1956 at Bell Labs — originally to optimize signal transmission, not trading. It was later adopted by gamblers and professional investors, most famously by Ed Thorp (who used it to beat blackjack and later Wall Street) and Charlie Munger.

The core idea is elegant: given a repeatable bet with known odds, there is one exact fraction of your bankroll you should wager to maximize long-term growth. Bet too little and you leave money on the table. Bet too much and volatility will eventually ruin you — even with a positive edge.

For crypto traders, this matters enormously. Markets on Binance, Bybit, and OKX are volatile by nature. A single overleveraged position on a 10x perpetual contract can wipe out weeks of careful gains. Kelly gives you a defensible, mathematically grounded answer to the question every trader wrestles with: how much should I put in this trade?

Key Takeaway: The Kelly Criterion maximizes long-term portfolio growth by finding the optimal fraction of capital to risk per trade — not too much, not too little.

The Kelly Formula: Simple Math, Powerful Results

The basic Kelly formula has just two inputs:

Say you have been trading BTC/USDT on Binance for six months. Your strategy wins 58% of the time. Your average winning trade returns $120 while your average losing trade costs $80. That gives you R = 120 / 80 = 1.5. Plugging in: f = 0.58 − (0.42 / 1.5) = 0.58 − 0.28 = 0.30. The formula says risk 30% of capital per trade.

In practice, most professional traders use Half Kelly — 15% in this case — or even Quarter Kelly. Real-world trading involves estimation errors, slippage, and changing market conditions that pure math ignores. Scaling down buys you resilience.

Key Takeaway: Full Kelly is mathematically optimal but psychologically brutal. Half Kelly delivers roughly 75% of the growth with dramatically smaller drawdowns. Most professionals use it as a ceiling, not a target.

Implementing the Kelly Criterion in Python

Here is a clean Python implementation you can run locally or integrate directly into a trading bot. No external libraries are needed for the core calculation.

def kelly_fraction(win_rate: float, win_loss_ratio: float) -> float:
    """
    Calculate optimal position size using the Kelly Criterion.
    win_rate: probability of a winning trade (0.0 to 1.0)
    win_loss_ratio: average win / average loss
    Returns: fraction of capital to risk (0.0 to 1.0)
    """
    q = 1 - win_rate
    kelly = win_rate - (q / win_loss_ratio)
    return max(0.0, kelly)  # Kelly can be negative — never bet negative


# Example: BTC/USDT strategy on Binance
win_rate = 0.58
avg_win_usdt = 120
avg_loss_usdt = 80

win_loss_ratio = avg_win_usdt / avg_loss_usdt  # 1.5

full_kelly = kelly_fraction(win_rate, win_loss_ratio)
half_kelly = full_kelly / 2

print(f"Full Kelly:  {full_kelly:.2%}")  # 30.00%
print(f"Half Kelly:  {half_kelly:.2%}")  # 15.00%

account_balance = 10_000  # USDT
position_size_full = account_balance * full_kelly
position_size_half = account_balance * half_kelly

print(f"Full Kelly position: ${position_size_full:,.2f}")
print(f"Half Kelly position: ${position_size_half:,.2f}")

This is the foundation. But in real trading you do not know your win rate from a handful of trades — you estimate it from your execution history. The next step is computing Kelly dynamically from your actual trade log.

import numpy as np

def kelly_from_trade_history(returns: list) -> dict:
    """
    Calculate Kelly fraction from a list of trade returns.
    returns: list of percentage returns, e.g. [0.05, -0.03, 0.08]
    Positive = profit, Negative = loss.
    """
    if len(returns) < 10:
        raise ValueError("Need at least 10 trades for a reliable estimate")

    wins = [r for r in returns if r > 0]
    losses = [abs(r) for r in returns if r < 0]

    if not wins or not losses:
        return {"kelly": 0.0, "half_kelly": 0.0}

    win_rate = len(wins) / len(returns)
    avg_win = np.mean(wins)
    avg_loss = np.mean(losses)
    ratio = avg_win / avg_loss

    kelly = win_rate - ((1 - win_rate) / ratio)
    kelly = max(0.0, kelly)

    return {
        "win_rate": round(win_rate, 4),
        "avg_win": round(avg_win, 4),
        "avg_loss": round(avg_loss, 4),
        "win_loss_ratio": round(ratio, 4),
        "full_kelly": round(kelly, 4),
        "half_kelly": round(kelly / 2, 4),
    }


# Replace with your actual trade history from Bybit or OKX
trades = [
    0.05, -0.03, 0.08, -0.02, 0.12, -0.04,
    0.06, 0.09, -0.05, 0.07, -0.02, 0.11,
    -0.06, 0.04, 0.08, -0.03, 0.05, -0.04,
    0.10, -0.02
]

result = kelly_from_trade_history(trades)
for key, value in result.items():
    print(f"{key}: {value}")

Pulling Real Trade Data from Binance and Bybit

A Kelly calculation is only as good as the data behind it. Using made-up numbers defeats the purpose. Here is how to pull your actual execution history from Binance and feed it directly into the calculator.

# Requires: pip install python-binance numpy
from binance.client import Client
import numpy as np

API_KEY = "your_api_key"
API_SECRET = "your_api_secret"

client = Client(API_KEY, API_SECRET)

def get_binance_trade_returns(symbol: str, limit: int = 200) -> list:
    """
    Fetch closed trades for a symbol and compute percentage returns.
    Groups consecutive buy/sell trades into round trips.
    """
    trades = client.get_my_trades(symbol=symbol, limit=limit)
    returns = []
    buy_price = None

    for trade in trades:
        price = float(trade["price"])
        is_buyer = trade["isBuyer"]

        if is_buyer:
            buy_price = price
        elif buy_price is not None:
            pnl = (price - buy_price) / buy_price
            returns.append(pnl)
            buy_price = None

    return returns


# Pull BTC/USDT history and calculate Kelly
returns = get_binance_trade_returns("BTCUSDT", limit=200)

if len(returns) >= 10:
    result = kelly_from_trade_history(returns)
    print(f"Win rate: {result['win_rate']:.0%}")
    print(f"Recommended position size: {result['half_kelly']:.2%} of account")
else:
    print("Not enough closed trades yet. Keep trading and check back.")

For Bybit users, the pybit library provides a similar interface via get_executions(). On OKX, the REST endpoint /api/v5/trade/fills returns your fill history in the same structure. The Kelly math is identical — only the data source changes.

Key Takeaway: Use at least 30–50 closed trades before trusting your Kelly output. Fewer trades means high variance in your win rate estimate, which produces unreliable position sizes.

Combining Kelly with Real-Time Signals from VoiceOfChain

Kelly Criterion tells you how much to risk. It does not tell you when to enter. That is where signal platforms like VoiceOfChain come in. VoiceOfChain provides real-time trading signals across major crypto assets along with historical accuracy metrics — which map directly onto the win_rate input in your Kelly formula.

The workflow: VoiceOfChain emits a signal for ETH/USDT on Binance with a stated 65% historical accuracy over the past 90 days. You feed that win rate into Kelly alongside your own average win/loss ratio from past ETH trades. The result is a position size calibrated to both the signal quality and your personal execution history — two inputs most traders never combine systematically.

import requests

VOC_API_URL = "https://api.voiceofchain.com/v1/signals"
VOC_API_KEY = "your_voc_api_key"

def get_signal_win_rate(symbol: str) -> float:
    """Fetch historical signal accuracy for a symbol from VoiceOfChain."""
    response = requests.get(
        f"{VOC_API_URL}/{symbol}/stats",
        headers={"Authorization": f"Bearer {VOC_API_KEY}"}
    )
    data = response.json()
    return data.get("win_rate", 0.5)  # default 50% if unavailable


# Your personal average reward-to-risk from past ETH trades
avg_win = 0.08
avg_loss = 0.05
ratio = avg_win / avg_loss  # 1.6

signal_win_rate = get_signal_win_rate("ETHUSDT")

kelly = kelly_fraction(signal_win_rate, ratio)
print(f"Signal win rate: {signal_win_rate:.0%}")
print(f"Full Kelly: {kelly:.2%}")
print(f"Half Kelly (recommended): {kelly/2:.2%}")

This combination adapts automatically. If VoiceOfChain signals for a specific asset have been underperforming, the win rate input drops, and Kelly reduces your position size without any emotional override. The system self-calibrates.

Common Mistakes When Applying Kelly to Crypto

The Kelly Criterion is simple in theory and easy to misapply in practice. These are the mistakes that cost traders money:

Kelly Fraction Reference: What Different Values Mean in Practice
Kelly FractionInterpretationRecommended Action
Negative or 0%No detectable edgeDo not trade this strategy
1%–5%Small edge, high uncertaintyUse Quarter Kelly or gather more data
5%–15%Moderate edgeUse Half Kelly — standard for most strategies
15%–25%Strong edgeUse Half Kelly — double-check for overfitting
Above 25%Unusually high edgeBe suspicious — likely too few trades or curve-fitting

Frequently Asked Questions

Can I use Kelly Criterion with leverage trading on Binance or Bybit?
Yes, but carefully. Kelly should be applied to your notional position size, not just the margin you post. If you use 5x leverage on Bybit and Kelly says risk 10% of capital, you should post only 2% as margin to maintain the correct notional exposure. Confusing margin with notional is a common and expensive error.
How many trades do I need before I can trust my Kelly calculation?
A minimum of 30 closed trades is needed for any reliability, but 100+ is the professional standard. With fewer trades, your win rate estimate carries too much statistical noise and the Kelly fraction you compute may be far from your true edge. Build sample size through backtesting or paper trading first.
What is the difference between Full Kelly and Half Kelly?
Full Kelly maximizes long-term geometric growth but produces large drawdowns — often 30–50% peak-to-trough — because it assumes you know your edge perfectly. Half Kelly delivers roughly 75% of the growth with much smaller drawdowns, making it far more manageable in practice. Most professional traders and quant funds use fractional Kelly between 0.25x and 0.5x.
Does Kelly Criterion work specifically for crypto, or is it designed for stocks?
Kelly works for any repeatable bet with quantifiable odds, and crypto is no exception. The higher volatility of crypto markets on exchanges like OKX and Coinbase actually makes proper position sizing more important, not less. The math is identical — only the inputs change depending on your strategy and asset class.
What should I do if my Kelly fraction comes out negative?
A negative Kelly result is the formula telling you this strategy has no detectable edge — do not trade it. Either your win rate is too low, your losses are too large relative to your wins, or you do not have enough trade history. Do not override the signal. Fix the strategy or gather more data before committing real capital.
Can Kelly Criterion be applied to long-term crypto investing or DCA?
Kelly is designed for active trading with discrete, repeatable bets that have measurable outcomes. For DCA or long-term holding on Coinbase or similar platforms, it is less applicable since there are no clean win/loss events to measure. That said, you can use Kelly to size your initial allocation to crypto relative to other asset classes in a mixed portfolio.

Conclusion

The Kelly Criterion will not turn a losing strategy into a profitable one — but it will stop a winning strategy from destroying your account through poor position sizing. Most traders fail not on the entry signal but on the bet size: too large when confident, too small when scared, no consistency either way.

With the Python code above, you can compute your optimal fraction in seconds, update it as your trade history grows, and plug it directly into a workflow powered by real-time signals from platforms like VoiceOfChain. Start with Half Kelly, track your results over 30+ trades, and adjust. The traders who survive long enough to compound are the ones who never let a single bad trade end the game.

Key Takeaway: Kelly Criterion is not magic — it is discipline made mathematical. Implement it once, use it consistently, and it becomes one of the most valuable tools in your trading stack.
◈   more on this topic
⌘ api Kraken API Documentation for Crypto Traders: Essentials and Examples ◉ basics Mastering the ccxt library documentation for crypto traders