Simulators¶
Simulators are classes that take in a bankroll and a strategy and apply that strategy to a situation. They can be used to evaluate the efficacy of strategies in certain domains.
Repeated Binary Simulator¶
- class keeks.simulators.repeated_binary.RepeatedBinarySimulator(payoff: float, loss: float, fee_per_bet: float, probability: float, trials: int = 1000, seed: int | None = None)[source]¶
Bases:
objectSimulator for binary betting strategies with a fixed probability.
This simulator uses the same probability for each trial, simulating repeated bets on events with identical odds.
- Parameters:
payoff (float) – The amount won per unit bet on a successful outcome.
loss (float) – The amount lost per unit bet on an unsuccessful outcome.
fee_per_bet (float) – The flat fee charged once per settled bet, regardless of outcome. This is an absolute bankroll amount, not a fraction of the stake, so it does not scale with bet size: it is subtracted from a winning settlement and added to a losing one. Note this differs in unit from the singular
transaction_cost_ratetaken by strategies inkeeks.binary_strategies, which is a per-unit fraction of the bet used for sizing.probability (float) – The fixed probability of a successful outcome for all trials.
trials (int, default=1000) – The number of betting trials to simulate.
seed (int or None, default=None) – Seed for a private outcome generator. When omitted, the process-global
randomgenerator is used for backward compatibility.
- Raises:
ValueError – If
payoffis not finite and positive, iflossorfee_per_betis not finite and nonnegative, ifprobabilityis not finite within[0, 1], or iftrialsis not a nonnegative integer, or ifseedis not a nonnegative integer orNone.
Notes
RNG family and seeding. All outcome draws come from Python’s
random.Random- this is the one simulator in the package on the stdlib generator family; the multi-outcome and allocation simulators draw from private numpynumpy.random.Generatorinstances on spawnedSeedSequencechildren, so cross-generation seeded comparisons are not aligned by seed alone. With aseedthe outcome generator is private and a seeded run replays byte-identically; without one, the process-globalrandomgenerator drives the draws.- evaluate_strategy(strategy: BaseStrategy, bankroll: BankRoll) None[source]¶
Evaluate a betting strategy over multiple trials with fixed probability.
For each trial, the strategy is evaluated with the fixed probability, and the bankroll is updated based on the outcome. The simulation stops early if the bankroll is depleted (bankruptcy).
- Parameters:
strategy (BaseStrategy) – The betting strategy to evaluate.
bankroll (BankRoll) – The bankroll to use for the simulation.
- Returns:
The bankroll object is updated in-place with the results of the simulation.
- Return type:
None
- Raises:
ValueError – If
strategyis aBaseStrategywhosepayofforlossdiffers from this simulator’s, since it would then size bets against different odds than the ones the simulator settles at, or if the strategy returns a non-finite or out-of-range stake fraction.
Random Binary Simulator¶
- class keeks.simulators.random_binary.RandomBinarySimulator(payoff: float, loss: float, fee_per_bet: float, trials: int = 1000, stdev: float = 0.1, seed: int | None = None)[source]¶
Bases:
objectSimulator for binary betting strategies with random probabilities.
This simulator generates random probabilities for each trial, centered around 0.5 with a configurable standard deviation. It evaluates a betting strategy against these random probabilities and updates the bankroll accordingly.
- Parameters:
payoff (float) – The amount won per unit bet on a successful outcome.
loss (float) – The amount lost per unit bet on an unsuccessful outcome.
fee_per_bet (float) – The flat fee charged once per settled bet, regardless of outcome. This is an absolute bankroll amount, not a fraction of the stake, so it does not scale with bet size: it is subtracted from a winning settlement and added to a losing one. Note this differs in unit from the singular
transaction_cost_ratetaken by strategies inkeeks.binary_strategies, which is a per-unit fraction of the bet used for sizing.trials (int, default=1000) – The number of betting trials to simulate.
stdev (float, default=0.1) – The standard deviation of the normal distribution used to generate probabilities. Samples are clamped to [0.0, 1.0].
seed (int or None, default=None) – Seed for private outcome and probability generators. When omitted, the process-global
randomandnumpy.randomgenerators are used for backward compatibility.
- Raises:
ValueError – If
payoffis not finite and positive, ifloss,fee_per_betorstdevis not finite and nonnegative, or iftrialsis not a nonnegative integer, or ifseedis not a nonnegative integer orNone.
Notes
RNG family and seeding. This simulator mixes two generator families: bet outcomes draw from Python’s
random.Randomand win probabilities from a numpynumpy.random.Generator(default_rng). With aseed, both generators are private instances driven by that one integer and a seeded run replays byte-identically; without one, both fall back to the process-global generators (random.randomandnumpy.random.normal). Cross-family seeded comparisons with the multi-outcome and allocation simulators, which draw from spawnedSeedSequencechildren only, are not aligned by seed alone - see the reproducibility contracts there.- evaluate_strategy(strategy: BaseStrategy, bankroll: BankRoll) None[source]¶
Evaluate a betting strategy over multiple trials.
For each trial, a random probability is generated, the strategy is evaluated with this probability, and the bankroll is updated based on the outcome. The simulation stops early if the bankroll is depleted (bankruptcy).
- Parameters:
strategy (BaseStrategy) – The betting strategy to evaluate.
bankroll (BankRoll) – The bankroll to use for the simulation.
- Returns:
The bankroll object is updated in-place with the results of the simulation.
- Return type:
None
- Raises:
ValueError – If
strategyis aBaseStrategywhosepayofforlossdiffers from this simulator’s, since it would then size bets against different odds than the ones the simulator settles at, or if the strategy returns a non-finite or out-of-range stake fraction.
Random Uncertain Binary Simulator¶
- class keeks.simulators.random_uncertain_binary.RandomUncertainBinarySimulator(payoff: float, loss: float, fee_per_bet: float, trials: int = 1000, stdev: float = 0.1, uncertainty_stdev: float = 0.05, seed: int | None = None)[source]¶
Bases:
objectSimulator for binary betting strategies with random probabilities and uncertainty.
This simulator generates random probabilities for each trial, centered around 0.5 with a configurable standard deviation. It adds an additional uncertainty factor to the actual outcome probability, simulating imperfect information.
- Parameters:
payoff (float) – The amount won per unit bet on a successful outcome.
loss (float) – The amount lost per unit bet on an unsuccessful outcome.
fee_per_bet (float) – The flat fee charged once per settled bet, regardless of outcome. This is an absolute bankroll amount, not a fraction of the stake, so it does not scale with bet size: it is subtracted from a winning settlement and added to a losing one. Note this differs in unit from the singular
transaction_cost_ratetaken by strategies inkeeks.binary_strategies, which is a per-unit fraction of the bet used for sizing.trials (int, default=1000) – The number of betting trials to simulate.
stdev (float, default=0.1) – The standard deviation of the normal distribution used to generate probabilities. Samples are clamped to [0.0, 1.0].
uncertainty_stdev (float, default=0.05) – The standard deviation of the normal distribution used to add uncertainty to the actual outcome probability. The resulting outcome probability is clamped to [0.0, 1.0].
seed (int or None, default=None) – Seed for private outcome, probability, and uncertainty generators. When omitted, the process-global
randomandnumpy.randomgenerators are used for backward compatibility.
- Raises:
ValueError – If
payoffis not finite and positive, ifloss,fee_per_bet,stdevoruncertainty_stdevis not finite and nonnegative, iftrialsis not a nonnegative integer, or ifseedis not a nonnegative integer orNone.
Notes
RNG family and seeding. Like
RandomBinarySimulator, this simulator mixes two generator families: bet outcomes draw from Python’srandom.Randomand both the win probabilities and the uncertainty adjustments from one numpynumpy.random.Generator(default_rng). With aseed, all generators are private instances driven by that one integer and a seeded run replays byte-identically; without one, every draw falls back to the process-global generators. Cross-family seeded comparisons with the multi-outcome and allocation simulators, which draw from spawnedSeedSequencechildren only, are not aligned by seed alone - see the reproducibility contracts there.- evaluate_strategy(strategy: BaseStrategy, bankroll: BankRoll) None[source]¶
Evaluate a betting strategy over multiple trials with uncertainty.
For each trial, a random probability is generated, the strategy is evaluated with this probability, but the actual outcome is determined by the probability plus a random uncertainty factor. The simulation stops early if the bankroll is depleted (bankruptcy).
- Parameters:
strategy (BaseStrategy) – The betting strategy to evaluate.
bankroll (BankRoll) – The bankroll to use for the simulation.
- Returns:
The bankroll object is updated in-place with the results of the simulation.
- Return type:
None
- Raises:
ValueError – If
strategyis aBaseStrategywhosepayofforlossdiffers from this simulator’s, since it would then size bets against different odds than the ones the simulator settles at, or if the strategy returns a non-finite or out-of-range stake fraction.
Historical Binary Simulator¶
Replays a log of real bets: each trial uses a recorded probability and settles on the
recorded outcome, so you can ask what a strategy would have done with your own bets.
It draws no random numbers and takes no seed; the number of trials is the length
of the log. Settlement matches the repeated binary simulator.
from keeks import BankRoll, HistoricalBinarySimulator, KellyCriterion
simulator = HistoricalBinarySimulator(
payoff=1.0, loss=1.0, fee_per_bet=0.0,
probabilities=[0.55, 0.60, 0.52],
outcomes=[True, False, True],
)
bankroll = BankRoll(initial_funds=1000)
simulator.evaluate_strategy(KellyCriterion(payoff=1.0, loss=1.0, transaction_cost_rate=0.0), bankroll)
- class keeks.simulators.historical_binary.HistoricalBinarySimulator(payoff: float, loss: float, fee_per_bet: float, probabilities: Sequence[float], outcomes: Sequence[bool | int])[source]¶
Bases:
objectReplay a recorded sequence of binary bets through a strategy.
Each trial uses the recorded probability and settles on the recorded outcome, so the run answers “what would this strategy have done with my bets?”. Settlement, validation, hooks and early-stop behaviour match
RepeatedBinarySimulator. No random numbers are drawn, so there is noseed.- Parameters:
payoff (float) – The amount won per unit bet on a successful outcome.
loss (float) – The amount lost per unit bet on an unsuccessful outcome.
fee_per_bet (float) – The flat fee, in currency, charged once per settled bet.
probabilities (sequence of float) – The probability estimate for each recorded bet, each in
[0, 1].outcomes (sequence of bool or int) – Whether each recorded bet won:
True/Falseor1/0. Must be the same length asprobabilities.
- Raises:
ValueError – If the sequences differ in length, a probability is not finite within
[0, 1], an outcome is not boolean-like, or the odds controls are invalid.
- evaluate_strategy(strategy: BaseStrategy, bankroll: BankRoll) None[source]¶
Replay the recorded bets through
strategy, updatingbankrollin place.The run stops early if the bankroll is depleted or a settlement raises
RuinError(reported as a warning).- Parameters:
strategy (BaseStrategy) – The betting strategy to evaluate.
bankroll (BankRoll) – The bankroll to use for the simulation.
- Raises:
ValueError – If the strategy’s
payofforlossdiffers from this simulator’s, or it returns an invalid stake fraction.