<jupyter_start><jupyter_text>Example 5.4 / Computations We aim at computing bounds under copula information.<jupyter_code>import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import rc
from matplotlib import style
from matplotlib.ticker import (AutoMinorLocator, MultipleLocator)
style.use('ggplot')
print("Necessary Packages imported")
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from scipy.stats import multivariate_normal
from tqdm import tqdm<jupyter_output>Necessary Packages imported<jupyter_text>If on GPU:<jupyter_code>physical_devices = tf.config.list_physical_devices('GPU') 
tf.config.experimental.set_memory_growth(physical_devices[0], True)<jupyter_output><empty_output><jupyter_text>Define the functions for the computation of the bounds using a similar neural network approach as in "Bounds on Multi-asset Derivativesvia Neural Networks" by<NAME>, <NAME><jupyter_code>def compute_bound(payoff,
                  generate_samples_mu1t1,
                  generate_samples_mu2t1,
                  generate_samples_mu3t1,
                  generate_samples_mu1t2,
                  generate_samples_mu2t2,
                  generate_samples_mu3t2,
                  lower_bound=True,
                  batch_size=2**8,
                  gamma = 100,
                  max_iter = 20000,
                  inner_iter = 10,
                  nr_neurons = 128,
                  l_r = 0.001,
                  depth = 1,
                  copula_payoffs=[],
                  copula_prices=[],
                 martingale = True):
    # Number of additional constraints:
    N = len(copula_prices)
    if N>0:
        alpha = tf.Variable(np.ones([N,1]),trainable=True,dtype = "float32")
    # Create Tensors for the Input
    def build_model(martingale):
        
        #t1
        x_1t1 = keras.Input(shape=(1,),name = "x_1t1")
        x_2t1 = keras.Input(shape=(1,),name = "x_2t1")
        x_3t1 = keras.Input(shape=(1,),name = "x_3t1")
        x_t1 = layers.concatenate([x_1t1, x_2t1, x_3t1])
        
        #t2
        x_1t2 = keras.Input(shape=(1,),name = "x_1t2")
        x_2t2 = keras.Input(shape=(1,),name = "x_2t2")
        x_3t2 = keras.Input(shape=(1,),name = "x_3t2")

        
        # Create the NN       
        u_1t1 = layers.Dense(nr_neurons,activation = "relu")(x_1t1)
        u_2t1 = layers.Dense(nr_neurons,activation = "relu")(x_2t1)
        u_3t1 = layers.Dense(nr_neurons,activation = "relu")(x_3t1)
        u_1t2 = layers.Dense(nr_neurons,activation = "relu")(x_1t2)
        u_2t2 = layers.Dense(nr_neurons,activation = "relu")(x_2t2)
        u_3t2 = layers.Dense(nr_neurons,activation = "relu")(x_3t2)
        
        if martingale:
            H_1 = layers.Dense(nr_neurons,activation = "relu")(x_t1)
            H_2 = layers.Dense(nr_neurons,activation = "relu")(x_t1)
            H_3 = layers.Dense(nr_neurons,activation = "relu")(x_t1)
        
        # Create deep layers
        for i in range(depth):
            u_1t1 = layers.Dense(nr_neurons,activation = "relu")(u_1t1)
            u_2t1 = layers.Dense(nr_neurons,activation = "relu")(u_2t1)
            u_3t1 = layers.Dense(nr_neurons,activation = "relu")(u_3t1)
            u_1t2 = layers.Dense(nr_neurons,activation = "relu")(u_1t2)
            u_2t2 = layers.Dense(nr_neurons,activation = "relu")(u_2t2)
            u_3t2 = layers.Dense(nr_neurons,activation = "relu")(u_3t2)
            if martingale:
                H_1 = layers.Dense(nr_neurons,activation = "relu")(H_1)
                H_2 = layers.Dense(nr_neurons,activation = "relu")(H_2)
                H_3 = layers.Dense(nr_neurons,activation = "relu")(H_3)
            
        # Output Layers
        u_1t1_out = layers.Dense(1)(u_1t1)
        u_2t1_out = layers.Dense(1)(u_2t1)
        u_3t1_out = layers.Dense(1)(u_3t1)
        u_1t2_out = layers.Dense(1)(u_1t2)
        u_2t2_out = layers.Dense(1)(u_2t2)
        u_3t2_out = layers.Dense(1)(u_3t2)
        if martingale:
            H_1_out = layers.Dense(1)(H_1)
            H_2_out = layers.Dense(1)(H_2)
            H_3_out = layers.Dense(1)(H_3)
            model = keras.Model(inputs=[x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2],
                                outputs = [u_1t1_out,u_2t1_out,u_3t1_out,
                                           u_1t2_out,u_2t2_out,u_3t2_out,
                                           H_1_out,H_2_out,H_3_out])
        else:
            model = keras.Model(inputs=[x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2],
                    outputs = [u_1t1_out,u_2t1_out,u_3t1_out,
                               u_1t2_out,u_2t2_out,u_3t2_out])
        return model
    
    # Loss function
    def loss(model,x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2,martingale):
        if martingale:
            u_1t1, u_2t1, u_3t1, u_1t2, u_2t2, u_3t2, H_1, H_2, H_3 = model({"x_1t1":x_1t1,
                                                                          "x_2t1":x_2t1,
                                                                          "x_3t1":x_3t1,
                                                                          "x_1t2":x_1t2,
                                                                          "x_2t2":x_2t2,
                                                                          "x_3t2":x_3t2},
                                                                            training=True)
            hedge = u_1t1 + u_2t1 + u_3t1 + u_1t2+ u_2t2+ u_3t2 + H_1*(x_1t2-x_1t1) + H_2*(x_2t2-x_2t1)+H_3*(x_3t2-x_3t1)
        else:
            u_1t1, u_2t1, u_3t1, u_1t2, u_2t2, u_3t2 = model({"x_1t1":x_1t1,
                                                                          "x_2t1":x_2t1,
                                                                          "x_3t1":x_3t1,
                                                                          "x_1t2":x_1t2,
                                                                          "x_2t2":x_2t2,
                                                                          "x_3t2":x_3t2},
                                                                            training=True)
            hedge = u_1t1 + u_2t1 + u_3t1 + u_1t2+ u_2t2+ u_3t2              
        s = payoff(x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2)*(1-2*int(lower_bound)) - hedge            
        loss = tf.reduce_mean(u_1t1 + u_2t1 + u_3t1 + u_1t2+ u_2t2+ u_3t2)+ \
        0.5*gamma*tf.reduce_mean(tf.square(tf.nn.relu(s)))           
        return loss

   
    # Define Gradient    
    def grad(model,x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2,martingale):
        with tf.GradientTape() as tape:
            loss_value = loss(model,x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2,martingale)
        return loss_value, tape.gradient(loss_value,model.trainable_variables)
    
    # Loss function munder constraints
    
    def constraints(x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2):
        constr = [f(x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2)-pi for f,pi in zip(copula_payoffs,copula_prices)]
        constr = tf.convert_to_tensor(constr,dtype = tf.float32)
        return tf.transpose(tf.reshape(constr,[N,batch_size]))
    
    def grad_constraints(model,x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2,martingale):
        with tf.GradientTape() as tape:
            loss_value = loss_constraints(model,x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2,martingale)
        return loss_value, tape.gradient(loss_value,model.trainable_variables)
    
    def loss_constraints(model,x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2,martingale):
        if martingale:
            u_1t1, u_2t1, u_3t1, u_1t2, u_2t2, u_3t2, H_1, H_2, H_3  = model({"x_1t1":x_1t1,
                                                                          "x_2t1":x_2t1,
                                                                          "x_3t1":x_3t1,
                                                                          "x_1t2":x_1t2,
                                                                          "x_2t2":x_2t2,
                                                                          "x_3t2":x_3t2},
                                                                            training=True)
            hedge = u_1t1 + u_2t1 + u_3t1 + u_1t2+ u_2t2+ u_3t2 + \
            H_1*(x_1t2-x_1t1) + H_2*(x_2t2-x_2t1)+H_3*(x_3t2-x_3t1) + \
            tf.linalg.matmul(constraints(x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2),alpha)
        else:
            u_1t1, u_2t1, u_3t1, u_1t2, u_2t2, u_3t2  = model({"x_1t1":x_1t1,
                                                                          "x_2t1":x_2t1,
                                                                          "x_3t1":x_3t1,
                                                                          "x_1t2":x_1t2,
                                                                          "x_2t2":x_2t2,
                                                                          "x_3t2":x_3t2},
                                                              training=True)
            hedge = u_1t1 + u_2t1 + u_3t1 + u_1t2+ u_2t2+ u_3t2 +\
            tf.linalg.matmul(constraints(x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2),alpha)
        s = payoff(x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2)*(1-2*int(lower_bound)) - hedge
        loss = tf.reduce_mean(u_1t1 + u_2t1 + u_3t1 + u_1t2+ u_2t2+ u_3t2)+ \
        0.5*gamma*tf.reduce_mean(tf.square(tf.nn.relu(s)))          
        return loss
    
    def grad_alpha(model,x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2,martingale):
        with tf.GradientTape() as tape:
            loss_value = loss_constraints(model,x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2,martingale)
        return loss_value, tape.gradient(loss_value,[alpha])
    
    
    # Create Optimizer and Model
    optimizer = tf.keras.optimizers.Adam(learning_rate = l_r, beta_1=0.9, beta_2=0.999)
    optimizer_sgd = tf.keras.optimizers.SGD(learning_rate = l_r*10)
    model = build_model(martingale)
    tf.keras.utils.plot_model(model,'model.png',show_shapes=True)
    losses = []

    # Training Loop
    if N == 0: # No Constraints
        for epoch in tqdm(range(int(max_iter))):
            x_1t1 = next(generate_samples_mu1t1(batch_size))
            x_2t1 = next(generate_samples_mu2t1(batch_size))
            x_3t1 = next(generate_samples_mu3t1(batch_size))
            x_1t2 = next(generate_samples_mu1t2(batch_size))
            x_2t2 = next(generate_samples_mu2t2(batch_size))
            x_3t2 = next(generate_samples_mu3t2(batch_size))
            loss_value, grads = grad(model,x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2,martingale)
            optimizer.apply_gradients(zip(grads, model.trainable_variables))
            losses.append(loss_value.numpy()*(1-2*int(lower_bound)))
            if epoch % 1000 == 0 and epoch > 0:
                print("Iteration:{}, Avg. Loss: {}".format((epoch),np.mean(losses[-(round(epoch*0.05))])))
    else:
        for epoch in tqdm(range(int(max_iter))):
            x_1t1 = next(generate_samples_mu1t1(batch_size))
            x_2t1 = next(generate_samples_mu2t1(batch_size))
            x_3t1 = next(generate_samples_mu3t1(batch_size))
            x_1t2 = next(generate_samples_mu1t2(batch_size))
            x_2t2 = next(generate_samples_mu2t2(batch_size))
            x_3t2 = next(generate_samples_mu3t2(batch_size))
            loss_value, grads = grad_constraints(model,x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2,martingale)
            optimizer.apply_gradients(zip(grads, model.trainable_variables))
            for inner_epoch in range(int(inner_iter)):
                x_1t1 = next(generate_samples_mu1t1(batch_size))
                x_2t1 = next(generate_samples_mu2t1(batch_size))
                x_3t1 = next(generate_samples_mu3t1(batch_size))
                x_1t2 = next(generate_samples_mu1t2(batch_size))
                x_2t2 = next(generate_samples_mu2t2(batch_size))
                x_3t2 = next(generate_samples_mu3t2(batch_size))
                loss_value, grad_a = grad_alpha(model,x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2,martingale)
                optimizer_sgd.apply_gradients(zip(grad_a, [alpha]))
            losses.append(loss_value.numpy()*(1-2*int(lower_bound)))
            if epoch % 1000 == 0 and epoch > 0:
                print("Iteration:{}, Avg. Loss: {}".format((epoch),np.mean(losses[-(round(epoch*0.05))])))        
            
    print("Iteration result: {}".format(np.mean(losses[-(round(max_iter*0.05))])))
    return np.mean(losses[-(round(max_iter*0.05))]), model<jupyter_output><empty_output><jupyter_text>Lognormal DistributionsWe consider a Black-Scholes market model with$S_{t_i}^k = S_0 \exp\left(-\frac{{\sigma_{i}^k}^2}{2}{t_i}+\sqrt{t_i}{\sigma_{i}^k}X_i^k\right)$ for $i=1,2$,$k=1,2,3$.with $S_0^1=9$, $S_0^2=10$, $S_0^3=11$, $t_1=1,t_2=2$ and ${\sigma_{i}^k}=0.2$ for all $i,k$$$(X_i^1,X_i^2,X_i^3) \sim \mathcal{N}(0,\Sigma)$$for $$\Sigma = \begin{pmatrix}&1 &\rho_{1,2} &\rho_{1,3}\\&\rho_{1,2} &1  &\rho_{2,3}\\&\rho_{1,3} &\rho_{2,3} &1 \\\end{pmatrix}$$<jupyter_code># Set the parameters
