Пример #1
0
def putPercentChange(ticker, strike):
    putChart = options.get_puts(ticker)
    csv = putChart.to_csv(ticker + '.csv')
    tickerDf = pd.read_csv(ticker + '.csv')
    oneRowDataframe = tickerDf.loc[tickerDf['Strike'] == strike]
    percentChange = oneRowDataframe.iloc[0]['% Change']
    return percentChange
Пример #2
0
def getDetailedQuote(stock, ax1 = None):
    
    '''
    # get the detailded bid/ask quote data for charting
    # input : 
        stock - stock ticker of the option of interest
        ax1 - matplotlib axis , if desired to specify
    # for use with bestPick frame:
    #   bestPick['Stock'] would be the input
    # output is a matplotlib AxesSubplot object
    '''
    
    # find the current price of the stock in question
    currentPrice=stock_info.get_live_price(stock)
    stockOptionVals=options.get_puts(stock, date='05/15/20')
    asksExist = stockOptionVals['Ask'] != '-'
    bidsExist = stockOptionVals['Bid'] != '-'
    
    stockOptionVals = stockOptionVals[bidsExist & asksExist] 
    stockOptions = stockOptionVals.plot(x='Strike',y=['Bid','Ask'],
                                                xlim=[.25*currentPrice,1.75*currentPrice],
                                                title='Bid and Ask Prices for {} Options Contracts'.format(stock), ax = ax1)
    # plot the current stock price as a vertical line in green
    stockOptions.axvline(currentPrice, color='green', ls='--')
    stockOptions.set_xlabel('Strike Price ($)')
    stockOptions.set_ylabel('Contract Price ($)')
    
    return stockOptions
Пример #3
0
def calculateStopLoss(ticker, strike, optionType):
    if optionType == 'Call' or optionType == 'call':
        callChart = options.get_calls(ticker)
        cdf = pd.DataFrame(callChart)
        oneRowDataframe = cdf.loc[cdf['Strike'] == strike]
        ask = oneRowDataframe.iloc[0]['Ask']
        bid = oneRowDataframe.iloc[0]['Bid']
        currPrice = oneRowDataframe.iloc[0]['Last Price']
        limitPriceUpper = (currPrice - (currPrice * .2)) - (ask - bid)
        limitPriceLower = (currPrice - (currPrice * .15)) - (ask - bid)
        if limitPriceLower < 0 or limitPriceUpper < 0:
            print("No need to set stop loss! This option premium is too low for a stop loss!")
        elif limitPriceUpper != limitPriceLower:
            print("Set Stop Loss Between: $", limitPriceUpper, "and $", limitPriceLower)




    if optionType == 'Put' or optionType == 'Put':
        putChart = options.get_puts(ticker)
        pdf = pd.DataFrame(putChart)
        oneRowDataframe = pdf.loc[pdf['Strike'] == strike]
        ask = oneRowDataframe.iloc[0]['Ask']
        bid = oneRowDataframe.iloc[0]['Bid']
        currPrice = oneRowDataframe.iloc[0]['Last Price']
        limitPriceUpper = (currPrice - (currPrice * .2)) - (ask - bid)
        limitPriceLower = (currPrice - (currPrice * .15)) - (ask - bid)
        if limitPriceLower < 0 or limitPriceUpper < 0:
            print("No need to set stop loss! This option premium is too low for a stop loss!")
        elif limitPriceUpper != limitPriceLower:
            print("Set Stop Loss Between: $", limitPriceUpper, "and $", limitPriceLower)
Пример #4
0
def putVolatility(ticker, strike):
    putChart = options.get_puts(ticker)
    csv = putChart.to_csv(ticker + '.csv')
    tickerDf = pd.read_csv(ticker + '.csv')
    oneRowDataframe = tickerDf.loc[tickerDf['Strike'] == strike]
    volatility = oneRowDataframe.iloc[0]['Implied Volatility']
    return volatility
