ypchangchatgpt commited on
Commit
ef4de14
1 Parent(s): a2f3e3c

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +138 -0
  2. requirements.txt +5 -0
app.py ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 不使用 for 迴圈。
2
+ # 發佈到 Hugging Face 伺服器,程式不能有 %reset -f (magic functions)
3
+
4
+ import numpy as np
5
+ from scipy import stats
6
+ import matplotlib
7
+ import matplotlib.pyplot as plt
8
+ import mpltw
9
+
10
+ matplotlib.use("Agg")
11
+ # 使用 gradio+matplotlib 套件,這行一定要寫。
12
+
13
+ font_size = 8
14
+ plt.rcParams.update({"font.size": font_size})
15
+
16
+ plt.close("all")
17
+
18
+
19
+ #%%
20
+ # quasi-random numbers 時,調整避免產生的模擬資料是 0 或 1。
21
+ # 寫為函數:
22
+ def generate_Sobol(Sobol_seq, n=1, epsilon=0):
23
+ quasi_random_numbers = Sobol_seq.random(n)
24
+ # quasi_random_numbers = epsilon + (1 - 2 * epsilon) * quasi_random_numbers
25
+ d = Sobol_seq.d
26
+ l_bounds = np.repeat(epsilon, d)
27
+ u_bounds = np.repeat(1-epsilon, d)
28
+ quasi_random_numbers = stats.qmc.scale(quasi_random_numbers, l_bounds, u_bounds)
29
+ return quasi_random_numbers
30
+
31
+ def Black_Scholes(S0, K, r, T, sigma, option_type):
32
+ d1 = (np.log(S0/K)+(r+sigma**2/2)*T)/(sigma*np.sqrt(T))
33
+ d2 = d1-sigma*np.sqrt(T)
34
+ if option_type == "call":
35
+ return S0*stats.norm.cdf(d1)-K*np.exp(-r*T)*stats.norm.cdf(d2)
36
+ if option_type == "put":
37
+ return K*np.exp(-r*T)*stats.norm.cdf(-d2)-S0*stats.norm.cdf(-d1)
38
+
39
+ def European_option_simulation(S0, K, r, T, sigma, Z):
40
+ ST = S0*np.exp((r-0.5*sigma**2)*T+sigma*np.sqrt(T)*Z)
41
+ payoff = np.maximum(ST-K, 0)
42
+ prices = np.exp(-r*T)*np.mean(payoff, axis=0)
43
+ return prices
44
+
45
+
46
+ #%%
47
+ def plot_European_option(S0, K, r, T, sigma, n, m, seed, bins, alpha):
48
+ S0 = np.float64(S0)
49
+ K = np.float64(K)
50
+ r = np.float64(r)
51
+ T = np.float64(T)
52
+ sigma = np.float64(sigma)
53
+
54
+ price_true = Black_Scholes(S0, K, r, T, sigma, option_type="call")
55
+ print("European call option price =", price_true)
56
+
57
+ n = int(n)
58
+ m = int(m)
59
+ seed = int(seed)
60
+ bins = int(bins)
61
+ alpha = np.float64(alpha)
62
+
63
+ # pseudo-random numbers
64
+ np.random.seed(seed)
65
+ u_pseudo = np.random.rand(n, m)
66
+ Z_pseudo = stats.norm.ppf(u_pseudo)
67
+
68
+ # quasi-random numbers
69
+ Sobol_seq = stats.qmc.Sobol(d=m, scramble=True, seed=seed)
70
+ """
71
+ scramble 內建值為 True。
72
+ Scramble 是指將一個序列或集合中的元素加干擾的過程。
73
+ """
74
+
75
+ u_quasi = generate_Sobol(Sobol_seq, n=n, epsilon=1e-8)
76
+ Z_quasi = stats.norm.ppf(u_quasi)
77
+ """
78
+ Sobol_seq = stats.qmc.Sobol(d=n, seed=seed)
79
+ u_quasi = Sobol_seq.random(m)
80
+ Z_quasi = stats.norm.ppf(u_quasi).T
81
+ # 這個寫法沒有明顯效果,所以要注意 d 的設定。
82
+ """
83
+
84
+ prices_pseudo = European_option_simulation(S0, K, r, T, sigma, Z_pseudo)
85
+ prices_quasi = European_option_simulation(S0, K, r, T, sigma, Z_quasi)
86
+
87
+ fig = plt.figure(figsize=(4, 8))
88
+ plt.subplot(211)
89
+ plt.hist(prices_pseudo,
90
+ bins=bins,
91
+ density=True,
92
+ alpha=alpha,
93
+ ec="black")
94
+ plt.axvline(x=price_true, color="red")
95
+ plt.xlabel("simulate option price")
96
+ plt.ylabel("density")
97
+ plt.title("Simulate option prices with pseudo-random numbers")
98
+
99
+ plt.subplot(212)
100
+ plt.hist(prices_quasi,
101
+ bins=bins,
102
+ density=True,
103
+ alpha=alpha,
104
+ ec="black")
105
+ plt.axvline(x=price_true, color="red")
106
+ plt.xlabel("simulate option price")
107
+ plt.ylabel("density")
108
+ plt.title("Simulate option prices with quasi-random numbers")
109
+
110
+ plt.tight_layout()
111
+ return fig
112
+
113
+
114
+ #%%
115
+ import gradio as gr
116
+
117
+ S0 = gr.Textbox(value="100", label="S0") # initial stock price
118
+ K = gr.Textbox(value="100", label="K") # strike price
119
+ r = gr.Textbox(value="0.02", label="r") # risk-free interest rate
120
+ T = gr.Textbox(value="0.5", label="T") # time to maturity
121
+ sigma = gr.Textbox(value="0.2", label="sigma") # volatility
122
+ n = gr.Textbox(value="10000", label="n") # number of simulations
123
+ m = gr.Textbox(value="1000", label="m") # number of repeated experiments
124
+ seed = gr.Textbox(value="123457", label="seed")
125
+ bins = gr.Slider(minimum=10, maximum=60, step=5, value=40, label="bins")
126
+ alpha = gr.Slider(minimum=0, maximum=1, step=0.1, value=0.6, label="alpha")
127
+ inputs = [S0, K, r, T, sigma, n, m, seed, bins, alpha]
128
+
129
+ outputs = [gr.Plot()]
130
+
131
+ interface = gr.Interface(fn=plot_European_option,
132
+ inputs=inputs,
133
+ outputs=outputs,
134
+ title="European call option")
135
+
136
+ interface.launch()
137
+ # share=True 一定要寫,瀏覽器才可以看到結果。
138
+ # 但發佈到 Hugging Face 伺服器,則 share=True 不能寫。
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ numpy
2
+ scipy
3
+ matplotlib
4
+ mpltw
5
+ gradio