def searchStrikeIterator(stock, type, expir, price): """Iterate through a list of possible strike option iterators from greatest to least (to prevent a possible match for rounding, but not actually exist for 1-3 more option strike prices). Return strike iterator. :param stock: :param type: :param expir: :param price: :return: """ actualPrice = price if actualPrice > 1000: strikeOptionList = [2.5, 5, 10, 50] elif actualPrice > 100: strikeOptionList = [1, 2.5, 5, 10, 50] else: strikeOptionList = [.5, 1, 2.5, 5, 10, 50] for i in range(len(strikeOptionList)): strikeIterator = strikeOptionList[i] price = price - (price % strikeIterator) checkStrike = strikeIterator * round( price / strikeIterator) + strikeIterator * 0 checkStrike2 = strikeIterator * round( price / strikeIterator) + strikeIterator * 1 checkStrike3 = strikeIterator * round( price / strikeIterator) + strikeIterator * 2 if r.find_options_by_expiration_and_strike(stock, expir, str(checkStrike), type) \ and r.find_options_by_expiration_and_strike(stock, expir, str(checkStrike2), type) \ and r.find_options_by_expiration_and_strike(stock, expir, str(checkStrike3), type): return strikeIterator return 5
def test_find_options_by_expiration_and_strike(self): info = r.find_options_by_expiration_and_strike(self.symbol, self.expiration_date, self.strike) assert (len(info) == 2) assert (info[0]['expiration_date'] == self.expiration_date) assert (float(info[0]['strike_price']) == self.strike) info = r.find_options_by_expiration_and_strike(self.symbol, self.expiration_date, self.strike, 'call') assert (len(info) == 1) assert (info[0]['type'] == 'call')
def test_find_options_by_expiration_and_strike(self): info = r.find_options_by_expiration_and_strike(self.symbol, self.expiration_date, self.strike) self.assertEqual(len(info), 2) self.assertEqual(info[0]['expiration_date'], self.expiration_date) self.assertEqual(float(info[0]['strike_price']), self.strike) info = r.find_options_by_expiration_and_strike(self.symbol, self.expiration_date, self.strike, 'call') self.assertEqual(len(info), 1) self.assertEqual(info[0]['type'], 'call')
def get_current_price(credit_spread: CreditSpread, strike: float) -> float: return float( rs.find_options_by_expiration_and_strike( credit_spread.symbol, credit_spread.expiration_date, str(strike), optionType=credit_spread.option_type, info='adjusted_mark_price')[0])
def purchase_loop(symbol: str, quantity: int, expiration_date: str, sell_strike: float, buy_strike: float, option_type: str): buy_price: float = 0 sell_price: float = 0 reorder: bool = True add_event_log('function[purchase_loop] Entering') while reorder: print('checking price') # update price # buy buy_price = float( rs.find_options_by_expiration_and_strike( symbol, expiration_date, str(buy_strike), option_type, info='adjusted_mark_price')[0]) print('Buy Price: {0}'.format(buy_price)) # sell sell_price = float( rs.find_options_by_expiration_and_strike( symbol, expiration_date, str(sell_strike), option_type, info='adjusted_mark_price')[0]) print('Sell Price: {0}'.format(sell_price)) price: float = round(sell_price - buy_price, 2) cancel_order = buy_credit_spread(symbol, quantity, price, expiration_date, sell_strike, buy_strike, option_type) print("placed the order") time.sleep(30) open_positions = Enumerable(rs.get_all_open_option_orders()).where( lambda x: x['state'] == 'queued') if len(open_positions) > 0: reorder = True rs.helper.request_post(cancel_order) add_event_log('function[purchase_loop] Order Canceled') else: reorder = False add_event_log('function[purchase_loop] Order Complete') add_event_log('function[purchase_loop] Exiting')
def sell_loop(credit_spread: CreditSpread): add_event_log('function[sell_loop] Entering') reorder: bool = True while reorder: # update price # buy bid_price: float = float( rs.find_options_by_expiration_and_strike( credit_spread.symbol, credit_spread.expiration_date, str(credit_spread.buy_strike), credit_spread.option_type, info='adjusted_mark_price')) # sell ask_price: float = float( rs.find_options_by_expiration_and_strike( credit_spread.symbol, credit_spread.expiration_date, str(credit_spread.sell_strike), credit_spread.option_type, info='adjusted_mark_price')) price: float = ask_price - bid_price cancel_order = sell_credit_spread(credit_spread.symbol, credit_spread.quantity, price, credit_spread.expiration_date, credit_spread.sell_strike, credit_spread.buy_strike, credit_spread.option_type) time.sleep(10) open_positions = Enumerable(rs.get_all_open_option_orders()).where( lambda x: x['state'] == 'queued') if len(open_positions) > 0: reorder = True rs.helper.request_post(cancel_order) add_event_log('function[sell_loop] Order Canceled') else: reorder = False add_event_log('function[sell_loop] Order Complete') add_event_log('function[sell_loop] Exiting')
def validateStrike(stock, type, expir, strike): """Given parameters that should all be correct validate strike price. If strike price is not correct, return a correct one. :param stock: :param type: :param expir: :param strike: :return: """ price = s.tickerPrice(stock) if not r.find_options_by_expiration_and_strike(stock, expir, strike, type): strikeIterator = searchStrikeIterator(stock, type, expir, price) price = roundPrice(price, strikeIterator, type) return grabStrike(price, strikeIterator, type, 0) else: return strike
def stPcOption(stock, strike, type, expir): option = r.find_options_by_expiration_and_strike(stock, expir, strike, type)[0] curr = '{:.2f}'.format(round(float(option['adjusted_mark_price']), 2)) prev = '{:.2f}'.format(round(float(option['previous_close_price']), 2)) breakeven = '{:.2f}'.format(round(float(option['break_even_price']), 2)) iv = int(float(option['implied_volatility']) * 100) perc = s.grabPercent(float(curr), float(prev)) volume = int(option['volume']) volume = s.formatThousand(volume) oi = int(option['open_interest']) oi = s.formatThousand(oi) res = '{}{:>8}{}{:>8}{:>10}{:>12}'.format( '[' + str(strike) + type[0].upper() + ' ' + expir + '] $' + str(curr), perc, '\nVol:' + str(volume), 'OI:' + str(oi), 'IV:' + str(iv) + '% ', 'BE:' + str(breakeven) + '\n') return res
def get_strike_target(symbol: str, delta_target: float, expiration_date: str, current_price: int): """Finds the strike price that corresponds to the given Delta""" add_event_log('function[get_strike_target] Entering') delta = 1.0 while delta > delta_target: current_price -= 1 current_option = rs.find_options_by_expiration_and_strike( symbol, expiration_date, str(current_price), optionType='put') if len(current_option) > 0: delta = abs(float(current_option[0]['delta'])) elif current_price > 0: continue else: raise Exception add_event_log('function[get_strike_target] Exiting') return int(current_price)
def pcOption(stock, strike, type, expir): """Given parameters needed to collect option data, validate/correct type, exp, and strike, and return option data relating to all of these fields. Also returns a msg if something major was defaulted when the user attempted to provide that certain parameter. :param stock: :param strike: :param type: :param expir: :return: """ type = validateType(type) exp = validateExp(stock, expir, type, strike) vstrike = validateStrike(stock, type, exp, strike) res = str(stock.upper()) + " " + exp[5:] + " " + str( vstrike) + type[0].upper() + " " msg = "" if expir and expir != exp: msg += 'Defaulted expiration date to ' + exp + '. YYYY-MM-DD\n' + optionFormat + '\n' if vstrike != strike: msg += 'Strike price ' + strike + ' did not exist for ' + stock.upper() + \ '.\nDefaulted strike to ' + str(vstrike) + ' (1 ITM).\n' option = r.find_options_by_expiration_and_strike(stock, exp, vstrike, type)[0] curr = '{:.2f}'.format(round(float(option['adjusted_mark_price']), 2)) prev = '{:.2f}'.format(round(float(option['previous_close_price']), 2)) breakeven = '{:.2f}'.format(round(float(option['break_even_price']), 2)) iv = int(float(option['implied_volatility']) * 100) perc = s.grabPercent(float(curr), float(prev)) volume = int(option['volume']) volume = s.formatThousand(volume) oi = int(option['open_interest']) oi = s.formatThousand(oi) res = '{:<4}{:<6}{:>10}{:>2}{:>7}{:>7}{:>11}'.format( res, '$' + str(curr), perc + '\n', 'Vol:' + str(volume), 'OI:' + str(oi), 'IV:' + str(iv) + '%', 'BE:' + str(breakeven) + '\n') return res, msg
def pcOptionMin(stock, type, expir, strike_value=None, DTE=None, price=None, strikeIterator=None): """Given parameters needed to collect option data, provide the current volume and price for option. ***Used for anomaly_option_controller (parameters are verified). :param stock: :param strike: :param type: :param expir: :return: """ totalValue = 0 for i in range(len(expir)): j = 0 while True: strike = grabStrike(price, strikeIterator[i], type, j) j += 1 option = r.find_options_by_expiration_and_strike( stock, expir[i], strike, type) if not option or not option[0]['volume']: break volume = int(option[0]['volume']) if volume > 25: curr = round(float(option[0]['adjusted_mark_price']) * 100, 2) value = curr * volume totalValue += value strike_value['[' + str(DTE[i]) + ' DTE] ' + str(strike) + type.upper()[:1]] = value print('[' + str(DTE[i]) + ' DTE] ' + str(strike) + type.upper()[:1]) else: break return totalValue
def validateExp(stock, expir, type, strike=None): """Given an expiration date return an expiration that is provided if correct or a default date. :param stock: :param expir: :param type: :param strike: :return: """ if expir and re.match(r'^\d{4}-\d{2}-\d{2}$', expir): while True and strike: print("Trying", stock, expir, strike, type) options = r.find_options_by_expiration_and_strike( stock, expir, strike, type) if options and options[0]: print("EZ") return expir else: expir = cal.generate_next_month_exp(expir) else: return cal.third_friday(cal.getYear(), cal.getMonth(), cal.getMonthlyDay()).strftime("%Y-%m-%d")