When the Fee Eats the Edge
The textbook Kelly criterion assumes the only thing standing between you and your payoff is the outcome. Real instruments charge you either way, and the charge is very often a flat fee: a fixed amount per settled bet that does not care how much you staked.
That combination has a sharp consequence. keeks sizes bets in proportion to your edge, so a thin edge means a small stake, and a small stake is exactly where a flat fee does the most damage.
The obvious version
Start with the easy case, which is the one that gets written about. A win pays you the payoff on your stake and then the fee comes off:
amt = (self.payoff * bet_amount) - self.transaction_costs
if amt >= 0:
bankroll.deposit(amt)
else:
bankroll.withdraw(abs(amt))
That else is not defensive programming. If the fee is larger than the payoff on your stake, you won the bet and your bankroll went down. The break-even stake is fee / payoff, and Kelly walks you toward it as your edge thins:
edge p kelly f stake win pays net
0.200 0.6000 0.2000 200.00 200.00 199.00
0.050 0.5250 0.0500 50.00 50.00 49.00
0.010 0.5050 0.0100 10.00 10.00 9.00
0.002 0.5010 0.0020 2.00 2.00 1.00
0.001 0.5005 0.0010 1.00 1.00 -0.00
A one-dollar fee, a thousand-dollar bankroll, even money. At a 0.1% edge Kelly stakes exactly a dollar, and the fee takes all of it.
This is a real effect and it is worth having handled. It is also not the expensive one.
The version that actually costs you
Look at the 1% edge row. Kelly stakes ten dollars, a win pays nine, nothing looks broken. A one-dollar fee on a ten-dollar bet reads as a 10% cost: annoying, survivable.
Except the fee is not competing with your stake. It is competing with your profit, and at a 1% edge on a ten-dollar bet your expected profit is ten cents.
The fee is ten times your entire edge.
Run it and the ten-dollar-bet-with-a-one-dollar-fee that sounded survivable is not:
500 bets at a 1% edge, $1,000 bankroll, varying the flat fee
fee final bankroll
0.00 1343.14
0.50 1058.62
1.00 774.10
2.00 205.05
5.00 1.71
The edge is real and unchanged in every row. At a fee of zero you make 34%. At one dollar you lose a quarter of the bankroll. At five you are wiped out.
The break-even, and why it is a square root
Per bet, your expected gross profit is your edge times your stake. Under Kelly at even money the stake is roughly your edge times your bankroll, so:
expected gross profit per bet = edge x stake = edge² x bankroll
Set that against the fee and the condition to make money at all is
edge² x bankroll > fee i.e. edge > sqrt(fee / bankroll)
The edge is squared because it enters twice: once as your advantage per unit staked, and once through Kelly deciding how much to stake. That is the part I find genuinely counterintuitive, and it is why fees feel so much worse in practice than a percentage-of-stake calculation suggests.
For a one-dollar fee and a thousand-dollar bankroll that is sqrt(0.001) = 3.16%. Not the 0.1% where a win literally loses money, thirty times higher.

The simulation crosses break-even right where the formula says: expected gross profit per bet is 0.999 against a 1.00 fee at a 3.16% edge, and the median outcome flips from losing to winning within a few tenths of a percent of that line.
What the square root implies
The right panel is the same formula read the other way. Because the required edge falls with the square root of the bankroll, quadrupling your bankroll only halves the edge you need:
| bankroll | edge required |
|---|---|
| $1,000 | 3.16% |
| $10,000 | 1.00% |
| $100,000 | 0.32% |
| $1,000,000 | 0.10% |
A 1% edge is a good edge. It is unprofitable at a thousand dollars against a one-dollar fee and comfortably profitable at ten thousand, with nothing changing but the size of the account. Fixed costs are a threshold on capital, not a tax on returns, and the threshold moves slowly.
What to do about it
Compute net-of-cost expected value before sizing, not after settling. The quantity that decides whether to bet is edge x stake - fee, and it is knowable before you place anything. A strategy that sizes on gross edge and discovers the fee at settlement is sizing for a different game.
Treat a non-positive net as a no-bet. Not a small bet. If the arithmetic says this wager cannot pay for itself, the correct stake is zero, and clamping it to something tiny makes it worse because the fee does not shrink with it.
Push fees into the payoff terms. keeks’ Kelly does this directly:
adjusted_payoff = self.payoff - self.transaction_cost
adjusted_loss = self.loss + self.transaction_cost
Once the costs are inside the payoff structure, the sizing formula is solving the right problem and everything downstream follows. Note the unit though: strategies take transaction_cost as a per-unit fraction of the stake, while simulators take transaction_costs as a flat fee per settled bet. The distinction is exactly the subject of this post, and the two names differ by one letter, so it is worth checking which one you are setting.
And know your capital threshold. sqrt(fee / bankroll) is one line of arithmetic and it tells you whether an edge is worth pursuing at your size before you build anything.
Running it
from keeks.bankroll import BankRoll
from keeks.binary_strategies import KellyCriterion
from keeks.simulators.repeated_binary import RepeatedBinarySimulator
bank = BankRoll(initial_funds=1000.0, percent_bettable=1.0, max_draw_down=1.0)
strategy = KellyCriterion(payoff=1.0, loss=1.0, transaction_cost=0.0)
sim = RepeatedBinarySimulator(payoff=1.0, loss=1.0, transaction_costs=1.0,
probability=0.505, trials=500, seed=7)
sim.evaluate_strategy(strategy, bank)
print(bank.total_funds)
pip install keeks==0.6.0.
Stay in the loop
Get notified when I publish new posts. No spam, unsubscribe anytime.