def getOptionVolume(aSymbol, aPrice, startDay): """ this routine will provide option volume for one Stock Symbol around one price. Will retrun a list of strike prices Parameters ---------- aSymbol : Stock aPrice : the Max or Min move for a closing price startDay : Earnings week Returns ------- Tuples: ([0] strikePlus, [1] strikeMinus, [2] aOccVolumeDFNextWeek, [3] aOccVolumeDFNextMontlyExpiry) strikePlus/strikeMinus: Strike bounds Plus/Minus from aPrice - to id Min/Max parameters aOccVolumeDFNextWeek: Option Volume for next week around strike price, aOccVolumeDFNextMontlyExpiry: Option Volume for next Monthly Expiry around strike pric """ # todo - if next week equals next expiry push out next expiry # get OCC Volume for aSymbol aOccVolumeDF = getOccVolume(aSymbol) # if aOccVolumeDF is empty send back 0 and empty DF if aOccVolumeDF.empty: return (0, 0, pd.DataFrame(), pd.DataFrame()) strikePlus, strikeMinus = getStrikes(aPrice, aOccVolumeDF, startDay) # print('strikePlus: ', strikePlus) # print(('strikeMinus: ', strikeMinus)) # get list of OCC strikes between <= strikePlus and >= StrikeMinus strikes = [ strike for strike in aOccVolumeDF.Strike if (strike >= strikeMinus and strike <= strikePlus) ] # print('strikes: \n', strikes) # strikes = list(set(strikes)) # print('unique strikes: ', strikes) # get the Volume for Strikes aOccVolumeDF = aOccVolumeDF[aOccVolumeDF.Strike.isin(strikes)] # print('aOccVolumeDF:\n', aOccVolumeDF) # Get the Volume for Next Friday Option Strikes aOccVolumeDFNextWeek = aOccVolumeDF.loc[( aOccVolumeDF.expiry == dateUtils.nextFridayOrgFormat( dateUtils.getDateFromISO8601(startDay)))] # Get the Volume for Next Friday Monthly Option Strikes aOccVolumeDFNextMontlyExpiry = aOccVolumeDF.loc[ aOccVolumeDF.expiry == dateUtils.getNextThirdFridayFromDate( dateUtils.getDateFromISO8601(startDay))] # print('aOccVolumeDFNextWeek:\n', aOccVolumeDFNextWeek) # print('aOccVolumeDFNextMontlyExpiry: \n', aOccVolumeDFNextMontlyExpiry) return (strikePlus, strikeMinus, aOccVolumeDFNextWeek, aOccVolumeDFNextMontlyExpiry)
def getCloseStrikePrice(ib, qualityContracts, aStockSymbol, price, startDate, right, exchange = 'SMART' ): """ Get closes prices that is five points above, five points below :Keyword arguments ib -- ib_insync instance qualityContracts -- a qualified Stock Symbol aStockSymbol -- the stock price -- price to find Option :returns Strike Prices """ # print(qualityContracts.symbol) # [ticker] = ib.reqTickers(qualityContracts) chains = ib.reqSecDefOptParams(qualityContracts.symbol, '', qualityContracts.secType, qualityContracts.conId) chain = next(c for c in chains if c.tradingClass == aStockSymbol and c.exchange == exchange) # if price >= then $40 Get to the next round at +/- 5 # if price < $40 get to round at the +/-2 if price >= 40 : strikePlus = (5 * round(price / 5)) + 5 strikeMinus = (5 * round(price / 5)) - 5 # print('strikePlus', strikePlus) # print('strikeMinus', strikeMinus) else: strikePlus = (2 * round(price / 2)) + 3 strikeMinus = (2 * round(price / 2)) - 3 # print('strikePlus', strikePlus) # print('strikeMinus', strikeMinus) # get strikes at strikePlus strikes = [strike for strike in chain.strikes if strike >= strikeMinus and strike <= strikePlus ] # print('strikes: ', strikes) # get experation date in proper format dateFromISOFromat = dateUtils.getDateFromISO8601(startDate) nextFridayDateFormat = dateUtils.nextFriday(dateFromISOFromat) expiration = dateUtils.nextFridayOrgFormat(nextFridayDateFormat) # = sorted(exp for exp in chain.expirations) print('expiration: ', expiration) contracts = [Option(qualityContracts.symbol, expiration, strike, right, exchange) for strike in strikes] ib.qualifyContracts(*contracts) # print('contracts: ', contracts, '\n\n\n') # Todo: should this be ib.reqSecDefOptParams instead of ib.reqContractDetails??? optionContractsDetails = [ib.reqContractDetails(cd) for cd in contracts] return strikes, contracts
def checkStrikePrices(strikePlus, strikeMinus, aOccVolumeDF, startDay): aOccVolumeDFpd = pd.DataFrame(aOccVolumeDF) nextThrdFri = dateUtils.getNextThirdFridayFromDate(dateUtils.getDateFromISO8601(startDay)) nexFriday = dateUtils.nextFridayOrgFormat(dateUtils.getDateFromISO8601(startDay)) listOfExpiryNextThrdFriday = aOccVolumeDFpd.loc[aOccVolumeDFpd['expiry'] == nextThrdFri] listOfExpiryNextFriday = aOccVolumeDFpd.loc[aOccVolumeDFpd['expiry'] == nexFriday] #todo make sure the +2 amnd -2 are good adjustments if listOfExpiryNextFriday.Strike.min() > strikeMinus: strikeMinus=listOfExpiryNextFriday.Strike.min() +2 if listOfExpiryNextFriday.Strike.max() < strikePlus: strikePlus=listOfExpiryNextFriday.Strike.max() -2 return strikePlus, strikeMinus
def getOptionVolumeNextFriExpiryCount(aSymbol, startDay, lenDF): """ # TODO - OCC change their Web Site -- need to rework if we want open interest Calculate the next Friday total Call / Put Open Interest If there are no options for Friday goto Monthly else return O Parameters ---------- aSymbol : Stock startDay : Earnings week Returns ------- Volume of Call / Put open interest """ # get OCC Volume for aSymbol aOccVolumeDF = getOccVolume(aSymbol) # if aOccVolumeDF is empty send back 0 and empty DF if aOccVolumeDF.empty: print(lenDF, '- ' + aSymbol + ': No OCC Option Volume') return (0, 0) # else: # print(aSymbol + ': OCC Option Volumes') # Get the Volume for Next Friday Option Strikes aOccVolumeDFNextWeek = aOccVolumeDF.loc[(aOccVolumeDF.expiry == dateUtils.nextFridayOrgFormat(dateUtils.getDateFromISO8601(startDay)))] if aOccVolumeDFNextWeek.empty: #nothing for Next Friday? # Get the Volume for Next Friday Monthly Option Strikes aOccVolumeDFNextMontlyExpiry = aOccVolumeDF.loc[aOccVolumeDF.expiry == dateUtils.getNextThirdFridayFromDate(dateUtils.getDateFromISO8601(startDay))] theCallsOpenInterest = aOccVolumeDFNextMontlyExpiry.Call.sum() thePutsOpenInterest = aOccVolumeDFNextMontlyExpiry.Put.sum() else: #use puts/calls for next Friday theCallsOpenInterest = aOccVolumeDFNextWeek.Call.sum() thePutsOpenInterest = aOccVolumeDFNextWeek.Put.sum() return theCallsOpenInterest, thePutsOpenInterest