Пример #5
0
    def update_options_list(self, option_type, strike, date):
        empty = {
            'Last Trade Date': '',
            'Strike': '',
            'Last Price': '',
            'Bid': '',
            'Ask': '',
            'Change': '',
            '% Change': '',
            'Volume': '',
            'Open Interest': '',
            'Implied Volatility': ''
        }
        contract_name = option_naming(self.ticker, strike, date, option_type)
        orig_date = date
        if contract_name not in self.observed_options:
            #breakdown date string
            """
            month_int = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November','December']
            month_today = month_int.index(date[0:date.index(' ')])+1
            date = date[date.index(' ')+1:]
            day_today = int(date[0:date.index(',')])
            year_today = int(date[-4:])
            strike_date_datetime = datetime.date(year_today, month_today, day_today)
            tod = datetime.date(year = datetime.datetime.today().year, month = datetime.datetime.today().month, day = datetime.datetime.today().day)
            years_to_maturity = (strike_date_datetime-tod).days/365
            """
            years_to_maturity = years_to_maturity_calc(date)
            #get implied volatility
            if option_type.lower() == 'call':
                df = options.get_calls(self.ticker, orig_date)
            else:
                df = options.get_puts(self.ticker, orig_date)
            iv = float(df.loc[df['Strike'] == strike]['Implied Volatility'].
                       to_list()[0][0:-1].replace(',', '')) / 100

            #calculate greeks
            grks = option_greeks(self.prices_today[-1], strike,
                                 years_to_maturity, iv,
                                 self.risk_free_rate)[option_type.lower()]

            #calculate prices
            price = round(
                option_price(self.prices_today[-1], strike, years_to_maturity,
                             iv, self.risk_free_rate)[option_type.lower()], 2)

            opt = {
                'Expir Date': orig_date,
                'Strike Price': '${}'.format(strike)
            }

            opt['Value'] = '${}'.format(price)
            opt['Type'] = option_type
            opt['Implied Vol'] = '{}%'.format(np.round(iv * 100, 4))
            opt.update(grks)
            self.observed_options[contract_name] = opt
        return self.observed_options
Пример #6
0
def find_spreads(ticker, date, spread_type, rr=None, pop=None):
    try:
        curr_price = math.floor(si.get_live_price(ticker))
        if spread_type == 'cs':
            data = []
            puts = options.get_puts(ticker, date)
            puts_filtered = puts[puts['Strike'] <= curr_price]
            for i in range(0, len(puts_filtered) - 1):
                for j in range(i + 1, len(puts_filtered)):
                    calculate(spread_type, data, puts_filtered.iloc[i],
                              puts_filtered.iloc[j])
            df = pd.DataFrame(data,
                              columns=[
                                  'Strike 1\n(LONG)', 'Strike 2\n(SHORT)',
                                  'S1 Spread\nDiff', 'S2 Spread\nDiff',
                                  'Net\nCredit', 'Max\nLoss', 'Max\nGain',
                                  'Risk/Reward\nRatio', 'PoP\n(%)'
                              ])
            pd.set_option('display.max_rows', df.shape[0] + 1)
            if rr != None:
                df = df.loc[(df['Risk/Reward\nRatio'] >= float(rr))]
            if pop != None:
                df = df.loc[(df['PoP\n(%)'] >= float(pop))]
            # if rr == None and pop == None:
            #     df = df.loc[(df['Risk/Reward Ratio'] >= .25) & (df['PoP (%)'] <= 99.99)]
            return 'No good credit spreads found. The optional filters (R/R & PoP) may be too strict' if df.empty else df  # .sort_values(by='Risk/Reward', ascending=False)
        elif spread_type == 'ds':
            data = []
            calls = options.get_calls(ticker, date)
            calls_filtered = calls[calls['Strike'] >= curr_price]
            for i in range(0, len(calls_filtered) - 1):
                for j in range(i + 1, len(calls_filtered)):
                    calculate(spread_type, data, calls_filtered.iloc[i],
                              calls_filtered.iloc[j])
            df = pd.DataFrame(data,
                              columns=[
                                  'Strike 1\n(LONG)', 'Strike 2\n(SHORT)',
                                  'S1 Spread\nDiff', 'S2 Spread\nDiff',
                                  'Net\nDebit', 'Max\nLoss', 'Max\nGain',
                                  'Risk/Reward\nRatio', 'PoP\n(%)'
                              ])
            pd.set_option('display.max_rows', df.shape[0] + 1)
            if rr != None:
                df = df.loc[(df['Risk/Reward\nRatio'] >= float(rr))]
            if pop != None:
                df = df.loc[(df['PoP\n(%)'] >= float(pop))]
            # if rr == None and pop == None:
            #     df = df.loc[(df['Risk/Reward Ratio'] >= 2) & (df['PoP (%)'] >= 20)]
            return 'No good debit spreads found. The optional filters (R/R & PoP) may be too strict' if df.empty else df  # .sort_values(by='Risk/Reward', ascending=False)
        else:
            return 'Not a valid spread type'
    except AssertionError:
        return 'Not a valid ticker symbol'
    except ValueError:
        return 'Not a valid contract expiration date'
