Ejemplo n.º 1
0
async def histcont_command(ctx, ticker=""):
    """Displays historical quarterly-contracts [quiverquant.com]"""
    try:
        # Debug user input
        if cfg.DEBUG:
            logger.debug("!stocks.gov.histcont %s", ticker)

        if ticker == "":
            raise Exception("A ticker is required")

        # Retrieve Data
        df_contracts = quiverquant_model.get_government_trading(
            "quarter-contracts", ticker=ticker)

        if df_contracts.empty:
            logger.debug("No quarterly government contracts found")
            return

        # Output Data
        amounts = df_contracts.sort_values(by=["Year", "Qtr"])["Amount"].values

        qtr = df_contracts.sort_values(by=["Year", "Qtr"])["Qtr"].values
        year = df_contracts.sort_values(by=["Year", "Qtr"])["Year"].values

        quarter_ticks = [
            f"{quarter[0]}" if quarter[1] == 1 else ""
            for quarter in zip(year, qtr)
        ]
        plt.style.use("seaborn")

        fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)

        ax.plot(np.arange(0, len(amounts)), amounts / 1000, "-*", lw=2, ms=15)

        ax.set_xlim([-0.5, len(amounts) - 0.5])
        ax.set_xticks(np.arange(0, len(amounts)))
        ax.set_xticklabels(quarter_ticks)
        ax.grid()
        ax.set_title(
            f"Historical Quarterly Government Contracts for {ticker.upper()}")
        ax.set_xlabel("Date")
        ax.set_ylabel("Amount ($1k)")
        fig.tight_layout()

        plt.savefig("gov_histcont.png")
        imagefile = "gov_histcont.png"

        img = Image.open(imagefile)
        print(img.size)
        im_bg = Image.open(cfg.IMG_BG)
        h = img.height + 240
        w = img.width + 520

        img = img.resize((w, h), Image.ANTIALIAS)
        x1 = int(0.5 * im_bg.size[0]) - int(0.5 * img.size[0])
        y1 = int(0.5 * im_bg.size[1]) - int(0.5 * img.size[1])
        x2 = int(0.5 * im_bg.size[0]) + int(0.5 * img.size[0])
        y2 = int(0.5 * im_bg.size[1]) + int(0.5 * img.size[1])
        img = img.convert("RGB")
        im_bg.paste(img, box=(x1 - 5, y1, x2 - 5, y2))
        im_bg.save(imagefile, "PNG", quality=100)

        image = Image.open(imagefile)
        image = autocrop_image(image, 0)
        image.save(imagefile, "PNG", quality=100)

        uploaded_image = gst_imgur.upload_image("gov_histcont.png",
                                                title="something")
        image_link = uploaded_image.link
        if cfg.DEBUG:
            logger.debug("Image URL: %s", image_link)
        title = "Stocks: Historical Quarterly Government Contract " + ticker
        embed = disnake.Embed(title=title, colour=cfg.COLOR)
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )
        embed.set_image(url=image_link)
        os.remove("gov_histcont.png")

        await ctx.send(embed=embed)

    except Exception as e:
        embed = disnake.Embed(
            title="ERROR Stocks: Historical Quarterly Government Contract",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 2
0
async def historical_command(ctx, signal: str = "", start=""):
    """Displays historical price comparison between similar companies [Yahoo Finance]"""
    try:

        # Debug user input
        if cfg.DEBUG:
            logger.debug("!stocks.scr.historical %s %s", signal, start)

        # Check for argument
        if signal not in so.d_signals_desc:
            raise Exception("Invalid preset selected!")

        register_matplotlib_converters()

        screen = ticker.Ticker()

        if signal in finviz_model.d_signals:
            screen.set_filter(signal=finviz_model.d_signals[signal])

        else:
            preset_filter = configparser.RawConfigParser()
            preset_filter.optionxform = str  # type: ignore
            preset_filter.read(so.presets_path + signal + ".ini")

            d_general = preset_filter["General"]
            d_filters = {
                **preset_filter["Descriptive"],
                **preset_filter["Fundamental"],
                **preset_filter["Technical"],
            }

            d_filters = {k: v for k, v in d_filters.items() if v}

            if d_general["Signal"]:
                screen.set_filter(filters_dict=d_filters,
                                  signal=d_general["Signal"])
            else:
                screen.set_filter(filters_dict=d_filters)

        if start == "":
            start = datetime.now() - timedelta(days=365)
        else:
            start = datetime.strptime(start, cfg.DATE_FORMAT)

        # Output Data
        l_min = []
        l_leg = []
        l_stocks = screen.ScreenerView(verbose=0)

        if len(l_stocks) > 10:
            description = (
                "\nThe limit of stocks to compare with are 10. Hence, 10 random similar stocks will be displayed."
                "\nThe selected list will be: ")
            random.shuffle(l_stocks)
            l_stocks = sorted(l_stocks[:10])
            description = description + (", ".join(l_stocks))
            logger.debug(description)

        plt.style.use("seaborn")
        plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI)

        while l_stocks:
            l_parsed_stocks = []
            for symbol in l_stocks:
                try:
                    df_similar_stock = yf.download(
                        symbol,
                        start=datetime.strftime(start, "%Y-%m-%d"),
                        progress=False,
                        threads=False,
                    )
                    if not df_similar_stock.empty:
                        plt.plot(
                            df_similar_stock.index,
                            df_similar_stock["Adj Close"].values,
                        )
                        l_min.append(df_similar_stock.index[0])
                        l_leg.append(symbol)

                    l_parsed_stocks.append(symbol)
                except Exception as e:
                    error = (
                        f"{e}\nDisregard previous error, which is due to API Rate limits from Yahoo Finance. "
                        f"Because we like '{symbol}', and we won't leave without getting data from it."
                    )
                    embed = disnake.Embed(
                        title=
                        "ERROR Stocks: [Yahoo Finance] Historical Screener",
                        colour=cfg.COLOR,
                        description=error,
                    )
                    embed.set_author(
                        name=cfg.AUTHOR_NAME,
                        icon_url=cfg.AUTHOR_ICON_URL,
                    )

                    await ctx.send(embed=embed, delete_after=30.0)

            for parsed_stock in l_parsed_stocks:
                l_stocks.remove(parsed_stock)

        if signal:
            plt.title(
                f"Screener Historical Price using {finviz_model.d_signals[signal]} signal"
            )
        else:
            plt.title(f"Screener Historical Price using {signal} preset")

        plt.xlabel("Time")
        plt.ylabel("Share Price ($)")
        plt.legend(l_leg)
        plt.grid(b=True, which="major", color="#666666", linestyle="-")
        plt.minorticks_on()
        plt.grid(b=True,
                 which="minor",
                 color="#999999",
                 linestyle="-",
                 alpha=0.2)
        # ensures that the historical data starts from same datapoint
        plt.xlim([max(l_min), df_similar_stock.index[-1]])

        plt.savefig("scr_historical.png")
        imagefile = "scr_historical.png"

        img = Image.open(imagefile)
        print(img.size)
        im_bg = Image.open(cfg.IMG_BG)
        h = img.height + 240
        w = img.width + 520

        img = img.resize((w, h), Image.ANTIALIAS)
        x1 = int(0.5 * im_bg.size[0]) - int(0.5 * img.size[0])
        y1 = int(0.5 * im_bg.size[1]) - int(0.5 * img.size[1])
        x2 = int(0.5 * im_bg.size[0]) + int(0.5 * img.size[0])
        y2 = int(0.5 * im_bg.size[1]) + int(0.5 * img.size[1])
        img = img.convert("RGB")
        im_bg.paste(img, box=(x1 - 5, y1, x2 - 5, y2))
        im_bg.save(imagefile, "PNG", quality=100)

        image = Image.open(imagefile)
        image = autocrop_image(image, 0)
        image.save(imagefile, "PNG", quality=100)

        uploaded_image = gst_imgur.upload_image("scr_historical.png",
                                                title="something")
        image_link = uploaded_image.link
        if cfg.DEBUG:
            logger.debug("Image URL: %s", image_link)
        title = "Stocks: [Yahoo Finance] Historical Screener"
        embed = disnake.Embed(title=title,
                              description=description,
                              colour=cfg.COLOR)
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )
        embed.set_image(url=image_link)
        os.remove("scr_historical.png")

        await ctx.send(embed=embed)

    except Exception as e:
        embed = disnake.Embed(
            title="ERROR Stocks: [Yahoo Finance] Historical Screener",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 3
0
async def gtrades_command(
    ctx,
    ticker: str = "",
    gov_type="",
    past_transactions_months: int = 10,
    raw: bool = False,
):
    """Displays government trades [quiverquant.com]"""
    try:
        # Debug user input
        if cfg.DEBUG:
            logger.debug(
                "!stocks.gov.gtrades %s %s %s %s",
                ticker,
                gov_type,
                past_transactions_months,
                raw,
            )

        if ticker == "":
            raise Exception("A ticker is required")

        possible_args = ["congress", "senate", "house"]
        if gov_type == "":
            gov_type = "congress"
        elif gov_type not in possible_args:
            raise Exception(
                "Enter a valid government argument, options are: congress, senate and house"
            )

        # Retrieve Data
        df_gov = quiverquant_model.get_government_trading(gov_type, ticker)

        if df_gov.empty:
            raise Exception(f"No {gov_type} trading data found")

        # Output Data
        df_gov = df_gov.sort_values("TransactionDate", ascending=False)

        start_date = datetime.now() - timedelta(days=past_transactions_months *
                                                30)

        df_gov["TransactionDate"] = pd.to_datetime(df_gov["TransactionDate"])

        df_gov = df_gov[df_gov["TransactionDate"] > start_date]

        if df_gov.empty:
            logger.debug("No recent %s trading data found", gov_type)
            return

        df_gov["min"] = df_gov["Range"].apply(
            lambda x: x.split("-")[0].strip("$").replace(",", "").strip())
        df_gov["max"] = df_gov["Range"].apply(
            lambda x: x.split("-")[1].replace(",", "").strip().strip("$")
            if "-" in x else x.strip("$").replace(",", "").split("\n")[0])

        df_gov["lower"] = df_gov[["min", "max", "Transaction"]].apply(
            lambda x: int(float(x["min"]))
            if x["Transaction"] == "Purchase" else -int(float(x["max"])),
            axis=1,
        )
        df_gov["upper"] = df_gov[["min", "max", "Transaction"]].apply(
            lambda x: int(float(x["max"]))
            if x["Transaction"] == "Purchase" else -1 * int(float(x["min"])),
            axis=1,
        )

        df_gov = df_gov.sort_values("TransactionDate", ascending=True)
        plt.style.use("seaborn")

        fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)

        ax.fill_between(
            df_gov["TransactionDate"].unique(),
            df_gov.groupby("TransactionDate")["lower"].sum().values / 1000,
            df_gov.groupby("TransactionDate")["upper"].sum().values / 1000,
        )

        ax.set_xlim([
            df_gov["TransactionDate"].values[0],
            df_gov["TransactionDate"].values[-1],
        ])
        ax.grid()
        ax.set_title(f"{gov_type.capitalize()} trading on {ticker}")
        ax.set_xlabel("Date")
        ax.set_ylabel("Amount ($1k)")
        plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%Y/%m/%d"))
        plt.gcf().autofmt_xdate()
        fig.tight_layout()

        plt.savefig("gov_gtrades.png")
        imagefile = "gov_gtrades.png"

        img = Image.open(imagefile)
        print(img.size)
        im_bg = Image.open(cfg.IMG_BG)
        h = img.height + 240
        w = img.width + 520

        img = img.resize((w, h), Image.ANTIALIAS)
        x1 = int(0.5 * im_bg.size[0]) - int(0.5 * img.size[0])
        y1 = int(0.5 * im_bg.size[1]) - int(0.5 * img.size[1])
        x2 = int(0.5 * im_bg.size[0]) + int(0.5 * img.size[0])
        y2 = int(0.5 * im_bg.size[1]) + int(0.5 * img.size[1])
        img = img.convert("RGB")
        im_bg.paste(img, box=(x1 - 5, y1, x2 - 5, y2))
        im_bg.save(imagefile, "PNG", quality=100)

        image = Image.open(imagefile)
        image = autocrop_image(image, 0)
        image.save(imagefile, "PNG", quality=100)

        uploaded_image = gst_imgur.upload_image("gov_gtrades.png",
                                                title="something")
        image_link = uploaded_image.link
        if cfg.DEBUG:
            logger.debug("Image URL: %s", image_link)
        title = "Stocks: [quiverquant.com] Government Trades"
        if raw:
            description = df_gov.to_string()
            embed = disnake.Embed(title=title,
                                  description=description,
                                  colour=cfg.COLOR)
        else:
            embed = disnake.Embed(title=title, colour=cfg.COLOR)
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )
        embed.set_image(url=image_link)
        os.remove("gov_gtrades.png")

        await ctx.send(embed=embed)

    except Exception as e:
        embed = disnake.Embed(
            title="ERROR Stocks: [quiverquant.com] Government Trades",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 4
0
async def topbuys_command(
    ctx,
    gov_type="",
    past_transactions_months: int = 5,
    num: int = 20,
    raw: bool = False,
):
    """Displays most purchased stocks by the congress/senate/house [quiverquant.com]"""
    try:
        # Debug user input
        if cfg.DEBUG:
            logger.debug(
                "!stocks.gov.topbuys %s %s %s %s",
                gov_type,
                past_transactions_months,
                num,
                raw,
            )

        possible_args = ["congress", "senate", "house"]
        if gov_type == "":
            gov_type = "congress"
        elif gov_type not in possible_args:
            raise Exception(
                "Enter a valid government argument, options are: congress, senate and house"
            )

        # Retrieve Data
        df_gov = quiverquant_model.get_government_trading(gov_type)

        if df_gov.empty:
            logger.debug("No %s trading data found", gov_type)
            return

        df_gov = df_gov.sort_values("TransactionDate", ascending=False)
        start_date = datetime.now() - timedelta(days=past_transactions_months *
                                                30)

        df_gov["TransactionDate"] = pd.to_datetime(df_gov["TransactionDate"])

        df_gov = df_gov[df_gov["TransactionDate"] > start_date].dropna()
        # Catch bug where error shown for purchase of >5,000,000
        df_gov["Range"] = df_gov["Range"].apply(
            lambda x: "$5,000,001-$5,000,001" if x == ">$5,000,000" else x)
        df_gov["min"] = df_gov["Range"].apply(
            lambda x: x.split("-")[0].strip("$").replace(",", "").strip())
        df_gov["max"] = df_gov["Range"].apply(
            lambda x: x.split("-")[1].replace(",", "").strip().strip("$")
            if "-" in x else x.strip("$").replace(",", ""))
        df_gov["lower"] = df_gov[["min", "max", "Transaction"]].apply(
            lambda x: float(x["min"])
            if x["Transaction"] == "Purchase" else -float(x["max"]),
            axis=1,
        )
        df_gov["upper"] = df_gov[["min", "max", "Transaction"]].apply(
            lambda x: float(x["max"])
            if x["Transaction"] == "Purchase" else -float(x["min"]),
            axis=1,
        )

        df_gov = df_gov.sort_values("TransactionDate", ascending=True)
        if raw:
            df = pd.DataFrame(
                df_gov.groupby("Ticker")["upper"].sum().div(1000).sort_values(
                    ascending=False).head(n=num))
            description = "```" + df.to_string() + "```"

        plt.style.use("seaborn")
        fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)

        df_gov.groupby("Ticker")["upper"].sum().div(1000).sort_values(
            ascending=False).head(n=num).plot(kind="bar", rot=0, ax=ax)

        ax.set_ylabel("Amount [1k $]")
        ax.set_title(
            f"Top {num} purchased stocks over last {past_transactions_months} "
            f"months (upper bound) for {gov_type.upper()}")
        plt.gcf().axes[0].yaxis.get_major_formatter().set_scientific(False)
        fig.tight_layout()

        plt.savefig("gov_topbuys.png")
        imagefile = "gov_topbuys.png"

        img = Image.open(imagefile)
        print(img.size)
        im_bg = Image.open(cfg.IMG_BG)
        h = img.height + 240
        w = img.width + 520

        img = img.resize((w, h), Image.ANTIALIAS)
        x1 = int(0.5 * im_bg.size[0]) - int(0.5 * img.size[0])
        y1 = int(0.5 * im_bg.size[1]) - int(0.5 * img.size[1])
        x2 = int(0.5 * im_bg.size[0]) + int(0.5 * img.size[0])
        y2 = int(0.5 * im_bg.size[1]) + int(0.5 * img.size[1])
        img = img.convert("RGB")
        im_bg.paste(img, box=(x1 - 5, y1, x2 - 5, y2))
        im_bg.save(imagefile, "PNG", quality=100)

        image = Image.open(imagefile)
        image = autocrop_image(image, 0)
        image.save(imagefile, "PNG", quality=100)

        uploaded_image = gst_imgur.upload_image("gov_topbuys.png",
                                                title="something")
        image_link = uploaded_image.link
        if cfg.DEBUG:
            logger.debug("Image URL: %s", image_link)
        title = f"Stocks: [quiverquant.com] Top purchases for {gov_type.upper()}"
        if raw:
            embed = disnake.Embed(title=title,
                                  description=description,
                                  colour=cfg.COLOR)
        else:
            embed = disnake.Embed(title=title, colour=cfg.COLOR)
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )
        embed.set_image(url=image_link)
        os.remove("gov_topbuys.png")

        await ctx.send(embed=embed)

    except Exception as e:
        embed = disnake.Embed(
            title=
            f"ERROR Stocks: [quiverquant.com] Top purchases for {gov_type.upper()}",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 5
0
async def chain_command(
    ctx,
    ticker: str = None,
    expiry: str = None,
    opt_type: str = None,
    min_sp: float = None,
    max_sp: float = None,
):
    """Show calls/puts for given ticker and expiration"""
    try:
        # Debug
        if cfg.DEBUG:
            logger.debug("opt-chain %s %s %s %s %s", ticker, expiry, opt_type,
                         min_sp, max_sp)

        # Check for argument
        if not ticker:
            raise Exception("Stock ticker is required")

        dates = yfinance_model.option_expirations(ticker)

        if not dates:
            raise Exception("Stock ticker is invalid")

        options = yfinance_model.get_option_chain(ticker, str(expiry))
        calls_df = options.calls
        puts_df = options.puts

        column_map = {
            "openInterest": "oi",
            "volume": "vol",
            "impliedVolatility": "iv"
        }
        columns = [
            "strike",
            "bid",
            "ask",
            "volume",
            "openInterest",
            "impliedVolatility",
        ]

        if opt_type == "Calls":
            df = calls_df[columns].rename(columns=column_map)
        if opt_type == "Puts":
            df = puts_df[columns].rename(columns=column_map)

        min_strike = np.percentile(df["strike"], 1)
        max_strike = np.percentile(df["strike"], 100)

        if min_sp:
            min_strike = min_sp
        if max_sp:
            max_strike = max_sp
            if min_sp > max_sp:  # type: ignore
                min_sp, max_sp = max_strike, min_strike

        df = df[df["strike"] >= min_strike]
        df = df[df["strike"] <= max_strike]

        df["iv"] = pd.to_numeric(df["iv"].astype(float))

        formats = {"iv": "{:.2f}"}
        for col, f in formats.items():
            df[col] = df[col].map(lambda x: f.format(x))  # pylint: disable=W0640
        df.set_index("strike", inplace=True)

        title = f"Stocks: {opt_type} Option Chain for {ticker.upper()} on {expiry} [yfinance]"

        embeds: list = []
        # Weekly Calls Pages
        i, i2, end = 0, 0, 20
        df_pg = []
        embeds_img = []
        dindex = len(df.index)
        while i < dindex:
            df_pg = df.iloc[i:end]
            df_pg.append(df_pg)
            figp = df2img.plot_dataframe(
                df_pg,
                fig_size=(1000, (40 + (40 * 20))),
                col_width=[3, 3, 3, 3],
                tbl_cells=dict(height=35, ),
                font=dict(
                    family="Consolas",
                    size=20,
                ),
                template="plotly_dark",
                paper_bgcolor="rgba(0, 0, 0, 0)",
            )
            imagefile = f"opt-chain{i}.png"

            df2img.save_dataframe(fig=figp, filename=imagefile)
            image = Image.open(imagefile)
            image = autocrop_image(image, 0)
            image.save(imagefile, "PNG", quality=100)

            uploaded_image = gst_imgur.upload_image(imagefile,
                                                    title="something")
            image_link = uploaded_image.link
            embeds_img.append(f"{image_link}", )
            embeds.append(disnake.Embed(
                title=title,
                colour=cfg.COLOR,
            ), )
            i2 += 1
            i += 20
            end += 20
            os.remove(imagefile)

        # Author/Footer
        for i in range(0, i2):
            embeds[i].set_author(
                name=cfg.AUTHOR_NAME,
                url=cfg.AUTHOR_URL,
                icon_url=cfg.AUTHOR_ICON_URL,
            )
            embeds[i].set_footer(
                text=cfg.AUTHOR_NAME,
                icon_url=cfg.AUTHOR_ICON_URL,
            )

        i = 0
        for i in range(0, i2):
            embeds[i].set_image(url=embeds_img[i])

            i += 1
        embeds[0].set_footer(text=f"Page 1 of {len(embeds)}")
        options = [
            disnake.SelectOption(label="Home", value="0", emoji="🟢"),
        ]

        await ctx.send(embed=embeds[0], view=Menu(embeds, options))

    except Exception as e:
        embed = disnake.Embed(
            title="ERROR Stock-Options: Expirations",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )
        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 6
0
async def arktrades_command(ctx, ticker: str = "", num: int = 10):
    """Displays trades made by ark [cathiesark.com]"""

    try:
        # Debug user input
        if cfg.DEBUG:
            logger.debug("!stocks.dd.arktrades %s", ticker)

        if ticker:
            ark_holdings = ark_model.get_ark_trades_by_ticker(ticker)
            ark_holdings = ark_holdings.drop(
                columns=["ticker", "everything.profile.companyName"])

        if ark_holdings.empty:
            raise Exception(
                "Issue getting data from cathiesark.com. Likely no trades found.\n"
            )

        ark_holdings["Total"] = ark_holdings["Total"] / 1_000_000
        ark_holdings.rename(columns={
            "direction": "B/S",
            "weight": "F %"
        },
                            inplace=True)

        ark_holdings.index = pd.Series(
            ark_holdings.index).apply(lambda x: x.strftime("%Y-%m-%d"))

        df = ark_holdings.head(num)
        dindex = len(df.head(num).index)
        formats = {"Close": "{:.2f}", "Total": "{:.2f}"}
        for col, f in formats.items():
            df[col] = df[col].map(lambda x: f.format(x))  # pylint: disable=W0640

        title = f"Stocks: [cathiesark.com] {ticker.upper()} Trades by Ark"

        embeds: list = []

        i, i2, end = 0, 0, 20
        df_pg = []
        embeds_img = []
        dindex = len(df.index)
        while i < dindex:
            df_pg = df.iloc[i:end]
            df_pg.append(df_pg)
            fig = df2img.plot_dataframe(
                df_pg,
                fig_size=(900, (40 + (40 * 20))),
                col_width=[5, 10, 4, 4, 3, 4, 5],
                tbl_cells=dict(height=35, ),
                font=dict(
                    family="Consolas",
                    size=20,
                ),
                template="plotly_dark",
                paper_bgcolor="rgba(0, 0, 0, 0)",
            )
            imagefile = f"disc-insider{i}.png"

            df2img.save_dataframe(fig=fig, filename=imagefile)
            image = Image.open(imagefile)
            image = autocrop_image(image, 0)
            image.save(imagefile, "PNG", quality=100)
            uploaded_image = gst_imgur.upload_image(imagefile,
                                                    title="something")
            image_link = uploaded_image.link
            embeds_img.append(f"{image_link}", )
            embeds.append(disnake.Embed(
                title=title,
                colour=cfg.COLOR,
            ), )
            i2 += 1
            i += 20
            end += 20
            os.remove(imagefile)

        # Author/Footer
        for i in range(0, i2):
            embeds[i].set_author(
                name=cfg.AUTHOR_NAME,
                url=cfg.AUTHOR_URL,
                icon_url=cfg.AUTHOR_ICON_URL,
            )
            embeds[i].set_footer(
                text=cfg.AUTHOR_NAME,
                icon_url=cfg.AUTHOR_ICON_URL,
            )

        i = 0
        for i in range(0, i2):
            embeds[i].set_image(url=embeds_img[i])

            i += 1
        embeds[0].set_footer(text=f"Page 1 of {len(embeds)}")
        options = [
            disnake.SelectOption(label="Home", value="0", emoji="🟢"),
        ]

        await ctx.send(embed=embeds[0], view=Menu(embeds, options))

    except Exception as e:
        embed = disnake.Embed(
            title=f"ERROR Stocks: [cathiesark.com] {ticker} Trades by Ark",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 7
0
async def dpotc_command(ctx, ticker: str = ""):
    """Dark pools (ATS) vs OTC data [FINRA]"""

    try:
        # Debug user input
        if cfg.DEBUG:
            logger.debug("!stocks.dps.dpotc %s", ticker)

        # Check for argument
        if ticker == "":
            raise Exception("Stock ticker is required")

        ticker = ticker.upper()

        stock = yf.download(ticker, progress=False)
        if stock.empty:
            raise Exception("Stock ticker is invalid")

        # Retrieve data
        ats, otc = finra_model.getTickerFINRAdata(ticker)

        # Debug user output
        if cfg.DEBUG:
            logger.debug(ats.to_string())
            logger.debug(otc.to_string())

        # Output data
        title = f"Stocks: [FINRA] Dark Pools (ATS) vs OTC {ticker}"
        embed = disnake.Embed(title=title, colour=cfg.COLOR)
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        plt.style.use("seaborn")
        plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
        if ats.empty and otc.empty:
            raise Exception("Stock ticker is invalid")
        _, _ = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)

        plt.subplot(3, 1, (1, 2))
        if not ats.empty and not otc.empty:
            plt.bar(
                ats.index,
                (ats["totalWeeklyShareQuantity"] +
                 otc["totalWeeklyShareQuantity"]) / 1_000_000,
                color="tab:orange",
            )
            plt.bar(
                otc.index,
                otc["totalWeeklyShareQuantity"] / 1_000_000,
                color="tab:blue",
            )
            plt.legend(["ATS", "OTC"])

        elif not ats.empty:
            plt.bar(
                ats.index,
                ats["totalWeeklyShareQuantity"] / 1_000_000,
                color="tab:orange",
            )
            plt.legend(["ATS"])

        elif not otc.empty:
            plt.bar(
                otc.index,
                otc["totalWeeklyShareQuantity"] / 1_000_000,
                color="tab:blue",
            )
            plt.legend(["OTC"])

        plt.ylabel("Total Weekly Shares [Million]")
        plt.grid(b=True,
                 which="major",
                 color="#666666",
                 linestyle="-",
                 alpha=0.2)
        plt.title(f"Dark Pools (ATS) vs OTC (Non-ATS) Data for {ticker}")

        plt.subplot(313)
        if not ats.empty:
            plt.plot(
                ats.index,
                ats["totalWeeklyShareQuantity"] / ats["totalWeeklyTradeCount"],
                color="tab:orange",
            )
            plt.legend(["ATS"])

            if not otc.empty:
                plt.plot(
                    otc.index,
                    otc["totalWeeklyShareQuantity"] /
                    otc["totalWeeklyTradeCount"],
                    color="tab:blue",
                )
                plt.legend(["ATS", "OTC"])

        else:
            plt.plot(
                otc.index,
                otc["totalWeeklyShareQuantity"] / otc["totalWeeklyTradeCount"],
                color="tab:blue",
            )
            plt.legend(["OTC"])

        plt.ylabel("Shares per Trade")
        plt.grid(b=True,
                 which="major",
                 color="#666666",
                 linestyle="-",
                 alpha=0.2)
        plt.gcf().autofmt_xdate()
        plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%m/%d"))
        plt.gca().xaxis.set_major_locator(mdates.DayLocator(interval=4))
        plt.xlabel("Weeks")
        file_name = ticker + "_dpotc.png"
        plt.savefig(file_name)
        imagefile = file_name

        img = Image.open(imagefile)
        print(img.size)
        im_bg = Image.open(cfg.IMG_BG)
        h = img.height + 240
        w = img.width + 520

        img = img.resize((w, h), Image.ANTIALIAS)
        x1 = int(0.5 * im_bg.size[0]) - int(0.5 * img.size[0])
        y1 = int(0.5 * im_bg.size[1]) - int(0.5 * img.size[1])
        x2 = int(0.5 * im_bg.size[0]) + int(0.5 * img.size[0])
        y2 = int(0.5 * im_bg.size[1]) + int(0.5 * img.size[1])
        img = img.convert("RGB")
        im_bg.paste(img, box=(x1 - 5, y1, x2 - 5, y2))
        im_bg.save(imagefile, "PNG", quality=100)

        image = Image.open(imagefile)
        image = autocrop_image(image, 0)
        image.save(imagefile, "PNG", quality=100)

        plt.close("all")
        uploaded_image = gst_imgur.upload_image(file_name, title="something")
        image_link = uploaded_image.link
        embed.set_image(url=image_link)
        os.remove(file_name)

        await ctx.send(embed=embed)

    except Exception as e:
        embed = disnake.Embed(
            title=f"ERROR Stocks: [FINRA] Dark Pools (ATS) vs OTC {ticker}",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 8
0
async def psi_command(ctx, ticker: str = ""):
    """Price vs short interest volume [Stockgrid]"""

    try:
        # Debug user input
        if cfg.DEBUG:
            logger.debug("!stocks.dps.psi %s", ticker)

        # Check for argument
        if ticker == "":
            raise Exception("Stock ticker is required")

        ticker = ticker.upper()

        stock = yf.download(ticker, progress=False)
        if stock.empty:
            raise Exception("Stock ticker is invalid")

        # Retrieve data
        df, prices = stockgrid_model.get_short_interest_volume(ticker)

        # Debug user output
        if cfg.DEBUG:
            logger.debug(df.to_string())

        # Output data
        title = f"Stocks: [Stockgrid] Price vs Short Interest Volume {ticker}"
        embed = disnake.Embed(title=title, colour=cfg.COLOR)
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )
        plt.style.use("seaborn")
        _, axes = plt.subplots(
            2,
            1,
            figsize=plot_autoscale(),
            dpi=PLOT_DPI,
            gridspec_kw={"height_ratios": [2, 1]},
        )

        axes[0].bar(
            df["date"],
            df["total_volume"] / 1_000_000,
            width=timedelta(days=1),
            color="b",
            alpha=0.4,
            label="Total Volume",
        )
        axes[0].bar(
            df["date"],
            df["short_volume"] / 1_000_000,
            width=timedelta(days=1),
            color="r",
            alpha=0.4,
            label="Short Volume",
        )

        axes[0].set_ylabel("Volume (1M)")
        ax2 = axes[0].twinx()
        ax2.plot(
            df["date"].values,
            prices[len(prices) - len(df):],  # noqa: E203
            c="k",
            label="Price",
        )
        ax2.set_ylabel("Price ($)")

        lines, labels = axes[0].get_legend_handles_labels()
        lines2, labels2 = ax2.get_legend_handles_labels()
        ax2.legend(lines + lines2, labels + labels2, loc="upper left")

        axes[0].grid()
        axes[0].ticklabel_format(style="plain", axis="y")
        plt.title(f"Price vs Short Volume Interest for {ticker}")
        plt.gcf().autofmt_xdate()

        axes[1].plot(
            df["date"].values,
            100 * df["short_volume%"],
            c="green",
            label="Short Vol. %",
        )

        axes[1].set_ylabel("Short Vol. %")

        axes[1].grid(axis="y")
        lines, labels = axes[1].get_legend_handles_labels()
        axes[1].legend(lines, labels, loc="upper left")
        axes[1].set_ylim([0, 100])
        file_name = ticker + "_psi.png"
        plt.savefig(file_name)
        imagefile = file_name

        img = Image.open(imagefile)
        print(img.size)
        im_bg = Image.open(cfg.IMG_BG)
        h = img.height + 240
        w = img.width + 520

        img = img.resize((w, h), Image.ANTIALIAS)
        x1 = int(0.5 * im_bg.size[0]) - int(0.5 * img.size[0])
        y1 = int(0.5 * im_bg.size[1]) - int(0.5 * img.size[1])
        x2 = int(0.5 * im_bg.size[0]) + int(0.5 * img.size[0])
        y2 = int(0.5 * im_bg.size[1]) + int(0.5 * img.size[1])
        img = img.convert("RGB")
        im_bg.paste(img, box=(x1 - 5, y1, x2 - 5, y2))
        im_bg.save(imagefile, "PNG", quality=100)

        image = Image.open(imagefile)
        image = autocrop_image(image, 0)
        image.save(imagefile, "PNG", quality=100)
        plt.close("all")
        uploaded_image = gst_imgur.upload_image(file_name, title="something")
        image_link = uploaded_image.link
        embed.set_image(url=image_link)
        os.remove(file_name)

        await ctx.send(embed=embed)

    except Exception as e:
        embed = disnake.Embed(
            title=
            f"ERROR Stocks: [Stockgrid] Price vs Short Interest Volume {ticker}",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 9
0
async def donchian_command(ctx,
                           ticker="",
                           upper_length="25",
                           lower_length="100",
                           start="",
                           end=""):
    """Displays chart with donchian channel [Yahoo Finance]"""

    try:

        # Debug
        if cfg.DEBUG:
            logger.debug(
                "!stocks.ta.donchian %s %s %s %s %s",
                ticker,
                upper_length,
                lower_length,
                start,
                end,
            )

        # Check for argument
        if ticker == "":
            raise Exception("Stock ticker is required")

        if start == "":
            start = datetime.now() - timedelta(days=365)
        else:
            start = datetime.strptime(start, cfg.DATE_FORMAT)

        if end == "":
            end = datetime.now()
        else:
            end = datetime.strptime(end, cfg.DATE_FORMAT)

        if not upper_length.lstrip("-").isnumeric():
            raise Exception("Number has to be an integer")
        upper_length = float(upper_length)
        if not lower_length.lstrip("-").isnumeric():
            raise Exception("Number has to be an integer")
        lower_length = float(lower_length)

        ticker = ticker.upper()
        df_stock = discordbot.helpers.load(ticker, start)
        if df_stock.empty:
            raise Exception("Stock ticker is invalid")

        # Retrieve Data
        df_stock = df_stock.loc[(df_stock.index >= start)
                                & (df_stock.index < end)]

        df_ta = volatility_model.donchian(df_stock["High"], df_stock["Low"],
                                          upper_length, lower_length)

        # Output Data
        plt.style.use("seaborn")
        fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
        ax.plot(df_stock.index, df_stock["Adj Close"].values, color="k", lw=3)
        ax.plot(df_ta.index,
                df_ta.iloc[:, 0].values,
                "b",
                lw=1.5,
                label="upper")
        ax.plot(df_ta.index, df_ta.iloc[:, 1].values, "b", lw=1.5, ls="--")
        ax.plot(df_ta.index,
                df_ta.iloc[:, 2].values,
                "b",
                lw=1.5,
                label="lower")
        ax.set_title(f"{ticker} donchian")
        ax.set_xlim(df_stock.index[0], df_stock.index[-1])
        ax.set_xlabel("Time")
        ax.set_ylabel("Price ($)")

        ax.legend(
            [ticker, df_ta.columns[0], df_ta.columns[1], df_ta.columns[2]])
        ax.fill_between(
            df_ta.index,
            df_ta.iloc[:, 0].values,
            df_ta.iloc[:, 2].values,
            alpha=0.1,
            color="b",
        )
        ax.grid(b=True, which="major", color="#666666", linestyle="-")

        plt.gcf().autofmt_xdate()
        fig.tight_layout(pad=1)

        plt.legend()

        plt.savefig("ta_donchian.png")
        imagefile = "ta_donchian.png"

        img = Image.open(imagefile)
        print(img.size)
        im_bg = Image.open(cfg.IMG_BG)
        h = img.height + 240
        w = img.width + 520

        img = img.resize((w, h), Image.ANTIALIAS)
        x1 = int(0.5 * im_bg.size[0]) - int(0.5 * img.size[0])
        y1 = int(0.5 * im_bg.size[1]) - int(0.5 * img.size[1])
        x2 = int(0.5 * im_bg.size[0]) + int(0.5 * img.size[0])
        y2 = int(0.5 * im_bg.size[1]) + int(0.5 * img.size[1])
        img = img.convert("RGB")
        im_bg.paste(img, box=(x1 - 5, y1, x2 - 5, y2))
        im_bg.save(imagefile, "PNG", quality=100)

        image = Image.open(imagefile)
        image = discordbot.helpers.autocrop_image(image, 0)
        image.save(imagefile, "PNG", quality=100)

        uploaded_image = gst_imgur.upload_image("ta_donchian.png",
                                                title="something")
        image_link = uploaded_image.link
        if cfg.DEBUG:
            logger.debug("Image URL: %s", image_link)
        title = "Stocks: Donchian-Channels " + ticker
        embed = disnake.Embed(title=title, colour=cfg.COLOR)
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )
        embed.set_image(url=image_link)
        os.remove("ta_donchian.png")

        await ctx.send(embed=embed)

    except Exception as e:
        embed = disnake.Embed(
            title="ERROR Stocks: Donchian-Channels",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 10
0
async def est_command(ctx, ticker: str = ""):
    """Displays earning estimates [Business Insider]"""

    try:

        # Debug
        if cfg.DEBUG:
            logger.debug("!stocks.dd.est %s", ticker)

        # Check for argument
        if ticker == "":
            raise Exception("Stock ticker is required")

        (
            df_year_estimates,
            df_quarter_earnings,
            df_quarter_revenues,
        ) = business_insider_model.get_estimates(ticker)

        if (df_quarter_revenues.empty and df_year_estimates.empty
                and df_quarter_earnings.empty):
            raise Exception("Enter a valid ticker")

        # Debug user output
        if cfg.DEBUG:
            logger.debug(df_year_estimates.to_string())
            logger.debug(df_quarter_earnings.to_string())
            logger.debug(df_quarter_revenues.to_string())

        dindex = len(df_year_estimates.index)
        fig = df2img.plot_dataframe(
            df_year_estimates,
            fig_size=(1200, (40 + (60 * dindex))),
            col_width=[12, 4, 4, 4, 4],
            tbl_cells=dict(height=35, ),
            font=dict(
                family="Consolas",
                size=20,
            ),
            template="plotly_dark",
            paper_bgcolor="rgba(0, 0, 0, 0)",
        )
        imagefile = "estimates.png"

        df2img.save_dataframe(fig=fig, filename=imagefile)
        image = Image.open(imagefile)
        image = autocrop_image(image, 0)
        image.save(imagefile, "PNG", quality=100)
        uploaded_image = gst_imgur.upload_image(imagefile, title="something")
        link_estimates = uploaded_image.link

        os.remove(imagefile)

        fig = df2img.plot_dataframe(
            df_quarter_earnings,
            fig_size=(1200, (40 + (40 * 20))),
            col_width=[5, 5, 4, 4, 5, 4],
            tbl_cells=dict(height=35, ),
            font=dict(
                family="Consolas",
                size=20,
            ),
            template="plotly_dark",
            paper_bgcolor="rgba(0, 0, 0, 0)",
        )
        imagefile = "earnings.png"

        df2img.save_dataframe(fig=fig, filename=imagefile)
        image = Image.open(imagefile)
        image = autocrop_image(image, 0)
        image.save(imagefile, "PNG", quality=100)
        uploaded_image = gst_imgur.upload_image(imagefile, title="something")
        link_earnings = uploaded_image.link
        os.remove(imagefile)

        fig = df2img.plot_dataframe(
            df_quarter_revenues,
            fig_size=(1200, (40 + (40 * 20))),
            col_width=[5, 5, 4, 4, 5, 4],
            tbl_cells=dict(height=35, ),
            font=dict(
                family="Consolas",
                size=20,
            ),
            template="plotly_dark",
            paper_bgcolor="rgba(0, 0, 0, 0)",
        )
        imagefile = "revenues.png"

        df2img.save_dataframe(fig=fig, filename=imagefile)
        image = Image.open(imagefile)
        image = autocrop_image(image, 0)
        image.save(imagefile, "PNG", quality=100)
        uploaded_image = gst_imgur.upload_image(imagefile, title="something")
        link_revenues = uploaded_image.link
        os.remove(imagefile)

        embeds = [
            disnake.Embed(
                title=f"**{ticker.upper()} Year Estimates**",
                color=cfg.COLOR,
            ),
            disnake.Embed(
                title=f"**{ticker.upper()} Quarter Earnings**",
                colour=cfg.COLOR,
            ),
            disnake.Embed(
                title=f"**{ticker.upper()} Quarter Revenues**",
                colour=cfg.COLOR,
            ),
        ]
        embeds[0].set_image(url=link_estimates)
        embeds[1].set_image(url=link_earnings)
        embeds[2].set_image(url=link_revenues)
        # Output data
        choices = [
            disnake.SelectOption(label=f"{ticker.upper()} Year Estimates",
                                 value="0",
                                 emoji="🟢"),
            disnake.SelectOption(label=f"{ticker.upper()} Quarter Earnings",
                                 value="1",
                                 emoji="🟢"),
            disnake.SelectOption(label=f"{ticker.upper()} Quarter Revenues",
                                 value="2",
                                 emoji="🟢"),
        ]

        await ctx.send(embed=embeds[0], view=Menu(embeds, choices))
    except Exception as e:
        embed = disnake.Embed(
            title="ERROR Stocks: [Business Insider] Earning Estimates",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 11
0
async def qtrcontracts_command(ctx, num: int = 20, analysis=""):
    """Displays a look at government contracts [quiverquant.com]"""
    try:
        # Debug user input
        if cfg.DEBUG:
            logger.debug("!stocks.gov.qtrcontracts %s %s", num, analysis)

        possible_args = ["total", "upmom", "downmom"]
        if analysis == "":
            analysis = "total"
        elif analysis not in possible_args:
            raise Exception(
                "Enter a valid analysis argument, options are: total, upmom and downmom"
            )

        # Retrieve Data
        df_contracts = quiverquant_model.get_government_trading(
            "quarter-contracts")

        if df_contracts.empty:
            raise Exception("No quarterly government contracts found")

        tickers = quiverquant_model.analyze_qtr_contracts(analysis, num)
        plt.style.use("seaborn")

        # Output Data
        if analysis in {"upmom", "downmom"}:
            description = tickers.to_string()
            fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
            max_amount = 0
            quarter_ticks = []
            for symbol in tickers:
                amounts = (
                    df_contracts[df_contracts["Ticker"] == symbol].sort_values(
                        by=["Year", "Qtr"])["Amount"].values)

                qtr = (
                    df_contracts[df_contracts["Ticker"] == symbol].sort_values(
                        by=["Year", "Qtr"])["Qtr"].values)
                year = (
                    df_contracts[df_contracts["Ticker"] == symbol].sort_values(
                        by=["Year", "Qtr"])["Year"].values)

                ax.plot(np.arange(0, len(amounts)),
                        amounts / 1_000_000,
                        "-*",
                        lw=2,
                        ms=15)

                if len(amounts) > max_amount:
                    max_amount = len(amounts)
                    quarter_ticks = [
                        f"{quarter[0]} - Q{quarter[1]} "
                        for quarter in zip(year, qtr)
                    ]

            ax.set_xlim([-0.5, max_amount - 0.5])
            ax.set_xticks(np.arange(0, max_amount))
            ax.set_xticklabels(quarter_ticks)
            ax.grid()
            ax.legend(tickers)
            titles = {
                "upmom": "Highest increasing quarterly Government Contracts",
                "downmom": "Highest decreasing quarterly Government Contracts",
            }
            ax.set_title(titles[analysis])
            ax.set_xlabel("Date")
            ax.set_ylabel("Amount ($1M)")
            fig.tight_layout()

            plt.savefig("gov_qtrcontracts.png")
            imagefile = "gov_qtrcontracts.png"

            img = Image.open(imagefile)
            print(img.size)
            im_bg = Image.open(cfg.IMG_BG)
            h = img.height + 240
            w = img.width + 520

            img = img.resize((w, h), Image.ANTIALIAS)
            x1 = int(0.5 * im_bg.size[0]) - int(0.5 * img.size[0])
            y1 = int(0.5 * im_bg.size[1]) - int(0.5 * img.size[1])
            x2 = int(0.5 * im_bg.size[0]) + int(0.5 * img.size[0])
            y2 = int(0.5 * im_bg.size[1]) + int(0.5 * img.size[1])
            img = img.convert("RGB")
            im_bg.paste(img, box=(x1 - 5, y1, x2 - 5, y2))
            im_bg.save(imagefile, "PNG", quality=100)

            image = Image.open(imagefile)
            image = autocrop_image(image, 0)
            image.save(imagefile, "PNG", quality=100)

            uploaded_image = gst_imgur.upload_image("gov_qtrcontracts.png",
                                                    title="something")
            image_link = uploaded_image.link
            if cfg.DEBUG:
                logger.debug("Image URL: %s", image_link)
            title = "Stocks: [quiverquant.com] Government contracts"
            embed = disnake.Embed(title=title,
                                  description=description,
                                  colour=cfg.COLOR)
            embed.set_author(
                name=cfg.AUTHOR_NAME,
                icon_url=cfg.AUTHOR_ICON_URL,
            )
            embed.set_image(url=image_link)
            os.remove("gov_qtrcontracts.png")

            await ctx.send(embed=embed)

        elif analysis == "total":

            tickers.index = [
                ind + " " * (7 - len(ind)) for ind in tickers.index
            ]
            tickers[:] = [
                str(round(val[0] / 1e9, 2)) for val in tickers.values
            ]
            tickers.columns = ["Amount [M]"]

            embed = disnake.Embed(
                title="Stocks: [quiverquant.com] Government contracts",
                description=tickers.to_string(),
                colour=cfg.COLOR,
            )
            embed.set_author(
                name=cfg.AUTHOR_NAME,
                icon_url=cfg.AUTHOR_ICON_URL,
            )

            await ctx.send(embed=embed)

    except Exception as e:
        embed = disnake.Embed(
            title="ERROR Stocks: [quiverquant.com] Government contracts",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 12
0
async def lins_command(ctx, ticker: str = "", num: int = 10):
    """Display insider activity for a given stock ticker. [Source: Finviz]

    Parameters
    ----------
    ticker : Stock Ticker
    num : Number of latest insider activity to display
    """
    try:
        # Debug
        if cfg.DEBUG:
            logger.debug("disc-lins %s", num)

        d_finviz_insider = finviz_model.get_last_insider_activity(ticker)

        df = pd.DataFrame.from_dict(d_finviz_insider)
        df.set_index("Date", inplace=True)

        df = df[
            [
                "Relationship",
                "Transaction",
                "#Shares",
                "Cost",
                "Value ($)",
                "#Shares Total",
                "Insider Trading",
                "SEC Form 4",
            ]
        ]

        df = df.head(num)
        df = df.replace(to_replace="Option Exercise", value="Opt Ex.", regex=True)

        title = f"Insider Trading for {ticker.upper()}"

        embeds: list = []

        i, i2, end = 0, 0, 20
        df_pg = []
        embeds_img = []
        dindex = len(df.index)
        while i < dindex:
            df_pg = df.iloc[i:end]
            df_pg.append(df_pg)
            fig = df2img.plot_dataframe(
                df_pg,
                fig_size=(1600, (40 + (40 * 20))),
                col_width=[5, 14, 4, 4, 3, 4, 5, 8, 7],
                tbl_cells=dict(
                    height=35,
                ),
                font=dict(
                    family="Consolas",
                    size=20,
                ),
                template="plotly_dark",
                paper_bgcolor="rgba(0, 0, 0, 0)",
            )
            imagefile = f"disc-insider{i}.png"

            df2img.save_dataframe(fig=fig, filename=imagefile)
            image = Image.open(imagefile)
            image = autocrop_image(image, 0)
            image.save(imagefile, "PNG", quality=100)
            uploaded_image = gst_imgur.upload_image(imagefile, title="something")
            image_link = uploaded_image.link
            embeds_img.append(
                f"{image_link}",
            )
            embeds.append(
                disnake.Embed(
                    title=title,
                    colour=cfg.COLOR,
                ),
            )
            i2 += 1
            i += 20
            end += 20
            os.remove(imagefile)

        # Author/Footer
        for i in range(0, i2):
            embeds[i].set_author(
                name=cfg.AUTHOR_NAME,
                url=cfg.AUTHOR_URL,
                icon_url=cfg.AUTHOR_ICON_URL,
            )
            embeds[i].set_footer(
                text=cfg.AUTHOR_NAME,
                icon_url=cfg.AUTHOR_ICON_URL,
            )

        i = 0
        for i in range(0, i2):
            embeds[i].set_image(url=embeds_img[i])

            i += 1
        embeds[0].set_footer(text=f"Page 1 of {len(embeds)}")
        options = [
            disnake.SelectOption(label="Home", value="0", emoji="🟢"),
        ]

        await ctx.send(embed=embeds[0], view=Menu(embeds, options))

    except Exception as e:
        embed = disnake.Embed(
            title="ERROR Insider Activity [Source: Finviz]",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 13
0
async def spos_command(ctx, ticker: str = ""):
    """Net short vs position [Stockgrid]"""

    try:
        # Debug user input
        if cfg.DEBUG:
            logger.debug("!stocks.dps.spos %s", ticker)

        # Check for argument
        if ticker == "":
            raise Exception("Stock ticker is required")

        ticker = ticker.upper()

        stock = yf.download(ticker, progress=False)
        if stock.empty:
            raise Exception("Stock ticker is invalid")

        # Retrieve data
        df = stockgrid_model.get_net_short_position(ticker)

        # Debug user output
        if cfg.DEBUG:
            logger.debug(df.to_string())

        # Output data
        title = f"Stocks: [Stockgrid] Net Short vs Position {ticker}"
        embed = disnake.Embed(title=title, colour=cfg.COLOR)
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )
        plt.style.use("seaborn")
        fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)

        ax = fig.add_subplot(111)
        ax.bar(
            df["dates"],
            df["dollar_net_volume"] / 1_000,
            color="r",
            alpha=0.4,
            label="Net Short Vol. (1k $)",
        )
        ax.set_ylabel("Net Short Vol. (1k $)")

        ax2 = ax.twinx()
        ax2.plot(
            df["dates"].values,
            df["dollar_dp_position"],
            c="tab:blue",
            label="Position (1M $)",
        )
        ax2.set_ylabel("Position (1M $)")

        lines, labels = ax.get_legend_handles_labels()
        lines2, labels2 = ax2.get_legend_handles_labels()
        ax2.legend(lines + lines2, labels + labels2, loc="upper left")

        ax.grid()
        plt.title(f"Net Short Vol. vs Position for {ticker}")
        plt.gcf().autofmt_xdate()
        file_name = ticker + "_spos.png"
        plt.savefig(file_name)
        imagefile = file_name

        img = Image.open(imagefile)
        print(img.size)
        im_bg = Image.open(cfg.IMG_BG)
        h = img.height + 240
        w = img.width + 520

        img = img.resize((w, h), Image.ANTIALIAS)
        x1 = int(0.5 * im_bg.size[0]) - int(0.5 * img.size[0])
        y1 = int(0.5 * im_bg.size[1]) - int(0.5 * img.size[1])
        x2 = int(0.5 * im_bg.size[0]) + int(0.5 * img.size[0])
        y2 = int(0.5 * im_bg.size[1]) + int(0.5 * img.size[1])
        img = img.convert("RGB")
        im_bg.paste(img, box=(x1 - 5, y1, x2 - 5, y2))
        im_bg.save(imagefile, "PNG", quality=100)

        image = Image.open(imagefile)
        image = autocrop_image(image, 0)
        image.save(imagefile, "PNG", quality=100)

        plt.close("all")
        uploaded_image = gst_imgur.upload_image(file_name, title="something")
        image_link = uploaded_image.link
        embed.set_image(url=image_link)
        os.remove(file_name)

        await ctx.send(embed=embed)

    except Exception as e:
        embed = disnake.Embed(
            title=f"ERROR Stocks: [Stockgrid] Net Short vs Position {ticker}",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 14
0
async def toplobbying_command(ctx, num: int = 10, raw: bool = False):
    """Displays top lobbying firms [quiverquant.com]"""
    try:
        # Debug user input
        if cfg.DEBUG:
            logger.debug("!stocks.gov.toplobbying %s %s", num, raw)

        # Retrieve Data
        df_lobbying = quiverquant_model.get_government_trading(
            "corporate-lobbying")

        if df_lobbying.empty:
            raise Exception("No corporate lobbying found")

        df_lobbying["Amount"] = df_lobbying.Amount.astype(float).fillna(
            0) / 100_000

        lobbying_by_ticker = pd.DataFrame(
            df_lobbying.groupby("Ticker")["Amount"].agg("sum")).sort_values(
                by="Amount", ascending=False)
        plt.style.use("seaborn")
        fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
        lobbying_by_ticker.head(num).plot(kind="bar", ax=ax)
        ax.set_xlabel("Ticker")
        ax.set_ylabel("Total Amount ($100k)")
        ax.set_title(
            f"Corporate Lobbying Spent since {df_lobbying['Date'].min()}")
        fig.tight_layout()

        plt.savefig("ta_toplobbying.png")
        imagefile = "ta_toplobbying.png"

        img = Image.open(imagefile)
        print(img.size)
        im_bg = Image.open(cfg.IMG_BG)
        h = img.height + 240
        w = img.width + 520

        img = img.resize((w, h), Image.ANTIALIAS)
        x1 = int(0.5 * im_bg.size[0]) - int(0.5 * img.size[0])
        y1 = int(0.5 * im_bg.size[1]) - int(0.5 * img.size[1])
        x2 = int(0.5 * im_bg.size[0]) + int(0.5 * img.size[0])
        y2 = int(0.5 * im_bg.size[1]) + int(0.5 * img.size[1])
        img = img.convert("RGB")
        im_bg.paste(img, box=(x1 - 5, y1, x2 - 5, y2))
        im_bg.save(imagefile, "PNG", quality=100)

        image = Image.open(imagefile)
        image = autocrop_image(image, 0)
        image.save(imagefile, "PNG", quality=100)

        uploaded_image = gst_imgur.upload_image("ta_toplobbying.png",
                                                title="something")
        image_link = uploaded_image.link
        if cfg.DEBUG:
            logger.debug("Image URL: %s", image_link)
        title = "Stocks: [quiverquant.com] Top Lobbying Firms"
        if raw:
            description = lobbying_by_ticker.head(num).to_string()
            embed = disnake.Embed(title=title,
                                  description=description,
                                  colour=cfg.COLOR)
        else:
            embed = disnake.Embed(title=title, colour=cfg.COLOR)
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )
        embed.set_image(url=image_link)
        os.remove("ta_toplobbying.png")

        await ctx.send(embed=embed)

    except Exception as e:
        embed = disnake.Embed(
            title="ERROR Stocks: [quiverquant.com] Top Lobbying Firms",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 15
0
async def contracts_command(ctx,
                            ticker: str = "",
                            past_transaction_days: int = 10,
                            raw: bool = False):
    """Displays contracts associated with tickers [quiverquant.com]"""
    try:
        # Debug user input
        if cfg.DEBUG:
            logger.debug("!stocks.gov.contracts %s %s %s", ticker,
                         past_transaction_days, raw)

        if ticker == "":
            raise Exception("A ticker is required")

        # Retrieve Data
        df_contracts = quiverquant_model.get_government_trading(
            "contracts", ticker)

        if df_contracts.empty:
            raise Exception("No government contracts found")

        # Output Data
        df_contracts["Date"] = pd.to_datetime(df_contracts["Date"]).dt.date

        df_contracts = df_contracts[df_contracts["Date"].isin(
            df_contracts["Date"].unique()[:past_transaction_days])]

        df_contracts.drop_duplicates(inplace=True)
        plt.style.use("seaborn")

        fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)

        df_contracts.groupby("Date").sum().div(1000).plot(kind="bar",
                                                          rot=0,
                                                          ax=ax)
        ax.set_ylabel("Amount ($1k)")
        ax.set_title(f"Sum of latest government contracts to {ticker}")
        fig.tight_layout()

        plt.savefig("gov_contracts.png")
        imagefile = "gov_contracts.png"

        img = Image.open(imagefile)
        print(img.size)
        im_bg = Image.open(cfg.IMG_BG)
        h = img.height + 240
        w = img.width + 520

        img = img.resize((w, h), Image.ANTIALIAS)
        x1 = int(0.5 * im_bg.size[0]) - int(0.5 * img.size[0])
        y1 = int(0.5 * im_bg.size[1]) - int(0.5 * img.size[1])
        x2 = int(0.5 * im_bg.size[0]) + int(0.5 * img.size[0])
        y2 = int(0.5 * im_bg.size[1]) + int(0.5 * img.size[1])
        img = img.convert("RGB")
        im_bg.paste(img, box=(x1 - 5, y1, x2 - 5, y2))
        im_bg.save(imagefile, "PNG", quality=100)

        image = Image.open(imagefile)
        image = autocrop_image(image, 0)
        image.save(imagefile, "PNG", quality=100)

        uploaded_image = gst_imgur.upload_image("gov_contracts.png",
                                                title="something")
        image_link = uploaded_image.link
        if cfg.DEBUG:
            logger.debug("Image URL: %s", image_link)
        title = f"Stocks: [quiverquant.com] Contracts by {ticker}"
        if raw:
            description = df_contracts.to_string()
            embed = disnake.Embed(title=title,
                                  description=description,
                                  colour=cfg.COLOR)
        else:
            embed = disnake.Embed(title=title, colour=cfg.COLOR)
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )
        embed.set_image(url=image_link)
        os.remove("gov_contracts.png")

        await ctx.send(embed=embed)

    except Exception as e:
        embed = disnake.Embed(
            title=f"ERROR Stocks: [quiverquant.com] Contracts by {ticker}",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 16
0
async def feargreed_command(ctx, indicator=""):
    """CNN Fear and Greed Index [CNN]"""

    try:
        # Debug user input
        if cfg.DEBUG:
            logger.debug("econ-futures")

        # Check for argument
        possible_indicators = ("", "jbd", "mv", "pco", "mm", "sps", "spb", "shd")

        if indicator not in possible_indicators:
            raise Exception(
                f"Select a valid indicator from {', '.join(possible_indicators)}"  # nosec
            )

        # Retrieve data
        fig = plt.figure(figsize=[1, 1], dpi=10)

        report, _ = cnn_model.get_feargreed_report(indicator, fig)
        cnn_view.fear_and_greed_index(indicator=indicator, export="png")
        plt.close("all")

        # Output data
        now = datetime.datetime.now()
        image_path = os.path.join(
            cfg.GST_PATH,
            "exports",
            "economy",
            f"feargreed_{now.strftime('%Y%m%d_%H%M%S')}.png",
        )

        i = 0
        while not os.path.exists(image_path) and i < 10:
            now -= datetime.timedelta(seconds=1)
            image_path = os.path.join(
                cfg.GST_PATH,
                "exports",
                "economy",
                f"feargreed_{now.strftime('%Y%m%d_%H%M%S')}.png",
            )
            i += 1

        embed = disnake.Embed(
            title="Economy: [CNN] Fear Geed Index",
            description=report,
            colour=cfg.COLOR,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        if os.path.exists(image_path):
            uploaded_image = gst_imgur.upload_image(
                image_path, title="FearGreed Charts"
            )
            embed.set_image(url=uploaded_image.link)

        else:
            logger.error("Error when uploading the the image to Imgur.")

        await ctx.send(embed=embed)

    except Exception as e:
        logger.error("ERROR Economy: [CNN] Feargreed. %s", e)
        embed = disnake.Embed(
            title="ERROR Economy: [CNN] Feargreed",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 17
0
async def cg_command(ctx, ticker="", length="14", start="", end=""):
    """Displays chart with centre of gravity [Yahoo Finance]"""

    try:

        # Debug
        if cfg.DEBUG:
            logger.debug(
                "!stocks.ta.cg %s %s %s %s",
                ticker,
                length,
                start,
                end,
            )

        # Check for argument
        if ticker == "":
            raise Exception("Stock ticker is required")

        if start == "":
            start = datetime.now() - timedelta(days=365)
        else:
            start = datetime.strptime(start, cfg.DATE_FORMAT)

        if end == "":
            end = datetime.now()
        else:
            end = datetime.strptime(end, cfg.DATE_FORMAT)

        if not length.lstrip("-").isnumeric():
            raise Exception("Number has to be an integer")
        length = float(length)

        ticker = ticker.upper()
        df_stock = discordbot.helpers.load(ticker, start)
        if df_stock.empty:
            raise Exception("Stock ticker is invalid")

        # Retrieve Data
        df_stock = df_stock.loc[(df_stock.index >= start)
                                & (df_stock.index < end)]
        df_close = df_stock["Adj Close"]
        df_close.columns = ["values"]
        df_ta = momentum_model.cg(df_close, length)

        # Output Data
        plt.style.use("seaborn")
        fig, axes = plt.subplots(2, 1, figsize=plot_autoscale(), dpi=PLOT_DPI)
        ax = axes[0]
        ax.set_title(f"{ticker} Centre of Gravity")
        ax.plot(df_stock.index, df_stock["Adj Close"].values, "k", lw=1)
        ax.set_xlim(df_stock.index[0], df_stock.index[-1])
        ax.set_ylabel("Share Price ($)")
        ax.grid(b=True, which="major", color="#666666", linestyle="-")

        ax2 = axes[1]
        ax2.plot(df_ta.index, df_ta.values, "b", lw=2, label="CG")
        # shift cg 1 bar forward for signal
        signal = df_ta.values
        signal = np.roll(signal, 1)
        ax2.plot(df_ta.index, signal, "g", lw=1, label="Signal")
        ax2.set_xlim(df_stock.index[0], df_stock.index[-1])
        ax2.grid(b=True, which="major", color="#666666", linestyle="-")

        plt.gcf().autofmt_xdate()
        fig.tight_layout(pad=1)
        plt.legend()

        plt.savefig("ta_cg.png")
        imagefile = "ta_cg.png"

        img = Image.open(imagefile)
        print(img.size)
        im_bg = Image.open(cfg.IMG_BG)
        h = img.height + 240
        w = img.width + 520

        img = img.resize((w, h), Image.ANTIALIAS)
        x1 = int(0.5 * im_bg.size[0]) - int(0.5 * img.size[0])
        y1 = int(0.5 * im_bg.size[1]) - int(0.5 * img.size[1])
        x2 = int(0.5 * im_bg.size[0]) + int(0.5 * img.size[0])
        y2 = int(0.5 * im_bg.size[1]) + int(0.5 * img.size[1])
        img = img.convert("RGB")
        im_bg.paste(img, box=(x1 - 5, y1, x2 - 5, y2))
        im_bg.save(imagefile, "PNG", quality=100)

        image = Image.open(imagefile)
        image = discordbot.helpers.autocrop_image(image, 0)
        image.save(imagefile, "PNG", quality=100)

        uploaded_image = gst_imgur.upload_image("ta_cg.png", title="something")
        image_link = uploaded_image.link
        if cfg.DEBUG:
            logger.debug("Image URL: %s", image_link)
        title = "Stocks: Center-of-Gravity " + ticker
        embed = disnake.Embed(title=title, colour=cfg.COLOR)
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )
        embed.set_image(url=image_link)
        os.remove("ta_cg.png")

        await ctx.send(embed=embed)

    except Exception as e:
        embed = disnake.Embed(
            title="ERROR Stocks: Center-of-Gravity",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 18
0
async def overview_command(
    ctx,
    ticker: str = None,
    expiry: str = None,
    min_sp: float = None,
    max_sp: float = None,
):
    """Options Overview"""

    try:

        # Debug
        startTime2 = time.time()
        if cfg.DEBUG:
            print(f"!stocks.opt.iv {ticker} {expiry} {min_sp} {max_sp}")

        # Check for argument
        if ticker is None:
            raise Exception("Stock ticker is required")

        # Get options info/dates, Look for logo_url
        df = get_options_info(ticker)  # Barchart Options IV Overview

        dates = yfinance_model.option_expirations(ticker)  # Expiration dates
        tup = f"{ticker.upper()}"
        url = yf.Ticker(tup).info["logo_url"]
        url += "?raw=true" if url else ""

        if not dates:
            raise Exception("Stock ticker is invalid")

        options = yfinance_model.get_option_chain(ticker, str(expiry))
        calls = options.calls
        puts = options.puts
        current_price = yfinance_model.get_price(ticker)

        min_strike2 = np.percentile(calls["strike"], 1)
        max_strike2 = np.percentile(calls["strike"], 100)
        min_strike = 0.75 * current_price
        max_strike = 1.95 * current_price

        if len(calls) > 40:
            min_strike = 0.75 * current_price
            max_strike = 1.25 * current_price

        if min_sp:
            min_strike = min_sp
            min_strike2 = min_sp
        if max_sp:
            max_strike = max_sp
            max_strike2 = max_sp
            if min_sp > max_sp:  # type: ignore
                min_sp, max_sp = max_strike2, min_strike2

        call_oi = calls.set_index("strike")["openInterest"] / 1000
        put_oi = puts.set_index("strike")["openInterest"] / 1000

        df_opt = pd.merge(call_oi, put_oi, left_index=True, right_index=True)
        df_opt = df_opt.rename(columns={
            "openInterest_x": "OI_call",
            "openInterest_y": "OI_put"
        })

        max_pain = op_helpers.calculate_max_pain(df_opt)
        fig = go.Figure()

        dmax = df_opt[["OI_call", "OI_put"]].values.max()
        dmin = df_opt[["OI_call", "OI_put"]].values.min()
        fig.add_trace(
            go.Scatter(
                x=df_opt.index,
                y=df_opt["OI_call"],
                name="Calls",
                mode="lines+markers",
                line=dict(color="green", width=3),
            ))

        fig.add_trace(
            go.Scatter(
                x=df_opt.index,
                y=df_opt["OI_put"],
                name="Puts",
                mode="lines+markers",
                line=dict(color="red", width=3),
            ))
        fig.add_trace(
            go.Scatter(
                x=[current_price, current_price],
                y=[dmin, dmax],
                mode="lines",
                line=dict(color="gold", width=2),
                name="Current Price",
            ))
        fig.add_trace(
            go.Scatter(
                x=[max_pain, max_pain],
                y=[dmin, dmax],
                mode="lines",
                line=dict(color="grey", width=3, dash="dash"),
                name=f"Max Pain: {max_pain}",
            ))
        fig.update_xaxes(
            range=[min_strike, max_strike],
            constrain="domain",
        )
        fig.update_layout(
            margin=dict(l=0, r=0, t=60, b=20),
            template=cfg.PLT_SCAT_STYLE_TEMPLATE,
            title=f"Open Interest for {ticker.upper()} expiring {expiry}",
            title_x=0.5,
            legend_title="",
            xaxis_title="Strike",
            yaxis_title="Open Interest (1k)",
            xaxis=dict(rangeslider=dict(visible=False), ),
            legend=dict(yanchor="top", y=0.99, xanchor="left", x=0.01),
            dragmode="pan",
        )
        config = dict({"scrollZoom": True})
        imagefile = "opt_oi.png"
        fig.write_image(imagefile)

        plt_link = ""
        if cfg.INTERACTIVE:
            html_ran = random.randint(69, 69420)
            fig.write_html(f"in/oi_{html_ran}.html", config=config)
            plt_link = f"[Interactive]({cfg.INTERACTIVE_URL}/oi_{html_ran}.html)"

        img = Image.open(imagefile)
        im_bg = Image.open(cfg.IMG_BG)

        h = img.height + 240
        w = img.width + 520

        img = img.resize((w, h), Image.ANTIALIAS)
        x1 = int(0.5 * im_bg.size[0]) - int(0.5 * img.size[0])
        y1 = int(0.5 * im_bg.size[1]) - int(0.5 * img.size[1])
        x2 = int(0.5 * im_bg.size[0]) + int(0.5 * img.size[0])
        y2 = int(0.5 * im_bg.size[1]) + int(0.5 * img.size[1])
        img = img.convert("RGB")
        im_bg.paste(img, box=(x1 - 5, y1, x2 - 5, y2))
        im_bg.save(imagefile, "PNG", quality=100)
        image = Image.open(imagefile)
        image = autocrop_image(image, 0)
        image.save(imagefile, "PNG", quality=100)

        uploaded_image_oi = gst_imgur.upload_image(imagefile,
                                                   title="something")
        image_link_oi = uploaded_image_oi.link

        column_map = {
            "openInterest": "oi",
            "volume": "vol",
            "impliedVolatility": "iv"
        }
        columns = [
            "strike",
            "bid",
            "ask",
            "volume",
            "openInterest",
            "impliedVolatility",
        ]

        calls_df = calls[columns].rename(columns=column_map)
        puts_df = puts[columns].rename(columns=column_map)

        calls_df = calls_df[calls_df["strike"] >= min_strike2]
        calls_df = calls_df[calls_df["strike"] <= max_strike2]
        puts_df = puts_df[puts_df["strike"] >= min_strike2]
        puts_df = puts_df[puts_df["strike"] <= max_strike2]

        calls_df["iv"] = pd.to_numeric(calls_df["iv"].astype(float))
        puts_df["iv"] = pd.to_numeric(puts_df["iv"].astype(float))

        formats = {"iv": "{:.2f}"}
        for col, f in formats.items():
            calls_df[col] = calls_df[col].map(lambda x: f.format(x)  # pylint: disable=W0640
                                              )
            puts_df[col] = puts_df[col].map(lambda x: f.format(x)  # pylint: disable=W0640
                                            )

        calls_df.set_index("strike", inplace=True)
        puts_df.set_index("strike", inplace=True)

        if "-" in df.iloc[0, 1]:
            iv = f"```diff\n-             {df.iloc[0, 1]}\n```"
        else:
            iv = f"```yaml\n              {df.iloc[0, 1]}\n```"

        pfix, sfix = f"{ticker.upper()} ", f" expiring {expiry}"
        if expiry == dates[0]:
            pfix = f"{ticker.upper()} Weekly "
            sfix = ""

        embeds = [
            disnake.Embed(
                title=f"{ticker.upper()} Overview",
                color=cfg.COLOR,
            ),
            disnake.Embed(
                title=f"{pfix}Open Interest{sfix}",
                description=plt_link,
                colour=cfg.COLOR,
            ),
        ]
        choices = [
            disnake.SelectOption(label=f"{ticker.upper()} Overview",
                                 value="0",
                                 emoji="🟢"),
            disnake.SelectOption(label=f"{pfix}Open Interest{sfix}",
                                 value="1",
                                 emoji="🟢"),
        ]
        embeds_img = []

        i, i2, end = 0, 0, 20
        df_calls = []
        dindex = len(calls_df.index)
        while i <= dindex:
            df_calls = calls_df.iloc[i:end]
            df_calls.append(df_calls)
            figp = df2img.plot_dataframe(
                df_calls,
                fig_size=(1000, (40 + (40 * 20))),
                col_width=[3, 3, 3, 3],
                tbl_cells=cfg.PLT_TBL_CELLS,
                font=cfg.PLT_TBL_FONT,
                template=cfg.PLT_TBL_STYLE_TEMPLATE,
                paper_bgcolor="rgba(0, 0, 0, 0)",
            )
            imagefile = f"opt-calls{i}.png"

            df2img.save_dataframe(fig=figp, filename=imagefile)
            image = Image.open(imagefile)
            image = autocrop_image(image, 0)
            image.save(imagefile, "PNG", quality=100)
            uploaded_image = gst_imgur.upload_image(imagefile,
                                                    title="something")
            image_link = uploaded_image.link
            embeds_img.append(f"{image_link}", )
            embeds.append(
                disnake.Embed(
                    title=f"{pfix}Calls{sfix}",
                    colour=cfg.COLOR,
                ), )
            i2 += 1
            i += 20
            end += 20
            os.remove(imagefile)

        # Add Calls page field
        i, page, puts_page = 2, 0, 3
        i3 = i2 + 2
        choices.append(
            disnake.SelectOption(label="Calls Page 1", value="2",
                                 emoji="🟢"), )
        for i in range(2, i3):
            page += 1
            puts_page += 1

            embeds[i].add_field(name=f"Calls Page {page}",
                                value="_ _",
                                inline=True)

        # Puts Pages
        i, end = 0, 20
        df_puts = []

        dindex = len(puts_df.index)
        while i <= dindex:
            df_puts = puts_df.iloc[i:end]
            df_puts.append(df_puts)
            figp = df2img.plot_dataframe(
                df_puts,
                fig_size=(1000, (40 + (40 * 20))),
                col_width=[3, 3, 3, 3],
                tbl_cells=cfg.PLT_TBL_CELLS,
                font=cfg.PLT_TBL_FONT,
                template=cfg.PLT_TBL_STYLE_TEMPLATE,
                paper_bgcolor="rgba(0, 0, 0, 0)",
            )
            imagefile = f"opt-puts{i}.png"

            df2img.save_dataframe(fig=figp, filename=imagefile)
            image = Image.open(imagefile)
            image = autocrop_image(image, 0)
            image.save(imagefile, "PNG", quality=100)
            uploaded_image = gst_imgur.upload_image(imagefile,
                                                    title="something")
            image_link = uploaded_image.link
            embeds_img.append(f"{image_link}", )
            embeds.append(
                disnake.Embed(
                    title=f"{pfix}Puts{sfix}",
                    colour=cfg.COLOR,
                ), )
            i2 += 1
            i += 20
            end += 20
            os.remove(imagefile)

        # Add Puts page field
        i, page = 0, 0
        puts_page -= 1
        i2 += 2
        choices.append(
            disnake.SelectOption(label="Puts Page 1",
                                 value=f"{puts_page}",
                                 emoji="🟢"), )
        for i in range(puts_page, i2):
            page += 1
            embeds[i].add_field(name=f"Puts Page {page}",
                                value="_ _",
                                inline=True)

        # Author/Footer
        for i in range(0, i2):
            embeds[i].set_author(
                name=cfg.AUTHOR_NAME,
                url=cfg.AUTHOR_URL,
                icon_url=cfg.AUTHOR_ICON_URL,
            )
            embeds[i].set_footer(
                text=cfg.AUTHOR_NAME,
                icon_url=cfg.AUTHOR_ICON_URL,
            )

        # Set images to Pages
        i = 0
        img_i = 0
        embeds[1].set_image(url=image_link_oi)
        for i in range(2, i2):
            embeds[i].set_image(url=embeds_img[img_i])
            img_i += 1
            i += 1

        if url:
            embeds[0].set_thumbnail(url=f"{url}")
        else:
            embeds[0].set_thumbnail(url=cfg.AUTHOR_ICON_URL)

        # Overview Section
        embeds[0].add_field(name=f"{df.iloc[0, 0]}", value=iv, inline=False)

        embeds[0].add_field(name=f"•{df.iloc[1, 0]}",
                            value=f"```css\n{df.iloc[1, 1]}\n```",
                            inline=True)
        for N in range(2, 6):
            embeds[0].add_field(
                name=f"_ _ _ _ _ _ _ _ _ _ •{df.iloc[N, 0]}",
                value=f"```css\n{df.iloc[N, 1]}\n```",
                inline=True,
            )

        embeds[0].add_field(name="_ _", value="_ _", inline=False)
        for N in range(6, 8):
            embeds[0].add_field(
                name=f"_ _ _ _ _ _ _ _ _ _ •{df.iloc[N, 0]}",
                value=f"```css\n{df.iloc[N, 1]}\n```",
                inline=True,
            )

        embeds[0].add_field(name="_ _", value="_ _", inline=False)
        for N in range(8, 10):
            embeds[0].add_field(
                name=f"_ _ _ _ _ _ _ _ _ _ •{df.iloc[N, 0]}",
                value=f"```css\n{df.iloc[N, 1]}\n```",
                inline=True,
            )

        embeds[0].add_field(name="_ _", value="_ _", inline=False)
        for N in range(10, 12):
            embeds[0].add_field(
                name=f"_ _ _ _ _ _ _ _ _ _ •{df.iloc[N, 0]}",
                value=f"```css\n{df.iloc[N, 1]}\n```",
                inline=True,
            )

        embeds[0].set_footer(text=f"Page 1 of {len(embeds)}")
        executionTime2 = time.time() - startTime2
        print(
            f"\n> {__name__} is finished: time in seconds: {executionTime2}\n")
        await ctx.send(embed=embeds[0], view=Menu(embeds, choices))

    except Exception as e:
        embed = disnake.Embed(
            title="ERROR Options: Overview",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 19
0
async def fib_command(ctx, ticker="", start="", end=""):
    """Displays chart with fibonacci retracement [Yahoo Finance]"""

    try:

        # Debug
        if cfg.DEBUG:
            logger.debug(
                "!stocks.ta.fib %s %s %s",
                ticker,
                start,
                end,
            )

        # Check for argument
        if ticker == "":
            raise Exception("Stock ticker is required")

        if start == "":
            start = datetime.now() - timedelta(days=365)
            f_start = None
        else:
            start = datetime.strptime(start, cfg.DATE_FORMAT)
            f_start = start

        if end == "":
            end = datetime.now()
            f_end = None
        else:
            end = datetime.strptime(end, cfg.DATE_FORMAT)
            f_end = None

        ticker = ticker.upper()
        df_stock = discordbot.helpers.load(ticker, start)
        if df_stock.empty:
            raise Exception("Stock ticker is invalid")

        # Retrieve Data
        df_stock = df_stock.loc[(df_stock.index >= start)
                                & (df_stock.index < end)]

        start = start.strftime("%Y-%m-%d")
        end = end.strftime("%Y-%m-%d")
        (
            df_fib,
            min_date,
            max_date,
            min_pr,
            max_pr,
        ) = custom_indicators_model.calculate_fib_levels(
            df_stock, 120, f_start, f_end)

        levels = df_fib.Price
        plt.style.use("seaborn")
        fig, ax = plt.subplots(figsize=(plot_autoscale()), dpi=cfp.PLOT_DPI)

        ax.plot(df_stock["Adj Close"], "b")
        ax.plot([min_date, max_date], [min_pr, max_pr], c="k")

        for i in levels:
            ax.axhline(y=i, c="g", alpha=0.5)

        for i in range(5):
            ax.fill_between(df_stock.index,
                            levels[i],
                            levels[i + 1],
                            alpha=0.6)

        ax.set_ylabel("Price")
        ax.set_title(f"Fibonacci Support for {ticker.upper()}")
        ax.set_xlim(df_stock.index[0], df_stock.index[-1])

        ax1 = ax.twinx()
        ax1.set_ylim(ax.get_ylim())
        ax1.set_yticks(levels)
        ax1.set_yticklabels([0, 0.235, 0.382, 0.5, 0.618, 1])

        plt.gcf().autofmt_xdate()
        fig.tight_layout(pad=1)

        plt.savefig("ta_fib.png")
        imagefile = "ta_fib.png"

        img = Image.open(imagefile)
        print(img.size)
        im_bg = Image.open(cfg.IMG_BG)
        h = img.height + 240
        w = img.width + 520

        img = img.resize((w, h), Image.ANTIALIAS)
        x1 = int(0.5 * im_bg.size[0]) - int(0.5 * img.size[0])
        y1 = int(0.5 * im_bg.size[1]) - int(0.5 * img.size[1])
        x2 = int(0.5 * im_bg.size[0]) + int(0.5 * img.size[0])
        y2 = int(0.5 * im_bg.size[1]) + int(0.5 * img.size[1])
        img = img.convert("RGB")
        im_bg.paste(img, box=(x1 - 5, y1, x2 - 5, y2))
        im_bg.save(imagefile, "PNG", quality=100)

        image = Image.open(imagefile)
        image = discordbot.helpers.autocrop_image(image, 0)
        image.save(imagefile, "PNG", quality=100)

        uploaded_image = gst_imgur.upload_image("ta_fib.png",
                                                title="something")
        image_link = uploaded_image.link
        if cfg.DEBUG:
            logger.debug("Image URL: %s", image_link)
        title = "Stocks: Fibonacci-Retracement-Levels " + ticker
        str_df_fib = "```" + df_fib.to_string(index=False) + "```"
        embed = disnake.Embed(title=title,
                              colour=cfg.COLOR,
                              description=str_df_fib)
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )
        embed.set_image(url=image_link)
        os.remove("ta_fib.png")

        await ctx.send(embed=embed)

    except Exception as e:
        embed = disnake.Embed(
            title="ERROR Stocks: Fibonacci-Retracement-Levels",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed, delete_after=30.0)
Ejemplo n.º 20
0
async def pt_command(ctx, ticker: str = "", raw: bool = False, start=""):
    """Displays price targets [Business Insider]"""

    # Debug
    if cfg.DEBUG:
        logger.debug("!stocks.dd.pt %s", ticker)

    # Check for argument
    if ticker == "":
        raise Exception("Stock ticker is required")

    if start == "":
        start = datetime.now() - timedelta(days=365)
    else:
        start = datetime.strptime(start, cfg.DATE_FORMAT)

    if raw not in [True, False]:
        raise Exception("raw argument has to be true or false")

    df_analyst_data = business_insider_model.get_price_target_from_analysts(
        ticker)
    stock = discordbot.helpers.load(ticker, start)
    print(df_analyst_data)
    if df_analyst_data.empty or stock.empty:
        raise Exception("Enter valid ticker")

    # Output Data

    if raw:
        df_analyst_data.sort_index(ascending=False)
        report = "```" + df_analyst_data.to_string() + "```"
        embed = disnake.Embed(
            title="Stocks: [Business Insider] Price Targets",
            description=report,
            colour=cfg.COLOR,
        ).set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )
        ctx.send(embed=embed)
    else:
        plt.style.use("seaborn")
        plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
        if start:
            df_analyst_data = df_analyst_data[start:]

        plt.plot(stock.index, stock["Adj Close"].values, lw=3)

        plt.plot(df_analyst_data.groupby(by=["Date"]).mean())

        plt.scatter(df_analyst_data.index,
                    df_analyst_data["Price Target"],
                    c="r",
                    s=40)

        plt.legend(["Closing Price", "Average Price Target", "Price Target"])

        plt.title(f"{ticker} (Time Series) and Price Target")
        plt.xlim(stock.index[0], stock.index[-1])
        plt.xlabel("Time")
        plt.ylabel("Share Price")
        plt.grid(b=True, which="major", color="#666666", linestyle="-")
        plt.savefig("ta_pt.png")
        imagefile = "ta_pt.png"

        img = Image.open(imagefile)
        print(img.size)
        im_bg = Image.open(cfg.IMG_BG)
        h = img.height + 240
        w = img.width + 520

        img = img.resize((w, h), Image.ANTIALIAS)
        x1 = int(0.5 * im_bg.size[0]) - int(0.5 * img.size[0])
        y1 = int(0.5 * im_bg.size[1]) - int(0.5 * img.size[1])
        x2 = int(0.5 * im_bg.size[0]) + int(0.5 * img.size[0])
        y2 = int(0.5 * im_bg.size[1]) + int(0.5 * img.size[1])
        img = img.convert("RGB")
        im_bg.paste(img, box=(x1 - 5, y1, x2 - 5, y2))
        im_bg.save(imagefile, "PNG", quality=100)

        image = Image.open(imagefile)
        image = discordbot.helpers.autocrop_image(image, 0)
        image.save(imagefile, "PNG", quality=100)

        uploaded_image = gst_imgur.upload_image("ta_pt.png", title="something")
        image_link = uploaded_image.link
        if cfg.DEBUG:
            logger.debug("Image URL: %s", image_link)
        title = "Stocks: [Business Insider] Price Targets " + ticker
        embed = disnake.Embed(title=title, colour=cfg.COLOR)
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )
        embed.set_image(url=image_link)
        os.remove("ta_pt.png")

        await ctx.send(embed=embed)