def estimateSigma(self, gamma_sigma, param, K, F, T): a = self._a #param=np.exp(param) #transform to restrict a to be postive effective_K = 1 - np.exp(-a * T) * (1 - K / F) f0 = F + gamma_sigma[0] k0 = effective_K * F + gamma_sigma[0] d1 = (np.log(f0 / k0) + (r + 0.5 * gamma_sigma[1]**2) * T) / (gamma_sigma[1] * np.sqrt(T)) d2 = d1 - gamma_sigma[1] * np.sqrt(T) #call_price = np.exp(a*T)/F *(f0*norm.cdf(d1)-k0*norm.cdf(d2)) f1 = -2 * a * (effective_K - 1) * ndtr(d2) * np.exp(a * T) f2 = 4 * a**2 * (effective_K - 1)**2 * ndtr(d2)**2 * np.exp(2 * a * T) f3 = f0**2 * norm._pdf(d1)**2 * np.exp(a * T) * effective_K**2 f4 = f0 * norm._pdf(d1) / (F * np.sqrt(T)) estimate_sigma = (f1 + np.sqrt(f2 + (f3 * (param[0] * effective_K + param[1])**2) / (k0**2 * np.sqrt(T)))) / f4 return estimate_sigma
def tn_pdf(x, loc, scale, lower=0, upper=1): if upper == np.inf: Z = 1 - norm._cdf(lower-loc/scale) else: Z = norm._cdf((upper-loc)/scale) - norm._cdf((lower-loc)/scale) pdf_psi = norm._pdf((x - loc) / scale) return pdf_psi / (scale * Z)
def vega(self): vegaCall = self.S * norm._pdf(self.d1) * np.sqrt(self.T) vegaPut = vegaCall return namedtuple('Vega', ['call', 'put'])(**{ "call": vegaCall, "put": vegaPut })
def gamma(self): gammaCall = norm._pdf(self.d1) / float( self.S * self.sigma * np.sqrt(self.T)) gammaPut = gammaCall return namedtuple('Gamma', ['call', 'put'])(**{ "call": gammaCall, "put": gammaPut })
def theoreticalDistribution(self, strikes): probability = [] for strike in strikes: probability.append(norm._pdf(self.computeValues(strike=strike).d2)) return namedtuple('Distruibution', ['strike', 'probability'])(**{ "strike": strikes, "probability": probability })
def theta(self): thetaCall = -self.K * self.r * np.exp(-self.r * self.T) * ndtr( self.d2) - (self.sigma * self.S * norm._pdf(self.d1) / (2 * np.sqrt(self.T))) thetaPut = self.K * self.r * np.exp(-self.r * self.T) + thetaCall return namedtuple('Theta', ['call', 'put'])(**{ "call": thetaCall, "put": thetaPut })
def implied_vol(mkt_price, F, K, T_maturity, *args): Max_iteration = 500 PRECISION = 1.0e-5 sigma = 0.4 for i in range(0, Max_iteration): d1 = (np.log(F / K) + ( 0.5 * sigma ** 2) * T_maturity) / (sigma * np.sqrt(T_maturity)) d2 = d1 - sigma * np.sqrt(T_maturity) bls_price = F * ndtr(d1) - K * ndtr(d2) vega = F * norm._pdf(d1) * np.sqrt(T_maturity) diff = mkt_price - bls_price if (abs(diff) < PRECISION): return sigma sigma = sigma + diff/vega # f(x) / f'(x) return sigma
def compute_delta(current_price, strike, interest_rate, days_to_expiry, option_price, is_call): # epsilon is how far off the guess is epsilon = 1 # initial guess is 0.5 volatility = 0.50 t = days_to_expiry / 365.0 # This calculator assumes the interest rate is a percent interest_rate = interest_rate / 100.0 for _ in range(MAX_ITERATIONS): # Log the value previously calculated to computer percent change # between iterations orig_volatility = volatility # Calculate the value of the call price d1, d2 = d(volatility, current_price, strike, interest_rate, t) if is_call: value = call_price(volatility, current_price, strike, interest_rate, t, d1, d2) - option_price else: value = put_price(volatility, current_price, strike, interest_rate, t, d1, d2) - option_price # Calculate vega, the derivative of the price with respect to # volatility vega = current_price * norm._pdf(d1) * sqrt(t) # Update for value of the volatility volatility += -value / vega # Check the percent change between current and last iteration epsilon = abs((volatility - orig_volatility) / orig_volatility) if epsilon < TOLERANCE: break # http://janroman.dhis.org/stud/I2014/BS2/BS_Daniel.pdf, compute put delta return -ndtr(-d1)
def mytruncpdf_01bounds(x, loc, scale): Z = norm._cdf((1-loc)/scale) - norm._cdf(-loc/scale) pdf_psi = norm._pdf((x - loc) / scale) return pdf_psi / (scale * Z)
def tn_pdf_01(x, loc, scale): Z = norm._cdf((1-loc)/scale) - norm._cdf(-loc/scale) pdf_psi = norm._pdf((x - loc) / scale) return pdf_psi / (scale * Z)