In [30]:
!python2.7 optimize.py
In [4]:
%%file roll.py
"""
rolls a slightly biased (100-sided) die
"""
import random
import numpy as np
import numpy.random as npr
import state
def win(x):
'''
a simple win/loss: where win if (100 > x > 50)
'''
return int(bool(100 > x > 50))
def die():
'''
a simple win/loss: where win if (100 > random(1,100) > 50)
'''
rng = state.random_state(module=random)
return win(rng.randint(1,100))
_win = np.vectorize(win)
def dice(N=1):
'''
a simple win/loss: where win if (100 > random(1,100,N) > 50)
'''
rng = state.random_state(module=npr)
return _win(rng.randint(1,100,N))
def many_die(N=1):
'''roll simple (biased) win/loss N times'''
rolls = []
for i in range(N):
rolls.append(die())
return rolls
# EOF
In [40]:
# %load use_roll.py
"""
usage testing of roll
"""
import roll
def multi_roll(N, pool):
_die = lambda i:roll.die()
rolls = np.asarray(pool.map(_die, xrange(N)), int)
return rolls
if __name__ == '__main__':
N = 25
import time
import pathos
pool = pathos.pools.ThreadPool()
start = time.time()
print(roll.many_die(N))
print "%s: loop" % (time.time() - start)
start = time.time()
print(roll.dice(N))
print "%s: vector" % (time.time() - start)
start = time.time()
print(multi_roll(N, pool))
print "%s: pool" % (time.time() - start)
pool.close()
pool.join()
# EOF
In [5]:
%%file trials.py
"""
monte carlo trials for betting strategies, and measures of success
"""
import numpy as np
def monte(bettor, initial_funds, initial_bet, number_bets, number_players, W,L, pool=None):
"monte carlo run for a betting strategy"
if pool:
_bettor = lambda i:bettor(initial_funds, initial_bet, number_bets, W,L)
return np.array(pool.map(_bettor, xrange(number_players)))
history = []
while len(history) < number_players:
history.append(bettor(initial_funds, initial_bet, number_bets, W,L))
return np.array(history)
def alive(history, number_players):
"find the percentage of players that are not broke"
return 100. * sum(np.asarray(history, bool).T[-1])/number_players
def gains(history, number_players, initial_funds):
"find the percentage of players that have profited"
return 100. * sum(history.T[-1] > initial_funds)/number_players
def profit(history, number_players, initial_funds):
"find the total profit"
return np.max(history.T[-1]) - initial_funds
def margin(history, number_players, initial_funds):
"find the percentage the return on investment is over the initial funds"
initial = number_players * initial_funds
return 100.* (sum(history.T[-1]) - initial)/initial
# EOF
In [59]:
%%file optimize.py
'''
monte carlo optimization of betting strategies for a given quantitative measure
'''
import numpy as np
import strategy
def monte_stats(bettor, initial_funds, initial_bet, number_bets, number_players, W,L, pool=None):
"get the desired stats from a monte carlo run"
import numpy as np
from trials import monte, alive, gains, profit, margin
settings = np.seterr(over='ignore', invalid='ignore')
history = monte(bettor, initial_funds, initial_bet, number_bets, number_players, W,L, pool)
survived = alive(history, number_players)
profited = gains(history, number_players, initial_funds)
max_profit = profit(history, number_players, initial_funds)
ave_profit = margin(history, number_players, initial_funds)
np.seterr(**settings)
return survived, profited, max_profit, ave_profit
def safety_metric(initial_funds, survived, profited, max_profit, ave_profit):
"we define optimality with (4*profited + survived)/5"
return (4*profited + survived)/5
def profit_metric(initial_funds, survived, profited, max_profit, ave_profit):
"we define optimality with (max_profit - ave_profit)"
return max_profit - (np.mean(ave_profit) * initial_funds)
def optimize_WL(metric, players=100, funds=None, bet=None, number_bets=None, symmetric=False,
outerPool=None, innerPool=None):
"soewhat hacky Monte Carlo optimization of betting parameters for martingale strategy"
samples = int(np.random.uniform(100., 1000.)) if players is None else int(players)
if funds is None: funds = np.random.uniform(1000. ,1000000.)
if bet is None: bet = np.random.uniform(1. ,1000.)
number_bets = int(np.random.uniform(10.,10000.)) if number_bets is None else int(number_bets)
bettor = strategy.martingale
W = np.random.uniform(0.1, 10., samples)
L = W if symmetric else np.random.uniform(0.1, 10., samples)
if outerPool is None:
import pathos
outerPool = pathos.pools.SerialPool
if innerPool:
innerPool = innerPool()
def measure(W,L, pool):
"let's hide this, because it's ugly (*groan*)" # good indicator a class should be built
return safety_metric(funds, *monte_stats(bettor, funds, bet, number_bets, samples, W,L, pool))
# use imap to run the monte carlo, because it's cool
p = outerPool()
results = p.imap(measure, W,L, [innerPool]*samples)
i = 0
best_result = 0.0
best_value = W[0],L[0]
for result in results:
if result > best_result:
best_result = result
best_value = W[i],L[i]
print "best: %s @ %s" % (best_result, best_value)
i += 1
if not i%np.floor_divide(samples, 10):
print "{:.2f}% done".format(100. * i / samples)
p.close()
p.join()
if innerPool:
innerPool.close()
innerPool.join()
return best_value
if __name__ == '__main__':
import pathos
#oPool = pathos.pools.ParallelPool
oPool = pathos.pools.ProcessPool
iPool = None
initial_funds = 10000
initial_bet = 100
number_bets = 100
number_players = 300 # XXX: THIS SHOULD BE MUCH LARGER
metric = safety_metric
symmetric = True
import time
print "optimizing W,L for symmetric=%s\n%s\n" % (symmetric, metric.__doc__)
start = time.time()
optimize_WL(metric, number_players, initial_funds, initial_bet, number_bets, symmetric,
oPool, iPool)
print "\ntime: %s" % (time.time() - start)
# EOF
In [2]:
!python2.7 optimize.py
In [ ]: