def run(ctx, config_yaml, output_csv): """This command loads config.yaml and the current ENV-ironment, creates a single merged dict, and prints to stdout. """ # read the configuration file c = app.get_config_dict(ctx, [config_yaml]) # use cache to reduce web traffic session = requests_cache.CachedSession( cache_name='cache', backend='sqlite', expire_after=datetime.timedelta(days=days_to_cache)) # all data will also be combined into one CSV all_df = None for ticker in c['config']['options']['long_puts']: option = Options(ticker, 'yahoo', session=session) # fetch all data df = option.get_all_data() # process the data df = long_puts_process_dataframe(df) # ensure the all_df (contains all data from all tickers) if all_df is None: all_df = df.copy(deep=True) else: all_df = all_df.append(df) # output the all_df, which contains all of the tickers long_puts_csv_out(output_csv, all_df)
def get_options_data(ticker='^GSPC'): tape = Options(ticker, 'yahoo') data = tape.get_all_data() data.to_csv('raw.csv') data = pd.read_csv('raw.csv') del data['JSON'] return data
def data_init(self): self.opt = Options(self.SYMBOL, self.data_provider) self.__underlying_price = self.opt.underlying_price self.data_building_core() self.lastGreeks = {'strike': None, 'data': {}, 'S': [], 'T': []} self.IVs = {'c': [], 'p': []} self.data_aggregate_IV()
def getstockopts(stockname, save=True): opts = Options(stockname, 'yahoo') expirydates = opts.expiry_dates dateexp = datetime(2017, 12, 15) #manually set to this calldata = opts.get_call_data(expiry=dateexp) putdata = opts.get_put_data(expiry=dateexp) prices = web.DataReader(stockname, 'yahoo', today) call_impt = calldata[['Last', 'Open_Int', 'Underlying_Price']] call_indexed_impt = call_impt.reset_index() put_impt = putdata[['Last', 'Open_Int', 'Underlying_Price']] put_indexed_impt = put_impt.reset_index() datstr = str(today.date()) comb_indexed_impt = pd.concat([call_indexed_impt, put_indexed_impt]) comb_indexed_impt.index = [datstr] * len(comb_indexed_impt.index) prices_indexed = prices.reset_index() prices_indexed.index = [datstr] * len(prices_indexed.index) if save: foldlists = os.listdir(datfold) foldname = stockname + '/' if stockname not in foldlists: os.mkdir(datfold + foldname) os.mkdir(datfold + foldname + 'options/') os.mkdir(datfold + foldname + 'prices/') stockoptlist = os.listdir(datfold + foldname + 'options/') stockpricelist = os.listdir(datfold + foldname + 'prices/') stockoptname = stockname + '-options.csv' stockpricename = stockname + '-prices.csv' if stockoptname not in stockoptlist: comb_indexed_impt.to_csv(datfold + foldname + 'options/' + stockoptname) else: comb_indexed_impt.to_csv(datfold + foldname + 'options/' + stockoptname, mode='a', header=False) if stockpricename not in stockpricelist: prices_indexed.to_csv(datfold + foldname + 'prices/' + stockpricename) else: prices_indexed.to_csv(datfold + foldname + 'prices/' + stockpricename, mode='a', header=False) print('stock : ' + stockname + ' DONE')
def update_option_chain(): conn = MySQLdb.connect(host="127.0.0.1", user="******", passwd="zhuang123", db="Analytics") x = conn.cursor() columns = [ 'ask', 'bid', 'change', 'contractSize', 'contractSymbol', 'currency', 'expiration', 'impliedVolatility', 'inTheMoney', 'lastPrice', 'lastTradeDate', 'openInterest', 'percentChange', 'strike', 'volume', 'pricingDate', 'underlying', 'underlyingPrice', 'type', 'mid' ] dt_columns = ['expiration', 'lastTradeDate'] for ticker in scrape_list(): try: option = Options(ticker, 'yahoo') option_chain = option.get_all_data() stmt = 'INSERT INTO OptionQuotes VALUES (' + ','.join( ['%s'] * len(columns)) + ')' for index, option in enumerate(option_chain['JSON'].tolist()): option['pricingDate'] = datetime.datetime.now().strftime( '%Y-%m-%d %H:%M:%S') option['underlying'] = option_chain.iloc[index]['Underlying'] option['underlyingPrice'] = option_chain.iloc[index][ 'Underlying_Price'] option['type'] = 'call' if ( option['underlyingPrice'] > option['strike'] and option['inTheMoney']) or ( option['underlyingPrice'] < option['strike'] and not option['inTheMoney']) else 'put' option['mid'] = (option['ask'] + option['bid']) / 2. values = [ option[column] if column not in dt_columns else datetime.datetime.fromtimestamp( option[column]).strftime('%Y-%m-%d %H:%M:%S') for column in columns ] print 'update', ticker, 'with values: ', values x.execute(stmt, tuple(values)) except Exception as e: print 'failed to update', ticker, 'becasue:', str(e) conn.commit() conn.close()
def all_options(ticker): tape = Options(ticker, 'yahoo') data = tape.get_all_data().reset_index() data['Moneyness'] = np.abs( data['Strike'] - data['Underlying_Price']) / data['Underlying_Price'] data['DTE'] = (data['Expiry'].dt.date - dt.datetime.today().date()).dt.days data = data[[ 'Strike', 'DTE', 'Type', 'IV', 'Vol', 'Open_Int', 'Moneyness', 'Root', 'Underlying_Price', 'Last', 'Bid', 'Ask', 'Expiry' ]] data['Mid'] = (data['Ask'] - data['Bid']) / 2 + data['Bid'] return data.reset_index()[data.columns]
def all_options(ticker, dte_ub, dte_lb, moneyness = 0.03): tape = Options(ticker, 'yahoo') data = tape.get_all_data().reset_index() data['Moneyness'] = np.abs(data['Strike'] - data['Underlying_Price'])/data['Underlying_Price'] data['DTE'] = (data['Expiry'] - dt.datetime.today()).dt.days data = data[['Strike', 'Expiry','DTE', 'Type', 'IV', 'Underlying_Price', 'Last','Bid','Ask', 'Moneyness']] data['Mid'] = (data['Ask'] - data['Bid'])/2 + data['Bid'] data = data.dropna() data = data[(abs(data['Moneyness']) <= moneyness) & (data['DTE'] <= dte_ub) & (data['DTE'] >= dte_lb)] return data.sort_values(['DTE','Type']).reset_index()[data.columns]#data.dropna().reset_index()[data.columns]
def download(ticker, stock_prices=False): data = Options(ticker, 'yahoo').get_all_data() body = pd.DataFrame(list(data['JSON'])) data = pd.DataFrame(list(data.index), columns=data.index.names) data = data.merge(body, left_on='Symbol', right_on='contractSymbol') del data['contractSymbol'] del data['strike'] del data['expiration'] data.columns = data.columns.str.lower() data['days_left'] = (data['expiry'] - datetime.datetime.today()).dt.days data['lasttradedate'] = data['lasttradedate'].apply( datetime.datetime.fromtimestamp) if stock_prices: data = get_stock_prices(data, ticker) return data
def getOptClosePrice(stock, source, expDate, strick): df_opt = Options(stock, source) data = df_opt.get_all_data() ''' print data.loc[(46, '2018-03-16','call'),('Last','Underlying_Price')].head() print data.loc[(46, '2018-03-16','call'),'Vol'].head() print '------------------' print data.iloc[0:5, 0:5] print '-------------' #Show the $100 strike puts at all expiry dates: ''' #print '1: ' , data.loc[(strick, expDate, 'call'),:] #.iloc[0:5, 0:5] res = data.loc[(strick, expDate, 'call'), ('Last', 'Underlying_Price')] #.iloc[0:5, 0:5] # print '1: ' , res # print '--------------' return res
def yahoo_options_dataframe(self, ticker): # fetch all data option = Options(ticker, 'yahoo', session=self.session) df = option.get_all_data() # reset_index() # copies multi-index values into columns # sets index to single ordinal integer df.reset_index(inplace=True) # rename a bunch of the columns df.rename(index=str, inplace=True, columns={ 'Strike': 'strike', 'Expiry': 'expiry', 'Type': 'type', 'Symbol': 'symbol', 'Last': 'lst', 'Bid': 'bid', 'Ask': 'ask', 'Chg': 'chg', 'Vol': 'vol', 'Open_Int': 'oi', 'Root': 'root', 'IsNonstandard': 'nonstandard', 'Underlying': 'underlying', 'Underlying_Price': 'underlyingprice', 'Quote_Time': 'quotetime' }) # delete unnecessary columns df.drop('PctChg', axis=1, inplace=True) df.drop('IV', axis=1, inplace=True) df.drop('Last_Trade_Date', axis=1, inplace=True) df.drop('JSON', axis=1, inplace=True) # normalize values for type column df['type'] = df.apply(lambda row: 'call' if row['type'] == 'calls' else 'put', axis=1) return df
def option_filter(ticker, moneyness_thresh, dte_thresh): fwd_date = dt.datetime.today() + dt.timedelta(days=dte_thresh) tape = Options(ticker, 'yahoo') data = tape.get_options_data(month=fwd_date.month, year=fwd_date.year).reset_index() data['Moneyness'] = np.abs( data['Strike'] - data['Underlying_Price']) / data['Underlying_Price'] data['DTE'] = (data['Expiry'] - dt.datetime.today()).dt.days data = data[[ 'Strike', 'DTE', 'Type', 'IV', 'Vol', 'Open_Int', 'Moneyness', 'Root', 'Underlying_Price', 'Last', 'Bid', 'Ask' ]] data['Mid'] = data['Ask'] - data['Bid'] filtered_data = data[(data['Moneyness'] <= moneyness_thresh) & ( data['DTE'] <= dte_thresh)].reset_index()[data.columns] put_ivs = filtered_data[filtered_data.Type == 'put'].pivot( index='Strike', columns='DTE', values='IV').dropna() call_ivs = filtered_data[filtered_data.Type == 'put'].pivot( index='Strike', columns='DTE', values='IV').dropna() hv_data = current_volatility([ticker]) put_ivs['Close'] = hv_data['close'][0] call_ivs['Close'] = hv_data['close'][0] put_ivs['Daily HV'] = hv_data['daily_ann'][0] call_ivs['Daily HV'] = hv_data['daily_ann'][0] put_ivs['Intra HV'] = hv_data['intra_ann'][0] call_ivs['Intra HV'] = hv_data['intra_ann'][0] put_ivs['Overnight HV'] = hv_data['ovrnt_ann'][0] call_ivs['Overnight HV'] = hv_data['ovrnt_ann'][0] put_ivs['Daily Dollar Vol'] = hv_data['daily_dollar_vol'][0] call_ivs['Daily Dollar Vol'] = hv_data['daily_dollar_vol'][0] put_ivs['Moneyness'] = np.abs(put_ivs.index - put_ivs['Close']) / put_ivs['Close'] call_ivs['Moneyness'] = np.abs(call_ivs.index - call_ivs['Close']) / call_ivs['Close'] call_ivs.index.name = ticker + ' Call Strike' put_ivs.index.name = ticker + ' Put Strike' return call_ivs, put_ivs
def compute_model_error(model, symbol, side, exp_start, exp_end, strike_low, strike_high): #Get the option prices options_sym = Options(symbol, 'yahoo') options_sym.expiry_dates options_data = options_sym.get_all_data() options_data = options_data.loc[(slice(strike_low,strike_high), slice(exp_start, exp_end), side),:] #get yesterdays stock price stock_price = float(Share(symbol).get_price()) labels = ["strike", "expiry", "option price", "pred price", "error"] data = [] for index, row in options_data.iterrows(): strike = index[0] expiration_date = index[1].date() option_price = row['Last'] pred_price = round(model(strike, stock_price, expiration_date, side), 2) data.append([strike, expiration_date.strftime('%Y-%m-%d'), option_price, pred_price, option_price-pred_price]) return labels, data
def update_option_chain(ticker): conn = MySQLdb.connect(host="127.0.0.1", user="******", passwd="zhuang123", db="Analytics") x = conn.cursor() columns = [ 'ask', 'bid', 'change', 'contractSize', 'contractSymbol', 'currency', 'expiration', 'impliedVolatility', 'inTheMoney', 'lastPrice', 'lastTradeDate', 'openInterest', 'percentChange', 'strike', 'volume' ] dt_columns = ['expiration', 'lastTradeDate'] try: aapl = Options(ticker, 'yahoo') option_chain = aapl.get_all_data() stmt = 'INSERT INTO OptionQuotes VALUES (' + ','.join( ['%s'] * 15) + ')' for option in option_chain['JSON'].tolist(): x.execute( stmt, tuple([ option[column] if column not in dt_columns else datetime.datetime.fromtimestamp( option[column]).strftime('%Y-%m-%d %H:%M:%S') for column in columns ])) conn.commit() except Exception as e: conn.rollback() print(e) conn.close() #update_option_chain('GOOG')
def xwYahooOptionChain(symbol,optype=None,bid=None,minstrike=None,maxstrike=None,expiry=None): stk = Options(symbol, 'yahoo') df = stk.get_all_data() df.drop(['Chg','PctChg','Vol','Open_Int','IV','Root','IsNonstandard','Underlying','Underlying_Price','Quote_Time','Last_Trade_Date','JSON'], axis=1,inplace=True) df.reset_index(inplace=True) if optype is not None: if optype.lower() == 'call': df = df.loc[df['Type'] == 'call'] if optype.lower() == 'put': df = df.loc[df['Type'] == 'put'] if bid is not None: if bid > 0: df = df.loc[df['Bid'] >= bid] if minstrike is not None and maxstrike is not None: if minstrike != maxstrike: df = df.loc[(df['Strike'] >= minstrike) & (df['Strike'] <= maxstrike)] df.sort_values(by=['Expiry','Strike','Type'],ascending=[True,True,True],inplace=True) df.set_index('Expiry',inplace=True) return df
def get_surf(ticker): q = Options(ticker, 'yahoo').get_all_data() q.reset_index(inplace=True) q.set_index('Symbol', inplace=True) vals = [] print(q.head()) #Iterate through the DataFrame pulled from the API for index, row in q.iterrows(): if row['Type'] == 'put': underlying = float(row['Underlying_Price']) #Midpoint of bid/ask spread price = (float(row['Ask']) + float(row['Bid'])) / 2.0 exp_d = (row['Expiry'] - datetime.now()).days exp_s = (row['Expiry'] - datetime.now()).seconds exp = (exp_d * 24 * 3600 + exp_s) / (365 * 24 * 3600) try: #Calculate the implied volatility impl = calc_impl_vol(price, 'p', underlying, float(row['Strike']), exp) vals.append([exp, float(row['Strike']), impl]) except: pass vals = array(vals).T combine_plots(vals[0], vals[1], vals[2])
def get_one_ticker(): ticker=company.get() option_data = Options(ticker,data_source='yahoo').get_all_data() option_data.reset_index(inplace=True) option_data.drop('JSON', axis=1, inplace=True) print option_data
def get_raw_data(ticker): tape = Options(ticker, 'yahoo') data = tape.get_all_data() return data
def H2_read_option_ws(symbol_store, dy): """ This function stands for hourly job 2, read option with symbol. Input here: -symbol_store = a list of symbols that shall be updated daily -dy = directory in string about where to find and store data. 5-19-18: changed from google to yahoo for function H2_read_option_ws and also, I dont think we need H1 function anymore. """ print("H2 google finance options info reading...") errorlist = [] spfile = dy + "/sp500.json" spfile_f = formulate_directory(spfile) index = 1 for symbol in symbol_store: try: data = Options(symbol, 'yahoo') # read the option data from google finance exp_list = [data.expiry_dates[0]] print('1', symbol, max(exp_list)) for i in range(10): data = Options( symbol, 'yahoo') # read the option data from google finance exp_list.append(data.expiry_dates[0]) df = data.get_options_data(expiry=max(exp_list)) row_num = df.shape[0] for j in range(10): df_tmp = data.get_options_data(expiry=max(exp_list)) if df_tmp.shape[0] > row_num: print("find larger df for %s, row num change %d -> %d" % (symbol, row_num, df_tmp.shape[0])) df = df_tmp.copy() row_num = df_tmp.shape[0] df.to_csv(spfile_f, sep=',', mode='a') print(index, " Done for :", symbol, "\n") except TypeError: traceback.print_exc() errorlist.append(symbol) continue #shall this be continue? except KeyError: traceback.print_exc() print('2', symbol, max(exp_list)) print("error with stock: ", symbol) errorlist.append(symbol) continue except Exception: traceback.print_exc() print('3', symbol, max(exp_list)) print("error with stock: ", symbol) errorlist.append(symbol) continue index += 1 factor = rd.random() * 15 time.sleep(0.1 * factor) path_error = dy + "/errorlist.txt" f = open(path_error, 'w') #shall use 'a' for append for elements in errorlist: f.write(str(elements)) f.close() print("H2 options info reading finished.") print("number of symbols with error: " + str(len(errorlist)) + "\n\n")
def get_options(ticker): tmp_df = Options(ticker, 'yahoo').get_all_data() print(tmp_df)
def get_one_ticker(one_ticker_name): option_data = Options(one_ticker_name,data_source='yahoo').get_all_data() option_data.reset_index(inplace=True) option_data.drop('JSON', axis=1, inplace=True) r=clean(option_data) return r
from pandas_datareader.data import Options import pandas as pd from pandas import DataFrame import datetime import csv import time import sys tickers = pd.read_csv('nxxx.csv', index_col=[0]) #List of Nyse symbols, Add Nasdaq money_list = [] #List from which we send option symbols to a .csv file for i in tickers.index: option = Options(i,'yahoo') data = option.get_all_data() # The returned data is a pandas DataFrame: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html # RTFM if not data.empty : i = 0 while i < 5: try: #money_list.append(data[data.Vol > 1000].index.get_level_values('Symbol')) print data[Symbol] except Exception as e: print "ERROR: " + str(e) time.sleep(1)
import pandas as pd import pandas.io.data as web import numpy as np import datetime import csv import os import urllib import re from pandas_datareader.data import Options tsla = Options('TSLA', 'yahoo') data = tsla.get_all_data() data.iloc[0:5, 0:5]
def get_data(): spy = Options('spy', 'yahoo') chain = spy.get_all_data() filename = './spy_' + strftime("%Y-%m-%d %H:%M:%S", gmtime()) + '.bin' pickle_store(chain, filename)
class OptionLib: def __init__(self, symbol='SPY', dataprovider='yahoo', riskfree=0.01, dividendrate=0.01): self.SYMBOL = symbol self.data_provider = dataprovider self.__oldsymbol = symbol self.__olddataprovider = dataprovider self.risk_free_rate = riskfree self.dividend_rate = dividendrate self.opt = None self.IVs = {'c': [], 'p': []} self.__last_quote = None self.__underlying_price = None self.__data = None self.__data_core = None self.data_selection = (0, 'c') self.tickSize = 0.5 self.data_init() ######################################################################################################### # Data Building and Housekeeping # ######################################################################################################### @waitSyncFlag def data_init(self): self.opt = Options(self.SYMBOL, self.data_provider) self.__underlying_price = self.opt.underlying_price self.data_building_core() self.lastGreeks = {'strike': None, 'data': {}, 'S': [], 'T': []} self.IVs = {'c': [], 'p': []} self.data_aggregate_IV() @waitSyncFlag def data_refresh(self): self.__underlying_price = self.opt.underlying_price self.data_building_core() self.lastGreeks = {'strike': None, 'data': {}, 'S': [], 'T': []} self.IVs = {'c': [], 'p': []} self.data_aggregate_IV() @parallelProcess def data_auto_refresh(self): # This should be running in another thread while True: if not (self.SYMBOL == self.__oldsymbol and self.data_provider == self.__olddataprovider): self.__oldsymbol, self.__olddataprovider = self.SYMBOL, self.data_provider self.__last_quote = self.opt.get_call_data( ).iloc[0]['Quote_Time'].to_pydatetime() self.data_init() print('Data Initialization for {} [ COMPLETE ]'.format( self.SYMBOL)) if not (self.opt.get_call_data().iloc[0] ['Quote_Time'].to_pydatetime() == self.__last_quote): self.__last_quote = self.opt.get_call_data( ).iloc[0]['Quote_Time'].to_pydatetime() self.data_refresh() print('Data Refreshing for {} [ COMPLETE ]'.format( self.SYMBOL)) @requireSyncFlag def data_building_core(self): try: assert self.opt df = self.opt.get_all_data() dflen = len(df.index.values) d = {} for i in range(dflen): dfindex = df.index.values[i] row = df.loc[dfindex] exp = dfindex[1].to_pydatetime() curr = row['Quote_Time'].to_pydatetime() toe = float((exp - curr).days) / 365.0 # Days until expiration dte = round(toe * 365) + 1 otype = 'c' if dfindex[2] == 'call' else 'p' # Index will be using expiry_date index expd = exp.date() j = self.opt.expiry_dates.index(expd) bso = Black_Scholes(option_type=otype, price=row['Underlying_Price'], strike=dfindex[0], interest_rate=self.risk_free_rate, dividend_yield=self.dividend_rate, volatility=row['IV'], expiry=toe) # Check if the index exists or not if not (j in d): d[j] = {'matrix': [], 'indexes': []} # [ [ Ask, Bid, Last, Vol, %, sigma, delta, gamma, kappa, theta, rho, dte, symbol] , (...) ] d[j]['matrix'].append([ row['Ask'], row['Bid'], row['Last'], int(row['Vol']), row['PctChg'], round(row['IV'], 2), round(bso.delta, 2), round(bso.gamma, 2), round(bso.kappa, 2), round(bso.theta, 2), round(bso.rho, 2), dte, dfindex[3] ]) # [ ( type, strike), ... ] d[j]['indexes'].append((otype, dfindex[0])) self.__data_core = d except AssertionError: raise DataFormatError( 'No Data from Yahoo, Check Internet Connection') @requireSyncFlag def data_aggregate_IV(self): """ Aggregate Contract's sigma by call and puts then store them in [ Time to Expiration, Strike, Volatility ] format for later plotting """ try: assert self.__data_core d = self.__data_core.copy() for t in d.keys(): matrix = d[t]['matrix'] indexes = d[t]['indexes'] for i in range(len(matrix)): # Format : [ Time to Expiration, Strike, Volatility ] self.IVs[indexes[i][0]].append( [matrix[i][11], indexes[i][1], matrix[i][5]]) except AssertionError: raise DataFormatError('Must input a pandas.DataFrame') def data_IVpT(self, expiry_index=0): """ Compute IV per timestamp :return: calls and puts """ dt = self.__data_core[expiry_index].copy() matrix = dt['matrix'] indexes = dt['indexes'] calls, puts = [], [] # calls = [ [ Strike, IV] , ... ] for i in range(len(matrix)): if indexes[i][0] == 'c': calls.append([indexes[i][1], matrix[i][5]]) else: puts.append([indexes[i][1], matrix[i][5]]) return calls, puts def data_aggregate_greeks(self, strike=None): """ :return: """ try: assert self.__data_core assert strike d = self.__data_core.copy() times = [] sigmas = [] for t in d.keys(): matrix = d[t]['matrix'] indexes = d[t]['indexes'] for i in range(len(matrix)): if indexes[i][0] == 'c' and indexes[i][1] == strike: sigmas.append(matrix[i][5]) times.append(float(matrix[i][11]) / 365.0) # Matrices are n x m # where n : the nb of contract_dates # compute underlyingPrice matrix underlyingPriceMatrix = np.array([ np.arange(0.0, self.__underlying_price * 2, self.tickSize) for i in range(len(sigmas)) ]) MatrixShape = underlyingPriceMatrix.shape sigmaMatrix = np.array([ np.ones(MatrixShape[1]) * sigmas[i] for i in range(MatrixShape[0]) ]).reshape(MatrixShape) expiryMatrix = np.array([ np.ones(MatrixShape[1]) * times[i] for i in range(MatrixShape[0]) ]).reshape(MatrixShape) ccontracts = [] pcontracts = [] for i in range(MatrixShape[0]): for j in range(MatrixShape[1]): cbso = Black_Scholes(option_type='c', strike=strike, price=underlyingPriceMatrix[i][j], interest_rate=self.risk_free_rate, dividend_yield=self.dividend_rate, expiry=expiryMatrix[i][j], volatility=sigmaMatrix[i][j]) pbso = Black_Scholes(option_type='p', strike=strike, price=underlyingPriceMatrix[i][j], interest_rate=self.risk_free_rate, dividend_yield=self.dividend_rate, expiry=expiryMatrix[i][j], volatility=sigmaMatrix[i][j]) #Access elements in matrix[i][j] ccontracts.append(cbso) pcontracts.append(pbso) cdelta = np.array([c.delta for c in ccontracts]).reshape(MatrixShape) cgamma = np.array([c.gamma for c in ccontracts]).reshape(MatrixShape) ctheta = np.array([c.theta for c in ccontracts]).reshape(MatrixShape) ckappa = np.array([c.kappa for c in ccontracts]).reshape(MatrixShape) crho = np.array([c.rho for c in ccontracts]).reshape(MatrixShape) pdelta = np.array([p.delta for p in pcontracts]).reshape(MatrixShape) pgamma = np.array([p.gamma for p in pcontracts]).reshape(MatrixShape) ptheta = np.array([p.theta for p in pcontracts]).reshape(MatrixShape) pkappa = np.array([p.kappa for p in pcontracts]).reshape(MatrixShape) prho = np.array([p.rho for p in pcontracts]).reshape(MatrixShape) greeks = {'c': {}, 'p': {}} greeks['c']['delta'] = cdelta greeks['c']['gamma'] = cgamma greeks['c']['theta'] = ctheta greeks['c']['kappa'] = ckappa greeks['c']['rho'] = crho greeks['p']['delta'] = pdelta greeks['p']['gamma'] = pgamma greeks['p']['theta'] = ptheta greeks['p']['kappa'] = pkappa greeks['p']['rho'] = prho self.lastGreeks['data'] = greeks self.lastGreeks['strike'] = strike self.lastGreeks['S'] = underlyingPriceMatrix self.lastGreeks['T'] = expiryMatrix except AssertionError: pass pass ######################################################################################################### # Client's Methods and Properties # ######################################################################################################### @property def index(self): opt = self.opt d = {'Expiry Dates': opt.expiry_dates} return pd.DataFrame(data=d).transpose() @property def data(self): print('Underlying @ {:.2f} \nLatest Option Quote @: {}\n'.format( self.__underlying_price, self.__last_quote)) print('Current Contracts Expires @ {}\n'.format( self.opt.expiry_dates[self.data_selection[0]])) obj = self.__data_core[self.data_selection[0]] data = np.array(obj['matrix']) indexes = obj['indexes'] filtered_matrix = [] filtered_indexes = [] for i in range(len(data)): if indexes[i][0] == self.data_selection[1]: filtered_matrix.append(data[i]) filtered_indexes.append(indexes[i][1]) columns = [ 'Ask', 'Bid', 'Last', 'Vol', '%', '\u03C3', '\u0394', '\u0393', '\u039A', '\u0398', '\u03A1', 'Days to Expiry', 'Symbol' ] df = pd.DataFrame(data=filtered_matrix, index=filtered_indexes, columns=columns) return df @property def VIEW_SELECTION(self): return 'CURRENTLY SELECTED DATA :: [ INDEX : {} | TYPE : {} | SYMBOL : {} ]'.format( self.data_selection[0], self.data_selection[1], self.SYMBOL) def select( self, INDEX=0, TYPE='c', ): """ Setting the data-selecting tuple """ try: assert TYPE == 'c' or TYPE == 'p' assert INDEX < len(self.opt.expiry_dates) self.data_selection = (INDEX, TYPE) except AssertionError: raise DataFormatError( 'Expiry index and option type ("c" or "p") must be valid') ######################################################################################################### # Plotting # ######################################################################################################### def plot_smile( self, expiry_index=None, ): """ Plot the IV smile for both calls and puts per timestamp """ expiry_index = expiry_index if expiry_index else self.data_selection[0] calls, puts = self.data_IVpT(expiry_index=expiry_index) k_calls, IV_calls = [], [] k_puts, IV_puts = [], [] for el in calls: k_calls.append(el[0]) IV_calls.append(el[1]) for el in puts: k_puts.append(el[0]) IV_puts.append(el[1]) plt.figure(figsize=(16, 7)) e = plt.scatter(k_calls, IV_calls, c='white', label="IV(call options)") f = plt.scatter(k_puts, IV_puts, c='red', label="IV(put options)") plt.xlabel('strike') plt.ylabel('Implied Volatility') plt.legend((e, f), ("IV (call options)", "IV (put options)")) def plot_surface( self, option_type=None, ): try: if option_type: assert option_type == 'c' or option_type == 'p' option_type = option_type if option_type else self.data_selection[1] plotdata = self.IVs[option_type] color = 'red' if option_type == 'p' else 'green' xaxis = [plotdata[i][0] for i in range(len(plotdata))] yaxis = [plotdata[i][1] for i in range(len(plotdata))] zaxis = [plotdata[i][2] for i in range(len(plotdata))] fig1 = plt.figure(figsize=(20, 12)) ax = fig1.add_subplot(111, projection='3d') ax.view_init() ax.scatter(xaxis, yaxis, zaxis, c=color) plt.xlabel("Time to Expiration (days)") plt.ylabel("Strikes") plt.title("Implied Volatility") fig2 = plt.figure(figsize=(20, 12)) ax2 = fig2.add_subplot(111, projection='3d') ax2.view_init() ax2.plot_trisurf(xaxis, yaxis, zaxis, cmap=cm.jet) plt.xlabel("Time to Expiration (days)") plt.ylabel("Strikes") plt.title("Implied Volatility") except AssertionError: print( 'You must specify option type as first argument and/or Invalid option type' ) except Exception as e: print(e) def plot_letter(self, LETTER=None, STRIKE=None, otype='c'): try: assert LETTER in ['delta', 'gamma', 'theta', 'kappa', 'rho'] data = {} S, T = [], [] strike = STRIKE if STRIKE else np.round(self.__underlying_price) if self.lastGreeks['strike'] and self.lastGreeks[ 'strike'] == strike: data, S, T = self.lastGreeks['data'], self.lastGreeks[ 'S'], self.lastGreeks['T'] else: self.data_aggregate_greeks(strike=strike) data, S, T = self.lastGreeks['data'], self.lastGreeks[ 'S'], self.lastGreeks['T'] print('Plotting {} with Strike {} for {} - {}\n'.format( LETTER, strike, self.SYMBOL, otype)) Z = data[otype][LETTER] fig = plt.figure(figsize=(20, 11)) ax = fig.add_subplot(111, projection='3d') ax.view_init(40, 290) ax.plot_wireframe(S, T, Z, rstride=1, cstride=1) ax.plot_surface(S, T, Z, facecolors=cm.jet(Z), linewidth=0.001, rstride=1, cstride=1, alpha=0.75) ax.set_zlim3d(0, Z.max()) ax.set_xlabel('Stock Price') ax.set_ylabel('Time to Expiration') ax.set_zlabel(LETTER) m = cm.ScalarMappable(cmap=cm.jet) m.set_array(Z) cbarDelta = plt.colorbar(m) except AssertionError: raise DataFormatError('Invalid Letter') except ValueError: raise DataFormatError( 'Invalid Calculations for {} :: Something went wrong on our end :$' .format(LETTER))
def _ProcessOne(self, sym, expir, time_out=None): """ process one symbol, one expiry date, one strike time_out: maximum seconds waiting for the request """ if time_out == None: time_out = self.req_timeout_1 # the default timeout length tmpOption = Options(sym, 'yahoo') logging.info("{} - {}: Requesting".format(sym, expir)) # set timeout for single request with timeout(seconds = time_out): mydata = tmpOption.get_options_data(expiry = expir) logging.info("{} - {}: Finished request, insert to table...".format(sym, expir)) mydata = mydata.reset_index() # within dataset "mydata", go through each row and insert to DB for i in range(len(mydata.index)): onerow = mydate.iloc[[i]] # clean data, sometime bid and ask contains strange values tmpBid = onerow.Bid[i] tmpAsk = onerow.Ask[i] if type(onerow.Bid[i]) is not numpy.float64: tmpBid = 0.0 if type(onerow.Ask[i]) is not numpy.float64: tmpAsk = 0.0 # clean data, sometime open_interest is not a number tmpOpenInt = onerow.Open_Int[i] if onerow.Open_Int[i] == '-': tmpOpenInt = 0 # replace missing value '-' with '0' # insert_str = insert_str.replace('NaT', '0') # insert_str = insert_str.replace(' -,', ' 0,') # for index symbols (^VIX ==> VIX) tmpsym = sym if tmpsym[0] == "^": tmpsym = tmpsym[1:] # Raw exception handeling function self,_HandelingRaw(i, onerow) # gen sql insert statement insert_str = """INSERT INTO OPT_{} (underlying_symbol, option_symbol, strike, expiry, option_type, quote_date, last, bid, ask, vol, open_int, IV, underlying_price) VALUES ('{}', '{}', {}, '{}', '{}', '{}', {}, {}, {}, {}, {}, {}, {});""".format(tmpsym,\ onerow.Root[i], onerow.Symbol[i], onerow.Strike[i], \ str(onerow.Expiry[i].date()), onerow.Type[i], str(onerow.Quote_Time[i].date()),\ onerow.Last[i], tmpBid, tmpAsk,\ onerow.Vol[i], tmpOpenInt, float(onerow.IV[i].strip('%'))/100,\ onerow.Underlying_Price[i]) # push into db try: self.rowcnt += self.cur.execute(insert_str) except Exception as err: # exception while inserting to database print("Exception occured while inserting to database") print(insert_str) print(mydata.iloc[[i]]) logging.error("Exception occured while inserting to database") logging.error(insert_str) logging.error(mydata.iloc[[i]]) raise self.conn.commit() # end of for loop logging.info("{} - {}: Inserted to table, {} rows affected.".format(sym, expir, self.rowcnt)) print("{} - {}: Inserted to table, {} rows affected.".format(sym, expir, self.rowcnt)) self.rowcnt = 0
import pandas_datareader as web from pandas_datareader.data import Options import datetime import quandl start = datetime.datetime(2015, 1, 1) end = datetime.datetime(2019, 1, 1) ########## Yahoo & Google ########## # Equity Prices facebook = web.DataReader("FB", "yahoo", start, end) # Option Prices fb_options = Options("FB", "yahoo") fb_options.get_options_data(expiry=fb_optipns.expirt_dates[0]) ########## Quandl ########## mydata = quandl.get("EIA/PET_RWTC_D", returns="numpy") realEstate_SF = quandl.get("ZILLOW/C13_ZRIFAH") stockApple = quandl.get("WIKI/AAPL.1") # .1 gives the first column
# -*- coding: utf-8 -*- """ Created on Thu Dec 6 23:36:56 2018 @author: dpsugasa """ import pandas as pd from numpy import sqrt,mean,log,diff import QuantLib as ql from pandas_datareader.data import Options import pandas_datareader.data as web import datetime opt = Options('spy', 'google') expiration_dates = [ql.Date(i.day, i.month, i.year) for i in opt.expiry_dates] expiry_index = 14 # choose the contracts expire on 11/17/2017 data = opt.get_call_data(expiry=opt.expiry_dates[expiry_index]) strikes = list(data.index.get_level_values('Strike')) premium = list(data['Last']) day_count = ql.Actual365Fixed() calendar = ql.UnitedStates() calculation_date = ql.Date(opt._quote_time.day,opt._quote_time.month,opt._quote_time.year) # 08/10/2017 spot = opt.underlying_price # spot price is 244.82 ql.Settings.instance().evaluationDate = calculation_date dividend_yield = ql.QuoteHandle(ql.SimpleQuote(0.0)) risk_free_rate = 0.01 dividend_rate = 0.0 flat_ts = ql.YieldTermStructureHandle( ql.FlatForward(calculation_date, risk_free_rate, day_count)) dividend_ts = ql.YieldTermStructureHandle(
import numpy as np import pandas as pd import pandas_datareader.data as web import datetime from pandas_datareader.data import Options start = datetime.datetime(2010, 1, 1) end = datetime.datetime(2013, 1, 27) goog = web.DataReader('GOOG', 'yahoo', start, end) goog.ix['2010-01-04'] goog_o = Options('GOOG', 'yahoo') goog_o.get_options_data(expiry=goog_o.expiry_dates[0])
# PANDAS import pandas_datareader.data as web import datetime start = datetime.datetime(2015,1,1) end = datetime.datetime(2017,1,1) facebook = web.DataReader('FB', 'google', start, end) facebook.head() from pandas_datareader.data import Options fb_options = Options('FB', 'google') options_df = fb_options.get_options_data(expiry=fb_options.expiry_dates[0]) options_df.head() # QUADL import quandl mydata = quandl.get('EIA/PET_RWTC_D') # can use , returns='numpy' import matplotlib.pyplot as plt mydata.plot() mydata = quandl.get('ZILLOW/C9_ZRIFAH') mydata = quandl.get('WIKI/AAPL') mydata.head()
def get_opts(ticker, nb_months=3): opts = Options(ticker, 'yahoo') data = opts.get_forward_data(nb_months, put=True) return data
def all_options(ticker): tape = Options(ticker, 'yahoo') data = tape.get_all_data().reset_index() data['Moneyness'] = np.abs(data['Strike'] - data['Underlying_Price'])/data['Underlying_Price'] data['DTE'] = (data['Expiry'] - dt.datetime.today()).dt.days data = data[['Strike', 'DTE', 'Type', 'IV', 'Vol','Open_Int', 'Moneyness', 'Root', 'Underlying_Price', 'Last','Bid','Ask']] data['Mid'] = (data['Ask'] - data['Bid'])/2 + data['Bid'] year = 365 strikes = data['Strike'].values time_to_expirations = data['DTE'].values ivs = data['IV'].values underlying = data['Underlying_Price'].values[0] types = data['Type'].values # Make sure nothing thows up assert len(strikes) == len(time_to_expirations) sigmas = data['IV'] deltas = [] gammas = [] thetas = [] vegas = [] for sigma, strike, time_to_expiration, flag in zip(sigmas, strikes, time_to_expirations, types): # Constants S = underlying K = strike t = time_to_expiration/float(year) r = 0.005 / 100 q = 0 / 100 try: delta = py_vollib.black_scholes_merton.greeks.analytical.delta(flag[0], S, K, t, r, sigma, q) deltas.append(delta) except: delta = 0.0 deltas.append(delta) try: gamma = py_vollib.black_scholes_merton.greeks.analytical.gamma(flag[0], S, K, t, r, sigma, q) gammas.append(gamma) except: gamma = 0.0 gammas.append(gamma) try: theta = py_vollib.black_scholes_merton.greeks.analytical.theta(flag[0], S, K, t, r, sigma, q) thetas.append(theta) except: theta = 0.0 thetas.append(theta) try: vega = py_vollib.black_scholes_merton.greeks.analytical.vega(flag[0], S, K, t, r, sigma, q) vegas.append(vega) except: vega = 0.0 vegas.append(vega) data['Delta'] = deltas data['Gamma'] = gammas data['Theta'] = thetas data['Vega'] = vegas return data.reset_index()[data.columns]#data.dropna().reset_index()[data.columns]
def greek_calc(ticker, dte_ub, dte_lb, prem_price_use='Mid', delta_filter=0.2, expiry_set=0): fwd_date = dt.datetime.today() + dt.timedelta(days=dte_ub) tape = Options(ticker, 'yahoo') options_chain = tape.get_options_data(month=fwd_date.month, year=fwd_date.year).reset_index() options_chain = options_chain[[ 'Strike', 'Expiry', 'Type', 'Last', 'Bid', 'Ask', 'Vol', 'Open_Int', 'IV', 'Underlying_Price' ]] df = options_chain df['DTE'] = (df['Expiry'] - dt.datetime.today()).dt.days df['Mid'] = (df['Ask'] + df['Bid']) / 2 df = df[(df['DTE'] <= dte_ub) & (df['DTE'] >= dte_lb)] df = df.reset_index()[df.columns] year = 365 premiums = df[prem_price_use].values # 'Last' or 'Mid' strikes = df['Strike'].values time_to_expirations = df['DTE'].values ivs = df['IV'].values underlying = df['Underlying_Price'].values[0] types = df['Type'].values # Make sure nothing thows up assert len(premiums) == len(strikes) assert len(strikes) == len(time_to_expirations) sigmas = [] deltas = [] gammas = [] thetas = [] vegas = [] for premium, strike, time_to_expiration, flag in zip( premiums, strikes, time_to_expirations, types): # Constants P = premium S = underlying K = strike t = time_to_expiration / float(year) r = 0.005 / 100 q = 0 / 100 try: sigma = py_vollib.black_scholes_merton.implied_volatility.implied_volatility( P, S, K, t, r, q, flag[0]) sigmas.append(sigma) except: sigma = 0.0 sigmas.append(sigma) try: delta = py_vollib.black_scholes_merton.greeks.analytical.delta( flag[0], S, K, t, r, sigma, q) deltas.append(delta) except: delta = 0.0 deltas.append(delta) try: gamma = py_vollib.black_scholes_merton.greeks.analytical.gamma( flag[0], S, K, t, r, sigma, q) gammas.append(gamma) except: gamma = 0.0 gammas.append(gamma) try: theta = py_vollib.black_scholes_merton.greeks.analytical.theta( flag[0], S, K, t, r, sigma, q) thetas.append(theta) except: theta = 0.0 thetas.append(theta) try: vega = py_vollib.black_scholes_merton.greeks.analytical.vega( flag[0], S, K, t, r, sigma, q) vegas.append(vega) except: vega = 0.0 vegas.append(vega) ivs = np.array(sigmas) df['Calc IV'] = ivs df['Delta'] = deltas df['Gamma'] = gammas df['Theta'] = thetas df['Vega'] = vegas df = df.dropna() expiry_filter = df.sort_values('DTE')['DTE'].drop_duplicates().values[min( expiry_set, len(df.sort_values('DTE')['DTE'].drop_duplicates()))] calls = df[(abs(df['Delta']) >= delta_filter) & (df['Type'] == 'call') & (df['DTE'] == expiry_filter)].reset_index()[df.columns] puts = df[(abs(df['Delta']) >= delta_filter) & (df['Type'] == 'put') & (df['DTE'] == expiry_filter)].reset_index()[df.columns] return calls, puts