Path: blob/master/src/FMNM/TC_pricer.py
1700 views
#!/usr/bin/env python31# -*- coding: utf-8 -*-2"""3Created on Mon Jun 10 09:56:25 201945@author: cantaro866"""78from time import time9import numpy as np10import numpy.matlib11import FMNM.cost_utils as cost121314class TC_pricer:15"""16Solver for the option pricing model of Davis-Panas-Zariphopoulou.17"""1819def __init__(self, Option_info, Process_info, cost_b=0, cost_s=0, gamma=0.001):20"""21Option_info: of type Option_param. It contains (S0,K,T)22i.e. current price, strike, maturity in years2324Process_info: of type Diffusion_process.25It contains (r,mu, sig) i.e. interest rate, drift coefficient, diffusion coeff26cost_b: (lambda in the paper) BUY cost27cost_s: (mu in the paper) SELL cost28gamma: risk avversion coefficient29"""3031if Option_info.payoff == "put":32raise ValueError("Not implemented for Put Options")3334self.r = Process_info.r # interest rate35self.mu = Process_info.mu # drift coefficient36self.sig = Process_info.sig # diffusion coefficient37self.S0 = Option_info.S0 # current price38self.K = Option_info.K # strike39self.T = Option_info.T # maturity in years40self.cost_b = cost_b # (lambda in the paper) BUY cost41self.cost_s = cost_s # (mu in the paper) SELL cost42self.gamma = gamma # risk avversion coefficient4344def price(self, N=500, TYPE="writer", Time=False):45"""46N = number of time steps47TYPE writer or buyer48Time: Boolean49"""50t = time() # measures run time51np.seterr(all="ignore") # ignore Warning for overflows5253x0 = np.log(self.S0) # current log-price54T_vec, dt = np.linspace(0, self.T, N + 1, retstep=True) # vector of time steps and time steps55delta = np.exp(-self.r * (self.T - T_vec)) # discount factor56dx = self.sig * np.sqrt(dt) # space step157dy = dx # space step258M = int(np.floor(N / 2))59y = np.linspace(-M * dy, M * dy, 2 * M + 1)60N_y = len(y) # dim of vector y61med = np.where(y == 0)[0].item() # point where y==06263def F(xx, ll, nn):64return np.exp(self.gamma * (1 + self.cost_b) * np.exp(xx) * ll / delta[nn])6566def G(xx, mm, nn):67return np.exp(-self.gamma * (1 - self.cost_s) * np.exp(xx) * mm / delta[nn])6869for portfolio in ["no_opt", TYPE]:70# interates on the zero option and writer/buyer portfolios71# Tree nodes at time N72x = np.array([x0 + (self.mu - 0.5 * self.sig**2) * dt * N + (2 * i - N) * dx for i in range(N + 1)])7374# Terminal conditions75if portfolio == "no_opt":76Q = np.exp(-self.gamma * cost.no_opt(x, y, self.cost_b, self.cost_s))77elif portfolio == "writer":78Q = np.exp(-self.gamma * cost.writer(x, y, self.cost_b, self.cost_s, self.K))79elif portfolio == "buyer":80Q = np.exp(-self.gamma * cost.buyer(x, y, self.cost_b, self.cost_s, self.K))81else:82raise ValueError("TYPE can be only writer or buyer")8384for k in range(N - 1, -1, -1):85# expectation term86Q_new = (Q[:-1, :] + Q[1:, :]) / 28788# create the logprice vector at time k89x = np.array([x0 + (self.mu - 0.5 * self.sig**2) * dt * k + (2 * i - k) * dx for i in range(k + 1)])9091# buy term92Buy = np.copy(Q_new)93Buy[:, :-1] = np.matlib.repmat(F(x, dy, k), N_y - 1, 1).T * Q_new[:, 1:]9495# sell term96Sell = np.copy(Q_new)97Sell[:, 1:] = np.matlib.repmat(G(x, dy, k), N_y - 1, 1).T * Q_new[:, :-1]9899# update the Q(:,:,k)100Q = np.minimum(np.minimum(Buy, Sell), Q_new)101102if portfolio == "no_opt":103Q_no = Q[0, med]104else:105Q_yes = Q[0, med]106107if TYPE == "writer":108price = (delta[0] / self.gamma) * np.log(Q_yes / Q_no)109else:110price = (delta[0] / self.gamma) * np.log(Q_no / Q_yes)111112if Time is True:113elapsed = time() - t114return price, elapsed115else:116return price117118119