Exemple #1
0
def view_ma(
    ma_type: str,
    s_ticker: str,
    s_interval: str,
    df_stock: pd.DataFrame,
    length: List[int],
    offset: int,
    export: str = "",
) -> pd.DataFrame:
    """Plots MA technical indicator

    Parameters
    ----------
    ma_type: str
        Type of moving average.  Either "EMA" "ZLMA" or "SMA"
    s_ticker : str
        Ticker
    s_interval : str
        Interval of data
    df_stock : pd.DataFrame
        Dataframe of prices
    length : List[int]
        Length of EMA window
    export : str
        Format to export data
    """
    if s_interval == "1440min":
        price_df = pd.DataFrame(df_stock["Adj Close"].values,
                                columns=["Price"],
                                index=df_stock.index)
    else:
        price_df = pd.DataFrame(df_stock["Close"].values,
                                columns=["Price"],
                                index=df_stock.index)

    l_legend = [s_ticker]
    for win in length:
        if ma_type == "EMA":
            df_ta = overlap_model.ema(s_interval, df_stock, win, offset)
            l_legend.append(f"EMA {win}")
        elif ma_type == "SMA":
            df_ta = overlap_model.sma(s_interval, df_stock, win, offset)
            l_legend.append(f"SMA {win}")
        elif ma_type == "WMA":
            df_ta = overlap_model.wma(s_interval, df_stock, win, offset)
            l_legend.append(f"WMA {win}")
        elif ma_type == "HMA":
            df_ta = overlap_model.hma(s_interval, df_stock, win, offset)
            l_legend.append(f"HMA {win}")
        elif ma_type == "ZLMA":
            df_ta = overlap_model.zlma(s_interval, df_stock, win, offset)
            l_legend.append(f"ZLMA {win}")

        price_df = price_df.join(df_ta)

    fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
    ax.set_title(f"{s_ticker} {ma_type.upper()}")

    ax.plot(price_df.index, price_df["Price"], lw=3, c="k")

    ax.set_xlabel("Time")
    ax.set_xlim([price_df.index[0], price_df.index[-1]])
    ax.set_ylabel(f"{s_ticker} Price")

    for idx in range(1, price_df.shape[1]):
        ax.plot(price_df.iloc[:, idx])

    ax.legend(l_legend)
    ax.grid(b=True, which="major", color="#666666", linestyle="-")

    if gtff.USE_ION:
        plt.ion()

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

    plt.show()
    print("")

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)).replace("common", "stocks"),
        f"{ma_type.lower()}{'_'.join([str(win) for win in length])}",
        price_df,
    )
def view_ma(
    series: pd.Series,
    length: List[int] = None,
    offset: int = 0,
    ma_type: str = "EMA",
    s_ticker: str = "",
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
) -> None:
    """Plots MA technical indicator

    Parameters
    ----------
    series : pd.Series
        Series of prices
    length : List[int]
        Length of EMA window
    ma_type: str
        Type of moving average.  Either "EMA" "ZLMA" or "SMA"
    s_ticker : str
        Ticker
    export : str
        Format to export data
    external_axes : Optional[List[plt.Axes]], optional
        External axes (1 axis is expected in the list), by default None
    """
    # Define a dataframe for adding EMA series to it
    price_df = pd.DataFrame(series)

    l_legend = [s_ticker]
    if not length:
        length = [20, 50]

    for win in length:
        if ma_type == "EMA":
            df_ta = overlap_model.ema(series, win, offset)
            l_legend.append(f"EMA {win}")
        elif ma_type == "SMA":
            df_ta = overlap_model.sma(series, win, offset)
            l_legend.append(f"SMA {win}")
        elif ma_type == "WMA":
            df_ta = overlap_model.wma(series, win, offset)
            l_legend.append(f"WMA {win}")
        elif ma_type == "HMA":
            df_ta = overlap_model.hma(series, win, offset)
            l_legend.append(f"HMA {win}")
        elif ma_type == "ZLMA":
            df_ta = overlap_model.zlma(series, win, offset)
            l_legend.append(f"ZLMA {win}")
        price_df = price_df.join(df_ta)

    plot_data = reindex_dates(price_df)

    # This plot has 1 axis
    if external_axes is None:
        _, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
    else:
        if len(external_axes) != 1:
            console.print("[red]Expected list of one axis item./n[/red]")
            return
        (ax, ) = external_axes

    ax.plot(plot_data.index, plot_data.iloc[:, 1].values)
    ax.set_xlim([plot_data.index[0], plot_data.index[-1]])
    ax.set_ylabel(f"{s_ticker} Price")
    for idx in range(2, plot_data.shape[1]):
        ax.plot(plot_data.iloc[:, idx])

    ax.set_title(f"{s_ticker} {ma_type.upper()}")
    ax.legend(l_legend)
    theme.style_primary_axis(
        ax,
        data_index=plot_data.index.to_list(),
        tick_labels=plot_data["date"].to_list(),
    )

    if external_axes is None:
        theme.visualize_output()

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)).replace("common", "stocks"),
        f"{ma_type.lower()}{'_'.join([str(win) for win in length])}",
        price_df,
    )
Exemple #3
0
def zlma_command(ticker="", window="", offset="", start="", end=""):
    """Displays chart with zero lag moving average [Yahoo Finance]"""

    # Debug
    if cfg.DEBUG:
        logger.debug(
            "ta-zlma %s %s %s %s %s",
            ticker,
            window,
            offset,
            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)

    l_legend = [ticker]

    if window == "":
        window = [20]
    else:
        window_temp = list()
        for wind in window.split(","):
            try:
                window_temp.append(float(wind))
            except Exception as e:
                raise Exception("Window needs to be a float") from e
        window = window_temp

    if offset == "":
        offset = 0

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

    # Retrieve Data
    price_df = pd.DataFrame(
        stock["Adj Close"].values, columns=["Price"], index=stock.index
    )
    i = 1
    for win in window:
        zlma_data = overlap_model.zlma(
            values=stock["Adj Close"], length=win, offset=offset
        )
        price_df = price_df.join(zlma_data)
        l_legend.append(f"ZLMA {win}")
        i += 1

    # Output Data
    start = start.strftime("%Y-%m-%d")
    end = end.strftime("%Y-%m-%d")
    price_df = price_df.loc[(price_df.index >= start) & (price_df.index < end)]

    fig = go.Figure()
    fig.add_trace(
        go.Scatter(
            name=f"{ticker}",
            x=price_df.index,
            y=price_df["Price"],
            line=dict(color="#fdc708", width=2),
            opacity=1,
        ),
    )
    for i in range(1, price_df.shape[1]):
        trace_name = price_df.columns[i].replace("_", " ")
        fig.add_trace(
            go.Scatter(
                name=trace_name,
                x=price_df.index,
                y=price_df.iloc[:, i],
                opacity=1,
            ),
        )
    fig.update_layout(
        margin=dict(l=0, r=0, t=50, b=20),
        template=cfg.PLT_TA_STYLE_TEMPLATE,
        colorway=cfg.PLT_TA_COLORWAY,
        title=f"{ticker} ZLMA",
        title_x=0.5,
        yaxis_title="Stock Price ($)",
        xaxis_title="Time",
        yaxis=dict(
            fixedrange=False,
        ),
        xaxis=dict(
            rangeslider=dict(visible=False),
            type="date",
        ),
        dragmode="pan",
        legend=dict(yanchor="top", y=0.99, xanchor="left", x=0.01),
    )
    config = dict({"scrollZoom": True})
    imagefile = "ta_zlma.png"

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

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

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

    return {
        "title": f"Stocks: Zero-Lag-Moving-Average {ticker}",
        "description": plt_link,
        "imagefile": imagefile,
    }
