File size: 3,225 Bytes
6e7c5f7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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):
    # Adapted from https://gist.github.com/thearn/5424244
    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 = flip(n, t)
    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()