Exemplo n.º 1
0
def getStockOptionPrice(ib, aStockSymbol, exchange = 'SMART'):
        """
        getStockOptionPrices

        :Keyword arguments
        ib                  -- ib_insync instance
        aStockSymbol        -- the Stock Symbol
        exchange            -- the exchange default is 'SMART'
        optionChain         -- type is ib_insync.objects.OptionChain
        marketPrice         -- Market Price of  the Underlying/Stock
        strikePriceRange    -- Strike prices within +- strikePriceRange dollar value of
                               the current marketPrice (default 20 )
        strikePriceMultiple -- Strike prices that are a multitude (eg $5 goes to 20, 25) of
                               strikePriceMultiple dollar value (default 5 )
        :returns
        Call price, Put Price
        """

        qualityContracts = Stock(aStockSymbol, 'SMART')
        ib.qualifyContracts(qualityContracts)
        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)

        [ticker] = ib.reqTickers(qualityContracts)

        # Get to the next 5 dont want to deal with missing data at the 1 and 2 level
        strike5 = (5 * round(ticker.marketPrice() / 5))
        # get strikes at strike5
        strikes = [strike for strike in chain.strikes
                   if strike5 == strike]

        expiration = dateUtils.getNextExpiryDate()  # = sorted(exp for exp in chain.expirations)
        rights = ['P', 'C']

        contracts = [Option(aStockSymbol, expiration, strike5, right, 'SMART')
                     for right in rights]

        ib.qualifyContracts(*contracts)

        contractsForExpiry = [aContract for aContract in contracts
                              if aContract.lastTradeDateOrContractMonth == dateUtils.getNextExpiryDate()]


        tickers = ib.reqTickers(*contractsForExpiry)

        if tickers[0].contract.right == 'C':
                tickerPriceCall = tickers[0].last
                tickerPricePut = tickers[1].last
        else:
                tickerPriceCall = tickers[1].last
                tickerPricePut = tickers[0].last

        return tickerPriceCall, tickerPricePut
Exemplo n.º 2
0
def getExpectedPriceRangeTillNextExpiryDays(underlyingPrice, impVol):
    """
    Get the expected price range of an underlying at the next
    monthly expiry.

    Parameters
    ----------
    underlyingPrice : price of the underlying stock
    impVol : implied volatility of the underlying

    Returns
    -------

    """
    print('underlyingPrice: ', type(underlyingPrice))
    print('impVol: ', type(impVol))

    try:
        priceTimesImpvol = underlyingPrice * impVol
        sqrtOfDaysDiv = math.sqrt(
            dateUtils.daysToExpiry(dateUtils.getNextExpiryDate()) / 365)
    except ValueError:
        print("****   in getExpectedPriceRangeTillNextExpiryDays")
        print("          ValueError: ", ValueError)
        print('          underlyingPrice: ', underlyingPrice)
        print('          impVol: ', impVol)
        return 0

    return round((priceTimesImpvol * sqrtOfDaysDiv), 2)
Exemplo n.º 3
0
def getOptionStraddlePrice(ib, qualityContracts, chain):
    """
    Get ATM (at the money) Option Straddle Price.

        :Keyword arguments
        ib                  -- ib_insync instance
        qualityContracts    -- a qualified Stock Symbol
        chain               -- chain of Options / list of expires and strike prices.

        :returns
        Straddle Price: which is to buy a call option and a put option on the same underlying stock
                        with the same expiration date and strike price.
        """

    [ticker] = ib.reqTickers(qualityContracts)

    # Get to the next round at 5  don't want to deal with missing data at the increments of 1 and 2
    # eg:  we want 125 or 130
    #      don't get 126,127,128, 129 / these price option are not always available
    strike5 = (5 * round(ticker.marketPrice() / 5))
    # ToDo should be a better way to get strike5 then loop
    # get strikes at strike5
    strikes = [strike for strike in chain.strikes if strike5 == strike]

    expiration = dateUtils.getNextExpiryDate(
    )  # = sorted(exp for exp in chain.expirations)
    rights = ['P', 'C']

    contracts = [
        Option(qualityContracts.symbol, expiration, strike5, right, 'SMART')
        for right in rights
    ]
    print('Straddle ', contracts)
    ib.qualifyContracts(*contracts)

    contractsForExpiry = [
        aContract for aContract in contracts
        if aContract.lastTradeDateOrContractMonth ==
        dateUtils.getNextExpiryDate()
    ]

    tickers = ib.reqTickers(*contractsForExpiry)

    # Todo - need to update to return close price when market closed else return last
    return tickers[0].close + tickers[1].close
