def main(*args): OPT_N = 4000000 iterations = 10 if len(args) >= 2: iterations = int(args[0]) callResultNumpy = np.zeros(OPT_N) putResultNumpy = -np.ones(OPT_N) stockPrice = randfloat(np.random.random(OPT_N), 5.0, 30.0) optionStrike = randfloat(np.random.random(OPT_N), 1.0, 100.0) optionYears = randfloat(np.random.random(OPT_N), 0.25, 10.0) callResultNumba = np.zeros(OPT_N) putResultNumba = -np.ones(OPT_N) time0 = time.time() for i in range(iterations): black_scholes(callResultNumpy, putResultNumpy, stockPrice, optionStrike, optionYears, RISKFREE, VOLATILITY) time1 = time.time() print("Numpy Time: %f msec" % ((1000 * (time1 - time0)) / iterations)) time0 = time.time() for i in range(iterations): black_scholes_numba(callResultNumba, putResultNumba, stockPrice, optionStrike, optionYears, RISKFREE, VOLATILITY) time1 = time.time() print("Numba Time: %f msec" % ((1000 * (time1 - time0)) / iterations)) delta = np.abs(callResultNumpy - callResultNumba) L1norm = delta.sum() / np.abs(callResultNumpy).sum() print("L1 norm: %E" % L1norm) print("Max absolute error: %E" % delta.max())
def main (*args): OPT_N = 4000000 iterations = 10 if len(args) >= 2: iterations = int(args[0]) callResultNumpy = np.zeros(OPT_N) putResultNumpy = -np.ones(OPT_N) stockPrice = randfloat(np.random.random(OPT_N), 5.0, 30.0) optionStrike = randfloat(np.random.random(OPT_N), 1.0, 100.0) optionYears = randfloat(np.random.random(OPT_N), 0.25, 10.0) callResultNumba = np.zeros(OPT_N) putResultNumba = -np.ones(OPT_N) time0 = time.time() for i in range(iterations): black_scholes(callResultNumpy, putResultNumpy, stockPrice, optionStrike, optionYears, RISKFREE, VOLATILITY) time1 = time.time() print("Numpy Time: %f msec" % ((1000 * (time1 - time0)) / iterations)) time0 = time.time() for i in range(iterations): black_scholes_numba(callResultNumba, putResultNumba, stockPrice, optionStrike, optionYears, RISKFREE, VOLATILITY) time1 = time.time() print("Numba Time: %f msec" % ((1000 * (time1 - time0)) / iterations)) delta = np.abs(callResultNumpy - callResultNumba) L1norm = delta.sum() / np.abs(callResultNumpy).sum() print("L1 norm: %E" % L1norm) print("Max absolute error: %E" % delta.max())
def leverage(self, strike): return 1.0 / black_scholes ((-1 if self.style == "put" else 1), self.price, strike, self.t/365.0, self.vol, self.r, self.d)
def main(*args): OPT_N = 40000 callResult = np.zeros(OPT_N) putResult = -np.ones(OPT_N) stockPrice = randfloat(np.random.random(OPT_N), 5.0, 30.0) optionStrike = randfloat(np.random.random(OPT_N), 1.0, 100.0) optionYears = randfloat(np.random.random(OPT_N), 0.25, 10.0) c = black_scholes(stockPrice, optionStrike, optionYears, RISKFREE, VOLATILITY) p = None return c, p
def portfolio_items(self, prices=None, mtm=False, payoff_asset=None, date=None, dt=0.0): retval = [] if prices == None: prices = self.prices for asset in self.portfolio: if asset[1] == "cash": retval.append(asset[0]) elif asset[1] == "spot": quantity = asset[0] underlying = asset[2] purchase = asset[3] if purchase < 0.0: raise ValueError retval.append(quantity * prices[underlying]) elif asset[1] == "put" or asset[1] == "call": quantity = asset[0] style = asset[1] expiry = asset[2] strike = asset[3] underlying = asset[4] purchase = asset[5] price = prices[underlying] value = 0.0 if strike < 0.0 or purchase < 0.0: raise ValueError if not mtm or underlying == payoff_asset: if asset[1] == "put" and price < strike: value = strike - price if asset[1] == "call" and price > strike: value = price - strike else: t = (date_fraction(date, expiry) - dt / 365.0) if (t < 0.0): t = 0.0 vol = self.vols[underlying] if (price < 0.0): price = 0.0 value = black_scholes((-1 if style == "put" else 1), price, strike, t, vol, self.r, 0.0) retval.append(quantity * value) elif asset[1] == "comment": pass else: raise Exception("unknown asset") return retval
def portfolio_items(self, prices = None, mtm=False, payoff_asset=None, date=None, dt = 0.0): retval = [] if prices == None: prices = self.prices for asset in self.portfolio: if asset[1] == "cash": retval.append(asset[0]) elif asset[1] == "spot": quantity = asset[0] underlying = asset[2] purchase = asset[3] if purchase < 0.0: raise ValueError retval.append(quantity * prices[underlying]) elif asset[1] == "put" or asset[1] == "call": quantity = asset[0] style = asset[1] expiry = asset[2] strike = asset[3] underlying = asset[4] purchase = asset[5] price = prices[underlying] value = 0.0 if strike < 0.0 or purchase < 0.0: raise ValueError if not mtm or underlying == payoff_asset: if asset[1] == "put" and price < strike: value = strike - price if asset[1] == "call" and price > strike: value = price - strike else: t = (date_fraction(date, expiry) -dt/365.0) if (t < 0.0): t = 0.0 vol = self.vols[underlying] if (price < 0.0): price = 0.0 value = black_scholes ((-1 if style == "put" else 1), price, strike, t, vol, self.r, 0.0) retval.append(quantity * value ) elif asset[1] == "comment": pass else: raise Exception ("unknown asset") return retval
def gearing(self, strike): """Calculate return dependence for given strike""" options = self.leverage(strike) return (lambda price_new, dt : options * black_scholes ((-1 if self.style == "put" else 1), price_new, strike, ((self.t-dt)/365.0), self.vol, self.r, self.d))
for o in calls: for o2 in puts: if o['expiration'] == o2['expiration']: strikec.append(int(o['strike'])) strikep.append(int(o2['strike'])) exp = datetime.strptime(o['expiration'][:-13], '%Y-%m-%d') pexps.append(exp.strftime('%s')) abc = 0 oldp = 0 while abc < len(calls): now = time.time() diff = (int(pexps[abc]) - int(now)) / 60 / 60 / 24 / 365 p1 = black_scholes(spot, strikep[abc], diff, ivs[puts[abc]['instrumentName']], 0.03, 0.0, -1) c1 = black_scholes(spot, strikec[abc], diff, ivs[calls[abc]['instrumentName']], 0.03, 0.0, 1) c2 = black_scholes(spot * 1.11, strikep[abc], diff, ivs[puts[abc]['instrumentName']], 0.03, 0.0, -1) p2 = black_scholes(spot * 1.11, strikec[abc], diff, ivs[calls[abc]['instrumentName']], 0.03, 0.0, 1) c3 = black_scholes(spot * 0.89, strikep[abc], diff, ivs[puts[abc]['instrumentName']], 0.03, 0.0, -1) p3 = black_scholes(spot * 0.89, strikec[abc], diff, ivs[calls[abc]['instrumentName']], 0.03, 0.0, 1) cost1 = (c1 + p1) cost2 = (c2 + p2) cost3 = (c3 + p3) profit = (cost2 - cost1) + (cost3 - cost1)
def gearing(self, strike): """Calculate return dependence for given strike""" options = self.leverage(strike) return (lambda price_new, dt: options * black_scholes( (-1 if self.style == "put" else 1), price_new, strike, ( (self.t - dt) / 365.0), self.vol, self.r, self.d))
def leverage(self, strike): return 1.0 / black_scholes( (-1 if self.style == "put" else 1), self.price, strike, self.t / 365.0, self.vol, self.r, self.d)
puts.append(s) #print(puts) civs[s] = iv pivs[s] = iv costp.append(has[options[o]['instrumentName']]) instsp.append(options[o]['instrumentName']) #print(len(puts)) #print(len(calls)) ccount = -1 for c in calls: ccount = ccount + 1 pcount = -1 for p in puts: pcount = pcount + 1 p1 = black_scholes(spot, p, diff, pivs[p], 0.03, 0.0, -1) c1 = black_scholes(spot, c, diff, civs[c], 0.03, 0.0, 1) if c1 > costc[ccount] * spot: print('c1 underpriced!') print(c1) print({ 'price': costc[ccount], 'call s': c, 'put s': p, 'instrument': instsc[ccount], 'e': e }) if p1 > costp[pcount] * spot: print('p1 underpriced!') print(p1) print({
data = requests.get( 'https://www.malaysiawarrants.com.my/mqmy/ScreenerJSONServlet?undefined&underlying=all&type=all&issuer=all&maturity=all&moneyness=all&moneynessPercent=all&effectiveGearing=all&expiry=all&indicator=all&sortBy=&sortOrder=asc' ).json()["data"] for x in data: warrant_name = x["dwSymbol"] price = float(x["underlying_price"].replace(",", "")) ex_price = float(x["exercisePrice"].replace(",", "")) cr = float(x["conv_ratio"].replace(",", "")) exdate = x["maturity"] vola = float(x["impliedVolalitiy"]) bid = float(x["bidPrice"].replace(",", "")) if vola == 0 or cr > 1000: continue d = datetime.datetime.strptime(exdate, '%d %b %y') exdate = d.strftime('%Y-%m-%d') exdate = datetime.datetime.strptime(exdate, '%Y-%m-%d') remaining_days = (exdate.date() - datetime.datetime.now().date()).days time = float(remaining_days / 365) bs = black_scholes(1, price, ex_price, time, vola / 100, rf / 100, cr) margin = round(bs / bid, 2) if margin < 1.7 and margin > 1.2 and remaining_days > 60: print("%s\nblackscholes: %s\nmarket: %s\nmargin: %s\nexpired: %s\n" % (warrant_name, bs, bid, margin, exdate))