Пример #1
0
def display_unemployment(
    start_year: int = 2015,
    raw: bool = False,
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Display US unemployment AlphaVantage

    Parameters
    ----------
    start_year : int, optional
        Start year for plot, by default 2010
    raw : bool, optional
        Flag to show raw data, by default False
    export : str, optional
        Format to export data, by default ""
    external_axes : Optional[List[plt.Axes]], optional
        External axes (1 axis is expected in the list), by default None
    """

    unemp = alphavantage_model.get_unemployment()

    if unemp.empty:
        console.print("Error getting data.  Check API Key")
        return

    un = unemp[unemp.date >= f"{start_year}-01-01"]

    if external_axes is None:
        _, ax = plt.subplots(figsize=plot_autoscale(), dpi=cfp.PLOT_DPI)

    else:
        if len(external_axes) != 1:
            console.print("[red]Expected list of 1 axis items./n[/red]")
            return
        (ax, ) = external_axes

    ax.plot(un.date, un.unemp, marker="o")
    ax.set_title(f"US Unemployment from {start_year}")
    ax.set_ylabel("US Unemployment  ")
    theme.style_primary_axis(ax)
    if external_axes is None:
        theme.visualize_output()

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "unemp",
        unemp,
    )

    if raw:
        print_rich_table(
            un.head(20),
            headers=["Date", "GDP"],
            title="US Unemployment",
            show_index=False,
        )

    console.print("")
Пример #2
0
def view(ticker: str, external_axes: Optional[List[plt.Axes]] = None):
    """View finviz image for ticker

    Parameters
    ----------
    ticker : str
        Stock ticker
    external_axes : Optional[List[plt.Axes]], optional
        External axes (1 axis is expected in the list), by default None
    """

    image_data = finviz_model.get_finviz_image(ticker)
    dataBytesIO = io.BytesIO(image_data)
    im = Image.open(dataBytesIO)

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

    ax.set_axis_off()
    fig.subplots_adjust(left=0, right=1, top=1, bottom=0)
    ax.imshow(im)
    # added for the watermark
    if not external_axes:
        theme.visualize_output()
Пример #3
0
def display_historical(
    data: pd.DataFrame,
    fund: str = "",
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Display historical fund price

    Parameters
    ----------
    data: pd.DataFrame
        Dataframe containing historical data
    fund: str
        Fund symbol or name
    export: str
        Format to export data
    external_axes:Optional[List[plt.Axes]]:
        External axes to plot on
    """
    console.print()
    if external_axes is None:
        _, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
    else:
        ax = external_axes[0]
    ax.plot(data.index, data.Close)
    ax.set_xlim([data.index[0], data.index[-1]])
    ax.set_xlabel("Date")
    ax.set_ylabel("Close Price")
    ax.set_title(f"{fund.title()} Price History")
    theme.style_primary_axis(ax)
    if external_axes is None:
        theme.visualize_output()

    export_data(export, os.path.dirname(os.path.abspath(__file__)), "historical", data)
Пример #4
0
def plot_payoff(
    current_price: float,
    options: List[Dict[Any, Any]],
    underlying: int,
    ticker: str,
    expiration: str,
    external_axes: Optional[List[plt.Axes]] = None,
) -> None:
    """Generate a graph showing the option payoff diagram"""
    x, yb, ya = generate_data(current_price, options, underlying)

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

    if ya:
        ax.plot(x, yb, label="Payoff Before Premium")
        ax.plot(x, ya, label="Payoff After Premium")
    else:
        ax.plot(x, yb, label="Payoff")
    ax.set_title(f"Option Payoff Diagram for {ticker} on {expiration}")
    ax.set_ylabel("Profit")
    ax.set_xlabel("Underlying Asset Price at Expiration")
    ax.xaxis.set_major_formatter("${x:.2f}")
    ax.yaxis.set_major_formatter("${x:.2f}")
    theme.style_primary_axis(ax)

    if external_axes is None:
        theme.visualize_output()
Пример #5
0
def display_non_zero_addresses(
    asset: str,
    since: int,
    until: int,
    interval: str,
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
) -> None:
    """Display addresses with non-zero balance of a certain asset
    [Source: https://glassnode.org]

    Parameters
    ----------
    asset : str
        Asset to search (e.g., BTC)
    since : int
        Initial date timestamp (e.g., 1_577_836_800)
    until : int
        End date timestamp (e.g., 1_609_459_200)
    interval : str
        Interval frequency (e.g., 24h)
    export : str
        Export dataframe data to csv,json,xlsx file
    external_axes : Optional[List[plt.Axes]], optional
        External axes (1 axis is expected in the list), by default None
    """

    df_addresses = get_non_zero_addresses(asset, interval, since, until)

    if df_addresses.empty:
        console.print("Error in glassnode request")
    else:

        # This plot has 1 axis
        if not external_axes:
            _, ax = plt.subplots(figsize=plot_autoscale(),
                                 dpi=cfgPlot.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(df_addresses.index, df_addresses["v"] / 1_000, linewidth=1.5)

        ax.set_title(f"{asset} Addresses with non-zero balances")
        ax.set_ylabel("Number of Addresses")
        ax.set_xlim(df_addresses.index[0], df_addresses.index[-1])

        theme.style_primary_axis(ax)

        if not external_axes:
            theme.visualize_output()

        export_data(
            export,
            os.path.dirname(os.path.abspath(__file__)),
            "nonzero",
            df_addresses,
        )
Пример #6
0
def display_yield_curve(date: datetime,
                        external_axes: Optional[List[plt.Axes]] = None):
    """Display yield curve based on US Treasury rates for a specified date.

    Parameters
    ----------
    date: datetime
        Date to get yield curve for
    external_axes: Optional[List[plt.Axes]]
        External axes to plot data on
    """
    rates, date_of_yield = fred_model.get_yield_curve(date)
    if rates.empty:
        console.print(
            f"[red]Yield data not found for {date.strftime('%Y-%m-%d')}[/red].\n"
        )
        return
    if external_axes is None:
        _, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)

    else:
        if len(external_axes) != 1:
            logger.error("Expected list of 3 axis items")
            console.print("[red]Expected list of 3 axis items./n[/red]")
            return
        (ax, ) = external_axes

    ax.plot(rates.Maturity, rates.Rate, "-o")
    ax.set_xlabel("Maturity")
    ax.set_ylabel("Rate (%)")
    theme.style_primary_axis(ax)
    if external_axes is None:
        ax.set_title(
            f"US Yield Curve for {date_of_yield.strftime('%Y-%m-%d')} ")
        theme.visualize_output()
Пример #7
0
def display_returns_vs_bench(
    portfolio: portfolio_model.Portfolio,
    benchmark: str = "SPY",
    external_axes: Optional[plt.Axes] = None,
):
    """Display portfolio returns vs benchmark

    Parameters
    ----------
    portfolio: Portfolio
        Custom portfolio object with trade list
    benchmark: str
        Symbol for benchmark.  Defaults to SPY
    external_axes: plt.Axes
        Optional axes to display plot on
    """
    if external_axes is None:
        _, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
    else:
        ax = external_axes

    portfolio.generate_holdings_from_trades()
    portfolio.add_benchmark(benchmark)

    cumulative_returns = (1 + portfolio.returns).cumprod()
    benchmark_c_returns = (1 + portfolio.benchmark_returns).cumprod()

    ax.plot(cumulative_returns.index, cumulative_returns, label="Portfolio")
    ax.plot(benchmark_c_returns.index, benchmark_c_returns, label="Benchmark")
    ax.set_ylabel("Cumulative Returns")
    ax.legend(loc="upper left")
    theme.style_primary_axis(ax)
    if not external_axes:
        theme.visualize_output()
Пример #8
0
def display_candle(
    data: pd.DataFrame,
    to_symbol: str,
    from_symbol: str,
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Show candle plot for fx data.

    Parameters
    ----------
    data : pd.DataFrame
        Loaded fx historical data
    to_symbol : str
        To forex symbol
    from_symbol : str
        From forex symbol
    external_axes: Optional[List[plt.Axes]]
        External axes (1 axis are expected in the list), by default None
    """
    candle_chart_kwargs = {
        "type": "candle",
        "style": theme.mpf_style,
        "mav": (20, 50),
        "volume": False,
        "xrotation": theme.xticks_rotation,
        "scale_padding": {
            "left": 0.3,
            "right": 1,
            "top": 0.8,
            "bottom": 0.8
        },
        "update_width_config": {
            "candle_linewidth": 0.6,
            "candle_width": 0.8,
            "volume_linewidth": 0.8,
            "volume_width": 0.8,
        },
        "warn_too_much_data": 10000,
    }
    # This plot has 2 axes
    if not external_axes:
        candle_chart_kwargs["returnfig"] = True
        candle_chart_kwargs["figratio"] = (10, 7)
        candle_chart_kwargs["figscale"] = 1.10
        candle_chart_kwargs["figsize"] = plot_autoscale()
        fig, _ = mpf.plot(data, **candle_chart_kwargs)
        fig.suptitle(
            f"{from_symbol}/{to_symbol}",
            x=0.055,
            y=0.965,
            horizontalalignment="left",
        )
        theme.visualize_output(force_tight_layout=False)
    else:
        if len(external_axes) != 1:
            console.print("[red]Expected list of 1 axis items./n[/red]")
            return
        (ax1, ) = external_axes
        candle_chart_kwargs["ax"] = ax1
        mpf.plot(data, **candle_chart_kwargs)
Пример #9
0
def display_marketcap_dominance(
    coin: str,
    start: str,
    end: str,
    interval: str,
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
) -> None:
    """Display market dominance of a coin over time
    [Source: https://messari.io/]

    Parameters
    ----------
    coin : str
        Crypto symbol to check market cap dominance
    start : int
        Initial date like string (e.g., 2021-10-01)
    end : int
        End date like string (e.g., 2021-10-01)
    interval : str
        Interval frequency (e.g., 1d)
    export : str
        Export dataframe data to csv,json,xlsx file
    external_axes : Optional[List[plt.Axes]], optional
        External axes (1 axis is expected in the list), by default None
    """

    df = get_marketcap_dominance(coin=coin, start=start, end=end, interval=interval)

    if df.empty:
        return

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

    ax.plot(df.index, df["marketcap_dominance"])

    ax.set_title(f"{coin}'s Market Cap Dominance over time")
    ax.set_ylabel(f"{coin} Percentage share")
    ax.set_xlim(df.index[0], df.index[-1])

    theme.style_primary_axis(ax)

    if not external_axes:
        theme.visualize_output()

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "mcapdom",
        df,
    )
Пример #10
0
def display_active_addresses(
    asset: str,
    since: int,
    until: int,
    interval: str,
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
) -> None:
    """Display active addresses of a certain asset over time
    [Source: https://glassnode.org]

    Parameters
    ----------
    asset : str
        Asset to search active addresses (e.g., BTC)
    since : int
        Initial date timestamp (e.g., 1_614_556_800)
    until : int
        End date timestamp (e.g., 1_614_556_800)
    interval : str
        Interval frequency (e.g., 24h)
    export : str
        Export dataframe data to csv,json,xlsx file
    external_axes : Optional[List[plt.Axes]], optional
        External axes (1 axis is expected in the list), by default None
    """

    df_addresses = get_active_addresses(asset, interval, since, until)

    if df_addresses.empty:
        return

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

    ax.plot(df_addresses.index, df_addresses["v"] / 1_000, linewidth=1.5)

    ax.set_title(f"Active {asset} addresses over time")
    ax.set_ylabel("Addresses [thousands]")
    ax.set_xlim(df_addresses.index[0], df_addresses.index[-1])

    theme.style_primary_axis(ax)

    if not external_axes:
        theme.visualize_output()

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "active",
        df_addresses,
    )
Пример #11
0
def display_cpi(
    interval: str,
    start_year: int = 2010,
    raw: bool = False,
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Display US consumer price index (CPI) from AlphaVantage

    Parameters
    ----------
    interval : str
        Interval for GDP.  Either "m" or "s"
    start_year : int, optional
        Start year for plot, by default 2010
    raw : bool, optional
        Flag to show raw data, by default False
    export : str, optional
        Format to export data, by default ""
    external_axes : Optional[List[plt.Axes]], optional
        External axes (1 axis is expected in the list), by default None
    """
    cpi_full = alphavantage_model.get_cpi(interval)
    if cpi_full.empty:
        console.print("Error getting data.  Check API Key")
        return
    cpi = cpi_full[cpi_full.date >= f"{start_year}-01-01"]
    int_string = "Semi-Annual" if interval == "s" else "Monthly"
    year_str = str(list(cpi.date)[-1].year)

    if external_axes is None:
        _, ax = plt.subplots(figsize=plot_autoscale(), dpi=cfp.PLOT_DPI)

    else:
        if len(external_axes) != 1:
            logger.error("Expected list of one axis item.")
            console.print("[red]Expected list of 1 axis item./n[/red]")
            return
        (ax, ) = external_axes

    ax.plot(cpi.date, cpi.CPI, marker="o")
    ax.set_title(f"{int_string} Consumer Price Index from {year_str}")
    ax.set_ylabel("CPI")
    theme.style_primary_axis(ax)
    if external_axes is None:
        theme.visualize_output()

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "cpi",
        cpi_full,
    )
    if raw:
        print_rich_table(cpi.head(20),
                         headers=["Date", "CPI"],
                         show_index=False,
                         title="US CPI")
        console.print("")
Пример #12
0
def display_rsi_strategy(
    ticker: str,
    df_stock: pd.DataFrame,
    periods: int,
    low_rsi: int,
    high_rsi: int,
    spy_bt: bool = True,
    no_bench: bool = False,
    shortable: bool = True,
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Strategy that buys when the stock is less than a threshold and shorts when it exceeds a threshold.

    Parameters
    ----------
    ticker : str
        Stock ticker
    df_stock : pd.Dataframe
        Dataframe of prices
    periods : int
        Number of periods for RSI calculation
    low_rsi : int
        Low RSI value to buy
    high_rsi : int
        High RSI value to sell
    spy_bt : bool
        Boolean to add spy comparison
    no_bench : bool
        Boolean to not show buy and hold comparison
    shortable : bool
        Boolean to allow for selling of the stock at cross
    export : str
        Format to export backtest results
    external_axes : Optional[List[plt.Axes]], optional
        External axes (3 axes are expected in the list), by default None
    """
    # This plot has 1 axis
    if not external_axes:
        _, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
    else:
        if len(external_axes) != 1:
            logger.error("Expected list of one axis item.")
            console.print("[red]Expected list of one axis item./n[/red]")
            return
        (ax, ) = external_axes

    res = bt_model.rsi_strategy(ticker, df_stock, periods, low_rsi, high_rsi,
                                spy_bt, no_bench, shortable)

    res.plot(title=f"RSI Strategy between ({low_rsi}, {high_rsi})", ax=ax)

    theme.style_primary_axis(ax)

    if not external_axes:
        theme.visualize_output()

    export_data(export, os.path.dirname(os.path.abspath(__file__)),
                "rsi_corss", res.stats)
Пример #13
0
def display_real_gdp(
    interval: str,
    start_year: int = 2010,
    raw: bool = False,
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Display US GDP from AlphaVantage

    Parameters
    ----------
    interval : str
        Interval for GDP.  Either "a" or "q"
    start_year : int, optional
        Start year for plot, by default 2010
    raw : bool, optional
        Flag to show raw data, by default False
    export : str, optional
        Format to export data, by default ""
    external_axes : Optional[List[plt.Axes]], optional
        External axes (1 axis is expected in the list), by default None
    """
    gdp_full = alphavantage_model.get_real_gdp(interval)

    if gdp_full.empty:
        return
    gdp = gdp_full[gdp_full.date >= f"{start_year}-01-01"]
    int_string = "Annual" if interval == "a" else "Quarterly"
    year_str = str(start_year) if interval == "a" else str(
        list(gdp.date)[-1].year)

    if external_axes is None:
        _, ax = plt.subplots(figsize=plot_autoscale(), dpi=cfp.PLOT_DPI)

    else:
        if len(external_axes) != 1:
            logger.error("Expected list of one axis item.")
            console.print("[red]Expected list of 1 axis items./n[/red]")
            return
        (ax, ) = external_axes

    ax.plot(gdp.date, gdp.GDP, marker="o")
    ax.set_title(f"{int_string} US GDP ($B) from {year_str}")
    ax.set_ylabel("US GDP ($B) ")
    theme.style_primary_axis(ax)
    if external_axes is None:
        theme.visualize_output()

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "gdp",
        gdp_full,
    )
    if raw:
        print_rich_table(gdp.head(20),
                         headers=["Date", "GDP"],
                         show_index=False,
                         title="US GDP")
Пример #14
0
def display_dwat(
    dependent_variable: pd.Series,
    residual: pd.DataFrame,
    plot: bool = False,
    export: str = "",
    external_axes: Optional[List[plt.axes]] = None,
):
    """Show Durbin-Watson autocorrelation tests

    Parameters
    ----------
    dependent_variable : pd.Series
        The dependent variable.
    residual : OLS Model
        The residual of an OLS model.
    plot : bool
        Whether to plot the residuals
    export : str
        Format to export data
    external_axes: Optional[List[plt.axes]]
        External axes to plot on
    """
    autocorrelation = regression_model.get_dwat(residual)

    if 1.5 < autocorrelation < 2.5:
        console.print(
            f"The result {autocorrelation} is within the range 1.5 and 2.5 which therefore indicates "
            f"autocorrelation not to be problematic.")
    else:
        console.print(
            f"The result {autocorrelation} is outside the range 1.5 and 2.5 and therefore autocorrelation "
            f"can be problematic. Please consider lags of the dependent or independent variable."
        )

    if plot:
        if external_axes is None:
            _, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
        else:
            ax = external_axes[0]

        ax.scatter(dependent_variable, residual)
        ax.axhline(y=0, color="r", linestyle="-")
        ax.set_ylabel("Residual")
        ax.set_xlabel(dependent_variable.name.capitalize())
        ax.set_title("Plot of Residuals")
        theme.style_primary_axis(ax)

        if external_axes is None:
            theme.visualize_output()

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        f"{dependent_variable.name}_dwat",
        autocorrelation,
    )

    console.print()
Пример #15
0
def display_big_mac_index(
    country_codes: List[str],
    raw: bool = False,
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Display Big Mac Index for given countries

    Parameters
    ----------
    country_codes : List[str]
        List of country codes to get for
    raw : bool, optional
        Flag to display raw data, by default False
    export : str, optional
        Format data, by default ""
    external_axes : Optional[List[plt.Axes]], optional
        External axes (3 axes are expected in the list), by default None
    """
    df_cols = ["Date"]
    df_cols.extend(country_codes)
    big_mac = pd.DataFrame(columns=df_cols)
    for country in country_codes:
        df1 = nasdaq_model.get_big_mac_index(country)
        if not df1.empty:
            big_mac[country] = df1["dollar_price"]
            big_mac["Date"] = df1["Date"]
    big_mac.set_index("Date", inplace=True)

    if not big_mac.empty:
        if external_axes is None:
            _, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)

        else:
            if len(external_axes) != 3:
                console.print("[red]Expected list of 3 axis items./n[/red]")
                return
            (ax, ) = external_axes

        big_mac.plot(ax=ax, marker="o")
        ax.legend()
        ax.set_title("Big Mac Index (USD)")
        ax.set_ylabel("Price of Big Mac in USD")
        theme.style_primary_axis(ax)
        if external_axes is None:
            theme.visualize_output()

        if raw:
            print_rich_table(big_mac,
                             headers=list(big_mac.columns),
                             title="Big Mac Index")
            console.print("")

        export_data(export, os.path.dirname(os.path.abspath(__file__)),
                    "bigmac", big_mac)
        console.print("")
    else:
        console.print("[red]Unable to get big mac data[/red]\n")
Пример #16
0
def display_gdp_capita(
    start_year: int = 2010,
    raw: bool = False,
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Display US GDP per Capita from AlphaVantage

    Parameters
    ----------
    start_year : int, optional
        Start year for plot, by default 2010
    raw : bool, optional
        Flag to show raw data, by default False
    export : str, optional
        Format to export data, by default
    external_axes : Optional[List[plt.Axes]], optional
        External axes (1 axis is expected in the list), by default None
    """
    gdp_capita = alphavantage_model.get_gdp_capita()
    if gdp_capita.empty:
        console.print("Error getting data.  Check API Key")
        return
    gdp = gdp_capita[gdp_capita.date >= f"{start_year}-01-01"]

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

    ax.plot(gdp.date, gdp.GDP, marker="o")
    ax.set_title(f"US GDP per Capita (Chained 2012 USD) from {start_year}")
    ax.set_ylabel("US GDP (Chained 2012 USD) ")
    theme.style_primary_axis(ax)
    if external_axes is None:
        theme.visualize_output()

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "gdpc",
        gdp_capita,
    )
    if raw:
        print_rich_table(
            gdp.head(20),
            headers=["Date", "GDP"],
            show_index=False,
            title="US GDP Per Capita",
        )
        console.print("")
Пример #17
0
def display_mentions(
    ticker: str,
    start: str,
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Plot weekly bars of stock's interest over time. other users watchlist. [Source: Google]

    Parameters
    ----------
    ticker : str
        Ticker
    start : str
        Start date as YYYY-MM-DD string
    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
    """
    df_interest = google_model.get_mentions(ticker)

    # 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:
            logger.error("Expected list of one axis item.")
            console.print("[red]Expected list of one axis item./n[/red]")
            return
        (ax, ) = external_axes

    ax.set_title(f"Interest over time on {ticker}")
    if start:
        df_interest = df_interest[start:]  # type: ignore
        ax.bar(df_interest.index, df_interest[ticker], width=2)
        ax.bar(
            df_interest.index[-1],
            df_interest[ticker].values[-1],
            width=theme.volume_bar_width,
        )
    else:
        ax.bar(df_interest.index, df_interest[ticker], width=1)
        ax.bar(
            df_interest.index[-1],
            df_interest[ticker].values[-1],
            width=theme.volume_bar_width,
        )
    ax.set_ylabel("Interest [%]")
    ax.set_xlim(df_interest.index[0], df_interest.index[-1])
    theme.style_primary_axis(ax)

    if external_axes is None:
        theme.visualize_output()

    export_data(export, os.path.dirname(os.path.abspath(__file__)), "mentions",
                df_interest)
Пример #18
0
def display_inflation(
    start_year: int = 2010,
    raw: bool = False,
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Display US Inflation from AlphaVantage

    Parameters
    ----------
    start_year : int, optional
        Start year for plot, by default 2010
    raw : bool, optional
        Flag to show raw data, by default False
    export : str, optional
        Format to export data, by default ""
    external_axes : Optional[List[plt.Axes]], optional
        External axes (1 axis is expected in the list), by default None
    """
    inflation = alphavantage_model.get_inflation()
    if inflation.empty:
        console.print("Error getting data.  Check API Key")
        return
    inf = inflation[inflation.date >= f"{start_year}-01-01"]

    if external_axes is None:
        _, ax = plt.subplots(figsize=plot_autoscale(), dpi=cfp.PLOT_DPI)

    else:
        if len(external_axes) != 1:
            logger.error("Expected list of one axis item.")
            console.print("[red]Expected list of 1 axis item./n[/red]")
            return
        (ax, ) = external_axes

    ax.plot(inf.date, inf.Inflation, marker="o")
    ax.set_title(f"US Inflation from {list(inf.date)[-1].year}")
    ax.set_ylabel("Inflation (%)")
    theme.style_primary_axis(ax)
    if external_axes is None:
        theme.visualize_output()

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "inf",
        inflation,
    )
    if raw:
        print_rich_table(
            inf.head(20),
            headers=["Date", "Inflation"],
            show_index=False,
            title="US Inflation",
        )
        console.print("")
Пример #19
0
def display_ema_cross(
    ticker: str,
    df_stock: pd.DataFrame,
    short_ema: int,
    long_ema: int,
    spy_bt: bool = True,
    no_bench: bool = False,
    shortable: bool = True,
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
):  # pylint: disable=R0913
    """Strategy where we go long/short when EMA(short) is greater than/less than EMA(short)

    Parameters
    ----------
    ticker : str
        Stock ticker
    df_stock : pd.Dataframe
        Dataframe of prices
    short_ema : int
        Length of short ema window
    long_ema : int
        Length of long ema window
    spy_bt : bool
        Boolean to add spy comparison
    no_bench : bool
        Boolean to not show buy and hold comparison
    shortable : bool
        Boolean to allow for selling of the stock at cross
    export : str
        Format to export data
    external_axes : Optional[List[plt.Axes]], optional
        External axes (3 axes are expected in the list), by default None
    """
    # This plot has 1 axis
    if not external_axes:
        _, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
    else:
        if len(external_axes) != 1:
            logger.error("Expected list of one axis item.")
            console.print("[red]Expected list of one axis item./n[/red]")
            return
        (ax, ) = external_axes

    res = bt_model.ema_cross_strategy(ticker, df_stock, short_ema, long_ema,
                                      spy_bt, no_bench, shortable)
    res.plot(title=f"EMA Cross for EMA({short_ema})/EMA({long_ema})", ax=ax)

    theme.style_primary_axis(ax)

    if not external_axes:
        theme.visualize_output()

    export_data(export, os.path.dirname(os.path.abspath(__file__)),
                "ema_cross", res.stats)
Пример #20
0
def display_regions(
    ticker: str,
    num: int = 5,
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Plot bars of regions based on stock's interest. [Source: Google]

    Parameters
    ----------
    ticker : str
        Ticker
    num: int
        Number of regions to show
    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
    """
    df_interest_region = google_model.get_regions(ticker)

    # 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:
            logger.error("Expected list of one axis item.")
            console.print("[red]Expected list of one axis item./n[/red]")
            return
        (ax, ) = external_axes

    if df_interest_region.empty:
        console.print("No region data found.")
        console.print("")
        return

    df_interest_region = df_interest_region.sort_values(
        [ticker], ascending=False).head(num)
    df = df_interest_region.sort_values([ticker], ascending=True)

    ax.set_title(f"Top's regions interest on {ticker}")
    ax.barh(y=df.index,
            width=df[ticker],
            color=theme.get_colors(reverse=True),
            zorder=3)
    ax.set_xlabel("Interest [%]")
    ax.set_ylabel("Region")
    theme.style_primary_axis(ax)

    if external_axes is None:
        theme.visualize_output()

    export_data(export, os.path.dirname(os.path.abspath(__file__)), "regions",
                df)
Пример #21
0
def display_qqplot(
    name: str,
    df: pd.DataFrame,
    target: str,
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Show QQ plot for data against normal quantiles

    Parameters
    ----------
    name : str
        Stock ticker
    df : pd.DataFrame
        Dataframe
    target : str
        Column in data to look at
    external_axes : Optional[List[plt.Axes]], optional
        External axes (1 axis is expected in the list), by default None
    """
    # Statsmodels has a UserWarning for marker kwarg-- which we don't use
    warnings.filterwarnings(category=UserWarning, action="ignore")
    data = df[target]

    # 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:
            logger.error("Expected list of one axis item.")
            console.print("[red]Expected list of 1 axis items./n[/red]")
            return
        (ax, ) = external_axes

    qqplot(
        data,
        stats.distributions.norm,
        fit=True,
        line="45",
        color=theme.down_color,
        ax=ax,
    )
    ax.get_lines()[1].set_color(theme.up_color)

    ax.set_title(f"Q-Q plot for {name} {target}")
    ax.set_ylabel("Sample quantiles")
    ax.set_xlabel("Theoretical quantiles")

    theme.style_primary_axis(ax)

    if external_axes is None:
        theme.visualize_output()
Пример #22
0
def display_btc_confirmed_transactions(
    since: int,
    until: int,
    export: str,
    external_axes: Optional[List[plt.Axes]] = None,
) -> None:
    """Returns BTC confirmed transactions [Source: https://api.blockchain.info/]

    Parameters
    ----------
    since : int
        Initial date timestamp (e.g., 1_609_459_200)
    until : int
        End date timestamp (e.g., 1_641_588_030)
    export : str
        Export dataframe data to csv,json,xlsx file
    external_axes : Optional[List[plt.Axes]], optional
        External axes (1 axis is expected in the list), by default None
    """

    df = blockchain_model.get_btc_confirmed_transactions()
    df = df[
        (df["x"] > datetime.fromtimestamp(since))
        & (df["x"] < datetime.fromtimestamp(until))
    ]

    # This plot has 1 axis
    if not external_axes:
        _, 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(df["x"], df["y"], lw=0.8)
    ax.set_ylabel("Transactions")
    ax.set_title("BTC Confirmed Transactions")
    ax.get_yaxis().set_major_formatter(
        ticker.FuncFormatter(lambda x, _: lambda_long_number_format(x))
    )

    theme.style_primary_axis(ax)

    if not external_axes:
        theme.visualize_output()

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "btcct",
        df,
    )
Пример #23
0
def display_vol_surface(
    ticker: str,
    export: str = "",
    z: str = "IV",
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Display vol surface

    Parameters
    ----------
    ticker : str
        Ticker to get surface for
    export : str
        Format to export data
    z : str
        The variable for the Z axis
    """
    data = yfinance_model.get_iv_surface(ticker)
    if data.empty:
        console.print(f"No options data found for {ticker}.\n")
        return
    X = data.dte
    Y = data.strike
    if z == "IV":
        Z = data.impliedVolatility
        label = "Volatility"
    elif z == "OI":
        Z = data.openInterest
        label = "Open Interest"
    elif z == "LP":
        Z = data.lastPrice
        label = "Last Price"
    if external_axes is None:
        fig = plt.figure()
        ax = plt.axes(projection="3d")
    else:
        ax = external_axes[0]
    ax.plot_trisurf(X, Y, Z, cmap="jet", linewidth=0.2)
    ax.set_xlabel("DTE")
    ax.set_ylabel("Strike")
    ax.set_zlabel(z)

    if external_axes is None:
        fig.suptitle(f"{label} Surface for {ticker.upper()}")
        theme.visualize_output(force_tight_layout=False)

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "vsurf",
        data,
    )
Пример #24
0
def realtime_performance_sector(
    raw: bool,
    export: str,
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Display Real-Time Performance sector. [Source: AlphaVantage]

    Parameters
    ----------
    raw : bool
        Output only raw data
    export : str
        Export dataframe data to csv,json,xlsx file
    external_axes : Optional[List[plt.Axes]], optional
        External axes (1 axis is expected in the list), by default None
    """
    df_sectors = alphavantage_model.get_sector_data()

    # pylint: disable=E1101
    if df_sectors.empty:
        return

    # pylint: disable=invalid-sequence-index
    df_rtp = df_sectors["Rank A: Real-Time Performance"]

    df_rtp = df_rtp.apply(lambda x: x * 100)

    if raw:
        print_rich_table(
            df_rtp.to_frame(),
            show_index=True,
            headers=["Sector", "Real-Time Performance"],
            title="Real-Time Performance",
        )

    else:
        ax = df_rtp.plot(kind="barh")
        theme.style_primary_axis(ax)
        ax.set_title("Real Time Performance (%) per Sector")
        ax.tick_params(axis="x", labelrotation=90)
        ax.xaxis.set_major_formatter(
            matplotlib.ticker.FormatStrFormatter("%.2f"))

        if external_axes is None:
            theme.visualize_output()

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "rtps",
        df_sectors,
    )
Пример #25
0
def display_simple_ema(
    ticker: str,
    df_stock: pd.DataFrame,
    ema_length: int,
    spy_bt: bool = True,
    no_bench: bool = False,
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Strategy where stock is bought when Price > EMA(l)

    Parameters
    ----------
    ticker : str
        Stock ticker
    df_stock : pd.Dataframe
        Dataframe of prices
    ema_length : int
        Length of ema window
    spy_bt : bool
        Boolean to add spy comparison
    no_bench : bool
        Boolean to not show buy and hold comparison
    export : bool
        Format to export backtest results
    external_axes : Optional[List[plt.Axes]], optional
        External axes (3 axes are expected in the list), by default None
    """

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

    res = bt_model.ema_strategy(ticker, df_stock, ema_length, spy_bt, no_bench)
    res.plot(title=f"Equity for EMA({ema_length})", ax=ax)

    theme.style_primary_axis(ax)

    if not external_axes:
        theme.visualize_output()

    console.print(res.display(), "\n")

    export_data(export, os.path.dirname(os.path.abspath(__file__)),
                "simple_ema", res.stats)
def display_volume(
    similar_tickers: List[str],
    start: str = (datetime.now() - timedelta(days=366)).strftime("%Y-%m-%d"),
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Display volume stock prices. [Source: Yahoo Finance]

    Parameters
    ----------
    similar_tickers : List[str]
        List of similar tickers
    start : str, optional
        Start date of comparison, by default 1 year ago
    export : str, optional
        Format to export historical prices, by default ""
    external_axes : Optional[List[plt.Axes]], optional
        External axes (1 axis is expected in the list), by default None
    """
    df_similar = yahoo_finance_model.get_historical(similar_tickers, start, "v")
    df_similar = df_similar[similar_tickers]

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

    df_similar = df_similar.div(1_000_000)
    companies_names = df_similar.columns.to_list()

    ax.plot(df_similar, label=companies_names)
    ax.set_title("Historical volume of similar companies")
    ax.set_ylabel("Volume [M]")
    # ensures that the historical data starts from same datapoint
    ax.set_xlim([df_similar.index[0], df_similar.index[-1]])

    ax.legend()
    theme.style_primary_axis(ax)

    if not external_axes:
        theme.visualize_output()

    export_data(
        export, os.path.dirname(os.path.abspath(__file__)), "volume", df_similar
    )
    console.print("")
Пример #27
0
def display_put_call_ratio(
    ticker: str,
    window: int = 30,
    start_date: str = (datetime.now() -
                       timedelta(days=366)).strftime("%Y-%m-%d"),
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Display put call ratio [Source: AlphaQuery.com]

    Parameters
    ----------
    ticker : str
        Stock ticker
    window : int, optional
        Window length to look at, by default 30
    start_date : str, optional
        Starting date for data, by default (datetime.now() - timedelta(days=366)).strftime("%Y-%m-%d")
    export : str, optional
        Format to export data, by default ""
    external_axes : Optional[List[plt.Axes]], optional
        External axes (1 axis is expected in the list), by default None
    """
    pcr = alphaquery_model.get_put_call_ratio(ticker, window, start_date)
    if pcr.empty:
        console.print("No data found.\n")
        return

    if not external_axes:
        _, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
    else:
        if len(external_axes) != 1:
            logger.error("Expected list of one axis item.")
            console.print("[red]Expected list of one axis item./n[/red]")
            return
        (ax, ) = external_axes

    ax.plot(pcr.index, pcr.values)
    ax.set_title(f"Put Call Ratio for {ticker.upper()}")
    theme.style_primary_axis(ax)

    if not external_axes:
        theme.visualize_output()

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "pcr",
        pcr,
    )
Пример #28
0
def display_allocation(
    portfolio: portfolio_model.Portfolio,
    export: str = "",
    external_axes: Optional[plt.Axes] = None,
):
    """Display allocation of assets vs time

    Parameters
    ----------
    portfolio: Portfolio
        Portfolio object with trades loaded
    export: str
        Format to export plot
    external_axes: plt.Axes
        Optional axes to display plot on
    """
    portfolio.generate_holdings_from_trades()
    all_holdings = pd.concat(
        [
            portfolio.portfolio["StockHoldings"],
            portfolio.portfolio["ETFHoldings"],
            portfolio.portfolio["CryptoHoldings"],
        ],
        axis=1,
    )
    all_holdings = all_holdings.drop(columns=["temp"])

    if external_axes is None:
        _, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
    else:
        ax = external_axes
    all_holdings.plot(ax=ax)
    ax.set_title("Individual Asset Holdings")
    if len(all_holdings.columns) > 10:
        legend_columns = round(len(all_holdings.columns) / 5)
    elif len(all_holdings.columns) > 40:
        legend_columns = round(len(all_holdings.columns) / 10)
    else:
        legend_columns = 1
    ax.legend(loc="upper left", ncol=legend_columns)
    ax.set_ylabel("Holdings ($)")
    theme.style_primary_axis(ax)
    if external_axes is None:
        theme.visualize_output()

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "rolling",
    )
Пример #29
0
def display_dupont(
    ticker: str,
    raw: bool = False,
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Shows the extended dupont ratio

    Parameters
    ----------
    ticker : str
        Fundamental analysis ticker symbol
    raw : str
        Show raw data instead of a graph
    export : bool
        Whether to export the dupont breakdown
    external_axes : Optional[List[plt.Axes]], optional
        External axes (1 axis is expected in the list), by default None
    """
    df = av_model.get_dupont(ticker)
    if df.empty:
        console.print("[red]Invalid response from AlphaVantage[/red]\n")
        return
    if raw:
        print_rich_table(df,
                         headers=list(df.columns),
                         show_index=True,
                         title="Extended Dupont")
        return
    if not external_axes:
        _, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
    else:
        if len(external_axes) != 1:
            logger.error("Expected list of one axis item.")
            console.print("[red]Expected list of one axis item./n[/red]")
            return
        (ax, ) = external_axes

    colors = theme.get_colors()
    df.transpose().plot(kind="line", ax=ax, color=colors)
    ax.set_title("Extended Dupont by Year")
    theme.style_primary_axis(ax)

    if not external_axes:
        theme.visualize_output()

    console.print("")
    export_data(export, os.path.dirname(os.path.abspath(__file__)), "dupont",
                df)
Пример #30
0
def get_plot(
    data: pd.DataFrame,
    dataset: str,
    column: str,
    export: str = "",
    external_axes: Optional[List[plt.axes]] = None,
):
    """Plot data from a dataset

    Parameters
    ----------
    data: pd.DataFrame
        Dataframe of custom data
    dataset: str
        Dataset name
    column: str
        Column for y data
    export: str
        Format to export image
    external_axes:Optional[List[plt.axes]]
        External axes to plot on
    """
    if isinstance(data.index, pd.MultiIndex):
        console.print(
            "The index appears to be a multi-index. "
            "Therefore, it is not possible to plot the data."
        )
    else:
        if external_axes is None:
            _, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
        else:
            ax = external_axes[0]

        if isinstance(data, pd.Series):
            ax.plot(data)
        elif isinstance(data, pd.DataFrame):
            ax.plot(data[column])

        ax.set_title(f"{column} data from dataset {dataset}")
        theme.style_primary_axis(ax)

        if external_axes is None:
            theme.visualize_output()

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        f"{column}_{dataset}_plot",
    )