Skip to content

Instantly share code, notes, and snippets.

@nenadg
Forked from breeko/absorbent_barriers.py
Created January 31, 2020 20:32
Show Gist options
  • Save nenadg/fee83f623217a81f191cb22c0dc37ea7 to your computer and use it in GitHub Desktop.
Save nenadg/fee83f623217a81f191cb22c0dc37ea7 to your computer and use it in GitHub Desktop.
Testing the idea of survival, absorbent barriers based on different strategies and payoffs
import numpy as np
import matplotlib.pyplot as plt
MAX_NUM_STEPS = 1000000
NUM_TRIALS = 100
START_CAPITAL = 100
MIN_BET_SIZE = 0.01
def test(payout, strategy, start_capital=START_CAPITAL, num_trials=NUM_TRIALS, max_num_steps=MAX_NUM_STEPS, min_bet_size=MIN_BET_SIZE):
""" Returns the capital based on given strategy
Inputs:
payout (function): returns payout, takes no arguments
strategy (function): returns amount to wager based on capital
start_capital (number): how much capital to start with
num_trials (integer): how many trials to run
max_num_step (integer): when to cut testing to avoid running forever
Returns:
List of performance based on the number of trials.
"""
results = []
for num_trial in range(num_trials):
capital = start_capital
num_step = 0
result_trial = [capital]
while capital > 0 and num_step < max_num_steps:
bet_size = min(capital, max(min_bet_size, strategy(capital)))
bet_return = payout() * bet_size
capital += bet_return
result_trial.append(capital)
num_step += 1
results.append(result_trial)
return results
def create_payout(payouts, probs, seed=None):
""" Creates a function that generates random payounts based on payouts and probabilities
Inputs:
payouts (list): list of possible payouts
probs (list): list of payout probabilities (must be same length as payouts and sum to 1)
seed (integer): seed to initialize random probabilities
Returns:
Function that returns payout based on probabilites provided
"""
assert len(payouts) == len(probs), "Payouts and probabilities must be of equal length"
assert sum(probs) == 1, "Probabilites must add up to 1"
np.random.seed(seed)
def payout():
return np.random.choice(payouts, p=probs)
return payout
def display_results(results):
""" Displays the results on series of tests
Inputs:
results (list): result of trials
Outputs:
None
"""
num_trials = len(results)
num_steps = [len(result) for result in results]
max_num_step = max(num_steps)
total_alive = sum([1 for result in results if result[-1] > 0])
deaths = [len(result) for result in results if result[-1] <= 0]
mean_capital = [0 for _ in range(max_num_step)]
mean_survivors_capital = [0 for _ in range(max_num_step)]
survivors = [0 for _ in range(max_num_step)]
quarter_point = max(num_steps) // 4
mid_point = max(num_steps) // 2
capital_quarter_point = [result[quarter_point] for result in results if len(result) > quarter_point]
capital_mid_point = [result[mid_point] for result in results if len(result) > mid_point]
capital_end = [result[max_num_step - 1] for result in results if len(result) > max_num_step - 1]
for result in results:
for idx, val in enumerate(result):
mean_capital[idx] += val / num_trials
# calculate running average of just survivors
survivors[idx] += 1
cur_survivors_capital = mean_survivors_capital[idx]
mean_survivors_capital[idx] += (val - cur_survivors_capital) / survivors[idx]
f = plt.figure(figsize=(10,14))
plt.subplot(711)
for result in results:
plt.plot(result)
plt.title("Performance")
plt.xlabel("Number of Steps")
plt.ylabel("Capital")
plt.subplot(712)
plt.plot(mean_capital)
plt.title("Mean capital")
plt.xlabel("Number of Steps")
plt.ylabel("Capital")
plt.subplot(713)
plt.plot(mean_survivors_capital)
plt.title("Mean survivor's capital")
plt.xlabel("Number of Steps")
plt.ylabel("Capital")
plt.subplot(714)
plt.title("Death rate")
plt.xlabel("Number of Steps")
plt.ylabel("Individuals")
plt.hist(deaths,bins=50)
plt.subplot(715)
plt.title("Quarter point capital distribution. {} steps".format(quarter_point))
plt.xlabel("Capital")
plt.ylabel("Indivduals")
plt.hist(capital_quarter_point,bins=50)
plt.subplot(716)
plt.title("Mid point capital distribution. {} steps".format(mid_point))
plt.xlabel("Capital")
plt.ylabel("Indivduals")
plt.hist(capital_mid_point,bins=50)
plt.subplot(717)
plt.title("End capital distribution. {} steps".format(max_num_step))
plt.xlabel("Capital")
plt.ylabel("Individuals")
plt.hist(capital_end,bins=50)
plt.tight_layout()
print("Number of individuals still alive: {} ({:0.0f}%)".format(total_alive, total_alive / len(results) * 100 ))
print("Number of steps alive: ")
print("10%: {:0.0f} \t25%: {:0.0f} \t50%: {:0.0f} \t99%: {:0.0f}".format(
np.percentile(num_steps, 10),
np.percentile(num_steps, 25),
np.percentile(num_steps, 50),
np.percentile(num_steps, 99)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment