예제 #1
0
def spos_command(ticker: str = ""):
    """Net short vs position [Stockgrid]"""

    # Debug user input
    if cfg.DEBUG:
        logger.debug("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}"

    fig = make_subplots(shared_xaxes=True, specs=[[{"secondary_y": True}]])

    fig.add_trace(
        go.Scatter(
            name="Position ($)",
            x=df["dates"].values,
            y=df["dollar_dp_position"] * 1_000,
            line=dict(color="#fdc708", width=2),
            opacity=1,
            showlegend=False,
        ),
        secondary_y=True,
    )
    fig.add_trace(
        go.Bar(
            name="Net Short Vol. ($)",
            x=df["dates"],
            y=df["dollar_net_volume"],
            opacity=1,
            showlegend=False,
        ),
        secondary_y=False,
    )
    # Set y-axes titles
    fig.update_xaxes(dtick="M1", tickformat="%b %d\n%Y")
    fig.update_yaxes(title_text="<b>Position</b> ($)", secondary_y=True)
    fig.update_traces(hovertemplate="%{y:.2s}")
    fig.update_layout(
        margin=dict(l=0, r=10, t=40, b=20),
        template=cfg.PLT_TA_STYLE_TEMPLATE,
        colorway=cfg.PLT_TA_COLORWAY,
        title=f"Net Short Vol. vs Position for {ticker}",
        title_x=0.5,
        yaxis_title="<b>Net Short Vol.</b> ($)",
        yaxis=dict(
            side="left",
            showgrid=False,
            fixedrange=False,
            layer="above traces",
            titlefont=dict(color="#d81aea"),
            tickfont=dict(color="#d81aea"),
            nticks=10,
        ),
        xaxis=dict(
            rangeslider=dict(visible=False),
            type="date",
            fixedrange=False,
        ),
        xaxis2=dict(
            rangeslider=dict(visible=False),
            type="date",
            fixedrange=False,
        ),
        dragmode="pan",
        legend=dict(orientation="h",
                    yanchor="bottom",
                    y=1.02,
                    xanchor="right",
                    x=1),
        yaxis2=dict(
            side="right",
            position=0.15,
            fixedrange=False,
            titlefont=dict(color="#fdc708"),
            tickfont=dict(color="#fdc708"),
            nticks=10,
        ),
        hovermode="x unified",
    )
    config = dict({"scrollZoom": True})
    imagefile = "dps_spos.png"

    # Check if interactive settings are enabled
    plt_link = ""
    if cfg.INTERACTIVE:
        html_ran = helpers.uuid_get()
        fig.write_html(f"in/spos_{html_ran}.html", config=config)
        plt_link = f"[Interactive]({cfg.INTERACTIVE_URL}/spos_{html_ran}.html)"

    fig.update_layout(
        width=800,
        height=500,
    )

    imagefile = helpers.image_border(imagefile, fig=fig)

    return {
        "title": title,
        "description": plt_link,
        "imagefile": imagefile,
    }
예제 #2
0
async def spos_command(ctx, ticker=""):
    """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 = discord.Embed(title=title, colour=cfg.COLOR)
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        fig = plt.figure(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)
        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 = discord.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)
예제 #3
0
async def spos_command(ctx, arg=""):
    """Gets price vs short interest volume plot from GST and sends it

    Parameters
    -----------
    arg: str
        ticker, -h or help

    Returns
    -------
    discord message
        Sends a message containing an image of net short position of a given
        ticker to the user
    """

    try:
        # Debug
        if cfg.DEBUG:
            print(f"!stocks.dps.spos {arg}")

        # Help
        if arg == "-h" or arg == "help":
            help_txt = "Plot net short position. [Source: Stockgrid]\n"
            help_txt += "\nPossible arguments:\n"
            help_txt += "<TICKER> Stock ticker. REQUIRED!\n"
            embed = discord.Embed(
                title="Stocks: [Stockgrid] Net Short vs Position HELP",
                description=help_txt,
                colour=cfg.COLOR,
            )
            embed.set_author(
                name=cfg.AUTHOR_NAME,
                icon_url=cfg.AUTHOR_ICON_URL,
            )

        else:
            if arg == "":
                title = "ERROR Stocks: [Stockgrid] Net Short vs Position"
                embed = discord.Embed(title=title, colour=cfg.COLOR)
                embed.set_author(
                    name=cfg.AUTHOR_NAME,
                    icon_url=cfg.AUTHOR_ICON_URL,
                )
                embed.set_description("No ticker entered."
                                      "\nEnter a valid ticker, example: GME")
                await ctx.send(embed=embed)
                if cfg.DEBUG:
                    print("ERROR: No ticker entered")
                return

            # Parse argument
            ticker = arg.upper()

            plt.ion()
            title = f"Stocks: [Stockgrid] Net Short vs Position {arg}"
            embed = discord.Embed(title=title, colour=cfg.COLOR)
            embed.set_author(
                name=cfg.AUTHOR_NAME,
                icon_url=cfg.AUTHOR_ICON_URL,
            )

            try:
                df = stockgrid_model.get_net_short_position(ticker)
            except Exception as e:
                title = "ERROR Stocks: [Stockgrid] Price vs Short Interest Volume"
                embed = discord.Embed(title=title, colour=cfg.COLOR)
                embed.set_author(
                    name=cfg.AUTHOR_NAME,
                    icon_url=cfg.AUTHOR_ICON_URL,
                )
                embed.set_description(f"Ticker given: {arg}"
                                      "\nEnter a valid ticker, example: GME")
                await ctx.send(embed=embed)
                if cfg.DEBUG:
                    print(
                        f"POSSIBLE ERROR: Wrong ticker parameter entered\n{e}")
                return

            fig = plt.figure(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)
            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:
        title = "INTERNAL ERROR"
        embed = discord.Embed(title=title, colour=cfg.COLOR)
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )
        embed.set_description(
            "Try updating the bot, make sure DEBUG is True in the config "
            "and restart it.\nIf the error still occurs open a issue at: "
            "https://github.com/GamestonkTerminal/GamestonkTerminal/issues"
            f"\n{e}")
        await ctx.send(embed=embed)
        if cfg.DEBUG:
            print(e)
예제 #4
0
def net_short_position(
    ticker: str,
    num: int,
    raw: bool,
    export: str,
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Plot net short position. [Source: Stockgrid]

    Parameters
    ----------
    ticker: str
        Stock to plot for
    num : int
        Number of last open market days to show
    raw : bool
        Flag to print raw data instead
    export : str
        Export dataframe data to csv,json,xlsx file
    external_axes : Optional[List[plt.Axes]], optional
        External axes (2 axis is expected in the list), by default None

    """
    df = stockgrid_model.get_net_short_position(ticker)

    if raw:
        df = df.sort_values(by="dates", ascending=False)

        df["Net Short Vol. (1k $)"] = df["dollar_net_volume"] / 1_000
        df["Position (1M $)"] = df["dollar_dp_position"]

        df = df[[
            "dates",
            "Net Short Vol. (1k $)",
            "Position (1M $)",
        ]]

        df["dates"] = df["dates"].dt.date

        print_rich_table(
            df.iloc[:num],
            headers=list(df.columns),
            show_index=False,
            title="Net Short Positions",
        )

    else:

        # This plot has 2 axis
        if not external_axes:
            _, ax1 = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
            ax2 = ax1.twinx()
        else:
            if len(external_axes) != 2:
                logger.error("Expected list of one axis item.")
                console.print("[red]Expected list of one axis item./n[/red]")
                return
            (ax1, ax2) = external_axes

        ax1.bar(
            df["dates"],
            df["dollar_net_volume"] / 1_000,
            color=theme.down_color,
            label="Net Short Vol. (1k $)",
        )
        ax1.set_ylabel("Net Short Vol. (1k $)")

        ax2.plot(
            df["dates"].values,
            df["dollar_dp_position"],
            c=theme.up_color,
            label="Position (1M $)",
        )
        ax2.set_ylabel("Position (1M $)")

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

        ax1.set_xlim(
            df["dates"].values[max(0,
                                   len(df) - num)],
            df["dates"].values[len(df) - 1],
        )

        ax1.set_title(f"Net Short Vol. vs Position for {ticker}")

        theme.style_twin_axes(ax1, ax2)

        if not external_axes:
            theme.visualize_output()

    console.print("")

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "shortpos",
        df,
    )
def net_short_position(ticker: str, num: int, raw: bool, export: str):
    """Plot net short position. [Source: Stockgrid]

    Parameters
    ----------
    ticker: str
        Stock to plot for
    num : int
        Number of last open market days to show
    raw : bool
        Flag to print raw data instead
    export : str
        Export dataframe data to csv,json,xlsx file
    """
    df = stockgrid_model.get_net_short_position(ticker)

    if raw:
        df = df.sort_values(by="dates", ascending=False)

        df["Net Short Vol. (1k $)"] = df["dollar_net_volume"] / 1_000
        df["Position (1M $)"] = df["dollar_dp_position"]

        df = df[[
            "dates",
            "Net Short Vol. (1k $)",
            "Position (1M $)",
        ]]

        df["dates"] = df["dates"].dt.date

        print(
            tabulate(
                df.iloc[:num],
                tablefmt="fancy_grid",
                floatfmt=".2f",
                headers=list(df.columns),
                showindex=False,
            ))

    else:
        fig = plt.figure(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.set_xlim(
            df["dates"].values[max(0,
                                   len(df) - num)],
            df["dates"].values[len(df) - 1],
        )

        ax.grid()
        plt.title(f"Net Short Vol. vs Position for {ticker}")
        plt.gcf().autofmt_xdate()

        if USE_ION:
            plt.ion()

        plt.show()
    print("")

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "shortpos",
        df,
    )
예제 #6
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)