<jupyter_start><jupyter_text>Python code for vallina option price:<jupyter_code>import numpy as np
import scipy.stats as ss

class VanillaOption:
    def __init__(
        self,
        otype = 1, # 1: 'call'
                  # -1: 'put'
        strike = 110.,
        maturity = 1.,
        market_price = 10.,
        n=1000,
        N=1000,
        r=0.0475,
        y=1,
        vol=0.2):
      self.otype = otype
      self.strike = strike
      self.maturity = maturity
      self.market_price = market_price #this will be used for calibration
      self.step = N
      self.path = n
      self.interest=r
      self.y=y
      self.vol=vol            

    def Euler_CEV(self,S0):
      o_type=self.otype
      T=self.maturity
      N=self.step
      n=self.path
      K=self.strike
      r=self.interest
      y0=self.y
      vol0=self.vol
      sum_value=0
      w=T/N
      for j in range(n):
        S=S0
        for i in range(N):
          z=np.random.normal()
          S=S+0.03*S*w+vol0*(S**y0)*np.sqrt(w)*z
        if (S-K)*o_type >0 :
          sum_value+=(S-K)*o_type
      return np.exp(-r*T)*sum_value/n<jupyter_output><empty_output><jupyter_text>- For $\sigma = 0.2$ and $\gamma = 1$, compute call price with $T = 1$ and $K = 97$. Dose it recover option price given by BSM formula?<jupyter_code>option=VanillaOption(strike=97)
option.Euler_CEV(100)<jupyter_output><empty_output><jupyter_text>So the price of call option is 10.85.<jupyter_code>class Gbm:
    def __init__(self,
                 init_state = 100.,
                 drift_ratio = .0475,
                 vol_ratio = .2
                ):
        self.init_state = init_state
        self.drift_ratio = drift_ratio
        self.vol_ratio = vol_ratio
        
    def bsm_price(self, vanilla_option):
        s0 = self.init_state
        sigma = self.vol_ratio
        r = self.drift_ratio
    
        otype = vanilla_option.otype
        k = vanilla_option.strike
        maturity = vanilla_option.maturity
    
        d1 = (np.log(s0 / k) + (r + 0.5 * sigma ** 2) 
              * maturity) / (sigma * np.sqrt(maturity))
        d2 = d1 - sigma * np.sqrt(maturity)
    
        return (otype * s0 * ss.norm.cdf(otype * d1) #line break needs parenthesis
                - otype * np.exp(-r * maturity) * k * ss.norm.cdf(otype * d2))
gbm1=Gbm(drift_ratio=0.03)
gbm1.bsm_price(option)<jupyter_output><empty_output><jupyter_text>So it recovers the option price to a great degree. Download option data and calibrate volatility and elasticity constant from 5 month call options.<jupyter_code>%cd~

!git clone https://github.com/cengaiyeung/20MA573.git
%cd 20MA573/src00/
%ls
#Read four-column data
#columns are otype, maturity, strike, option_price
np_option_data = np.loadtxt('20optiondata2.txt', comments='#', delimiter=',')
print('>>>>>>otype, maturity, strike, option_price')
print(np_option_data)
def maturity_choice(mat_choice):
  option_data=np_option_data[np_option_data[:,1] == mat_choice]
  return option_data

def op_list(option):
  num_row = option.shape[0]
  option_list = []
  for i in range(num_row):
    option1 = VanillaOption(
        
        otype = option[i,0],
        strike = option[i,2],
        maturity = option[i,1],
        market_price = option[i,3]
    )   
    option_list.append(option1)
  return option_list
op_list1 = op_list(maturity_choice(5/12))

import scipy.optimize as so

def error_function(vol_y):
  error = 0
  for i in np.arange(len(op_list1)):
    op_list1[i].y=vol_y[1]
    op_list1[i].vol=vol_y[0]
    error = error + ((op_list1[i]).Euler_CEV(100) - (op_list1[i]).market_price)**2
  return error

initial_guess=np.ones(2)
initial_guess[0]=0.1
so.fmin(error_function,initial_guess,xtol=0.0001,ftol=0.0001,maxiter=200,maxfun=200)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12123613312202852, 'fraction_numerical': 0.03565768621236133, 'mean_word_length': 2.572641509433962, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 24, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '618463', 'license': 'MIT', 'n_tokens_mistral': 1466, 'n_tokens_neox': 1374, 'n_words': 278, 'path': 'HW7.ipynb', 'repo_name': 'G750cloud/20MA573', 'size': '3786'}