|
import gradio as gr |
|
from PIL import Image |
|
from matplotlib import pyplot as plt |
|
import numpy as np |
|
import pickle |
|
import gzip |
|
import seaborn as sns |
|
sns.set_theme() |
|
|
|
def flip(n, t, seed=13): |
|
np.random.seed(seed) |
|
flips = np.random.randint(0, 2, size=(n, t)) |
|
heads = flips.cumsum(axis=1) |
|
return heads.astype(np.uint8) |
|
|
|
def load(filename): |
|
|
|
file = gzip.GzipFile(filename, 'rb') |
|
data = file.read() |
|
object = pickle.loads(data) |
|
file.close() |
|
return object |
|
|
|
def calc_outcome(p_win, win, loss, leverage): |
|
n = 1000000 |
|
t = 60 |
|
base=100 |
|
|
|
heads = load('flips.pkl.gz') |
|
tails = np.arange(t)+1 - heads |
|
p_loss = 1 - p_win |
|
log_win = np.log(1+leverage*win) |
|
log_loss = np.log(1-leverage*loss) |
|
log_outcome = heads*log_win + tails*log_loss |
|
outcome = base*(np.exp(log_outcome)) |
|
return outcome |
|
|
|
def process(p_win, win, loss, leverage): |
|
outcome = calc_outcome(p_win/100., win/100., loss/100., leverage/100.) |
|
ensemble = fig2img(plot_ensemble(outcome)[0]) |
|
time = fig2img(plot_time(outcome)[0]) |
|
richest = fig2img(plot_richest(outcome)[0]) |
|
return ensemble, time, richest |
|
|
|
def fig2img(fig): |
|
"""Convert a Matplotlib figure to a PIL Image and return it""" |
|
import io |
|
buf = io.BytesIO() |
|
fig.savefig(buf) |
|
buf.seek(0) |
|
img = Image.open(buf) |
|
return img |
|
|
|
def plot_ensemble(outcome): |
|
fig, ax = plt.subplots(1, 1, figsize=(4, 4)) |
|
ax.plot(outcome.mean(axis=0)) |
|
ax.set_xlabel('Time') |
|
ax.set_ylabel('Average Wealth ($)') |
|
ax.set_title('Ensemble (Collective) Perspective') |
|
fig.tight_layout() |
|
return fig, ax |
|
|
|
def plot_richest(outcome): |
|
fig, ax = plt.subplots(1, 1, figsize=(4, 4)) |
|
ax.plot(outcome.max(axis=0)/1e6) |
|
ax.set_xlabel('Time') |
|
ax.set_ylabel('Wealth ($ million)') |
|
ax.set_title('Richest Individual') |
|
fig.tight_layout() |
|
return fig, ax |
|
|
|
def plot_time(outcome): |
|
fig, ax = plt.subplots(1, 1, figsize=(4, 4)) |
|
ax.plot(np.percentile(outcome, 50, axis=0)) |
|
ax.set_xlabel('Time') |
|
ax.set_ylabel('Median Wealth ($)') |
|
ax.set_title('Time (Individual) Perspective') |
|
fig.tight_layout() |
|
return fig, ax |
|
|
|
css = "" |
|
|
|
with gr.Blocks(css=css) as demo: |
|
with gr.Column(): |
|
with gr.Row(): |
|
p_win = gr.Slider(0, 100, value=50, label='Win Prob.(%)', interactive=True) |
|
with gr.Row(): |
|
win = gr.Number(value=50, label='Gain (%)', interactive=True) |
|
loss = gr.Number(value=40, label='Loss (%)', interactive=True) |
|
with gr.Row(): |
|
leverage = gr.Slider(0, 100, value=100, label='Leverage (%)', interactive=True) |
|
with gr.Row(): |
|
btn = gr.Button('Go!') |
|
with gr.Column(scale=1, min_width=900): |
|
with gr.Row(): |
|
ensemble = gr.Image(label="Ensemble Perspective", shape=(300, 300), elem_id="plot_ensemble") |
|
time = gr.Image(label="Time Perspective", shape=(300, 300), elem_id="plot_time") |
|
richest = gr.Image(label="Richest Individual", shape=(300, 300), elem_id="plot_richest") |
|
|
|
btn.click(process, [p_win, win, loss, leverage], [ensemble, time, richest]) |
|
|
|
demo.launch() |