t_1 = 1
t_2 = 2
vol = 0.5
S_0_1 = 9
S_0_2 = 10
S_0_3 = 11
#Correlations / Put them together with the volatilities into a matrix which we call rho
rho_12 = 0.8
rho_13 = 0.8
rho_23 = 0.8


rho=np.array([[vol,rho_12,rho_13],[rho_12,vol,rho_23],[rho_13,rho_23,vol]])

def log_norm1_t1(batch_size):
    while True:
        x = S_0_1*tf.math.exp(np.sqrt(vol**2*t_1)*tf.random.normal(shape = [int(batch_size),1])-vol**2*(t_1/2))
        yield x            
def log_norm2_t1(batch_size):
    while True:
        x = S_0_2*tf.math.exp(np.sqrt(vol**2*t_1)*tf.random.normal(shape = [int(batch_size),1])-vol**2*(t_1/2))
        yield x
def log_norm3_t1(batch_size):
    while True:
        x = S_0_3*tf.math.exp(np.sqrt(vol**2*t_1)*tf.random.normal(shape = [int(batch_size),1])-vol**2*(t_1/2))
        yield x
def log_norm1_t2(batch_size):
    while True:
        x = S_0_1*tf.math.exp(np.sqrt(vol**2*t_2)*tf.random.normal(shape = [int(batch_size),1])-vol**2*(t_2/2))
        yield x            
