def opt_vol(self, type, symbol, option, underlying, day, month, year, strike): if type == "Equity": vol = 1 elif option == "CALL": call = Call(underlying, day, month, year, strike) vol = float(call.implied_volatility()) elif option == "PUT": put = Put(underlying, day, month, year, strike) vol = float(put.implied_volatility()) else: vol = 0 return vol
def get_quotes_from_yahoo(reload_weekly=False): if reload_weekly: tickers = save_weekly_earnings() else: with open("saveweekly.pickle", "rb") as f: tickers = pickle.load(f) for ticker in tickers: print(ticker) g = Stock(ticker, source='yahoo') price = g.price PutATM = Put(ticker, strike=price, source='yahoo') b = PutATM.price CallATM = Call(ticker, strike=price, source='yahoo') a = CallATM.price print("Put ATM:", a, "Call ATM:", b) iv = (a + b) poms = PutATM.strike pom = poms - iv coms = CallATM.strike com = coms + iv PutIV = Put(ticker, strike=pom, source='yahoo') PutIV2 = Put(ticker, strike=pom - 3, source='yahoo') pl = PutIV.price pl2 = PutIV2.price pis = PutIV.strike pis2 = PutIV2.strike CallIV = Call(ticker, strike=com, source='yahoo') CallIV2 = Call(ticker, strike=com + 3, source='yahoo') cl = CallIV.price cl2 = CallIV2.price cis = CallIV.strike cis2 = CallIV2.strike MaxLossP = pis - pis2 MaxLossC = cis - cis2 ProfitP = 100 * (pl - pl2) / (MaxLossP + 0.00001) ProfitC = 100 * (cl2 - cl) / (MaxLossC + 0.00001) print("Implied Volatility:", iv, "Puts Outside of IV:", pl, "Calls Outside of IV:", cl) print("Profit from selling puts at", pis, "and buying at", pis2, ":", ProfitP, "%") print("Profit from selling calls at", cis, "and buying at", cis2, ":", ProfitC, "%")
def get_delta(symbol: str, percent_move: float, expiry: str): symbol = symbol.upper() if is_cache_good(f'{symbol}|getdelta|{percent_move:.2f}|{expiry}'): return ast.literal_eval( r.hget(f'{symbol}|getdelta|{percent_move:.2f}|{expiry}', 'value')) s = Stock(symbol) up_px = s.price * (1 + percent_move / 100) down_px = s.price * (1 - percent_move / 100) call = Call(symbol, d=int(expiry[0:2]), m=int(expiry[3:5]), y=int(expiry[6:10])) up_delta_dict = get_strike_bracket(call.strikes, up_px) call.set_strike(up_delta_dict['lower_strike']) delta1 = call.delta() * up_delta_dict['lower_weight'] call.set_strike(up_delta_dict['higher_strike']) delta2 = call.delta() * (1 - up_delta_dict['lower_weight']) delta_up_move = delta1 + delta2 put = Put(symbol, d=int(expiry[0:2]), m=int(expiry[3:5]), y=int(expiry[6:10])) down_delta_dict = get_strike_bracket(put.strikes, down_px) put.set_strike(down_delta_dict['lower_strike']) delta1 = -put.delta() * down_delta_dict['lower_weight'] put.set_strike(down_delta_dict['higher_strike']) delta2 = -put.delta() * (1 - down_delta_dict['lower_weight']) delta_down_move = delta1 + delta2 return_dict = {'delta_up': delta_up_move, 'delta_down': delta_down_move} r.hset(f'{symbol}|getdelta|{percent_move:.2f}|{expiry}', 'time', datetime.utcnow().strftime('%s')) r.hset(f'{symbol}|getdelta|{percent_move:.2f}|{expiry}', 'value', str(return_dict)) return return_dict
def get_delta(symbol: str, percent_move: float, expiry: str): s = Stock(symbol) up_px = s.price * (1 + percent_move / 100) down_px = s.price * (1 - percent_move / 100) call = Call(symbol, d=int(expiry[0:2]), m=int(expiry[3:5]), y=int(expiry[6:10])) up_delta_dict = get_strike_bracket(call.strikes, up_px) call.set_strike(up_delta_dict['lower_strike']) delta1 = call.delta() * up_delta_dict['lower_weight'] call.set_strike(up_delta_dict['higher_strike']) delta2 = call.delta() * (1 - up_delta_dict['lower_weight']) delta_up_move = delta1 + delta2 put = Put(symbol, d=int(expiry[0:2]), m=int(expiry[3:5]), y=int(expiry[6:10])) down_delta_dict = get_strike_bracket(put.strikes, down_px) put.set_strike(down_delta_dict['lower_strike']) delta1 = -put.delta() * down_delta_dict['lower_weight'] put.set_strike(down_delta_dict['higher_strike']) delta2 = -put.delta() * (1 - down_delta_dict['lower_weight']) delta_down_move = delta1 + delta2 return {'delta_up': delta_up_move, 'delta_down': delta_down_move}
def yFinanceToWallStreet(optionChain, strikePrice): # Gets the relevant data to calculate greeks data = op.findGreekData(optionChain) # Gets the specific row with strike price wanted optionContract = data.loc[data['strike'] == strikePrice] # Checks if the option contract is a call if optionContract.iloc[0]['typeOfOption'] == 'Call': # Gets the date and converts it to work with WallStreet date = dateConverter(optionContract.iloc[0]['expirationDate']) # Returns the Call object that will be used to find greeks return Call(op.findTickerName( optionContract.iloc[0]['contractSymbol']), d=date[2], m=date[1], y=date[0], strike=strikePrice, source='yahoo') # If not a call option, assumes it is a Put option else: # Gets the date and converts it to work with WallStreet date = dateConverter(optionContract.iloc[0]['expirationDate']) # Returns the Put object that will be used to find greeks return Put(op.findTickerName(optionContract.iloc[0]['contractSymbol']), d=date[2], m=date[1], y=date[0], strike=strikePrice, source='yahoo')
def opt_values(self, type, symbol, option, underlying, day, month, year, strike): if type == "Equity": price = Stock(symbol).price delta = 1 elif option == "CALL": call = Call(underlying, day, month, year, strike) price = call.price delta = call.delta() elif option == "PUT": put = Put(underlying, day, month, year, strike) price = put.price delta = put.delta() else: price = 0 delta = 0 return price, delta
def updatePortfolio(currentPortfolio): value = currentPortfolio["Value"] for i in reversed(range(len(currentPortfolio["Current Options"]))): optionInfo = currentPortfolio["Current Options"][i] date = convertDate(optionInfo["Expiry"]) dateTup = dateToTuple(date) #update the Price, Underlying Price, and add it to value name = optionInfo["Stock Name"] strike = optionInfo["Strike"] isCall = optionInfo["Call"] option = Call(name, d=dateTup[0], m=dateTup[1], y=dateTup[2], strike=strike, source="yahoo") if isCall else Put(name, d=dateTup[0], m=dateTup[1], y=dateTup[2], strike=strike, source="yahoo") #lets update oldValue = value value += (option.price - optionInfo["Price"]) * 100 refreshLog(name, date, strike, optionInfo["Price"], option.price, oldValue, value, currentPortfolio["Spent"]) optionInfo["Price"] = option.price optionInfo["Underlying Price"] = option.underlying.price #if option is expired, lets move it if (date <= dt.datetime.now()): currentPortfolio["Past Options"].append(optionInfo) del currentPortfolio["Current Options"][i] #reset the new value for the portfolio currentPortfolio["Value"] = value return currentPortfolio
def get_expiries_bracket(symbol, num_of_days): c = Call(symbol) expiries = c.expirations curr_date = str(datetime.date(datetime.now())) longer_expiry = expiries[-1] shorter_expiry = expiries[0] shorter_day_bound = (datetime.strptime(shorter_expiry, '%d-%m-%Y') - datetime.strptime(curr_date, '%Y-%m-%d')).days longer_day_bound = (datetime.strptime(longer_expiry, '%d-%m-%Y') - datetime.strptime(curr_date, '%Y-%m-%d')).days for i in expiries: days_to_exp = abs( datetime.strptime(i, '%d-%m-%Y') - datetime.strptime(curr_date, '%Y-%m-%d')).days if days_to_exp < num_of_days and days_to_exp > shorter_day_bound: shorter_day_bound = days_to_exp shorter_expiry = i longer_day_bound = days_to_exp longer_expiry = i elif days_to_exp >= num_of_days: longer_day_bound = days_to_exp longer_expiry = i break shorter_weight = 1 if longer_day_bound != shorter_day_bound: shorter_weight = (longer_day_bound - num_of_days) / (longer_day_bound - shorter_day_bound) return { 'shorter_expiry': shorter_expiry, 'longer_expiry': longer_expiry, 'shorter_day_bound': shorter_day_bound, 'longer_day_bound': longer_day_bound, 'shorter_weight': shorter_weight }
def prob_move_pct(symbol: str, n_days: int, percent: float): symbol = symbol.upper() if is_cache_good(f'{symbol}|pmovepct|{n_days}|{percent}'): return ast.literal_eval( r.hget(f'{symbol}|pmovepct|{n_days}|{percent}', 'value')) return_dict = {"error": "no options"} try: c = Call(symbol) curr_date = str(datetime.date(datetime.now())) expiries = c.expirations expiry_to_use = expiries[0] for i in expiries: days_to_exp = abs( datetime.strptime(i, '%d-%m-%Y') - datetime.strptime(curr_date, '%Y-%m-%d')).days expiry_to_use = i if days_to_exp >= n_days: break my_delta = get_delta(symbol, percent, expiry_to_use) return_dict = { "symbol": symbol, "move_percent": percent, 'expiry': expiry_to_use, "prob_down": my_delta['delta_down'], "prob_up": my_delta['delta_up'] } r.hset(f'{symbol}|pmovepct|{n_days}|{percent}', 'time', datetime.utcnow().strftime('%s')) r.hset(f'{symbol}|pmovepct|{n_days}|{percent}', 'value', str(return_dict)) return return_dict except: return return_dict
def infos(udlying, day, month, year, stockprice, offset): """ Group information :param udlying: underlying stock object :param day: int digits :param month: int digits :param year: :param stockprice: stock price :param offset: strike offset :return: Tuple of all data """ u = Call(udlying, d=day, m=month, y=year, strike=stockprice + offset) price = u.price IV = u.implied_volatility() v = u.vega() g = u.gamma() strike = u.strike return (IV, v, g, price, strike)
def get_data(self, df): tup = df.shape x = tup[0] y = tup[1] prices = [] deltas = [] for i in range(x): if df.iloc[i, 1] == "Equity": price = Stock(df.iloc[i, 0]).price delta = 1 df.iloc[i, 2] = df.iloc[i, 0] elif df.iloc[i, 3] == "CALL": ticker = df.iloc[i, 2] strike = float(df.iloc[i, 5]) date = datetime.strptime(df.iloc[i, 6], '%m/%d/%Y') month = date.month day = date.day year = date.year call = Call(ticker, day, month, year, strike) price = call.price delta = call.delta() elif df.iloc[i, 3] == "PUT": ticker = df.iloc[i, 2] strike = float(df.iloc[i, 5]) date = datetime.strptime(df.iloc[i, 6], '%m/%d/%Y') month = date.month day = date.day year = date.year put = Put(ticker, day, month, year, strike) price = put.price delta = put.delta() else: price = 0 prices.append(price) deltas.append(delta) print(prices, deltas) df["Prices"] = prices df["Deltas"] = deltas return df
def opt_vol_r_T(self, type, symbol, option, underlying, day, month, year, strike): if type == "Equity": time = 1 rate = 1 vol = 1 elif option == "CALL": call = Call(underlying, day, month, year, strike) time = call.BandS.T rate = float(call.BandS.r) vol = float(call.implied_volatility()) elif option == "PUT": put = Put(underlying, day, month, year, strike) time = put.BandS.T rate = float(put.BandS.r) vol = float(put.implied_volatility()) else: time = 0; rate = 0; vol = 0 return time, rate, vol
def opt_rate(self, type, symbol, option, underlying, day, month, year, strike): if type == "Equity": rate = 1 elif option == "CALL": call = Call(underlying, day, month, year, strike) rate = float(call.BandS.r) elif option == "PUT": put = Put(underlying, day, month, year, strike) rate = float(put.BandS.r) else: rate = 0 return rate
def getOption(tickerSymbol, isCall): price = getStockPrice(tickerSymbol) date = getFutureDate() opt = None try: opt = Call( tickerSymbol, d=date[0], m=date[1], y=date[2], source="yahoo") if isCall else Put( tickerSymbol, d=date[0], m=date[1], y=date[2], source="yahoo") except: print("No options avail") return opt
def opt_time(self, type, symbol, option, underlying, day, month, year, strike): if type == "Equity": time = 1 elif option == "CALL": call = Call(underlying, day, month, year, strike) time = call.BandS.T elif option == "PUT": put = Put(underlying, day, month, year, strike) time = put.BandS.T else: time = 0 return time
def prob_move_sigma(symbol: str, n_days: int, sigma_fraction_to_use: float): symbol = symbol.upper() if is_cache_good(f'{symbol}|pmovesigma|{n_days}|{sigma_fraction_to_use}'): return ast.literal_eval( r.hget(f'{symbol}|pmovesigma|{n_days}|{sigma_fraction_to_use}', 'value')) return_dict = {"error": "no options"} try: c = Call(symbol) expiries = c.expirations curr_date = str(datetime.date(datetime.now())) expiry_to_use = expiries[0] my_n_days = 0 for i in expiries: days_to_exp = abs( datetime.strptime(i, '%d-%m-%Y') - datetime.strptime(curr_date, '%Y-%m-%d')).days expiry_to_use = i my_n_days = days_to_exp if days_to_exp >= n_days: break my_tuple = get_atm_ivol(Stock(symbol), my_n_days) my_percent = my_tuple[1] * 100 * sigma_fraction_to_use my_delta = get_delta(symbol, my_percent, expiry_to_use) prob_down = my_delta['delta_down'] prob_up = my_delta['delta_up'] norm_prob_down = 0 norm_prob_up = 0 if prob_up > prob_down: norm_prob_down = 0.5 norm_prob_up = prob_up * 0.5 / prob_down else: norm_prob_up = 0.5 norm_prob_down = prob_down * 0.5 / prob_up return_dict = { "symbol": symbol, "move_percent": my_percent, 'expiry': expiry_to_use, "prob_down": prob_down, "norm_prob_down": norm_prob_down, "prob_up": prob_up, "norm_prob_up": norm_prob_up } r.hset(f'{symbol}|pmovesigma|{n_days}|{sigma_fraction_to_use}', 'time', datetime.utcnow().strftime('%s')) r.hset(f'{symbol}|pmovesigma|{n_days}|{sigma_fraction_to_use}', 'value', str(return_dict)) return return_dict except: return return_dict
def get_options(sym, strike_date): put = Put(sym, d=strike_date.day, m=strike_date.month, y=strike_date.year, strict=True, source='yahoo') call = Call(sym, d=strike_date.day, m=strike_date.month, y=strike_date.year, strict=True, source='yahoo') stock = Stock(sym) price = get_closest(stock.price, put.strikes) put.set_strike(price) call.set_strike(price) return [ stock.price, price, put.price, put.volume, call.price, call.volume, format_date(put.expiration), format_date(call.expiration) ]
def get_expiries_bracket(symbol, num_of_days): symbol = symbol.upper() if is_cache_good(f'{symbol}|getexpiries|{num_of_days}'): return ast.literal_eval( r.hget(f'{symbol}|getexpiries|{num_of_days}', 'value')) c = Call(symbol) expiries = c.expirations curr_date = str(datetime.date(datetime.now())) longer_expiry = expiries[-1] shorter_expiry = expiries[0] shorter_day_bound = (datetime.strptime(shorter_expiry, '%d-%m-%Y') - datetime.strptime(curr_date, '%Y-%m-%d')).days longer_day_bound = (datetime.strptime(longer_expiry, '%d-%m-%Y') - datetime.strptime(curr_date, '%Y-%m-%d')).days for i in expiries: days_to_exp = abs( datetime.strptime(i, '%d-%m-%Y') - datetime.strptime(curr_date, '%Y-%m-%d')).days if days_to_exp < num_of_days and days_to_exp > shorter_day_bound: shorter_day_bound = days_to_exp shorter_expiry = i longer_day_bound = days_to_exp longer_expiry = i elif days_to_exp >= num_of_days: longer_day_bound = days_to_exp longer_expiry = i break shorter_weight = 1 if longer_day_bound != shorter_day_bound: shorter_weight = (longer_day_bound - num_of_days) / (longer_day_bound - shorter_day_bound) return_dict = { 'shorter_expiry': shorter_expiry, 'longer_expiry': longer_expiry, 'shorter_day_bound': shorter_day_bound, 'longer_day_bound': longer_day_bound, 'shorter_weight': shorter_weight } r.hset(f'{symbol}|getexpiries|{num_of_days}', 'time', datetime.utcnow().strftime('%s')) r.hset(f'{symbol}|getexpiries|{num_of_days}', 'value', str(return_dict)) return return_dict
def implied_forward(symbol, n_days): s = Stock(symbol) c = Call(symbol) curr_date = str(datetime.date(datetime.now())) expiries = c.expirations expiry_to_use = expiries[0] my_n_days = 0 for i in expiries: days_to_exp = abs( datetime.strptime(i, '%d-%m-%Y') - datetime.strptime(curr_date, '%Y-%m-%d')).days expiry_to_use = i my_n_days = days_to_exp if days_to_exp >= n_days: break call = Call(symbol, d=int(expiry_to_use[0:2]), m=int(expiry_to_use[3:5]), y=int(expiry_to_use[6:10])) put = Put(symbol, d=int(expiry_to_use[0:2]), m=int(expiry_to_use[3:5]), y=int(expiry_to_use[6:10])) bracket_dict = get_strike_bracket(call.strikes, s.price) forward = s.price if bracket_dict['lower_weight'] > 0.5: call.set_strike(bracket_dict['lower_strike']) put.set_strike(bracket_dict['lower_strike']) forward = bracket_dict['lower_strike'] - put.price + call.price else: call.set_strike(bracket_dict['higher_strike']) put.set_strike(bracket_dict['higher_strike']) forward = bracket_dict['higher_strike'] - put.price + call.price return { "symbol": symbol, "forward_price": forward, "current_price": s.price, "expiry": expiry_to_use }
if __name__ == '__main__': # Ticker print('Inserisci il titolo da analizzare :') nome = input() # Maturità T = 3.0 / 12 print('Inserisci la maturità :') T = float(input()) # Numero di simulazioni num_reps = 100 print('Inserisci il numero di simulazioni:') num_reps = int(input()) # Ricavo i dati da yahoo finance mu, sigma, s0 = getData(nome) delta_t = 0.001 # Ricavo i dati veri della strike call dal pacchetto wallstreet c = Call(nome, d=13, m=12, y=2019) strike_call = c.strikes[len(c.strikes) - 1] # Price Call con MonteCarlo e standard mc_call = mc_euro_options('c', s0, strike_call, T, mu, sigma, num_reps) call = vanilla_call_price(s0, strike_call, mu, sigma, T) print("Montecarlo price call : " + str(mc_call)) print("Price call standard : " + str(call))
# stored_price_range = price_range(12, 16) # c = Call('AMD', source='yahoo') # print(c.expirations) # price = [] # for strike_price in stored_price_range: # g = Call('AMD', d=4, m=8, y=2017, strike=strike_price, source='yahoo') # price.append(g.ask) # # print(price) # # plt.scatter(stored_price_range, price, color='red', marker='.', alpha=0.5, s=400) # plt.show() fut_opt13 = Call('AMD', d=4, m=8, y=2017, strike=13, source='yahoo') # print(future_option_price(fut_opt13, 30, 17, .8906)) price = [] for i in range(10, 17): option_price = future_option_price(fut_opt13, 1, i, .8906) price.append(option_price) plt.scatter(range(10, 17), price, color='red', marker='.', alpha=0.5, s=400) plt.show() # S0 = 13.36 # K = 17 # r=0.15 # sigma = 87.5
def best_call_trades(symbol, num_of_days): symbol = symbol.upper() if is_cache_good(f'{symbol}|calltrade|{num_of_days}'): return ast.literal_eval( r.hget(f'{symbol}|calltrade|{num_of_days}', 'value')) return_dict = {"error": "no options"} try: c = Call(symbol) range_dict = range_data_from_symbol(symbol, num_of_days) curr_date = str(datetime.date(datetime.now())) expiries = c.expirations expiry_to_use = expiries[0] for i in expiries: days_to_exp = abs( datetime.strptime(i, '%d-%m-%Y') - datetime.strptime(curr_date, '%Y-%m-%d')).days expiry_to_use = i if days_to_exp >= num_of_days: break c = Call(symbol, d=int(expiry_to_use[0:2]), m=int(expiry_to_use[3:5]), y=int(expiry_to_use[6:10])) counter = 0 spread_list = [] strikes = c.strikes for i in strikes: if i >= range_dict["high_range"] and counter < 10: counter = counter + 1 c.set_strike(i) spread_list.append({ 'strike': i, 'bid': c.bid, 'ask': c.ask, 'last': c.price, 'using_last': 'false', 'delta': c.delta() }) max_amt = 0 max_call_amt = 0 best_spread = {} best_call_written = {} for i in spread_list: #for call prob_winning_call = 1 - i['delta'] # Not expiring in the money i['using_last'] = 'false' if i['bid'] == 0 and i['ask'] == 0: i['bid'] = i['last'] i['ask'] = i['last'] i['using_last'] = 'true' premium_call = i['bid'] call_win_amt = premium_call * prob_winning_call if call_win_amt > max_call_amt: max_call_amt = call_win_amt best_call_written = i for j in spread_list: if i['strike'] < j['strike']: #for spread premium_per_dollar = (i['bid'] - j['ask']) / (j['strike'] - i['strike']) spread_using_last = 'false' if i['using_last'] == 'true' or j[ 'using_last'] == 'true': #If any leg uses last mark spread as last spread_using_last = 'true' prob_winning_spread = 1 - j['delta'] win_amt = premium_per_dollar * prob_winning_spread if win_amt > max_amt: max_amt = win_amt if spread_using_last == 'true': best_spread = { 'strike_to_sell': i['strike'], 'strike_to_buy': j['strike'], 'premium_received': i['last'], 'premium_paid': j['last'], 'expiry': expiry_to_use, 'spread_using_last': spread_using_last } else: best_spread = { 'strike_to_sell': i['strike'], 'strike_to_buy': j['strike'], 'premium_received': i['bid'], 'premium_paid': j['ask'], 'expiry': expiry_to_use, 'spread_using_last': spread_using_last } best_call_written['expiry'] = expiry_to_use return_dict = { "symbol": symbol, 'best_spread': best_spread, 'best_call': best_call_written } if best_spread and best_call_written: r.hset(f'{symbol}|calltrade|{num_of_days}', 'time', datetime.utcnow().strftime('%s')) r.hset(f'{symbol}|calltrade|{num_of_days}', 'value', str(return_dict)) return return_dict except: return return_dict
def get_atm_ivol(s, ndays=30): #Need to fix for divs, borrow etc to find atm symbol = s.ticker expiry_dict = get_expiries_bracket(symbol, ndays) #First Shorter One x = expiry_dict['shorter_expiry'] shorter_call = Call(symbol, d=int(x[0:2]), m=int(x[3:5]), y=int(x[6:10])) strike_dict = get_strike_bracket(shorter_call.strikes, s.price) shorter_call.set_strike(strike_dict['lower_strike']) lower_vol = shorter_call.implied_volatility() shorter_call.set_strike(strike_dict['higher_strike']) higher_vol = shorter_call.implied_volatility() shorter_ivol = lower_vol * strike_dict['lower_weight'] + higher_vol * ( 1 - strike_dict['lower_weight']) #Now longer One x = expiry_dict['longer_expiry'] longer_call = Call(symbol, d=int(x[0:2]), m=int(x[3:5]), y=int(x[6:10])) strike_dict = get_strike_bracket(longer_call.strikes, s.price) longer_call.set_strike(strike_dict['lower_strike']) lower_vol = longer_call.implied_volatility() longer_call.set_strike(strike_dict['higher_strike']) higher_vol = longer_call.implied_volatility() longer_ivol = lower_vol * strike_dict['lower_weight'] + higher_vol * ( 1 - strike_dict['lower_weight']) implied_ivol = shorter_ivol * expiry_dict[ 'shorter_weight'] + longer_ivol * (1 - expiry_dict['shorter_weight']) one_sigma_move_ndays_day = implied_ivol * math.sqrt(ndays / 365) return (implied_ivol, one_sigma_move_ndays_day)
args = sys.argv method = args[1] symbol = args[2] day = int(args[3]) month = int(args[4]) year = int(args[5]) min_strike = int(args[6]) max_strike = int(args[7]) step = int(args[8]) options = [] price = min_strike while price <= max_strike: option = Call(symbol, d=day, m=month, y=year, strike=price) if method == 'call' else Put( symbol, d=day, m=month, y=year, strike=price) options.append([ price, option.price, option.implied_volatility(), option.volume, option.underlying.price, option.delta(), option.gamma(), option.theta(), option.expiration ]) price += step df = pd.DataFrame(options, columns=[ 'Strike', 'Price', 'Implied Vol', 'Volume', 'Underlying', 'Delta', 'Gamma', 'Theta', 'Expiration'
def get_option_limit_price(symbol: str, pc: str, strike_hint: float, n_days: int): symbol = symbol.upper() pc = pc.upper() print(f'{symbol}|{pc}|{n_days}|{strike_hint}') if is_cache_good(f'{symbol}|{pc}|{n_days}|{strike_hint}', CACHE_TIMEOUT): return ast.literal_eval( r.hget(f'{symbol}|{pc}|{n_days}|{strike_hint}', 'value')) try: exp_dict = get_expiries_bracket(symbol, n_days) expiry_to_use = exp_dict['longer_expiry'] if exp_dict['shorter_weight'] > 0.5: expiry_to_use = exp_dict['shorter_expiry'] y = yf.Ticker(symbol) expiry = f'{expiry_to_use[6:10]}-{expiry_to_use[3:5]}-{expiry_to_use[0:2]}' o = y.option_chain(date=expiry) p = o.puts chart_list = list() p_strike = p.strike.tolist() p_ivol = p.impliedVolatility.tolist() for i in range(0, len(p_strike)): chart_list.append({ "group": "put", "ivol": p_ivol[i], "strike": p_strike[i] }) c = o.calls c_strike = c.strike.tolist() c_ivol = c.impliedVolatility.tolist() for i in range(0, len(c_strike)): chart_list.append({ "group": "call", "ivol": c_ivol[i], "strike": c_strike[i] }) strike_dict = get_strike_bracket(o.calls.strike.tolist(), strike_hint) if pc == "P": strike_dict = get_strike_bracket(o.puts.strike.tolist(), strike_hint) strike_to_use = strike_dict['higher_strike'] if strike_dict['lower_weight'] > 0.5: expiry_to_use = exp_dict['lower_strike'] my_option = Put(symbol, d=int(expiry_to_use[0:2]), m=int(expiry_to_use[3:5]), y=int(expiry_to_use[6:10])) if pc == "C": my_option = Call(symbol, d=int(expiry_to_use[0:2]), m=int(expiry_to_use[3:5]), y=int(expiry_to_use[6:10])) my_option.set_strike(strike_to_use) my_delta = my_option.delta() st = y.history(interval='5m', period='1d') stock_move = (max(st.High) - min(st.Low)) / 2 option_move = my_delta * stock_move return_dict = { 'symbol': symbol, 'pc': pc, 'strike': strike_to_use, 'bid': my_option.bid, 'ask': my_option.ask, 'last': my_option.price, 'expiry': expiry, 'delta': my_delta, 'option_move': option_move, 'chart_data': chart_list } r.hset(f'{symbol}|{pc}|{n_days}|{strike_hint}', 'time', datetime.utcnow().strftime('%s')) r.hset(f'{symbol}|{pc}|{n_days}|{strike_hint}', 'value', str(return_dict)) return return_dict except: return {"error": "No options were found"}
# https://github.com/mcdallas/wallstreet from wallstreet import Stock, Call, Put import numpy as mp s = Stock('AAPL') print(s.change) apple = Stock('AAPL', source='yahoo') print(apple) call = Call('AAPL', strike=apple.price, source='yahoo') p = Stock('BTC-USD') print(p) r = Call('RACE', d=10, m=7, y=2020) print(r.strikes) print(r.underlying.price)
def get_atm_ivol(s, ndays=30): #Need to fix for divs, borrow etc to find atm symbol = s.ticker symbol = symbol.upper() if is_cache_good(f'{symbol}|getatmivol|{ndays}'): return ast.literal_eval(r.hget(f'{symbol}|getatmivol|{ndays}', 'value')) expiry_dict = get_expiries_bracket(symbol, ndays) #First Shorter One x = expiry_dict['shorter_expiry'] shorter_call = Call(symbol, d=int(x[0:2]), m=int(x[3:5]), y=int(x[6:10])) strike_dict = get_strike_bracket(shorter_call.strikes, s.price) shorter_call.set_strike(strike_dict['lower_strike']) lower_vol = shorter_call.implied_volatility() shorter_call.set_strike(strike_dict['higher_strike']) higher_vol = shorter_call.implied_volatility() shorter_ivol = lower_vol * strike_dict['lower_weight'] + higher_vol * ( 1 - strike_dict['lower_weight']) #Now longer One x = expiry_dict['longer_expiry'] longer_call = Call(symbol, d=int(x[0:2]), m=int(x[3:5]), y=int(x[6:10])) strike_dict = get_strike_bracket(longer_call.strikes, s.price) longer_call.set_strike(strike_dict['lower_strike']) lower_vol = longer_call.implied_volatility() longer_call.set_strike(strike_dict['higher_strike']) higher_vol = longer_call.implied_volatility() longer_ivol = lower_vol * strike_dict['lower_weight'] + higher_vol * ( 1 - strike_dict['lower_weight']) implied_ivol = shorter_ivol * expiry_dict[ 'shorter_weight'] + longer_ivol * (1 - expiry_dict['shorter_weight']) one_sigma_move_ndays_day = implied_ivol * math.sqrt(ndays / 365) return_dict = (implied_ivol, one_sigma_move_ndays_day) r.hset(f'{symbol}|getatmivol|{ndays}', 'time', datetime.utcnow().strftime('%s')) r.hset(f'{symbol}|getatmivol|{ndays}', 'value', str(return_dict)) return return_dict
def contract(request, contract): typ = "" try: option = options_info.getOptionInfoFromContract(contract) ticker = option['ticker'] date = option['expirationDate'] optionType = option['type'] strike = option['strike'] index_number = re.search(r"\d", contract) ticker = contract[0:index_number.start()] stock = stock_info.StockInfo(ticker) name = stock.name amount = request.GET.get("quantity", "") if optionType == "Call": delta, gamma, rho, vega, theta = greek_options.getGreeks( greek_options.yFinanceToWallStreet( yfinance.Ticker(ticker).option_chain(date).calls, strike)) dates = greek_options.dateConverter(date) call = Call(ticker, d=dates[2], m=dates[1], y=dates[0], strike=strike, source='yahoo') price = call.price typ = "Call" else: delta, gamma, rho, vega, theta = greek_options.getGreeks( greek_options.yFinanceToWallStreet( yfinance.Ticker(ticker).option_chain(date).puts, strike)) dates = greek_options.dateConverter(date) put = Put(ticker, d=dates[2], m=dates[1], y=dates[0], strike=strike, source='yahoo') price = put.price typ = "Put" except: context = {} html_template = loader.get_template('error-404.html') return HttpResponse(html_template.render(context, request)) account = Account.objects.get(user_id=request.user.get_username()) if request.GET.get('type', "") == "Buy": # TODO type of option, strike transaction = Transaction(expiration_date=date, contract_symbol=contract, purchase_price=price, quantity=amount, typ=typ, strike=strike) transaction.save(force_insert=True) transaction.full_clean() account.balance -= int(price * float(int(amount)) * float(100)) account.save() account.transaction.add(transaction) transactions = account.transaction.filter(contract_symbol=contract) try: quantity = sum([t.quantity for t in transactions]) except: # TODO: Change this to "you cannot sell because you do not own the stock" context = {} html_template = loader.get_template('error-404.html') return HttpResponse(html_template.render(context, request)) elif request.GET.get('type', "") == "Sell": transactions = account.transaction.filter(contract_symbol=contract) try: transaction = transactions[0] transaction.pk = None except: # TODO: Change this to "you cannot sell because you do not own the stock" context = {} html_template = loader.get_template('error-404.html') return HttpResponse(html_template.render(context, request)) transaction.save(force_insert=True) transaction.full_clean() transaction.quantity = int(amount) * -1 transaction.save() transaction.full_clean() account.balance += int(price * float(int(amount)) * float(100)) account.save() account.transaction.add(transaction) quantity = sum([t.quantity for t in transactions]) else: pass account.save() account.full_clean() valuation = volatility_analysis.overorunder(ticker, date, optionType)[contract] quantity = sum([ t.quantity for t in account.transaction.filter(contract_symbol=contract) ]) return render( request, "contract.html", { 'contract': contract, 'delta': round(delta, 5), 'gamma': round(gamma, 5), 'rho': round(rho, 5), 'vega': round(vega, 5), 'theta': round(theta, 5), 'IV': ticker, 'name': name, 'option': option, 'price': price, 'quantity': quantity, 'valuation': valuation })
# strike_inc *= -1 errors = False if symbol is not None and len(symbol) > 0: try: s = Stock(symbol) window['__price'].update(s.price) except requests.exceptions.ConnectionError as ConnectionError: window['__price'].update("ERROR") errors = True # Get strikes and populate. # TODO: Wait for the price to update if expdate is not None and not errors: o = None # This is our option object. if is_call: o = Call(symbol, d=expdate.day, m=expdate.month, y=expdate.year) print("CALLS") else: o = Put(symbol, d=expdate.day, m=expdate.month, y=expdate.year) print("PUTS") if len(o.strikes) > 0: print("Strikes", o.strikes) strikes = get_strikes(price, o.strikes, is_call, num_options) for i, strik in enumerate(strikes): strike = Decimal(strik) o.set_strike(strike) row = f'r{i+1}' price = Decimal(o.price) window[row + 'c1'].update(o.strike) window[row + 'c2'].update(o.price)
def main(): parser = argparse.ArgumentParser( description="Find best trading strategies") group = parser.add_mutually_exclusive_group() parser.add_argument("ticker", type=str, help="stock ticker") # group.add_argument("-t", "--ticker", action="store_true") group.add_argument("-d", "--date", action="store_true") parser.add_argument("-s", "--strategy", help="the strategy") # parser.add_argument("y", type=int, help="the exponent") args = parser.parse_args() ticker = yf.Ticker(args.ticker) # get stock info print('****** Info **********') print(ticker.info) # input("Press Enter to continue...") # get historical market data print('****** History **********') hist = ticker.history(period="max") print(hist) # input("Press Enter to continue...") print('****** Actions **********') # show actions (dividends, splits) print(ticker.actions) # input("Press Enter to continue...") print('****** dividends **********') # show dividends print(ticker.dividends) # input("Press Enter to continue...") # show splits ticker.splits # show financials print('****** financials **********') print(ticker.financials) print(ticker.quarterly_financials) # input("Press Enter to continue...") # show major holders print(ticker.major_holders) # show institutional holders print(ticker.institutional_holders) # input("Press Enter to continue...") # show balance heet print(ticker.balance_sheet) print(ticker.quarterly_balance_sheet) # show cashflow ticker.cashflow ticker.quarterly_cashflow # show earnings print(ticker.earnings) print(ticker.quarterly_earnings) # show sustainability print(ticker.sustainability) # show analysts recommendations print(ticker.recommendations) # show next event (earnings, etc) print('****** calendars **********') print(ticker.calendar) # input("Press Enter to continue...") # show ISIN code - *experimental* # ISIN = International Securities Identification Number print(ticker.isin) # show options expirations print('****** calendars **********') print(ticker.options) # input("Press Enter to continue...") # get option chain for specific expiration opt = ticker.option_chain(ticker.options[0]) # data available via: opt.calls, opt.puts print(opt.calls) # input("Press Enter to continue...") print(opt.puts) # input("Press Enter to continue...") history = ticker.history() last_quote = (history.tail(1)['Close'].iloc[0]) last_price = int(last_quote) # calls for opt in ticker.options: try: data = [] dt = datetime.fromisoformat(opt) option = Call(args.ticker ) # d=dt.day, m=dt.month, y=dt.year, strike=ticker.) for strike in option.strikes: if strike < last_price - 40 or strike > last_price + 25: continue print(f'strike = {strike}') option.set_strike(strike) item = {} item['strike'] = strike item['price'] = option.price item['iv'] = option.implied_volatility() item['delta'] = option.delta() item['vega'] = option.vega() item['gamma'] = option.gamma() # print(f'theta = {option.theta()}') # print(f'vega = {option.vega()}') data.append(item) dataframe = pd.DataFrame(data) dataframe.to_csv(f'call-{args.ticker}-{dt}') print(dataframe.to_csv()) except Exception as e: print(f'{type(e)}: {str(e)} ') continue # put for opt in ticker.options: try: data = [] dt = datetime.fromisoformat(opt) option = Put( args.ticker ) # d=dt.day, m=dt.month, y=dt.year, strike=ticker.) for strike in option.strikes: if strike < last_price - 40 or strike > last_price + 25: continue print(f'strike = {strike}') option.set_strike(strike) item = {} item['strike'] = strike item['price'] = option.price item['iv'] = option.implied_volatility() item['delta'] = option.delta() item['vega'] = option.vega() item['gamma'] = option.gamma() # print(f'Rho = {option.rho()}') # print(f'type = {option.Option_type}') # print(f'theta = {option.theta()}') # print(f'vega = {option.vega()}') data.append(item) dataframe = pd.DataFrame(data) dataframe.to_csv(f'put-{args.ticker}-{dt}') print(dataframe.to_csv()) except Exception as e: print(f'{type(e)}: {str(e)} ') continue