Exemple #4
0
async def zlma_command(ctx, ticker="", window="", offset="", start="", end=""):
    """Displays chart with zero lag moving average [Yahoo Finance]"""

    try:
        # Debug
        if cfg.DEBUG:
            print(f"!stocks.ta.zlma {ticker} {window} {offset} {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)

        l_legend = [ticker]

        if window == "":
            window = [20]
        else:
            window_temp = list()
            for wind in window.split(","):
                try:
                    window_temp.append(float(wind))
                except Exception as e:
                    raise Exception("Window needs to be a float") from e
            window = window_temp

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

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

        # Retrieve Data
        price_df = pd.DataFrame(stock["Adj Close"].values,
                                columns=["Price"],
                                index=stock.index)
        i = 1
        for win in window:
            zlma_data = overlap_model.zlma(s_interval="1440min",
                                           df_stock=stock,
                                           length=win,
                                           offset=offset)
            price_df = price_df.join(zlma_data)
            l_legend.append(f"ZLMA {win}")
            i += 1

        # Output Data
        start = start.strftime("%Y-%m-%d")
        end = end.strftime("%Y-%m-%d")
        price_df = price_df.loc[(price_df.index >= start)
                                & (price_df.index < end)]

        fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
        ax.set_title(f"{ticker} ZLMA")

        ax.plot(price_df.index, price_df["Price"], lw=3, c="k")

        ax.set_xlabel("Time")
        ax.set_xlim([price_df.index[0], price_df.index[-1]])
        ax.set_ylabel(f"{ticker} Price")

        for idx in range(1, price_df.shape[1]):
            ax.plot(price_df.iloc[:, idx])

        ax.legend(l_legend)
        ax.grid(b=True, which="major", color="#666666", linestyle="-")

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

        plt.savefig("ta_zlma.png")
        uploaded_image = gst_imgur.upload_image("ta_zlma.png",
                                                title="something")
        image_link = uploaded_image.link
        if cfg.DEBUG:
            print(f"Image URL: {image_link}")
        title = "Stocks: Zero-Lag-Moving-Average " + ticker
        embed = discord.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_zlma.png")

        await ctx.send(embed=embed)

    except Exception as e:
        embed = discord.Embed(
            title="ERROR Stocks: Zero-Lag-Moving-Average",
            colour=cfg.COLOR,
            description=e,
        )
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )

        await ctx.send(embed=embed)
Exemple #5
0
def view_ma(
    values: pd.Series,
    length: List[int] = None,
    offset: int = 0,
    ma_type: str = "EMA",
    s_ticker: str = "",
    export: str = "",
) -> pd.DataFrame:
    """Plots MA technical indicator

    Parameters
    ----------
    values : pd.Series
        Series of prices
    length : List[int]
        Length of EMA window
    ma_type: str
        Type of moving average.  Either "EMA" "ZLMA" or "SMA"
    s_ticker : str
        Ticker
    export : str
        Format to export data
    """
    # Define a dataframe for adding EMA values to it
    price_df = pd.DataFrame(values)

    l_legend = [s_ticker]
    if not length:
        length = [20, 50]

    for win in length:
        if ma_type == "EMA":
            df_ta = overlap_model.ema(values, win, offset)
            l_legend.append(f"EMA {win}")
        elif ma_type == "SMA":
            df_ta = overlap_model.sma(values, win, offset)
            l_legend.append(f"SMA {win}")
        elif ma_type == "WMA":
            df_ta = overlap_model.wma(values, win, offset)
            l_legend.append(f"WMA {win}")
        elif ma_type == "HMA":
            df_ta = overlap_model.hma(values, win, offset)
            l_legend.append(f"HMA {win}")
        elif ma_type == "ZLMA":
            df_ta = overlap_model.zlma(values, win, offset)
            l_legend.append(f"ZLMA {win}")
        price_df = price_df.join(df_ta)

    fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
    ax.set_title(f"{s_ticker} {ma_type.upper()}")

    ax.plot(values.index, values.values, lw=3, c="k")

    ax.set_xlabel("Time")
    ax.set_xlim([price_df.index[0], price_df.index[-1]])
    ax.set_ylabel(f"{s_ticker} Price")

    for idx in range(1, price_df.shape[1]):
        ax.plot(price_df.iloc[:, idx])

    ax.legend(l_legend)
    ax.grid(b=True, which="major", color="#666666", linestyle="-")

    if gtff.USE_ION:
        plt.ion()

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

    plt.show()
    console.print("")

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)).replace("common", "stocks"),
        f"{ma_type.lower()}{'_'.join([str(win) for win in length])}",
        price_df,
    )