def log_norm2_t2(batch_size):
    while True:
        x = S_0_2*tf.math.exp(np.sqrt(vol**2*t_2)*tf.random.normal(shape = [int(batch_size),1])-vol**2*(t_2/2))
        yield x
def log_norm3_t2(batch_size):
    while True:
        x = S_0_3*tf.math.exp(np.sqrt(vol**2*t_2)*tf.random.normal(shape = [int(batch_size),1])-vol**2*(t_2/2))
        yield x<jupyter_output><empty_output><jupyter_text>It s easy to verify that$$E\left[1_{max \{ S_{t_i}^j S_{t_i}^k\} \leq K}\right] = Q\left(X_i^j \leq \frac{\log(K/S_{t_0}^j)+\frac{(\sigma_i^j)^2}{2}t_i}{\sqrt{t_i}\sigma_i^j},X_i^k \leq \frac{\log(K/S_{t_0}^k)+\frac{(\sigma_i^k)^2}{2}t_i}{\sqrt{t_i}\sigma_i^k}\right)$$Thus we may compute prices of the digital options by using the multivariate normal distribution<jupyter_code>def digital_option(correlation_matrix = rho,
                   spot_price1 =10,
                   spot_price2 = 10,
                   T=1,
                   strike = [1],
                  indices = [1,2]):
    volatility1 = rho[indices[0]-1,indices[0]-1]
    volatility2 = rho[indices[1]-1,indices[1]-1]
    x1 = (np.log(np.array(strike)/spot_price1)+T*0.5*volatility1**2)/(volatility1*np.sqrt(T))
    x2 = (np.log(np.array(strike)/spot_price2)+T*0.5*volatility2**2)/(volatility2*np.sqrt(T))
    x =x1.tolist()+x2.tolist()
    correlation = rho[indices[0]-1,indices[1]-1]
    cov_matrix_small = np.array([[1,correlation],[correlation,1]])
    distribution = multivariate_normal(mean= [0,0], cov=cov_matrix_small)
    return distribution.cdf(x)<jupyter_output><empty_output><jupyter_text>We calculate prices of relevant digital options (written at T=2)<jupyter_code>strikes = [8,9,10,11,12] # Set the Strikes


