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 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 }
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 best_put_trades(symbol, num_of_days): symbol = symbol.upper() if is_cache_good(f'{symbol}|puttrade|{num_of_days}'): return ast.literal_eval( r.hget(f'{symbol}|puttrade|{num_of_days}', 'value')) return_dict = {"error": "no options"} try: p = Put(symbol) range_dict = range_data_from_symbol(symbol, num_of_days) curr_date = str(datetime.date(datetime.now())) expiries = p.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 p = Put(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 = p.strikes for i in strikes: if i <= range_dict["high_range"] and counter < 15: counter = counter + 1 p.set_strike(i) spread_list.append({ 'strike': i, 'bid': p.bid, 'ask': p.ask, 'delta': -p.delta() }) max_amt = 0 max_put_amt = 0 best_spread = {} best_put_written = {} spread_list.reverse() for i in spread_list: #for call prob_winning_put = 1 - i['delta'] premium_put = i['bid'] put_win_amt = premium_put * prob_winning_put if put_win_amt > max_put_amt: max_put_amt = put_win_amt best_put_written = i for j in spread_list: if i['strike'] > j['strike']: #for spread premium_per_dollar = ( i['bid'] - j['ask']) / abs(j['strike'] - i['strike']) prob_winning_spread = 1 - j['delta'] win_amt = premium_per_dollar * prob_winning_spread if win_amt > max_amt: max_amt = win_amt best_spread = { 'strike_long': i['strike'], 'strike_short': j['strike'], 'premium_received': i['bid'], 'premium_paid': j['ask'], 'expiry': expiry_to_use } best_put_written['expiry'] = expiry_to_use return_dict = { "symbol": symbol, 'best_spread': best_spread, 'best_put': best_put_written } if best_spread and best_put_written: r.hset(f'{symbol}|puttrade|{num_of_days}', 'time', datetime.utcnow().strftime('%s')) r.hset(f'{symbol}|puttrade|{num_of_days}', 'value', str(return_dict)) return return_dict except: return return_dict
def putCreditSpread(tick, minDays, maxDays, strikeSpread, minPoP): s = Stock(tick) stockPrice = s.price validExpirations = expirationsOfInterest(tick, minDays, maxDays) print('List of valid expirations:\n') print(validExpirations) print('\n') my_columns = ['Expiry', 'PoP', 'Premium', 'Long Strike', 'Short Strike'] #spread_dataframe = pd.DataFrame(columns = my_columns) frames = [] for expDate in validExpirations[:1]: print('Current expiration being analyzed\n') print(expDate) expir = expDate.split('-') day = int(expir[0]) month = int(expir[1]) year = int(expir[2]) if day == 3: blah = 5 day = 5 month = 3 year = 2021 temp = Put(tick, d=day, m=month, y=year) spread_dataframe = pd.DataFrame(columns=my_columns) strikes = [] strike1 = [] strike2 = [] longStrike = [] shortStrike = [] longPremium = [] shortPremium = [] strikes = (temp.strikes) strikes = [ strike for strike in strikes if (strike / stockPrice > 1 - strikeSpread and strike / stockPrice < 1 + strikeSpread) ] strike1 = [a for (a, b) in itertools.product(strikes, strikes)] strike2 = [b for (a, b) in itertools.product(strikes, strikes)] for i in range(0, len(strike1)): if strike1[i] < strike2[i]: longStrike.append(strike1[i]) shortStrike.append(strike2[i]) temp.set_strike(strike1[i]) price = (temp.bid + temp.ask) / 2 longPremium.append(price) temp.set_strike(strike2[i]) price = (temp.bid + temp.ask) / 2 shortPremium.append(price) elif strike1[i] > strike2[i]: longStrike.append(strike2[i]) shortStrike.append(strike1[i]) temp.set_strike(strike1[i]) price = (temp.bid + temp.ask) / 2 shortPremium.append(price) temp.set_strike(strike2[i]) price = (temp.bid + temp.ask) / 2 longPremium.append(price) else: continue for i in range(0, len(shortStrike)): credit = shortPremium[i] - longPremium[i] strikeWidth = shortStrike[i] - longStrike[i] spread_dataframe = spread_dataframe.append(pd.Series( [ expir, 100 - credit / strikeWidth * 100, credit, longStrike[i], shortStrike[i] ], index=my_columns), ignore_index=True) frames.append(spread_dataframe) result = pd.concat(frames) spread_dataframe.sort_values('PoP', ascending=False, inplace=True) spread_dataframe.reset_index(drop=True, inplace=True) spread_dataframe = spread_dataframe[spread_dataframe['PoP'] >= minPoP] result.sort_values('PoP', ascending=False, inplace=True) result.reset_index(drop=True, inplace=True) result = result[spread_dataframe['PoP'] >= minPoP] return result
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"}
def best_put_protection(symbol, num_of_days): symbol = symbol.upper() if is_cache_good(f'{symbol}|putprotection|{num_of_days}'): return ast.literal_eval( r.hget(f'{symbol}|putprotection|{num_of_days}', 'value')) try: p = Put(symbol) s = Stock(symbol) curr_date = str(datetime.date(datetime.now())) expiries = p.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 p = Put(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 = p.strikes for i in reversed(strikes): if i <= s.price and counter < 10: counter = counter + 1 p.set_strike(i) spread_list.append({ 'strike': i, 'bid': p.bid, 'ask': p.ask, 'last': p.price, 'using_last': 'false', 'delta': -p.delta() }) min_put_strength = 100000 best_put = {} spread_list.reverse() for i in spread_list: #for put prob_in_the_money_put = i['delta'] i['using_last'] = 'false' if i['bid'] == 0 or i['ask'] == 0: i['bid'] = i['last'] i['ask'] = i['last'] i['using_last'] = 'true' premium_put = i['ask'] put_cost_per_money = premium_put / prob_in_the_money_put if put_cost_per_money < min_put_strength: min_put_strength = put_cost_per_money best_put = i best_put['expiry'] = expiry_to_use return_dict = {"symbol": symbol, 'best_put': best_put} if best_put: r.hset(f'{symbol}|putprotection|{num_of_days}', 'time', datetime.utcnow().strftime('%s')) r.hset(f'{symbol}|putprotection|{num_of_days}', 'value', str(return_dict)) return return_dict except: return {"error": "No options were found"}
def best_put_trades(symbol, num_of_days): symbol = symbol.upper() if is_cache_good(f'{symbol}|puttrade|{num_of_days}'): return ast.literal_eval( r.hget(f'{symbol}|puttrade|{num_of_days}', 'value')) try: p = Put(symbol) range_dict = range_data_from_symbol(symbol, num_of_days) curr_date = str(datetime.date(datetime.now())) expiries = p.expirations expiry_to_use = expiries[0] min_day_diff = 1000 for i in expiries: days_to_exp = abs( datetime.strptime(i, '%d-%m-%Y') - datetime.strptime(curr_date, '%Y-%m-%d')).days my_day_diff = abs(days_to_exp - num_of_days) if my_day_diff < min_day_diff: expiry_to_use = i min_day_diff = my_day_diff p = Put(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 = p.strikes for i in reversed(strikes): if i <= range_dict["low_range"] and counter < 10: counter = counter + 1 p.set_strike(i) spread_list.append({ 'strike': i, 'bid': p.bid, 'ask': p.ask, 'last': p.price, 'using_last': 'false', 'delta': -p.delta() }) max_amt = 0 max_put_amt = 0 best_spread = {} best_put_written = {} spread_list.reverse() for i in spread_list: #for put prob_winning_put = 1 - i['delta'] i['using_last'] = 'false' if i['bid'] == 0 or i['ask'] == 0: i['bid'] = i['last'] i['ask'] = i['last'] i['using_last'] = 'true' premium_put = i['bid'] put_win_amt = premium_put * prob_winning_put if put_win_amt > max_put_amt: max_put_amt = put_win_amt best_put_written = i for j in spread_list: if i['strike'] > j['strike']: #for spread premium_per_dollar = ( i['bid'] - j['ask']) / abs(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_put_written['expiry'] = expiry_to_use return_dict = { "symbol": symbol, 'best_spread': best_spread, 'best_put': best_put_written } if best_spread or best_put_written: r.hset(f'{symbol}|puttrade|{num_of_days}', 'time', datetime.utcnow().strftime('%s')) r.hset(f'{symbol}|puttrade|{num_of_days}', 'value', str(return_dict)) return return_dict except: return {"error": "No options were found"}