Generate and size combinations of wagers (straights and parlays).
Summary
Functions
Generate combinations of bets based on the provided sizes.
Calculate optimal Kelly stakes for a set of correlated bets.
Types
Functions
@spec generate([PainStaking.edge()], size_spec()) :: [ {PainStaking.edge(), [integer()]} ]
Generate combinations of bets based on the provided sizes.
sizes can be a list of integers, a range, or the atom :all.
Returns a list of {edge, [indices]} where indices are the positions in base_edges.
Examples
iex> e1 = {"1", [prob: 0.5], [eu: 2.0]}
iex> e2 = {"2", [prob: 0.5], [eu: 2.0]}
iex> combos = PainStaking.Combinations.generate([e1, e2], :all)
iex> Enum.count(combos)
3
@spec kelly([PainStaking.edge()], [{PainStaking.edge(), [integer()]}], keyword()) :: {:ok, [PainStaking.tagged_number()]}
Calculate optimal Kelly stakes for a set of correlated bets.
This function accounts for the correlations between parlays and their underlying legs by maximizing expected logarithmic growth across the joint distribution.
For small problems uses exact gradient ascent over all 2^N scenarios. For larger problems uses a mean-variance quadratic programming approximation which computes all moments analytically — no scenario enumeration.
Examples
iex> e1 = {"A", [prob: 0.5], [eu: 2.2]}
iex> e2 = {"B", [prob: 0.5], [eu: 2.2]}
iex> base = [e1, e2]
iex> candidates = PainStaking.Combinations.generate(base, [1, 2])
iex> {:ok, results} = PainStaking.Combinations.kelly(base, candidates)
iex> Enum.count(results)
3
iex> Enum.all?(results, fn {name, amt} -> is_binary(name) and is_float(amt) end)
true