[英]Pricing American Stock Option with TensorFlow Neural Network , Simulate by Monte Carlo
所以我想做的是使用Monte Carlo模擬美國期權(股票),並使用TensorFlow對其進行定價。
我使用兩個輔助函數get_continuation_function來創建TF運算符。 並使用prices_function創建用於定價的計算圖。
npv運算符是最佳運動決策的總和。 每次我檢查行使值是否大於預測的連續值(換句話說,期權是否在貨幣中)。
實際的定價函數是american_tf 。 我執行該功能以創建路徑,即訓練路徑的運動值。 然后,我向后遍歷training_functions,並在每個練習日期學習其價值和決策。
def get_continuation_function():
X = tf.placeholder(tf.float32, (None,1),name="X")
y = tf.placeholder(tf.float32, (None,1),name="y")
w = tf.Variable(tf.random_uniform((1,1))*0.1,,name="w")
b = tf.Variable(initial_value = tf.ones(1)*1,name="b")
y_hat = tf.add(tf.matmul(X, w), b)
pre_error = tf.pow(y-y_hat,2)
error = tf.reduce_mean(pre_error)
train = tf.train.AdamOptimizer(0.1).minimize(error)
return(X, y, train, w, b, y_hat)
def pricing_function(number_call_dates):
S = tf.placeholder(tf.float32,name="S")
# First excerise date
dts = tf.placeholder(tf.float32,name="dts")
# 2nd exersice date
K = tf.placeholder(tf.float32,name="K")
r = tf.placeholder(tf.float32,,name="r")
sigma = tf.placeholder(tf.float32,name="sigma")
dW = tf.placeholder(tf.float32,name="dW")
S_t = S * tf.cumprod(tf.exp((r-sigma**2/2) * dts + sigma * tf.sqrt(dts) * dW), axis=1)
E_t = tf.exp(-r * tf.cumsum(dts)) * tf.maximum(K-S_t, 0)
continuationValues = []
training_functions = []
previous_exersies = 0
npv = 0
for i in range(number_call_dates-1):
(input_x, input_y, train, w, b, y_hat) = get_continuation_function()
training_functions.append((input_x, input_y, train, w, b, y_hat))
X = tf.keras.activations.relu(S_t[:, i])
contValue = tf.add(tf.matmul(X, w),b)
continuationValues.append(contValue)
inMoney = tf.cast(tf.greater(E_t[:,i], 0.), tf.float32)
exercise = tf.cast(tf.greater(E_t[:,i], contValue[:,0]), tf.float32) * inMoney * (1-previous_exersies)
previous_exersies += exercise
npv += exercise*E_t[:,i]
# Last exercise date
inMoney = tf.cast(tf.greater(E_t[:,-1], 0.), tf.float32)
exercise = inMoney * (1-previous_exersies)
npv += exercise*E_t[:,-1]
npv = tf.reduce_mean(npv)
return([S, dts, K, r, sigma,dW, S_t, E_t, npv, training_functions])
def american_tf(S_0, strike, M, impliedvol, riskfree_r, random_train, random_pricing):
n_exercise = len(M)
with tf.Session() as sess:
S,dts,K,r,sigma,dW,S_t,E_t,npv,training_functions = pricing_function(n_exercise)
sess.run(tf.global_variables_initializer())
paths, exercise_values = sess.run([S_t,E_t], {
S: S_0,
dts: M,
K: strike,
r: riskfree_r,
sigma: impliedvol,
dW: random_train
})
for i in range(n_exercise-1)[::-1]:
(input_x,input_y,train,w,b,y_hat) = training_functions[i]
y= exercise_values[:,i+1:i+2]
X = paths[:,i]
print(input_x.shape)
print((exercise_values[:,i]>0).shape)
for epochs in range(100):
_ = sess.run(train, {input_x:X[exercise_values[:,i]>0],
input_y:y[exercise_values[:,i]>0]})
cont_value = sess.run(y_hat, {input_x:X, input_y:y})
exercise_values[:,i+1:i+2] = np.maximum(exercise_values[:,i+1:i+2], cont_value)
npv = sess.run(npv, {S: S_0, K: strike, r: riskfree_r, sigma: impliedvol, dW: N_pricing})
return npv
N_samples_learn = 1000
N_samples_pricing = 1000
calldates = 12
N = np.random.randn(N_samples_learn,calldates)
N_pricing = np.random.randn(N_samples_pricing,calldates)
american_tf(100., 90., [1.]*calldates, 0.25, 0.05, N, N_pricing)
Calldates是步驟數
訓練樣本集= 1000
測試樣本大小= 1000
但是我的錯誤很奇怪
---> 23 nput_y:y[exercise_values[:,i]>0]})
ValueError: Cannot feed value of shape (358,) for Tensor 'Placeholder_441:0', which has shape '(?, 1)'
@ hallo12在評論中討論了很多事情。 我只想上傳一個包含所有更改的工作版本。 該代碼經過測試,可以正常運行。 但是為了確保最終的訓練輸出正確,您可能需要與一些基准進行比較。
一般注釋 :在這種類型的應用程序中,最好將變量和時間維度分開,尤其是當您只有1個變量時。 例如,您的輸入數組應為3D
[time, training sample, input variable]
而不是使用[訓練樣本,時間]進行2D。 這樣,當您遍歷時間維度時,其余維度將保持不變。
import tensorflow as tf
import numpy as np
def get_continuation_function():
X = tf.placeholder(tf.float32, (None,1),name="X")
y = tf.placeholder(tf.float32, (None,1),name="y")
w = tf.Variable(tf.random_uniform((1,1))*0.1,name="w")
b = tf.Variable(initial_value = tf.ones(1)*1,name="b")
y_hat = tf.add(tf.matmul(X, w), b)
pre_error = tf.pow(y-y_hat,2)
error = tf.reduce_mean(pre_error)
train = tf.train.AdamOptimizer(0.1).minimize(error)
return(X, y, train, w, b, y_hat)
def pricing_function(number_call_dates):
S = tf.placeholder(tf.float32,name="S")
# First excerise date
dts = tf.placeholder(tf.float32,name="dts")
# 2nd exersice date
K = tf.placeholder(tf.float32,name="K")
r = tf.placeholder(tf.float32,name="r")
sigma = tf.placeholder(tf.float32,name="sigma")
dW = tf.placeholder(tf.float32,name="dW")
S_t = S * tf.cumprod(tf.exp((r-sigma**2/2) * dts + sigma * tf.sqrt(dts) * dW), axis=1)
E_t = tf.exp(-r * tf.cumsum(dts)) * tf.maximum(K-S_t, 0)
continuationValues = []
training_functions = []
previous_exersies = 0
npv = 0
for i in range(number_call_dates-1):
(input_x, input_y, train, w, b, y_hat) = get_continuation_function()
training_functions.append((input_x, input_y, train, w, b, y_hat))
X = tf.keras.activations.relu(S_t[:, i:i+1])
contValue = tf.add(tf.matmul(X, w),b)
continuationValues.append(contValue)
inMoney = tf.cast(tf.greater(E_t[:,i], 0.), tf.float32)
exercise = tf.cast(tf.greater(E_t[:,i], contValue[:,0]), tf.float32) * inMoney * (1-previous_exersies)
previous_exersies += exercise
npv += exercise*E_t[:,i]
# Last exercise date
inMoney = tf.cast(tf.greater(E_t[:,-1], 0.), tf.float32)
exercise = inMoney * (1-previous_exersies)
npv += exercise*E_t[:,-1]
npv = tf.reduce_mean(npv)
return([S, dts, K, r, sigma,dW, S_t, E_t, npv, training_functions])
def american_tf(S_0, strike, M, impliedvol, riskfree_r, random_train, random_pricing):
n_exercise = len(M)
with tf.Session() as sess:
S,dts,K,r,sigma,dW,S_t,E_t,npv,training_functions = pricing_function(n_exercise)
sess.run(tf.global_variables_initializer())
paths, exercise_values = sess.run([S_t,E_t], {
S: S_0,
dts: M,
K: strike,
r: riskfree_r,
sigma: impliedvol,
dW: random_train
})
for i in range(n_exercise-1)[::-1]:
(input_x,input_y,train,w,b,y_hat) = training_functions[i]
y= exercise_values[:,i+1:i+2]
X = paths[:,i]
print(input_x.shape)
print((exercise_values[:,i]>0).shape)
for epochs in range(100):
_ = sess.run(train, {input_x:(X[exercise_values[:,i]>0]).reshape(len(X[exercise_values[:,i]>0]),1),
input_y:(y[exercise_values[:,i]>0]).reshape(len(y[exercise_values[:,i]>0]),1)})
cont_value = sess.run(y_hat, {input_x:X.reshape(len(X),1), input_y:y.reshape(len(y),1)})
exercise_values[:,i+1:i+2] = np.maximum(exercise_values[:,i+1:i+2], cont_value)
npv = sess.run(npv, {S: S_0, K: strike, dts:M, r: riskfree_r, sigma: impliedvol, dW: N_pricing})
return npv
N_samples_learn = 1000
N_samples_pricing = 1000
calldates = 12
N = np.random.randn(N_samples_learn,calldates)
N_pricing = np.random.randn(N_samples_pricing,calldates)
print(american_tf(100., 90., [1.]*calldates, 0.25, 0.05, N, N_pricing))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.