def puts_chain(ticka):
    puts = pd.DataFrame()
    stock_expiry_cache[ticka] = friday()
    while (puts.empty):
        try:
            puts = opt.get_puts(ticka, stock_expiry_cache[ticka])
        except:
            stock_expiry_cache[ticka] = stock_expiry_cache[ticka] + \
                dt.timedelta(days=7)
    puts['profit'] = puts['Last Price'] / puts['Strike']
    return puts
Пример #8
0
def get_chain(ticker, date=None, c_p='Call'):
    '''
	Gets option chain from Yahoo Finance API
	Inputs:
		ticker: (str) Stock or ETF ticker symbol
		date: (str) Indicates maturity date for option (e.g: "2019-12-06")
		c_p: (str) Indicates call or put option
	Returns:
		Pandas DataFrame of option chain
	'''
    cols = {'Implied Volatility': 'IV'}
    if c_p == 'Call':
        df = options.get_calls(ticker, date).rename(columns=cols)
        return df.set_index("Strike")
    if c_p == 'Put':
        df = options.get_puts(ticker, date).rename(columns=cols)
        return df.set_index("Strike")
Пример #9
0
def find_em(ticker, exp_date):
    sd = .6827
    curr_price = round(si.get_live_price(ticker), 2)
    low = curr_price - (curr_price * (1 - sd))
    high = curr_price + (curr_price * (1 - sd))
    calls = options.get_calls(ticker, exp_date)
    calls = calls.loc[(calls['Strike'] >= low) & (calls['Strike'] <= high)]
    new_calls = calls['Implied Volatility'].str.replace(r'%',
                                                        r'').astype('float')
    puts = options.get_puts(ticker, exp_date)
    puts = puts.loc[(puts['Strike'] >= low) & (puts['Strike'] <= high)]
    new_puts = puts['Implied Volatility'].str.replace(r'%',
                                                      r'').astype('float')
    volatility = round((new_calls.mean() + new_puts.mean()) / 2, 2)
    d1 = datetime.today()
    d2 = datetime.strptime(exp_date, '%m/%d/%y')
    days_left = abs(d1 - d2).days + 1
    em = round(
        si.get_live_price(ticker) * (volatility / 100) *
        math.sqrt(days_left / 365), 2)
    return 'Volatility: {}, Expected movement: -/+{}'.format(volatility, em)
Пример #10
0
def get_iv(symbol):
    price = si.get_live_price(symbol)
    df = options.get_puts(symbol)
    index_value = (df["Strike"] - price).apply(abs).idxmin()
    df_iv = df.loc[index_value, :]
    return df_iv["Implied Volatility"]
Пример #11
0
print('\n')

pd.set_option('display.max_columns', None)  # View all columns
chain = options.get_options_chain(
    stock,
    'August 20, 2021')  # Give all options that expire before a particular date
#print(chain)                # All Options
#print('\n')
print('CALL Options: \n')
print(chain['calls'])  # CALL Options
print('\n')
print('PUT Options: \n')
print(chain['puts'])  # PUT Options
print('\n')

# Another way to get call and put options directly
chain = options.get_calls(stock, 'August 20, 2021')
#print(chain)

# Strike value depends on Stock's price, so modify as per requirement.
print('CALL Options: Strike <=150 \n')
print(chain[chain['Strike'] <= 150]
      )  # Get all rows where strike price is less than 150
print('\n')

chain = options.get_puts(stock, 'August 20, 2021')
#print(chain)
print('PUT Options: Strike <=150 \n')
print(chain[chain['Strike'] <= 150]
      )  # Get all rows where strike price is less than 150
