Python 用TensorFlow神经网络定价美国股票期权,蒙特卡罗模拟

Python 用TensorFlow神经网络定价美国股票期权,蒙特卡罗模拟,python,tensorflow,neural-network,montecarlo,stock,Python,Tensorflow,Neural Network,Montecarlo,Stock,所以我试着用蒙特卡罗模拟一个美式期权(股票),然后用TensorFlow来定价 我使用两个辅助函数,get\u continuation\u函数来创建TF操作符。和定价函数创建定价计算图 npv运算符是最佳运动决策的总和。每次我都会检查行使价值是否大于预测的延续价值(换句话说,期权是否在货币中) 而实际的定价函数是美式\u tf。我执行函数来创建路径,即训练路径的练习值。然后,我通过training_函数反向迭代,了解每个训练日期的值和决策 def get_continuation_functi

所以我试着用蒙特卡罗模拟一个美式期权(股票),然后用TensorFlow来定价

我使用两个辅助函数,get\u continuation\u函数来创建TF操作符。和定价函数创建定价计算图

npv运算符是最佳运动决策的总和。每次我都会检查行使价值是否大于预测的延续价值(换句话说,期权是否在货币中)

而实际的定价函数是美式\u tf。我执行函数来创建路径,即训练路径的练习值。然后,我通过training_函数反向迭代,了解每个训练日期的值和决策

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的评论中讨论了很多事情。我只想上传一个包含所有更改的工作版本。代码经过测试并运行,没有错误。但为了确保最终的培训输出是正确的,您可能需要与一些基准进行比较

一般性评论:在这种类型的应用程序中,最好将变量和时间维度分开,尤其是当您只有一个变量时。例如,您的输入数组应该是三维的,并带有

[time, training sample, input variable]
而不是使用[training sample,time]的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))

嗨,你好!也许我错过了什么,但什么是
M
?它意味着什么?它包含哪些数据?请提供一个提供给
M
的数据示例-否则此代码无法运行且难以理解抱歉,M是股票的时间步长。。在本例中,M=[1,1,1,1,1,1,1,1,1,1,1,1.],这意味着您需要对“输入x:x[exercise_values[:,i]>0]”进行重塑,使其形状为(358,1)谢谢:)。为什么输入x而不输入y?另外,对于美式看跌期权的定价,代码是否正确?@Tim可能会将其改为(?,1),而不是(某些数字,1),因为第一维度可能不同