def __init__(self, K, T, F, iv_slice, ir, wgttype = 'none'): self._K = K # vector self._T = T # scalar self._F = F # scalar self._iv = iv_slice # vector # added (4/20, 황보람) self._ir = ir self._wgttype = wgttype self._k = np.log(K / F) # vector # for vega weight self._vega = [] for i in range(len(self._k)): if i < 10: self._vega.append(bs_formula('p', self._F, self._K[i], self._T, self._ir(self._T), 0, self._iv[i], 'v')) elif i > 10: self._vega.append(bs_formula('c', self._F, self._K[i], self._T, self._ir(self._T), 0, self._iv[i], 'v')) else: self._vega.append(bs_formula('c', self._F, self._K[i], self._T, self._ir(self._T), 0, self._iv[i], 'v') + bs_formula('p', self._F, self._K[i], self._T, self._ir(self._T), 0, self._iv[i], 'v')) print 'K: ', K print 'F: ', F print 'self._k: ', self._k # constraints self.cons = ( # constraints for parameter itself { 'type': 'ineq', 'fun' : lambda x: np.array([x[0]]), 'jac' : lambda x: np.array([1., 0., 0., 0., 0.]) }, # for a { 'type': 'ineq', 'fun' : lambda x: np.array([x[1]]), 'jac' : lambda x: np.array([0., 1., 0., 0., 0.]) }, # for b { 'type': 'ineq', # original constraints 'fun' : lambda x: np.array([1-abs(x[2])]), 'jac' : lambda x: np.array([0., 0., -x[2]/abs(x[2]), 0., 0.]) }, # for rho {'type': 'ineq', 'fun': lambda x: np.array([x[4]]), 'jac': lambda x: np.array([0., 0., 0., 0., 1.]) }, # for sigma # constraints for parameter combination { 'type': 'ineq', 'fun' : lambda x: np.array([4 - x[1]*self._T*(1+abs(x[2]))]), 'jac' : lambda x: np.array([0., -self._T*(1+abs(x[2])), -x[1]*self._T*x[2]/abs(x[2]), 0., 0.]) } # combined constraints 1. preventing vertical arbitrage (Gatheral, 2004) ) self._x = np.array([0.] * 5) # Coefficients
def __init__(self, K, T, F, iv_slice, ir, init_val, wgttype='none'): self._K = K # vector self._T = T # scalar self._F = F # scalar self._iv = iv_slice # vector self._ir = ir self._wgttype = wgttype self._k = np.log(K / F) # vector iv_interp = interp1d(self._k, self._iv, kind='cubic') # ATMF vol interp (k = 0) self.iv_ATM = iv_interp(0) # for vega weight (possibly using) self.vega = [] for i in range(len(self._k)): if i < 10: self.vega.append( bs_formula('p', self._F, self._K[i], self._T, self._ir(self._T), 0, self._iv[i], 'v')) elif i > 10: self.vega.append( bs_formula('c', self._F, self._K[i], self._T, self._ir(self._T), 0, self._iv[i], 'v')) else: self.vega.append( bs_formula('c', self._F, self._K[i], self._T, self._ir(self._T), 0, self._iv[i], 'v') + bs_formula('p', self._F, self._K[i], self._T, self._ir(self._T), 0, self._iv[i], 'v')) # constraints for SVI-JW (>0): JW form should be optimized in raw-converted version self.cons = ( # constraints of parameter itself # constraints of parameter combination { 'type': 'ineq', 'fun': lambda x: np.array([2. * x[0] + x[1]]), }, # beta assumption ( -1 <= beta <= 1 ) { 'type': 'ineq', 'fun': lambda x: np.array([-2. * x[0] + x[2]]), }, # beta assumption ( -1 <= beta <= 1 ) { 'type': 'ineq', 'fun': lambda x: np.array([x[3]]), } # vt assumption ( in SVI-raw format, -1 < rho < 1 ) # Others (combination)? ) self._init_val = init_val self._x = np.array([0.] * 4) # Coefficients
def __init__(self, K, T, F, iv_slice, ir, init_val): self._K = K # vector self._T = T # scalar self._F = F # scalar self._iv = iv_slice # vector # added pt (4/20, 황보람) self.ir = ir self._k = np.log(K / F) # vector # for vega weight (possibly use) self.vega = [] for i in range(len(self._k)): if i < 10: self.vega.append( bs_formula('p', self._F, self._K[i], self._T, self.ir(self._T), 0, self._iv[i], 'v')) elif i > 10: self.vega.append( bs_formula('c', self._F, self._K[i], self._T, self.ir(self._T), 0, self._iv[i], 'v')) else: self.vega.append( bs_formula('c', self._F, self._K[i], self._T, self.ir(self._T), 0, self._iv[i], 'v') + bs_formula('p', self._F, self._K[i], self._T, self.ir(self._T), 0, self._iv[i], 'v')) # constraints for SVI-JW (>0): JW form should be optimized in raw-converted version self.cons = ( # constraints of parameter itself { 'type': 'ineq', 'fun': lambda x: np.array([x[0]]), #'jac' : lambda x: np.array([1., 0., 0.]) }, # for v # constraints of parameter combination { 'type': 'ineq', 'fun': lambda x: np.array([2. * x[1] + x[2]]), #'jac': lambda x: np.array([0., 2., 1.]) } # combined constraints 1. preventing vertical arbitrage (Gatheral, 2004) # Others (combination)? ) self._init_val = init_val self._x = np.array([0.] * 3) # Coefficients
def __init__(self, K, T, F, iv_slice, ir, init_val): self._K = K # vector self._T = T # scalar self._F = F # scalar self._iv = iv_slice # vector self.ir = ir self._k = np.log(K / F) # vector iv_interp = interp1d(self._k, self._iv, kind='cubic') # ATMF vol interp (k = 0) self.iv_ATM = iv_interp(0) # for vega weight (possibly using) self.vega = [] for i in range(len(self._k)): if i < 10: self.vega.append( bs_formula('p', self._F, self._K[i], self._T, self.ir(self._T), 0, self._iv[i], 'v')) elif i > 10: self.vega.append( bs_formula('c', self._F, self._K[i], self._T, self.ir(self._T), 0, self._iv[i], 'v')) else: self.vega.append( bs_formula('c', self._F, self._K[i], self._T, self.ir(self._T), 0, self._iv[i], 'v') + bs_formula('p', self._F, self._K[i], self._T, self.ir(self._T), 0, self._iv[i], 'v')) # constraints for SVI-JW (>0): JW form should be optimized in raw-converted version self.cons = ( # constraints of parameter itself # constraints of parameter combination { 'type': 'ineq', 'fun': lambda x: np.array([2. * x[0] + x[1]]), 'jac': lambda x: np.array([2., 1.]) } # abs(rho) < 1 in JW version # Others (combination)? ) self._init_val = init_val self._x = np.array([0.] * 2) # Coefficients
def __init__(self, K, T, F, iv_slice, ir, init_val, wgttype = 'none'): self._K = K # vector self._T = T # scalar self._F = F # scalar self._iv = iv_slice # vector self._ir = ir self._wgttype = wgttype self._k = np.log(K / F) # vector iv_interp = interp1d(self._k, self._iv, kind='cubic') # ATMF vol interp (k = 0) self.iv_ATM = iv_interp(0) # for vega weight (possibly using) self.vega = [] for i in range(len(self._k)): if i < 10: self.vega.append(bs_formula('p', self._F, self._K[i], self._T, self._ir(self._T), 0, self._iv[i], 'v')) elif i > 10: self.vega.append(bs_formula('c', self._F, self._K[i], self._T, self._ir(self._T), 0, self._iv[i], 'v')) else: self.vega.append(bs_formula('c', self._F, self._K[i], self._T, self._ir(self._T), 0, self._iv[i], 'v') + bs_formula('p', self._F, self._K[i], self._T, self._ir(self._T), 0, self._iv[i], 'v')) # constraints for SVI-JW (>0): JW form should be optimized in raw-converted version self.cons = ( # constraints of parameter itself # constraints of parameter combination {'type': 'ineq', 'fun': lambda x: np.array([2. * x[0] + x[1]]), }, # beta assumption ( -1 <= beta <= 1 ) {'type': 'ineq', 'fun': lambda x: np.array ([-2. * x[0] + x[2]]), }, # beta assumption ( -1 <= beta <= 1 ) {'type': 'ineq', 'fun': lambda x: np.array([x[3]]), } # vt assumption ( in SVI-raw format, -1 < rho < 1 ) # Others (combination)? ) self._init_val = init_val self._x = np.array([0.] * 4) # Coefficients
def __init__(self, K, T, F, iv_slice, ir, init_val): self._K = K # vector self._T = T # scalar self._F = F # scalar self._iv = iv_slice # vector # added pt (4/20, 황보람) self.ir = ir self._k = np.log(K / F) # vector # for vega weight (possibly use) self.vega = [] for i in range(len(self._k)): if i < 10: self.vega.append(bs_formula('p', self._F, self._K[i], self._T, self.ir(self._T), 0, self._iv[i], 'v')) elif i > 10: self.vega.append(bs_formula('c', self._F, self._K[i], self._T, self.ir(self._T), 0, self._iv[i], 'v')) else: self.vega.append(bs_formula('c', self._F, self._K[i], self._T, self.ir(self._T), 0, self._iv[i], 'v') + bs_formula('p', self._F, self._K[i], self._T, self.ir(self._T), 0, self._iv[i], 'v')) # constraints for SVI-JW (>0): JW form should be optimized in raw-converted version self.cons = ( # constraints of parameter itself { 'type': 'ineq', 'fun' : lambda x: np.array([x[0]]), #'jac' : lambda x: np.array([1., 0., 0.]) }, # for v # constraints of parameter combination {'type': 'ineq', 'fun': lambda x: np.array([2. * x[1] + x[2]]), #'jac': lambda x: np.array([0., 2., 1.]) } # combined constraints 1. preventing vertical arbitrage (Gatheral, 2004) # Others (combination)? ) self._init_val = init_val self._x = np.array([0.] * 3) # Coefficients
def __init__(self, K, T, F, iv_slice, ir, init_val): self._K = K # vector self._T = T # scalar self._F = F # scalar self._iv = iv_slice # vector self.ir = ir self._k = np.log(K / F) # vector iv_interp = interp1d(self._k, self._iv, kind='cubic') # ATMF vol interp (k = 0) self.iv_ATM = iv_interp(0) # for vega weight (possibly using) self.vega = [] for i in range(len(self._k)): if i < 10: self.vega.append(bs_formula('p', self._F, self._K[i], self._T, self.ir(self._T), 0, self._iv[i], 'v')) elif i > 10: self.vega.append(bs_formula('c', self._F, self._K[i], self._T, self.ir(self._T), 0, self._iv[i], 'v')) else: self.vega.append(bs_formula('c', self._F, self._K[i], self._T, self.ir(self._T), 0, self._iv[i], 'v') + bs_formula('p', self._F, self._K[i], self._T, self.ir(self._T), 0, self._iv[i], 'v')) # constraints for SVI-JW (>0): JW form should be optimized in raw-converted version self.cons = ( # constraints of parameter itself # constraints of parameter combination {'type': 'ineq', 'fun': lambda x: np.array([2. * x[0] + x[1]]), 'jac': lambda x: np.array([2., 1.]) } # abs(rho) < 1 in JW version # Others (combination)? ) self._init_val = init_val self._x = np.array([0.] * 2) # Coefficients
def __init__(self, K, T, F, iv_mat, ir, type = 'Heston', wgttype = 'none'): self._K = K # vector self._T = T # vector self._F = F # vector self._iv = iv_mat # matrix # added feature (4/20, 황보람) self.ir = ir self._k = [] self._theta = [] for i in range(len(self._T)): k_vec = np.log(K / F[i]) iv_interp = interp1d(k_vec, self._iv[i][:], kind='cubic') iv_ATM = iv_interp(0) self._k.append(np.array(k_vec)) # vector self._theta.append((iv_ATM ** 2.) * self._T[i]) # vector, ATM total variance proxy self._type = type self._wgttype = wgttype # for vega weight (possibly use) self.vega = [] for i in range(len(self._T)): for j in range(len(self._K)): if j < 10: self.vega.append(bs_formula('p', self._F[i], self._K[j], self._T[i], self.ir(self._T[i]), 0, self._iv[i][j], 'v')) elif j > 10: self.vega.append(bs_formula('c', self._F[i], self._K[j], self._T[i], self.ir(self._T[i]), 0, self._iv[i][j], 'v')) else: self.vega.append(bs_formula('c', self._F[i], self._K[j], self._T[i], self.ir(self._T[i]), 0, self._iv[i][j], 'v') + \ bs_formula('p', self._F[i], self._K[j], self._T[i], self.ir(self._T[i]), 0, self._iv[i][j], 'v')) self.vega = np.reshape(self.vega, (len(self._T), len(self._K))) # constraints for SSVI, Heston-like param. self.cons_SSVI_Heston = ( # constraints of parameter itself { 'type': 'ineq', 'fun' : lambda x: np.array([1 - np.abs(x[0])]), 'jac' : lambda x: np.array([-np.sign(x[0]), 0.]) }, # for rho {'type': 'ineq', 'fun': lambda x: np.array([x[1]]), 'jac': lambda x: np.array([0., 1.]) }, # for lambda # constraints of parameter combination {'type': 'ineq', 'fun': lambda x: np.array([4. * x[1] - (1. + np.abs(x[0]))]), 'jac': lambda x: np.array([-np.sign(x[0]), 4.]) } # free of static arbitrage condition ) self._x_Heston = np.array([0.] * 2) # Coefficients # constraints for SSVI, Power-law param. self.cons_SSVI_Power = ( # constraints of parameter itself {'type': 'ineq', 'fun': lambda x: np.array([1 - np.abs(x[0])]), 'jac': lambda x: np.array([-np.sign(x[0]), 0., 0.]) }, # for rho {'type': 'ineq', 'fun': lambda x: np.array([x[1]]), 'jac': lambda x: np.array([0., 1., 0.]) }, # for eta {'type': 'ineq', 'fun': lambda x: np.array([0.5 - np.abs(x[2] - 0.5)]), 'jac': lambda x: np.array([0., 0., -np.sign(x[2])]) }, # for gamma # constraints of parameter combination {'type': 'ineq', 'fun': lambda x: np.array(2 - x[1] * (1 + np.abs(x[0]))), 'jac': lambda x: np.array([-np.sign(x[0]), (1 + np.abs(x[0])), 0.]) } # free of static arbitrage condition ) self._x_Power = np.array([0.] * 3) # Coefficients
def __init__(self, K, T, F, iv_slice, ir, wgttype='none'): self._K = K # vector self._T = T # scalar self._F = F # scalar self._iv = iv_slice # vector # added (4/20, 황보람) self._ir = ir self._wgttype = wgttype self._k = np.log(K / F) # vector # for vega weight self._vega = [] for i in range(len(self._k)): if i < 10: self._vega.append( bs_formula('p', self._F, self._K[i], self._T, self._ir(self._T), 0, self._iv[i], 'v')) elif i > 10: self._vega.append( bs_formula('c', self._F, self._K[i], self._T, self._ir(self._T), 0, self._iv[i], 'v')) else: self._vega.append( bs_formula('c', self._F, self._K[i], self._T, self._ir(self._T), 0, self._iv[i], 'v') + bs_formula('p', self._F, self._K[i], self._T, self._ir(self._T), 0, self._iv[i], 'v')) print 'K: ', K print 'F: ', F print 'self._k: ', self._k # constraints self.cons = ( # constraints for parameter itself { 'type': 'ineq', 'fun': lambda x: np.array([x[0]]), 'jac': lambda x: np.array([1., 0., 0., 0., 0.]) }, # for a { 'type': 'ineq', 'fun': lambda x: np.array([x[1]]), 'jac': lambda x: np.array([0., 1., 0., 0., 0.]) }, # for b { 'type': 'ineq', # original constraints 'fun': lambda x: np.array([1 - abs(x[2])]), 'jac': lambda x: np.array([0., 0., -x[2] / abs(x[2]), 0., 0.]) }, # for rho { 'type': 'ineq', 'fun': lambda x: np.array([x[4]]), 'jac': lambda x: np.array([0., 0., 0., 0., 1.]) }, # for sigma # constraints for parameter combination { 'type': 'ineq', 'fun': lambda x: np.array([4 - x[1] * self._T * (1 + abs(x[2]))]), 'jac': lambda x: np.array([ 0., -self._T * (1 + abs(x[2])), -x[1] * self._T * x[2] / abs(x[2]), 0., 0. ]) } # combined constraints 1. preventing vertical arbitrage (Gatheral, 2004) ) self._x = np.array([0.] * 5) # Coefficients