print('\n')
Пример #12
0
def getOptionsData(personalRiskTolerance, budget, printOutput = 'True'):
    '''
    get the up to date stock options pareto.
    Currently hardcoded for the DOW stocks
    inputs: 
        personalRiskTolerance - risk level - number between 0 and 0.9
        budget - Number - larger than 2000
        printOutput - bool to determine whether print statements show
    outputs:
       stockPareto DataFrame (all options within the budget)
       bestPick DataFrame (highest value return within risk tolerance)
    hardcoded:
       options date - 5/15/2020
       stocks to pick from: All DOW stocks
    '''
    
    # date selection
    today = datetime.today()
    optionsDate = datetime(2020,5,15)
    t = ((optionsDate - today).days + ((optionsDate - today).seconds/86400))/365
    daysLeft = (optionsDate - today).days
    hoursLeft = int((optionsDate - today).seconds/3600)
    if printOutput:
        print('\nOptions will expire in approximately {} days and {} hours'.format(daysLeft,hoursLeft))
    stockPareto = pd.DataFrame()

    if printOutput:
        print('Pulling stock data...\n')

    # initial data capture and processing
    for stock in stock_info.tickers_dow():

        # checks if there is an option during the particular week.
        try:
            individualOptionsData = options.get_puts(stock,date=optionsDate)
            # capture stock, current price for each stock
            individualOptionsData['Stock Name'] = stock
            individualOptionsData['Current Price'] = stock_info.get_live_price(stock)
            # IV formatting to a number
            individualOptionsData['IV']= individualOptionsData['Implied Volatility'].str.slice_replace(-1,repl='').astype(float)/100

        # if not, skip the ticker
        except:
            if printOutput:
                print('No data from {}'.format(stock))
            continue

        # if successful at obtaining options data, fill DataFrame stockPareto with the values
        stockPareto = stockPareto.append(individualOptionsData)
        if printOutput:
            print('Data from {} collected'.format(stock))

    if printOutput:
        print('Data Capture Complete!')

    # bool logic to make sure options are worth investing in
    beingTraded = stockPareto['Volume'] != '-'
    asksExist = stockPareto['Ask'] != '-'
    bidsExist = stockPareto['Bid'] != '-'

    # filtering by bool logic
    stockPareto = stockPareto[beingTraded & asksExist & bidsExist]

    ####################################################
    ### formatting of key variables in the DataFrame ###
    ####################################################

    # POP derived from Black-Scholes model
    stockPareto['POP'] = 100*stats.norm.cdf((np.log(stockPareto['Current Price'] / stockPareto['Strike'] ) +
                                         ( (stockPareto['IV']**2) /2)*t) / (stockPareto['IV']*np.sqrt(t)))
    stockPareto['Strike'] = stockPareto['Strike'].astype(float)
    stockPareto['Bid'] = stockPareto['Bid'].astype(float)
    stockPareto['Ask'] = stockPareto['Ask'].astype(float)

    # determine number of each contract that is in budget
    # potential gain is the average contract selling price ~ (bid / ask) * 100
    # potential gain multiple contracts - potential gain * number of contracts that can be sold within budget
    stockPareto['contractsInBudget'] = np.floor(budget/(stockPareto['Strike']*100))
    stockPareto['Potential Gain'] = ((stockPareto['Ask'] + stockPareto['Bid'])/2) * 100
    stockPareto['Potential Gain Multiple Contracts'] = stockPareto['Potential Gain'] * stockPareto['contractsInBudget']
    ###########################
    ### plotting the pareto ###
    ###########################

    inBudget = stockPareto['contractsInBudget'] > 0
    isInteresting = stockPareto['Bid'] != 0
    stockPareto = stockPareto[inBudget & isInteresting]
    stockPareto = stockPareto.set_index('Contract Name')

    # this is the field which will show in the interactive plot
    stockPareto['printString'] = ('Stock: ' + stockPareto['Stock Name']+'\n'
                                  'Strike Price = $'+ round(stockPareto['Strike'],2).astype(str)+'\n'+
                                  'Current Price = $' + round(stockPareto['Current Price'],2).astype(str) + '\n' +
                                  'Potential Gain = $'+ round(stockPareto['Potential Gain Multiple Contracts'],2).astype(str)+'\n' + 
                                  'ROI = ' + round(((stockPareto['Potential Gain Multiple Contracts']/budget) * 100),2).astype(str) + '%\n' +
                                  'Probability of Profit = ' + round(stockPareto['POP'],2).astype(str))
    
    ####################
    ## Best Fit Logic ##
    ####################

    notBelowRisk = stockPareto['POP'] > (personalRiskTolerance*100)
    bestPick = stockPareto[notBelowRisk].sort_values(by='Potential Gain Multiple Contracts',ascending = False)
    bestPick = bestPick.loc[bestPick['Potential Gain Multiple Contracts'].idxmax()]

    if printOutput:
        print('The best OPTION is:')
        print(bestPick)
        
    return stockPareto, bestPick
