簡體   English   中英

使用TensorFlow神經網絡對美國股票期權定價,由Monte Carlo模擬

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM