File size: 4,385 Bytes
6e7c5f7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9090ef8
6e7c5f7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4bb75f2
 
6e7c5f7
 
 
4bb75f2
6e7c5f7
 
 
4bb75f2
6e7c5f7
 
 
4bb75f2
6e7c5f7
1915360
 
 
4bb75f2
 
 
 
 
 
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
103
104
105
106
107
108
109
110
111
112
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)
    plt.close(fig)
    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():
            gr.Markdown('Choose the probability of a positive outcome.')
        with gr.Row():
            p_win = gr.Slider(0, 100, value=50, label='Win Prob.(%)', interactive=True)
        with gr.Row():
            gr.Markdown('Choose the return, in percentage, for a positive (gain) and negative (loss) outcome. For example, a 50% gain and 40% loss means a bet of $100 will either result in $150 (50% gain) or $60 (40% loss).')
            win = gr.Number(value=50, label='Gain (%)', interactive=True)
            loss = gr.Number(value=40, label='Loss (%)', interactive=True)
        with gr.Row():
            gr.Markdown('Choose the leverage, that is, the percentage of your total assets that you are willing to bet.')
            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=800):
        with gr.Row():
            ensemble = gr.Image(label="Ensemble Perspective", height=300, width=300, elem_id="plot_ensemble")
            time = gr.Image(label="Time Perspective", height=300, width=300, elem_id="plot_time")
            richest = gr.Image(label="Richest Individual", height=300, width=300, elem_id="plot_richest")
    with gr.Column(scale=1, min_width=800):
        with gr.Row():
            gr.Markdown('The ensemble perspective shows the average wealth of an individual over time (which may be heavily affected by outliers, that is, an extremely rich individual). That is the expected value of the bet assuming ergodicity (in layman terms, "do over").')
            gr.Markdown('The time perspective shows the median wealth, that is, the typical wealth of an individual. It is the likely outcome for a regular individual.')
            gr.Markdown('This plot shows the wealth of the richest individual of them all, the one that got the best lucky streak out of 100,000 simulated individuals.')           

    btn.click(process, [p_win, win, loss, leverage], [ensemble, time, richest])
    
demo.launch()