Пример #13
0
async def on_message(message):
    print(message.content)
    if message.content.find("!") != -1:
        content = message.content.strip('!').lower().split()
        print(content)
        print(content[0])

        if content[0] == "day":
            if content[1] == "gain":
                await message.channel.send(
                    si.get_day_gainers().head(10).iloc[:, :3])
                await message.channel.send(
                    "-------------------------------------------")
                await message.channel.send(
                    si.get_day_gainers().head(10).iloc[:, 4:7])
            elif content[1] == "lose":
                await message.channel.send(
                    si.get_day_losers().head(10).iloc[:, :3])
                await message.channel.send(
                    "-------------------------------------------")
                await message.channel.send(
                    si.get_day_losers().head(10).iloc[:, 4:7])
            elif content[1] == "active":
                await message.channel.send(
                    si.get_day_most_active().head(10).iloc[:, :3])
                await message.channel.send(
                    "-------------------------------------------")
                await message.channel.send(
                    si.get_day_most_active().head(10).iloc[:, 4:7])

        elif content[0] == "crypto":
            await message.channel.send(si.get_top_crypto().head(10).iloc[:, :3]
                                       )
            await message.channel.send(
                "-------------------------------------------")
            await message.channel.send(si.get_top_crypto().head(10).iloc[:,
                                                                         4:5])

        elif content[0] == "help":
            embedVar = discord.Embed(title="List of functioning commands",
                                     description="",
                                     colour=0x00ff00)
            embedVar.add_field(name="\u200b",
                               value="!tsla\n!day gain\n!day loss",
                               inline=True)
            embedVar.add_field(
                name="\u200b",
                value="!calls tlsa 03/19/2021\n!puts tlsa 03/19/2021",
                inline=True)
            await message.channel.send(embed=embedVar)

        elif content[0] == "calls":
            await message.channel.send(
                op.get_calls(content[1], content[2]).iloc[:, 2:8])

        elif content[0] == "puts":
            await message.channel.send(
                op.get_puts(content[1], content[2]).iloc[:, 2:8])

        else:
            temp = si.get_quote_table(content[0])
            change = round(temp["Quote Price"] - temp["Previous Close"], 2)
            percentage = round(change / temp["Previous Close"] * 100, 2)

            displayQuote = str(round(temp["Quote Price"], 2))
            displayChange = str(change)
            displayPercentage = str(percentage)
            displayTicker = content[0].upper()
            displayClose = str(round(temp["Previous Close"], 2))

            dayRange = temp["Day's Range"].replace('-', '').split()

            dayLow = dayRange[0]
            dayHigh = dayRange[1]

            open = temp["Open"]
            close = temp["Previous Close"]

            volume = str(round(temp["Volume"] / 1000000, 2))
            volume = volume + "M"

            avgVolume = str(round(temp["Avg. Volume"] / 1000000, 2))
            avgVolume = avgVolume + "M"

            bid = temp["Bid"]
            ask = temp["Ask"]

            if change >= 0:
                rgb = 0x00ff00
                displayChange = "+" + displayChange
                displayPercentage = "+" + displayPercentage
            else:
                rgb = 0xff0000

            embedVar = discord.Embed(
                title=
                f"${displayTicker}\n${displayQuote} {displayChange} ({displayPercentage}%)",
                description="",
                colour=rgb)
            embedVar.add_field(
                name="\u200b",
                value=
                f"High: {dayHigh}\nLow: {dayLow}\n\nAsk: {ask}\nBid: {bid}",
                inline=True)
            embedVar.add_field(name="\u200b",
                               value=f"Open: {open}\nPrev.: {close}",
                               inline=True)
            embedVar.add_field(
                name="\u200b",
                value=f"Volume: {volume}\nAvg. Vol.: {avgVolume}",
                inline=True)

            await message.channel.send(embed=embedVar)
Пример #14
0
# randomly select calls or puts
random_option_type = random.choice(["Call", "Put"])
if (random_option_type == "Call"):
    # random OTM call strike price
    random_strike_price = round(
        random.uniform(current_price, current_price *
                       3)) + (random.randrange(0, 51, 50) / 100)
    try:
        option_chain = options.get_calls(random_ticker, date=random_date)
    except:
        pass
else:
    #random OTM put strike price
    random_strike_price = round(random.uniform(
        0, current_price)) + (random.randrange(0, 51, 50) / 100)
    try:
        option_chain = options.get_puts(random_ticker, date=random_date)
    except:
        pass
# make number a multiple of 5 if it's not
# print(str(random.randrange(0,round(si.get_live_price(random_ticker)/3)+1,1) + random.randrange(0, 96, 5)/10))

print("Ticker: {0}\n{1}: ${2} {3}, literally can't go t**s up".format(
    random_ticker, random_date, str(round(random_strike_price, 2)),
    random_option_type))
print("--- %s seconds ---" % (time.time() - start_time))
#print(option_chain)
#for line in option_chain:
#print(line)