Exemple #6
0
async def zlma_command(ctx, ticker="", window="", offset="", start="", end=""):
    """Displays chart with zero lag moving average [Yahoo Finance]"""

    try:
        # Debug
        if cfg.DEBUG:
            logger.debug(
                "!stocks.ta.zlma %s %s %s %s %s",
                ticker,
                window,
                offset,
                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)

        l_legend = [ticker]

        if window == "":
            window = [20]
        else:
            window_temp = list()
            for wind in window.split(","):
                try:
                    window_temp.append(float(wind))
                except Exception as e:
                    raise Exception("Window needs to be a float") from e
            window = window_temp

        if offset == "":
            offset = 0

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

        # Retrieve Data
        price_df = pd.DataFrame(stock["Adj Close"].values,
                                columns=["Price"],
                                index=stock.index)
        i = 1
        for win in window:
            zlma_data = overlap_model.zlma(values=stock["Adj Close"],
                                           length=win,
                                           offset=offset)
            price_df = price_df.join(zlma_data)
            l_legend.append(f"ZLMA {win}")
            i += 1

        # Output Data
        start = start.strftime("%Y-%m-%d")
        end = end.strftime("%Y-%m-%d")
        price_df = price_df.loc[(price_df.index >= start)
                                & (price_df.index < end)]

        fig = go.Figure()
        fig.add_trace(
            go.Scatter(
                name=f"{ticker}",
                x=price_df.index,
                y=price_df["Price"],
                line=dict(color="#fdc708", width=2),
                opacity=1,
            ), )
        for i in range(1, price_df.shape[1]):
            trace_name = price_df.columns[i].replace("_", " ")
            fig.add_trace(
                go.Scatter(
                    name=trace_name,
                    x=price_df.index,
                    y=price_df.iloc[:, i],
                    opacity=1,
                ), )
        fig.update_layout(
            margin=dict(l=0, r=0, t=50, b=20),
            template=cfg.PLT_TA_STYLE_TEMPLATE,
            colorway=cfg.PLT_TA_COLORWAY,
            title=f"{ticker} ZLMA",
            title_x=0.5,
            yaxis_title="Stock Price ($)",
            xaxis_title="Time",
            yaxis=dict(fixedrange=False, ),
            xaxis=dict(
                rangeslider=dict(visible=False),
                type="date",
            ),
            dragmode="pan",
            legend=dict(yanchor="top", y=0.99, xanchor="left", x=0.01),
        )
        config = dict({"scrollZoom": True})
        imagefile = "ta_zlma.png"

        # Check if interactive settings are enabled
        plt_link = ""
        if cfg.INTERACTIVE:
            html_ran = random.randint(69, 69420)
            fig.write_html(f"in/zlma_{html_ran}.html", config=config)
            plt_link = f"[Interactive]({cfg.INTERACTIVE_URL}/zlma_{html_ran}.html)"

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

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

        # Paste fig onto background img and autocrop background
        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)

        image = disnake.File(imagefile)

        print(f"Image {imagefile}")
        embed = disnake.Embed(
            title=f"Stocks: Zero-Lag-Moving-Average {ticker}",
            description=plt_link,
            colour=cfg.COLOR,
        )
        embed.set_image(url=f"attachment://{imagefile}")
        embed.set_author(
            name=cfg.AUTHOR_NAME,
            icon_url=cfg.AUTHOR_ICON_URL,
        )
        os.remove(imagefile)

        await ctx.send(embed=embed, file=image)

    except Exception as e:
        embed = disnake.Embed(
            title="ERROR Stocks: Zero-Lag-Moving-Average",
            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)