<jupyter_start><jupyter_text>Neural network implementation of the rough Bergomi modelHere we illustrate how to use the neural network implementation of the rough Bergomi model.Remarks: o Although still fast, the code has not been optimised for speed (the Matlab version has).o The underlying models are not implemented in Python. You must therefore consult the Matlab code to check the accuracy against the actual pricing models.The source code for the module 'NeuralNetworkPricing' can be found in "...\\code\\python_code"  Import libraries and set directories<jupyter_code>import sys, os
import numpy as np

project_folder = os.path.dirname(os.path.dirname(os.path.abspath('')))
source_code = project_folder + "\\code\\python_code"
weights_folder = project_folder + "\\code\\neural_networks\\data\\neural_network_weights\\rbergomi"
contracts_folder = project_folder + "\\code\\neural_networks\\data"

sys.path.append(source_code)
import NeuralNetworkPricing as nnp<jupyter_output><empty_output><jupyter_text>Pricing with the neural networks<jupyter_code># Define neural network based (rough Bergomi) model:
model = nnp.NeuralNetworkPricer(contracts_folder,weights_folder,"rbergomi")

# Plot the neural network contract grid:
import matplotlib.pyplot as plt 
plt.figure(figsize=(10, 6))
plt.scatter(model.T,model.k)
plt.title("Contract grid")
plt.xlabel("Expiration")
plt.ylabel("Log-moneyness")
plt.tight_layout()
plt.show()
# Set some parameters:
par = np.append(np.array([0.1,2.1,-0.90]),(pow(0.10,2))*np.ones((1,27))).reshape(30,1)

# Remark: The order is (H,eta,rho,xi1,xi2,...,xi27) where the forward variance curve
# is assumed piecewise flat with the gridpoints:
model.Txi
# Evaluate model in the contract grid:
iv_grid = model.Eval(par,model.k,model.T)

# Plot a few expiries:
npts = 25
plt.figure(1,figsize=(14,12))
j = -1
iList = [0,3,10,21,31,38,48,63]
for i in iList:
    j = j + 1
    plt.subplot(4,4,j+1)
    plt.plot(model.k[i*npts:(i+1)*npts],iv_grid[i*npts:(i+1)*npts],'.-')
    plt.title("Maturity=%1.3f "%model.T[i*npts])
    plt.xlabel("Log-moneyness")
    plt.ylabel("Implied volatility")
    
plt.tight_layout()
plt.show()<jupyter_output><empty_output><jupyter_text>A calibration example<jupyter_code># Load example contracts:
tmp = np.loadtxt(project_folder + "\\get_started\\example_contracts.txt")
k_orig = tmp[:,0].reshape(-1,1)
T_orig = tmp[:,1].reshape(-1,1)

# Filter contracts that are not within the neural network domain:
idxKeep = model.AreContractsInDomain(k_orig,T_orig)
k_obs = k_orig[idxKeep,:]
T_obs = T_orig[idxKeep,:]

print("Original number of observations: ",len(k_orig))
print("After filtering:",len(k_obs))

# Plot contracts before and after filtering:
plt.figure(figsize=(10, 6))
plt.scatter(T_orig,k_orig,label="Before filtering")
plt.scatter(T_obs,k_obs,label="After filtering")
plt.title("Observed contracts")
plt.xlabel("Expiration")
plt.ylabel("Log-moneyness")
plt.legend()
plt.tight_layout()
plt.show()
# Generate synthetic prices:
parTrue = np.append(np.array([0.1,2.1,-0.90]),(pow(0.15,2))*np.ones((1,27))).reshape(30,1)
iv_obs = model.Eval(parTrue,k_obs,T_obs)

# Calibrate the model to see if we can recover the parameters:
# Remark: We simplify by forcing the forward variance curve flat. This also avoids an overparameterised model.
from scipy.optimize import minimize

# Set parameter bounds:
# Remark: Optimizer occassionally goes beyond the specified bounds. Thus we make the bounds slightly more narrow.
bounds = []
eps = pow(10,-6) 
for i in range(0,len(model.lb)):
    bounds.append([model.lb[i]+eps,model.ub[i]-eps])
    
# Fix the forward variance curve flat:
bounds = bounds[0:4]
idxConvPar = np.concatenate((np.array([0,1,2]),3*np.ones(27))).astype(int)
par0 = np.array([0.2,1.6,-0.7,pow(0.25,2)])

# Define the error function:
def err_fun(parEval):
    return(np.sum(pow(iv_obs - model.Eval(parEval[idxConvPar].reshape(-1,1),k_obs,T_obs),2)))

# Optimize:
res = minimize(err_fun,par0,method='L-BFGS-B',bounds=bounds)
print("Optimisation message: ", res.message)
parCalib = res.x[idxConvPar].reshape(-1,1)

# Compare calibrated and true parameters:
print("[True , Calibrated]: ")
np.concatenate((parTrue,parCalib),1)
# Plot the fit:
iv_fit = model.Eval(parCalib,k_obs,T_obs)

uniqT = np.unique(T_obs)
npts = 25
plt.figure(1,figsize=(14,12))
j = -1
iList = np.arange(0,len(uniqT))
for i in iList:
    j = j + 1
    plt.subplot(4,4,j+1)
    idxT = T_obs == uniqT[i]
    plt.plot(k_obs[idxT],iv_obs[idxT],'b',label='Observed')
    plt.plot(k_obs[idxT],iv_fit[idxT],'--r',label='Fit')
    plt.title("Maturity=%1.3f "%uniqT[i])
    plt.xlabel("Log-moneyness")
    plt.ylabel("Implied volatility")
    plt.legend()
plt.tight_layout()
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1519949335022166, 'fraction_numerical': 0.02638800928857927, 'mean_word_length': 5.749287749287749, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '175252', 'license': 'MIT', 'n_tokens_mistral': 1829, 'n_tokens_neox': 1724, 'n_words': 380, 'path': 'get_started/neural_networks_in_python/rbergomi_example.ipynb', 'repo_name': 'steefeen/rough_volatility', 'size': '4737'}