Keeks
Python bet sizing and bankroll simulation for developers modeling repeated binary outcomes.
Given your estimated win probability, payoff, loss, and normalized transaction cost, Keeks calculates a model-derived fraction of the current bankroll to stake. You can then run the same rule over repeated trials and inspect the bankroll path.
Nine-strategy risk benchmark — what growth, drawdown and
early-stop behaviour each shipped strategy actually produces under identical, seeded assumptions,
and how that changes with edge, cost, probability-estimate error and the bankroll's loss cap.
Regenerate every number with uv run python benchmarks/strategy_benchmark.py.
Install
pip install keeks
Keeks supports Python 3.10 through 3.14.
Get a bet fraction
from keeks.binary_strategies import KellyCriterion
bankroll = 1_000.0
strategy = KellyCriterion(
payoff=1.0,
loss=1.0,
transaction_cost=0.01,
)
fraction = strategy.evaluate(probability=0.55, current_bankroll=bankroll)
amount = bankroll * fraction
print(f"Bankroll fraction: {fraction:.4%}")
print(f"Amount from a $1,000 bankroll: ${amount:.2f}")
Bankroll fraction: 9.0009%
Amount from a $1,000 bankroll: $90.01
evaluate() returns a fraction, not a currency amount. The example multiplies
that fraction by the current bankroll only to make the result concrete.
Compare repeated-bet strategies
Keeks includes a headless comparison example that gives every strategy a fresh bankroll under the same repeated-bet inputs:
python -m examples.strategy_comparison
The chart is one simulated comparison under the example's assumptions. It does not validate the probability estimate or predict future results.
Choose a strategy
All nine strategies expose evaluate(probability, current_bankroll), but their
constructors and sizing rules differ.
| Strategy | Choose it when you want to model |
|---|---|
KellyCriterion |
Full Kelly sizing from a binary win probability, payoff, loss, and cost. |
FractionalKellyCriterion |
A fixed fraction of the full-Kelly result. |
DrawdownAdjustedKelly |
Kelly sizing scaled by an acceptable-drawdown input. |
OptimalF |
A geometric-growth rule based on a supplied win rate, with a risk-fraction cap. |
FixedFractionStrategy |
A constant fraction above a minimum probability; useful as a baseline. |
CPPIStrategy |
A cushion-based rule relative to a bankroll floor. |
DynamicBankrollManagement |
A fraction adjusted from recent recorded outcomes. |
MertonShare |
A CRRA risk-aversion rule adapted to binary outcomes. |
NaiveStrategy |
A positive-expected-value rule without utility-based sizing. |
See the strategy API for constructor parameters and formulas.
Simulate a bankroll
Once you have chosen a strategy, pass it and a fresh BankRoll to a simulator:
from keeks.bankroll import BankRoll
from keeks.binary_strategies import FractionalKellyCriterion
from keeks.simulators.repeated_binary import RepeatedBinarySimulator
bankroll = BankRoll(
initial_funds=1_000.0,
percent_bettable=0.8,
max_draw_down=0.3,
)
strategy = FractionalKellyCriterion(
payoff=1.0,
loss=1.0,
transaction_cost=0.01,
fraction=0.5,
)
simulator = RepeatedBinarySimulator(
payoff=1.0,
loss=1.0,
transaction_costs=0.01,
probability=0.55,
trials=1_000,
)
simulator.evaluate_strategy(strategy, bankroll)
print(f"Final bankroll: ${bankroll.total_funds:.2f}")
bankroll.plot_history(fname="bankroll-history.png")
The test suite executes this exact block as a seeded, down-scaled demo — the simulator clamped to 50 trials with a fixed seed and the plot rendered headlessly — so the example stays runnable; the narrative above describes the full 1,000-trial run.
Simulation mutates the bankroll and records its history. Use matching payoff and
Simulation mutates the bankroll and records its history. Use matching payoff and
loss assumptions in the strategy and simulator: Keeks enforces the match. Every
simulator's evaluate_strategy checks that a BaseStrategy instance's payoff
and loss agree with the odds it settles at, and raises ValueError on a
mismatch. Duck-typed strategies that carry no odds of their own are not checked —
their compatibility stays your responsibility. The cost assumption is a separate
matter — see the note below.
Repeated sizing is not one-time pricing
strategy.evaluate(...) answers a repeated-bet question:
Given this binary model, what fraction of the current bankroll does this rule allocate now?
find_indifference_price(...) and supported
strategy.calculate_max_entry_price(...) methods answer a different question:
Given possible outcomes and their probabilities, what is the maximum entry price that leaves modeled utility unchanged for a one-time gamble?
Run the shipped decision-theory example with:
python -m examples.st_petersburg_paradox
See examples/st_petersburg_paradox.py and
the utilities documentation for
the one-time workflow.
Safety semantics and model limits
- Strategy fractions are floored at zero and capped so the modeled loss plus transaction cost cannot allocate more than the current bankroll.
BankRollcan restrict the bettable percentage and stop a simulation when a withdrawal breaches its configured maximum drawdown.- These constraints apply to the values in Keeks' binary model. They do not prevent losses, verify your probability estimate, or model spreads, slippage, market impact, venue-specific commissions, correlated positions, or portfolio rebalancing.
- A strategy's
transaction_costis a per-unit fractional cost that scales with stake size. A simulator'stransaction_costs(plural) is a flat, absolute bankroll amount charged once per settled bet. The two are different units — passing the same number to both models two different real-world costs, and Keeks does not convert between them. - Kelly-family strategies gate bets behind a default
min_probability=0.5: a trial probability below it returns 0.0 regardless of payoff asymmetry. Withpayoff=10,loss=1, and a 0.3 win probability, the true Kelly fraction is about 0.23, butevaluatereturns 0.0 until you pass a lowermin_probability.OptimalFhardcodes the same 0.5 gate.
Documentation and examples
- Full documentation
- Getting started
- Strategy API
- Bankroll API
- Simulators
- Nine-strategy risk benchmark
examples/strategy_comparison.pyexamples/st_petersburg_paradox.py
References
- [1] A New Interpretation of Information Rate - The original Kelly Criterion paper
- [2] The Kelly Criterion in Blackjack, Sports Betting, and the Stock Market - A practical guide to applying the Kelly Criterion
- [3] Fortune's Formula - The untold story of the scientific betting system that beat the casinos and Wall Street
Disclaimer
Keeks is for educational purposes. It does not provide investment, legal, or tax advice. Models and simulations can be wrong, and financial loss is possible. You are responsible for validating your inputs and deciding whether any real-world use is appropriate.
Contributing
Contributions are welcome. To set up the project and run its checks:
git clone https://github.com/wdm0006/keeks.git
cd keeks
make setup
make install-dev
make test
make lint
Build the documentation with:
make docs
Keeks is available under the MIT License.
Metadata
Release files for keeks 0.8.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| keeks-0.8.0.tar.gz | 1.2 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| keeks-0.8.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.3 MB
Release files / keeks-0.8.0.tar.gz
| Download URL | keeks-0.8.0.tar.gz |
|---|---|
| Size | 1.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bee34b256cf03f38109758cafd8335e1bfdca72572e274484238340c1c21152a
|
|
BLAKE2b-256 checksum How to use checksums |
f0c16c427d1f82e2270d2250334c86249b7ac40f3e6334f8421aa6f21577cdb0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 8, 2026.
Transparency logRelease files / keeks-0.8.0-py3-none-any.whl
| Download URL | keeks-0.8.0-py3-none-any.whl |
|---|---|
| Size | 54.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
01604f92671e2039128d7590b9fe62eb131676337561d74c2e660dc8df5abe56
|
|
BLAKE2b-256 checksum How to use checksums |
2764fda40f5c7c1e6e9fe30e01e5149328824abb6d5377b4a4035e9f164fa38b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 8, 2026.
Transparency log