prices_12 = [digital_option(rho,spot_price1 = S_0_1,spot_price2 = S_0_2,T=2,
                            strike = [s], indices = [1,2]) for s in strikes]
prices_13 = [digital_option(rho,spot_price1 = S_0_1,spot_price2 = S_0_3,T=2,
                            strike = [s], indices = [1,3]) for s in strikes]
prices_23 = [digital_option(rho,spot_price1 = S_0_2,spot_price2 = S_0_3,T=2,
                            strike = [s], indices = [2,3]) for s in strikes]
prices = prices_12+prices_13+prices_23

payoffs_12 = [lambda x_1,x_2,x_3, s=s: (np.amax([x_1,x_2],0)<s) for s in strikes]
payoffs_13 = [lambda x_1,x_2,x_3, s=s: (np.amax([x_1,x_3],0)<s) for s in strikes]
payoffs_23 = [lambda x_1,x_2,x_3, s=s:(np.amax([x_2,x_3],0)<s) for s in strikes]
payoffs = payoffs_12+payoffs_13+payoffs_23

payoffs_12_allargs = [lambda x_1t1,x_2t1,x_3t1, x_1t2,x_2t2,x_3t2, s=s: (np.amax([x_1t2,x_2t2],0)<s) for s in strikes]
payoffs_13_allargs = [lambda x_1t1,x_2t1,x_3t1, x_1t2,x_2t2,x_3t2, s=s: (np.amax([x_1t2,x_3t2],0)<s) for s in strikes]
payoffs_23_allargs = [lambda x_1t1,x_2t1,x_3t1, x_1t2,x_2t2,x_3t2, s=s:(np.amax([x_2t2,x_3t2],0)<s) for s in strikes]

