CoolFace
Apppublic

ypchangchatgpt/European_option_simulation-gradio-plotly

sourceHugging Faceunknownupdated 2y agoView on Hugging Face
0likes
app.py146 linesDownload Raw Back to root
1# 不使用 for 迴圈。2# 發佈到 Hugging Face 伺服器,程式不能有 %reset -f (magic functions)3 4import numpy as np5from scipy import stats6import plotly.graph_objects as go7from plotly.subplots import make_subplots8 9# quasi-random numbers 時,調整避免產生的模擬資料是 0 或 1。10# 寫為函數:11def generate_Sobol(Sobol_seq, n=1, epsilon=0):12    quasi_random_numbers = Sobol_seq.random(n)13    # quasi_random_numbers = epsilon + (1 - 2 * epsilon) * quasi_random_numbers14    d = Sobol_seq.d15    l_bounds = np.repeat(epsilon, d)16    u_bounds = np.repeat(1-epsilon, d)17    quasi_random_numbers = stats.qmc.scale(quasi_random_numbers, l_bounds, u_bounds)18    return quasi_random_numbers19 20def Black_Scholes(S0, K, r, T, sigma, option_type):21    d1 = (np.log(S0/K)+(r+sigma**2/2)*T)/(sigma*np.sqrt(T))22    d2 = d1-sigma*np.sqrt(T)23    if option_type == "call":24        return S0*stats.norm.cdf(d1)-K*np.exp(-r*T)*stats.norm.cdf(d2)25    if option_type == "put":26        return K*np.exp(-r*T)*stats.norm.cdf(-d2)-S0*stats.norm.cdf(-d1)27 28def European_option_simulation(S0, K, r, T, sigma, Z):29    ST = S0*np.exp((r-0.5*sigma**2)*T+sigma*np.sqrt(T)*Z)30    payoff = np.maximum(ST-K, 0)31    prices = np.exp(-r*T)*np.mean(payoff, axis=0)32    return prices33 34 35#%%36def plot_European_option(S0, K, r, T, sigma, n, m, seed, bins, alpha):37    S0 = np.float64(S0)38    K = np.float64(K)39    r = np.float64(r)40    T = np.float64(T)41    sigma = np.float64(sigma)42 43    price_true = Black_Scholes(S0, K, r, T, sigma, option_type="call")44    print("European call option price =", price_true)45 46    n = int(n)47    m = int(m)48    seed = int(seed)49    bins = int(bins)50    alpha = np.float64(alpha)51 52    # pseudo-random numbers53    np.random.seed(seed)54    u_pseudo = np.random.rand(n, m)55    Z_pseudo = stats.norm.ppf(u_pseudo)56 57    # quasi-random numbers58    Sobol_seq = stats.qmc.Sobol(d=m, scramble=True, seed=seed)59    # scramble 內建值為 True。60    # Scramble 是指將一個序列或集合中的元素加干擾的過程。61 62    u_quasi = generate_Sobol(Sobol_seq, n=n, epsilon=1e-8)63    Z_quasi = stats.norm.ppf(u_quasi)64    """65    Sobol_seq = stats.qmc.Sobol(d=n, seed=seed)66    u_quasi = Sobol_seq.random(m)67    Z_quasi = stats.norm.ppf(u_quasi).T68    # 這個寫法沒有明顯效果,所以要注意 d 的設定。69    """70 71    prices_pseudo = European_option_simulation(S0, K, r, T, sigma, Z_pseudo)72    prices_quasi = European_option_simulation(S0, K, r, T, sigma, Z_quasi)73    74    fig = make_subplots(rows=2, cols=1, subplot_titles=("pseudo-random numbers (np.random.uniform)",75                                                        "quasi-random numbers (qmc.Sobol)"))76    nbinsx = 3077    fig.add_trace(78        go.Histogram(x=prices_pseudo,79                     nbinsx=nbinsx,80                     histnorm="probability density",81                     name="pseudo-random numbers (np.random.uniform)",82                     marker=dict(color="rgba(0,0,255,0.15)", line=dict(width=1, color="black")),83                     opacity=1.0),84        row=1, col=1)85 86    fig.add_trace(87        go.Histogram(x=prices_quasi,88                     nbinsx=nbinsx,89                     histnorm="probability density",90                     name="quasi-random numbers (qmc.Sobol)",91                     marker=dict(color="rgba(255,0,0,0.15)", line=dict(width=1, color="black")),92                     opacity=1.0),93        row=2, col=1)94 95    fig.add_vline(x=price_true,96                  line_width=2,97                  line_dash="dash",98                  line_color="blue")99 100    fig.update_layout(101        title="不同方法計算的 call option 價格分布",102        height=900)103 104    fig.update_xaxes(title="call option 價格", row=1, col=1)105    fig.update_xaxes(title="call option 價格", row=2, col=1)106 107    fig.update_yaxes(title="density", row=1, col=1)108    fig.update_yaxes(title="density", row=2, col=1)109    return fig110 111 112#%%113# https://www.machinelearningnuggets.com/gradio-tutorial/114import gradio as gr115 116with gr.Blocks() as app:117    with gr.Row():118        with gr.Column(scale=15, min_width=0):119            S0 = gr.Textbox(value="100", label="S0")120            K = gr.Textbox(value="100", label="K")          # strike price121            # risk-free interest rate122            r = gr.Textbox(value="0.02", label="r")123            T = gr.Textbox(value="0.5", label="T")          # time to maturity124            sigma = gr.Textbox(value="0.2", label="sigma")  # volatility125            # number of simulations126            n = gr.Textbox(value="10000", label="n")127            # number of repeated experiments128            m = gr.Textbox(value="1000", label="m")129            seed = gr.Textbox(value="123457", label="seed")130            bins = gr.Slider(minimum=10, maximum=60, step=5, value=40, label="bins")131            alpha = gr.Slider(minimum=0, maximum=1, step=0.1, value=0.6, label="alpha")132            inputs = [S0, K, r, T, sigma, n, m, seed, bins, alpha]133 134            button = gr.Button(value="Submit")135 136        with gr.Column(scale=85):137            outputs = [gr.Plot()]138 139    button.click(fn=plot_European_option,140                 inputs=inputs,141                 outputs=outputs)142 143app.launch(share=True)144# share=True 一定要寫,瀏覽器才可以看到結果。145# 但發佈到 Hugging Face 伺服器,則 share=True 可以不寫。146