def getExpectedPriceRangeTillNextExpiryDays(underlyingPrice, impVol):
    """
    Get the expected price range of an underlying at the next
    monthly expiry.

    using:
    (Stock Price * IV)/SQRT(Days to Expiry/#Days in a Year)

    suggest using: # todo -- update to this Expected Price Range - do not think this is correct
                   # todo -- continue to include Days to Expiry. 6/10/2020
    (Stock Price * IV)/SQRT(#Days in a Year)


    Parameters
    ----------
    underlyingPrice : price of the underlying stock
    impVol : implied volatility of the underlying

    Returns
    -------

    """
    # print('underlyingPrice: ', type(underlyingPrice))
    # print('impVol: ', type(impVol))

    try:
        priceTimesImpvol = underlyingPrice * impVol
        sqrtOfDaysDiv = math.sqrt(
            dateUtils.daysToExpiry(dateUtils.getNextExpiryDate()) / 365)

    except ValueError:
        print("****   in getExpectedPriceRangeTillNextExpiryDays")
        print("          ValueError: ", ValueError)
        print('          underlyingPrice: ', underlyingPrice)
        print('          impVol: ', impVol)
        return 0

    return round((priceTimesImpvol * sqrtOfDaysDiv), 2)
def buildExcelFile(aStock, startday, theExpiryDateText):

    # Get the company info from BarChart.com
    stockInfo = companyInfo.getCompanyStockInfo(aStock)
    stockOverview = companyInfo.getCompanyOverview(aStock)
    stockFundamentals = companyInfo.getCompanyFundamentals(aStock)
    aText, stockRatings = companyInfo.getCompanyRatings(aStock)
    callOptions, putOptions, expiryText, aWebDriver = companyOptions.scrapeCompanyOptionData(
        aStock, theExpiryDateText)

    # Setup Excel output file
    outExcelFile = theBaseCompaniesDirectory + startday + '/' + aStock + '_SummaryWeekOf-' + startday + excelSuffix
    # Setup Fundamentals worksheet name
    sheetIsFundamentals = aStock + '-Fundamentals'

    # Starting point for data
    sheetRowStart = 4
    sheetColStart = 1

    # create writer and workbook
    writer = pd.ExcelWriter(outExcelFile, engine='xlsxwriter')
    fundamentalsWorkbook = writer.book

    # percentFormat  = fundamentalsWorkbook.add_format({'num_format': '0.0%'})
    # currencyFormat = fundamentalsWorkbook.add_format({'num_format': '$#,##0.00'})

    # ------------------------------------------------------------------
    # set up fundamentals Worksheet
    # ------------------------------------------------------------------
    # Transpose
    stockFundamentalsTranposed = stockFundamentals.T

    # Add the Ratings next
    stockRatings.to_excel(writer,
                          sheet_name=sheetIsFundamentals,
                          startrow=sheetRowStart + 3,
                          startcol=sheetColStart)
    # Add the fundamentals
    stockInfo.to_excel(writer,
                       sheet_name=sheetIsFundamentals,
                       startrow=sheetRowStart + 7,
                       startcol=sheetColStart,
                       header=False)
    stockFundamentalsTranposed.to_excel(writer,
                                        sheet_name=sheetIsFundamentals,
                                        startrow=sheetRowStart + 7,
                                        startcol=sheetColStart + 2,
                                        header=False)
    stockOverview.to_excel(writer,
                           sheet_name=sheetIsFundamentals,
                           startrow=sheetRowStart + 7,
                           startcol=sheetColStart + 4,
                           header=False)

    # Add the text info on Expiry and Recommendations
    fundamentalsWorkbookSheet = writer.sheets[sheetIsFundamentals]
    fundamentalsWorkbookSheet.write(sheetRowStart + 1, 1, aText)
    fundamentalsWorkbookSheet.write(sheetRowStart, 1, expiryText)
    fundamentalsWorkbookSheet.set_column('B:F', 25)
    fundamentalsWorkbookSheet.set_column('G:S', 18)
    # fundamentalsWorkbookSheet.conditional_format('B2:B8', {'type': '3_color_scale'})

    # ------------------------------------------------------------------
    # setup the Call/Put Option Worksheets
    # ------------------------------------------------------------------
    # include the DF header as Excel Header
    callOptions.to_excel(writer,
                         sheet_name=aStock + '-Call Options',
                         startrow=0,
                         header=True)
    putOptions.to_excel(writer,
                        sheet_name=aStock + '-Put Options',
                        startrow=0,
                        header=True)

    # ------------------------------------------------------------------
    # setup the Call/Put Option Worksheets
    # ------------------------------------------------------------------
    # Get aStock Excel file and add as a sheet
    inExcelFile = theBaseCompaniesDirectory + startday +\
                          '/SummaryWeekOf-' + startday + excelSuffix
    # Need to use pd.ExcelFile to read in the file to manipulate
    yahooEarningsDf_aSymbol_Sheet = pd.ExcelFile(inExcelFile).parse(aStock)
    # Add the aStock sheet to our Company Info
    yahooEarningsDf_aSymbol_Sheet.to_excel(writer,
                                           sheet_name=aStock +
                                           '-EarningsHistory',
                                           startrow=2,
                                           startcol=sheetColStart)

    # ------------------------------------------------------------------
    # setup summary Worksheet
    # ------------------------------------------------------------------
    # get 2 rows of summary data
    summaryRow = yahooEarningsDf_aSymbol_Sheet.iloc[0:1, 0:21]

    summaryRow = summaryRow[[
        "Symbol", "Company", "Earnings_Date", "Time", "Close",
        "ABSFwd1MinusClose", "ABSFwd1PlusClose", "Exp$Range", "Volume",
        "Option_Volume", "histVol", "impVol", "IV_Delta", "stdFwd1%",
        "stdFwd1$TimesClose", "std25Fwd1%", "std25Fwd1$TimesClose",
        "max1DayABS$Delta"
    ]].copy()

    summaryRow.rename(columns={'ABSFwd1MinusClose': 'ABS $ Minus'},
                      inplace=True)
    summaryRow.rename(columns={'ABSFwd1PlusClose': 'ABS $ Plus'}, inplace=True)
    summaryRow.rename(columns={'stdFwd1%': '1-SD % Move'}, inplace=True)
    summaryRow.rename(columns={"stdFwd1$TimesClose": '1-SD $ Move'},
                      inplace=True)
    summaryRow.rename(columns={'std25Fwd1%': '2.5-SD % Move'}, inplace=True)
    summaryRow.rename(columns={'max1DayABS$Delta': '1Day Max ABS Delta'},
                      inplace=True)
    summaryRow.rename(columns={'std25Fwd1$TimesClose': '2.5-SD $ Move'},
                      inplace=True)
    summaryRow.rename(columns={'Earnings_Date': 'Earnings'}, inplace=True)
    summaryRow.rename(columns={'histVol': 'Historic Vol'}, inplace=True)
    summaryRow.rename(columns={'impVol': 'Implied Vol'}, inplace=True)
    summaryRow.rename(columns={'IV_Delta': 'Vol Delta'}, inplace=True)

    #  Change to Earning Date Format: "Mon, Jul 06"
    summaryRow['Earnings'] = summaryRow['Earnings'].apply(
        str.replace, args=('-', '')).apply(dateUtils.monthDayFormat)

    summaryRow.to_excel(writer,
                        sheet_name=sheetIsFundamentals,
                        startrow=0,
                        startcol=1,
                        index=False)

    # ------------------------------------------------------------------
    # Create Plot and save as png file
    # Setup plot Worksheet
    # ------------------------------------------------------------------
    plotEarningPngFile(aStock, startday)
    # Get Plot file path
    aStockEarningsPlot = theBaseCompaniesDirectory + startday + '/rawData/' + aStock + '.png'
    # create image worksheet then add image
    imageWorksheet = fundamentalsWorkbook.add_worksheet(
        aStock + '-Earnings History Plot')
    imageWorksheet.insert_image('B3', aStockEarningsPlot)

    # ------------------------------------------------------------------
    # Setup Trade Plan Worksheet
    # ------------------------------------------------------------------
    # set up Trade Worksheet as the First Tab this is crudely done by instanciting the sheet first
    # this is done above   -->  tradePlanWorkbookSheet = writer.sheets[aStock+'-Trade Plan']
    # Todo - figure out how to order workbook sheets
    #        the worksheets are kept in "writer" as dict
    # format line like: 21 Days to expiration on 2020-07-17 -- Implied Volatility: 68.32%
    expiry_text_format = fundamentalsWorkbook.add_format({
        'bold':
        True,
        'font_color':
        '#C00000'
    })
    expiry_format = fundamentalsWorkbook.add_format({
        'bold': True,
        'font_color': 'navy',
        'border': 2,
        'valign': 'vcenter',
        'align': 'center',
        'fg_color': '#FAF1D3',
    })
    today_format = fundamentalsWorkbook.add_format({
        'bold': True,
        'font_color': '#C00000',
        'border': 2,
        'valign': 'vcenter',
        'align': 'center',
        'fg_color': '#FAF1D3',
    })
    call_label_format = fundamentalsWorkbook.add_format({
        'bold': True,
        'font_color': 'navy',
        'fg_color': '#D7E4BC',
        'border': 2,
        'valign': 'vcenter',
        'align': 'center'
    })
    put_label_format = fundamentalsWorkbook.add_format({
        'bold': True,
        'font_color': 'navy',
        'fg_color': '#f9cfb5',
        'border': 2,
        'valign': 'vcenter',
        'align': 'center'
    })
    open_format = fundamentalsWorkbook.add_format({
        'bold': True,
        'font_color': 'navy',
        'fg_color': '#93D07B',
        'border': 2,
        'valign': 'vcenter',
        'align': 'center'
    })
    close_format = fundamentalsWorkbook.add_format({
        'bold': True,
        'font_color': 'navy',
        'fg_color': '#eb813d',
        'border': 2,
        'valign': 'vcenter',
        'align': 'center'
    })
    trade_header_format = fundamentalsWorkbook.add_format({
        'bold': True,
        'font_color': 'navy',
        'fg_color': '#D7E4BC',
        'border': 2,
        'valign': 'vcenter',
        'align': 'center'
    })
    trade_text_format = fundamentalsWorkbook.add_format({
        'border': 1,
        'valign': 'vcenter',
        'align': 'center'
    })
    empty_expiryW_format = fundamentalsWorkbook.add_format({
        'bold':
        True,
        'font_color':
        'navy',
        'border':
        2,
        'valign':
        'vcenter',
        'align':
        'center',
        'fg_color':
        '#F2E1A9'
    })  # f2e1a9
    empty_expiryM_format = fundamentalsWorkbook.add_format({
        'border':
        2,
        'fg_color':
        '#FAF1D3'
    })
    empty_cell_format = fundamentalsWorkbook.add_format({
        'border': 2,
        'valign': 'center'
    })

    # tradePlanWorkbookSheet = writer.sheets[aStock+'-Trade Plan']
    tradePlanWorkbookSheet = fundamentalsWorkbook.add_worksheet(aStock +
                                                                '-Trade Plan')

    # [tradePlanWorkbookSheet.write(0, x, '', empty_cell_format) for x in range(0,7,1)]
    #
    for col_num, value in enumerate(summaryRow.columns.values):
        if col_num > 12:
            tradePlanWorkbookSheet.write(4, col_num - 12, value,
                                         trade_header_format)
            tradePlanWorkbookSheet.write(5, col_num - 12,
                                         summaryRow.iloc[0, col_num],
                                         trade_text_format)
        elif col_num > 6:
            tradePlanWorkbookSheet.write(2, col_num - 6, value,
                                         trade_header_format)
            tradePlanWorkbookSheet.write(3, col_num - 6,
                                         summaryRow.iloc[0, col_num],
                                         trade_text_format)
        else:
            tradePlanWorkbookSheet.write(0, col_num, value,
                                         trade_header_format)
            tradePlanWorkbookSheet.write(1, col_num, summaryRow.iloc[0,
                                                                     col_num],
                                         trade_text_format)

    tradePlanWorkbookSheet.set_row(1, 20)
    tradePlanWorkbookSheet.set_row(3, 20)
    tradePlanWorkbookSheet.set_row(5, 20)

    # Format Earning data?
    # [tradePlanWorkbookSheet.write(0, x, '', empty_cell_format) for x in range(0,7,1)]
    # Expiry Text / Implied Vol
    # next Expiry dates
    tradePlanWorkbookSheet.write(7, 1, expiryText, expiry_text_format)
    tradePlanWorkbookSheet.write(8, 1, "Next Expiry's ->", expiry_format)
    tradePlanWorkbookSheet.write(
        8, 2, 'Friday:  ' + dateUtils.getNextFridayExpiryFormat(),
        empty_expiryW_format)
    tradePlanWorkbookSheet.write(
        8, 3,
        "Monthly:  " + dateUtils.month3Format(dateUtils.getNextExpiryDate()),
        expiry_format)

    # [tradePlanWorkbookSheet.write(9, x, '', empty_expiryM_format) for x in range(2,4,2)]
    tradePlanWorkbookSheet.write(9, 2, '', empty_expiryW_format)
    tradePlanWorkbookSheet.write(9, 3, '', empty_expiryM_format)

    tradePlanWorkbookSheet.write(13, 0, "Today:  ", today_format)
    tradePlanWorkbookSheet.write(13, 1, dateUtils.getTodayStr(), today_format)
    tradePlanWorkbookSheet.write(13, 2, 'Strike', trade_header_format)
    tradePlanWorkbookSheet.write(13, 3, 'Price', trade_header_format)
    tradePlanWorkbookSheet.write(13, 4, 'IV', trade_header_format)
    tradePlanWorkbookSheet.write(13, 5, 'Volume', trade_header_format)
    # tradePlanWorkbookSheet.write(16, 6, 'IV', trade_header_format)
    tradePlanWorkbookSheet.write(13, 6, 'Time Executed', trade_header_format)

    tradePlanWorkbookSheet.write(14, 0, 'Open', open_format)
    tradePlanWorkbookSheet.write(14, 1, 'Call', call_label_format)
    tradePlanWorkbookSheet.write(15, 1, 'Put', put_label_format)

    [
        tradePlanWorkbookSheet.write(14, x, '', empty_cell_format)
        for x in range(2, 7, 1)
    ]
    [
        tradePlanWorkbookSheet.write(15, x, '', empty_cell_format)
        for x in range(2, 7, 1)
    ]
    [
        tradePlanWorkbookSheet.write(15, x, '', empty_cell_format)
        for x in range(2, 7, 1)
    ]

    [
        tradePlanWorkbookSheet.write(16, x, '', empty_expiryM_format)
        for x in range(1, 7, 1)
    ]
    tradePlanWorkbookSheet.set_row(16, 10)
    #
    tradePlanWorkbookSheet.write(17, 0, 'Close', close_format)
    tradePlanWorkbookSheet.write(17, 1, 'Call', trade_header_format)
    tradePlanWorkbookSheet.write(18, 1, 'Put', put_label_format)
    [
        tradePlanWorkbookSheet.write(17, x, '', empty_cell_format)
        for x in range(2, 7, 1)
    ]
    [
        tradePlanWorkbookSheet.write(18, x, '', empty_cell_format)
        for x in range(2, 7, 1)
    ]
    tradePlanWorkbookSheet.set_row(14, 40)
    tradePlanWorkbookSheet.set_row(15, 40)
    tradePlanWorkbookSheet.set_row(17, 40)
    tradePlanWorkbookSheet.set_row(18, 40)
    #
    tradePlanWorkbookSheet.set_tab_color('green')
    tradePlanWorkbookSheet.set_column('B:G', 22)
    # # Save excel
    writer.save()

    return aWebDriver