payoffs_allargs = payoffs_12_allargs+payoffs_13_allargs+payoffs_23_allargs<jupyter_output><empty_output><jupyter_text>Computation of bounds for the payoff function $$c_{2,K} = \left(\min_{k=1,2,3,i=1,2}S_{t_i}^k - K \right)_+$$for different values of $K$.<jupyter_code>numbers_discrete = 7# Amount of discretization points for the plot
max_iter = 20000 # Amount of overall interations
inner_iter = 10 # Amount of inner interations

Nr_Strike = 0 # To count computations

for K in np.linspace(4,11,numbers_discrete):
    Nr_Strike += 1
    def payoff(x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2):
        return (tf.nn.relu(tf.reduce_min([x_1t1,x_2t1,x_3t1,x_1t2,x_2t2,x_3t2],0)-K))
    #Display the strike
    print(K)
    lower_FH = []
    upper_FH = []
    lower_constraints_MG = []
    upper_constraints_MG = []
    lower_constraints = []
    upper_constraints = []
    lower_MG = []
    upper_MG = []
    
    print("upper_FH") 
    upper_FH.append(compute_bound(payoff,log_norm1_t1,log_norm2_t1,log_norm3_t1,
                                              log_norm1_t2,log_norm2_t2,log_norm3_t2,
                                                    lower_bound=False,martingale = False,
                                              inner_iter = inner_iter,max_iter = max_iter)[0])    
    print("upper_constraints")
    upper_constraints.append(compute_bound(payoff,log_norm1_t1,log_norm2_t1,log_norm3_t1,
                                              log_norm1_t2,log_norm2_t2,log_norm3_t2,
                                                    lower_bound=False,martingale = False,
                                           copula_payoffs=payoffs_allargs,copula_prices=prices,
                                              inner_iter = inner_iter,max_iter = max_iter)[0])
    print("upper_MG")
    upper_MG.append(compute_bound(payoff,log_norm1_t1,log_norm2_t1,log_norm3_t1,
                                              log_norm1_t2,log_norm2_t2,log_norm3_t2,
                                                    lower_bound=False,martingale = True,
                                              inner_iter = inner_iter,max_iter = max_iter)[0])


    print("upper_constraints_MG")
    upper_constraints_MG.append(compute_bound(payoff,log_norm1_t1,log_norm2_t1,log_norm3_t1,
                                              log_norm1_t2,log_norm2_t2,log_norm3_t2,
                                                    lower_bound=False,
                                                    copula_payoffs=payoffs_allargs,copula_prices=prices,
                                              inner_iter = inner_iter,max_iter = max_iter)[0])

    print("lower_constraints_MG")
    lower_constraints_MG.append(compute_bound(payoff,log_norm1_t1,log_norm2_t1,log_norm3_t1,
                                              log_norm1_t2,log_norm2_t2,log_norm3_t2,
                                                    lower_bound=True,
                                                    copula_payoffs=payoffs_allargs,copula_prices=prices,
                                              inner_iter = inner_iter,max_iter = max_iter)[0])
    print("lower_MG")
    lower_MG.append(compute_bound(payoff,log_norm1_t1,log_norm2_t1,log_norm3_t1,
                                              log_norm1_t2,log_norm2_t2,log_norm3_t2,
                                                    lower_bound=True,martingale = True,
                                              inner_iter = inner_iter,max_iter = max_iter)[0])
    print("lower_constraints")
    lower_constraints.append(compute_bound(payoff,log_norm1_t1,log_norm2_t1,log_norm3_t1,
                                              log_norm1_t2,log_norm2_t2,log_norm3_t2,
                                                    lower_bound=True,martingale = False,
                                           copula_payoffs=payoffs_allargs,copula_prices=prices,
                                              inner_iter = inner_iter,max_iter = max_iter)[0])
    print("lower_FH")
    lower_FH.append(compute_bound(payoff,log_norm1_t1,log_norm2_t1,log_norm3_t1,
                                              log_norm1_t2,log_norm2_t2,log_norm3_t2,
                                                    lower_bound=True,martingale = False,
                                              inner_iter = inner_iter,max_iter = max_iter)[0])
    df = pd.DataFrame([upper_constraints_MG,upper_MG,upper_constraints,upper_FH,
                       lower_constraints_MG,lower_MG,lower_constraints,lower_FH])
    df.to_csv("./qc_"+str(Nr_Strike)+"_new.csv", sep=',',index=False)<jupyter_output>4.0
upper_FH
{'fraction_non_alphanumeric': 0.11592380420101532, 'fraction_numerical': 0.060174188440221696, 'mean_word_length': 1.9859546655541649, 'pattern_counts': {'":': 24, '<': 35, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 131, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '558889', 'license': 'Unlicense', 'n_tokens_mistral': 8306, 'n_tokens_neox': 8046, 'n_words': 983, 'path': 'Example 5.4_Computation.ipynb', 'repo_name': 'juliansester/improved-dependence-pricing', 'size': '21495'}