def get_quote(ticker) -> pd.DataFrame:
    """Gets ticker quote from FMP"""
    try:
        df_fa = fa.quote(ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
    except ValueError:
        df_fa = pd.DataFrame()

    if not df_fa.empty:
        clean_df_index(df_fa)
        df_fa.loc["Market cap"][0] = lambda_long_number_format(
            df_fa.loc["Market cap"][0]
        )
        df_fa.loc["Shares outstanding"][0] = lambda_long_number_format(
            df_fa.loc["Shares outstanding"][0]
        )
        df_fa.loc["Volume"][0] = lambda_long_number_format(df_fa.loc["Volume"][0])
        # Check if there is a valid earnings announcement
        if df_fa.loc["Earnings announcement"][0]:
            earning_announcement = datetime.strptime(
                df_fa.loc["Earnings announcement"][0][0:19], "%Y-%m-%dT%H:%M:%S"
            )
            df_fa.loc["Earnings announcement"][
                0
            ] = f"{earning_announcement.date()} {earning_announcement.time()}"
    return df_fa
def get_quote(ticker) -> pd.DataFrame:
    """Gets ticker quote from FMP"""

    df_fa = pd.DataFrame()

    try:
        df_fa = fa.quote(ticker, cfg.API_KEY_FINANCIALMODELINGPREP)
    # Invalid API Keys
    except ValueError:
        console.print("[red]Invalid API Key[/red]\n")
    # Premium feature, API plan is not authorized
    except HTTPError:
        console.print("[red]API Key not authorized for Premium feature[/red]\n")

    if not df_fa.empty:
        clean_df_index(df_fa)
        df_fa.loc["Market cap"][0] = lambda_long_number_format(
            df_fa.loc["Market cap"][0]
        )
        df_fa.loc["Shares outstanding"][0] = lambda_long_number_format(
            df_fa.loc["Shares outstanding"][0]
        )
        df_fa.loc["Volume"][0] = lambda_long_number_format(df_fa.loc["Volume"][0])
        # Check if there is a valid earnings announcement
        if df_fa.loc["Earnings announcement"][0]:
            earning_announcement = datetime.strptime(
                df_fa.loc["Earnings announcement"][0][0:19], "%Y-%m-%dT%H:%M:%S"
            )
            df_fa.loc["Earnings announcement"][
                0
            ] = f"{earning_announcement.date()} {earning_announcement.time()}"
    return df_fa
Exemple #3
0
def get_shareholders(ticker: str) -> Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
    """Get shareholders from yahoo

    Parameters
    ----------
    ticker : str
        Stock ticker

    Returns
    -------
    pd.DataFrame
        Major holders
    pd.DataFrame
        Institutional holders
    pd.DataFrame
        Mutual Fund holders
    """
    stock = yf.Ticker(ticker)

    # Major holders
    df_major_holders = stock.major_holders
    df_major_holders[1] = df_major_holders[1].apply(
        lambda x: x.replace("%", "Percentage")
    )

    # Institutional holders
    df_institutional_shareholders = stock.institutional_holders
    df_institutional_shareholders.columns = (
        df_institutional_shareholders.columns.str.replace("% Out", "Stake")
    )
    df_institutional_shareholders["Shares"] = df_institutional_shareholders[
        "Shares"
    ].apply(lambda x: lambda_long_number_format(x))
    df_institutional_shareholders["Value"] = df_institutional_shareholders[
        "Value"
    ].apply(lambda x: lambda_long_number_format(x))
    df_institutional_shareholders["Stake"] = df_institutional_shareholders[
        "Stake"
    ].apply(lambda x: str(f"{100 * x:.2f}") + " %")

    # Mutualfunds holders
    df_mutualfund_shareholders = stock.mutualfund_holders
    df_mutualfund_shareholders.columns = df_mutualfund_shareholders.columns.str.replace(
        "% Out", "Stake"
    )
    df_mutualfund_shareholders["Shares"] = df_mutualfund_shareholders["Shares"].apply(
        lambda x: lambda_long_number_format(x)
    )
    df_mutualfund_shareholders["Value"] = df_mutualfund_shareholders["Value"].apply(
        lambda x: lambda_long_number_format(x)
    )
    df_mutualfund_shareholders["Stake"] = df_mutualfund_shareholders["Stake"].apply(
        lambda x: str(f"{100 * x:.2f}") + " %"
    )

    return df_major_holders, df_institutional_shareholders, df_mutualfund_shareholders
Exemple #4
0
def get_calendar_earnings(ticker: str) -> pd.DataFrame:
    """Get calendar earnings for ticker

    Parameters
    ----------
    ticker : [type]
        Stock ticker

    Returns
    -------
    pd.DataFrame
        Dataframe of calendar earnings
    """
    stock = yf.Ticker(ticker)
    df_calendar = stock.calendar

    if df_calendar.empty:
        return pd.DataFrame()

    df_calendar.iloc[0, :] = df_calendar.iloc[0, :].apply(
        lambda x: x.date().strftime("%m/%d/%Y"))

    df_calendar.iloc[1:, :] = df_calendar.iloc[1:, :].applymap(
        lambda x: lambda_long_number_format(x))

    return df_calendar
def clean_metrics_df(df_fa: pd.DataFrame, num: int, mask: bool = True) -> pd.DataFrame:
    """Clean metrics data frame

    Parameters
    ----------
    df_fa : pd.DataFrame
        Metrics data frame
    num : int
        Number of columns to clean
    mask : bool, optional
        Apply mask, by default True

    Returns
    -------
    pd.DataFrame
        Cleaned metrics data frame
    """

    df_fa = df_fa.iloc[:, 0:num]
    if mask:
        df_fa = df_fa.mask(df_fa.astype(object).eq(num * ["None"])).dropna()
        df_fa = df_fa.mask(df_fa.astype(object).eq(num * ["0"])).dropna()
    df_fa = df_fa.applymap(lambda x: lambda_long_number_format(x))
    clean_df_index(df_fa)
    df_fa.columns.name = "Fiscal Date Ending"
    df_fa = df_fa.rename(
        index={
            "Enterprise value over e b i t d a": "Enterprise value over EBITDA",
            "Net debt to e b i t d a": "Net debt to EBITDA",
            "D c f": "DCF",
            "Net income per e b t": "Net income per EBT",
        }
    )

    return df_fa
def short_interest(ticker: str, nyse: bool, days: int, raw: bool, export: str):
    """Plots the short interest of a stock. This corresponds to the
    number of shares that have been sold short but have not yet been
    covered or closed out. Either NASDAQ or NYSE [Source: Quandl]

    Parameters
    ----------
    ticker : str
        ticker to get short interest from
    nyse : bool
        data from NYSE if true, otherwise NASDAQ
    days : int
        Number of past days to show short interest
    raw : bool
        Flag to print raw data instead
    export : str
        Export dataframe data to csv,json,xlsx file
    """
    df_short_interest = quandl_model.get_short_interest(ticker, nyse)

    df_short_interest = df_short_interest.tail(days)

    df_short_interest.columns = [
        "".join(" " + char if char.isupper() else char.strip()
                for char in idx).strip()
        for idx in df_short_interest.columns.tolist()
    ]
    pd.options.mode.chained_assignment = None

    vol_pct = (100 * df_short_interest["Short Volume"].values /
               df_short_interest["Total Volume"].values)
    df_short_interest["% of Volume Shorted"] = [
        round(pct, 2) for pct in vol_pct
    ]

    if raw:
        df_short_interest["% of Volume Shorted"] = df_short_interest[
            "% of Volume Shorted"].apply(lambda x: f"{x/100:.2%}")
        df_short_interest = df_short_interest.applymap(
            lambda x: lambda_long_number_format(x)).sort_index(ascending=False)

        df_short_interest.index = df_short_interest.index.date

        print_rich_table(
            df_short_interest,
            headers=list(df_short_interest.columns),
            show_index=True,
            title="Short Interest of Stock",
        )

    console.print("")

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "psi(quandl)",
        df_short_interest,
    )
Exemple #7
0
def display_crypto_hacks(
    top: int, sortby: str, descend: bool, slug: str, export: str = ""
) -> None:
    """Display list of major crypto-related hacks. If slug is passed
    individual crypto hack is displayed instead of list of crypto hacks
    [Source: https://rekt.news]

    Parameters
    ----------
    slug: str
        Crypto hack slug to check (e.g., polynetwork-rekt)
    top: int
        Number of hacks to search
    sortby: str
        Key by which to sort data {Platform,Date,Amount [$],Audit,Slug,URL}
    descend: bool
        Flag to sort data descending
    export : str
        Export dataframe data to csv,json,xlsx file
    """
    if slug:
        text = rekt_model.get_crypto_hack(slug)
        if text:
            console.print(text)
        export_data(
            export,
            os.path.dirname(os.path.abspath(__file__)),
            "ch",
            text,
        )
    else:
        df = rekt_model.get_crypto_hacks()

        if df.empty:
            console.print("\nError in rekt request\n")
        else:
            if sortby in rekt_model.HACKS_COLUMNS:
                df = df.sort_values(by=sortby, ascending=descend)
            df["Amount [$]"] = df["Amount [$]"].apply(
                lambda x: lambda_long_number_format(x)
            )
            df["Date"] = df["Date"].dt.date

            print_rich_table(
                df.head(top),
                headers=list(df.columns),
                floatfmt=".1f",
                show_index=False,
                title="Major Crypto Hacks",
            )
            console.print("")

            export_data(
                export,
                os.path.dirname(os.path.abspath(__file__)),
                "ch",
                df,
            )
Exemple #8
0
def get_key_metrics(ticker: str) -> pd.DataFrame:
    """Get key metrics from overview

    Parameters
    ----------
    ticker : str
        Stock ticker

    Returns
    -------
    pd.DataFrame
        Dataframe of key metrics
    """
    # Request OVERVIEW data
    s_req = f"https://www.alphavantage.co/query?function=OVERVIEW&symbol={ticker}&apikey={cfg.API_KEY_ALPHAVANTAGE}"
    result = requests.get(s_req, stream=True)

    # If the returned data was unsuccessful
    if "Error Message" in result.json():
        console.print(result.json()["Error Message"])
    else:
        # check if json is empty
        if not result.json() or len(result.json()) < 2:
            console.print("No data found")
            return pd.DataFrame()

        df_fa = pd.json_normalize(result.json())
        df_fa = df_fa[list(result.json().keys())].T
        df_fa = df_fa.applymap(lambda x: lambda_long_number_format(x))
        clean_df_index(df_fa)
        df_fa = df_fa.rename(
            index={
                "E b i t d a": "EBITDA",
                "P e ratio": "PE ratio",
                "P e g ratio": "PEG ratio",
                "E p s": "EPS",
                "Return on equity t t m": "Return on equity TTM",
                "Price to sales ratio t t m": "Price to sales ratio TTM",
            }
        )
        as_key_metrics = [
            "Market capitalization",
            "EBITDA",
            "EPS",
            "PE ratio",
            "PEG ratio",
            "Price to book ratio",
            "Return on equity TTM",
            "Price to sales ratio TTM",
            "Dividend yield",
            "50 day moving average",
            "Analyst target price",
            "Beta",
        ]
        return df_fa.loc[as_key_metrics]

    return pd.DataFrame()
Exemple #9
0
def display_whales_transactions(
    min_value: int = 800000,
    top: int = 100,
    sortby: str = "date",
    descend: bool = False,
    show_address: bool = False,
    export: str = "",
) -> None:
    """Display huge value transactions from major blockchains. [Source: https://docs.whale-alert.io/]

    Parameters
    ----------
    min_value: int
        Minimum value of trade to track.
    top: int
        Limit of transactions. Maximum 100
    sortby: str
        Key to sort by.
    descend: str
        Sort in descending order.
    show_address: bool
        Flag to show addresses of transactions.
    export : str
        Export dataframe data to csv,json,xlsx file
    """

    df = whale_alert_model.get_whales_transactions(min_value)

    if df.empty:
        return

    df_data = df.copy()

    df = df.sort_values(by=sortby, ascending=descend)

    if not show_address:
        df = df.drop(["from_address", "to_address"], axis=1)
    else:
        df = df.drop(["from", "to", "blockchain"], axis=1)

    for col in ["amount_usd", "amount"]:
        df[col] = df[col].apply(lambda x: lambda_long_number_format(x))

    print_rich_table(
        df.head(top),
        headers=list(df.columns),
        show_index=False,
        title="Large Value Transactions",
    )
    console.print("")

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "whales",
        df_data,
    )
Exemple #10
0
def display_historical_tvl(
    dapps: str = "",
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Displays historical TVL of different dApps
    [Source: https://docs.llama.fi/api]

    Parameters
    ----------
    dapps: str
        dApps to search historical TVL. Should be split by , e.g.: anchor,sushiswap,pancakeswap
    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
    """

    # 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

    available_protocols = read_data_file("defillama_dapps.json")

    if isinstance(available_protocols, dict):
        for dapp in dapps.split(","):
            if dapp in available_protocols.keys():
                df = llama_model.get_defi_protocol(dapp)
                if not df.empty:
                    ax.plot(df, label=available_protocols[dapp])
            else:
                print(f"{dapp} not found\n")

        ax.set_ylabel("Total Value Locked ($)")
        ax.get_yaxis().set_major_formatter(
            ticker.FuncFormatter(lambda x, _: lambda_long_number_format(x)))
        cfg.theme.style_primary_axis(ax)
        ax.legend()
        ax.set_title("TVL in dApps")

        if not external_axes:
            cfg.theme.visualize_output()

        export_data(
            export,
            os.path.dirname(os.path.abspath(__file__)),
            "dtvl",
            None,
        )
Exemple #11
0
def get_overview(ticker: str) -> pd.DataFrame:
    """Get alpha vantage company overview

    Parameters
    ----------
    ticker : str
        Stock ticker

    Returns
    -------
    pd.DataFrame
        Dataframe of fundamentals
    """
    # Request OVERVIEW data from Alpha Vantage API
    s_req = f"https://www.alphavantage.co/query?function=OVERVIEW&symbol={ticker}&apikey={cfg.API_KEY_ALPHAVANTAGE}"
    result = requests.get(s_req, stream=True)

    # If the returned data was successful
    if result.status_code == 200:
        # Parse json data to dataframe
        if "Note" in result.json():
            console.print(result.json()["Note"], "\n")
            return pd.DataFrame()

        df_fa = pd.json_normalize(result.json())

        # Keep json data sorting in dataframe
        df_fa = df_fa[list(result.json().keys())].T
        df_fa.iloc[5:] = df_fa.iloc[5:].applymap(lambda x: lambda_long_number_format(x))
        clean_df_index(df_fa)
        df_fa = df_fa.rename(
            index={
                "E b i t d a": "EBITDA",
                "P e ratio": "PE ratio",
                "P e g ratio": "PEG ratio",
                "E p s": "EPS",
                "Revenue per share t t m": "Revenue per share TTM",
                "Operating margin t t m": "Operating margin TTM",
                "Return on assets t t m": "Return on assets TTM",
                "Return on equity t t m": "Return on equity TTM",
                "Revenue t t m": "Revenue TTM",
                "Gross profit t t m": "Gross profit TTM",
                "Diluted e p s t t m": "Diluted EPS TTM",
                "Quarterly earnings growth y o y": "Quarterly earnings growth YOY",
                "Quarterly revenue growth y o y": "Quarterly revenue growth YOY",
                "Trailing p e": "Trailing PE",
                "Forward p e": "Forward PE",
                "Price to sales ratio t t m": "Price to sales ratio TTM",
                "E v to revenue": "EV to revenue",
                "E v to e b i t d a": "EV to EBITDA",
            }
        )
        return df_fa
    return pd.DataFrame()
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,
    )
Exemple #13
0
def get_income_statements(
    ticker: str, number: int, quarterly: bool = False
) -> pd.DataFrame:
    """Get income statements for company

    Parameters
    ----------
    ticker : str
        Stock ticker
    number : int
        Number of past to get
    quarterly : bool, optional
        Flag to get quarterly instead of annual, by default False

    Returns
    -------
    pd.DataFrame
        Dataframe of income statements
    """
    url = (
        f"https://www.alphavantage.co/query?function=INCOME_STATEMENT&symbol={ticker}"
        f"&apikey={cfg.API_KEY_ALPHAVANTAGE}"
    )
    r = requests.get(url)

    # If the returned data was unsuccessful
    if "Error Message" in r.json():
        console.print(r.json()["Error Message"])
    else:
        # check if json is empty
        if not r.json():
            console.print("No data found")
        else:
            statements = r.json()
            df_fa = pd.DataFrame()

            if quarterly:
                if "quarterlyReports" in statements:
                    df_fa = pd.DataFrame(statements["quarterlyReports"])
            else:
                if "annualReports" in statements:
                    df_fa = pd.DataFrame(statements["annualReports"])

            if df_fa.empty:
                console.print("No data found")
                return pd.DataFrame()

            df_fa = df_fa.set_index("fiscalDateEnding")
            df_fa = df_fa.head(number)
            df_fa = df_fa.applymap(lambda x: lambda_long_number_format(x))
            return df_fa[::-1].T
    return pd.DataFrame()
def display_terra_asset_history(
    asset: str = "",
    address: str = "",
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
) -> None:
    """Displays the 30-day history of specified asset in terra address
    [Source: https://terra.engineer/]

    Parameters
    ----------
    asset : str
        Terra asset {ust,luna,sdt}
    address : str
        Terra address. Valid terra addresses start with 'terra'
    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 = terraengineer_model.get_history_asset_from_terra_address(
        address=address, asset=asset)

    # 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

    ax.plot(df["x"], df["y"])
    ax.set_ylabel(f"{asset.upper()} Amount")
    ax.set_title(f"{asset.upper()} Amount in {address}")
    ax.get_yaxis().set_major_formatter(
        ticker.FuncFormatter(lambda x, _: lambda_long_number_format(x)))

    cfg.theme.style_primary_axis(ax)

    if not external_axes:
        cfg.theme.visualize_output()

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "aterra",
        df,
    )
Exemple #15
0
def display_defi_tvl(
    top: int,
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
) -> None:
    """Displays historical values of the total sum of TVLs from all listed protocols.
    [Source: https://docs.llama.fi/api]

    Parameters
    ----------
    top: int
        Number of records to display
    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
    """

    # 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 = llama_model.get_defi_tvl()
    df_data = df.copy()
    df = df.tail(top)

    ax.plot(df["date"], df["totalLiquidityUSD"], ms=2)
    # ax.set_xlim(df["date"].iloc[0], df["date"].iloc[-1])

    ax.set_ylabel("Total Value Locked ($)")
    ax.set_title("Total Value Locked in DeFi")
    ax.get_yaxis().set_major_formatter(
        ticker.FuncFormatter(lambda x, _: lambda_long_number_format(x)))
    cfg.theme.style_primary_axis(ax)

    if not external_axes:
        cfg.theme.visualize_output()

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "stvl",
        df_data,
    )
Exemple #16
0
def lambda_long_number_format_with_type_check(
        x: Union[int, float]) -> Union[str, Any]:
    """Helper which checks if type of x is int or float and it's smaller then 10^18.
    If yes it apply long_num_format

    Parameters
    ----------
    x: int/float
        number to apply long_number_format method
    Returns
    -------
    Union[str, Any]
    """

    if isinstance(x, (int, float)) and x < 10**18:
        return lambda_long_number_format(x)
    return x
Exemple #17
0
def plot_data(
    df: pd.DataFrame,
    symbol: str,
    external_axes: Optional[List[plt.Axes]] = None,
):

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

    df_price = df[["price"]].copy()
    df_without_price = df.drop("price", axis=1)

    ax1.stackplot(
        df_without_price.index,
        df_without_price.transpose().to_numpy(),
        labels=df_without_price.columns.tolist(),
    )

    ax1.get_yaxis().set_major_formatter(
        ticker.FuncFormatter(lambda x, _: lambda_long_number_format(x)))
    ax1.legend(df_without_price.columns, fontsize="x-small", ncol=2)
    ax1.set_title(f"Exchange {symbol} Futures Open Interest")
    ax1.set_ylabel("Open futures value[$B]")

    ax2.plot(df_price.index, df_price)
    ax2.legend([f"{symbol} price"])
    ax2.set_ylabel(f"{symbol} Price [$]")
    ax2.set_xlim([df_price.index[0], df_price.index[-1]])
    ax2.set_ylim(bottom=0.0)

    theme.style_primary_axis(ax1)
    theme.style_primary_axis(ax2)

    if not external_axes:
        theme.visualize_output()
def display_anchor_yield_reserve(
        export: str = "",
        external_axes: Optional[List[plt.Axes]] = None) -> None:
    """Displays the 30-day history of the Anchor Yield Reserve.
    [Source: https://terra.engineer/]

    Parameters
    ----------
    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 = terraengineer_model.get_history_asset_from_terra_address(
        address="terra1tmnqgvg567ypvsvk6rwsga3srp7e3lg6u0elp8")

    # 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

    ax.plot(df["x"], df["y"])
    ax.set_ylabel("UST Amount")
    ax.set_title("Anchor UST Yield Reserve")
    ax.get_yaxis().set_major_formatter(
        ticker.FuncFormatter(lambda x, _: lambda_long_number_format(x)))

    cfg.theme.style_primary_axis(ax)

    if not external_axes:
        cfg.theme.visualize_output()

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "ayr",
        df,
    )
Exemple #19
0
def display_trading_pairs(top: int, sortby: str, descend: bool,
                          export: str) -> None:
    """Displays a list of available currency pairs for trading. [Source: Coinbase]

    Parameters
    ----------
    top: int
        Top n of pairs
    sortby: str
        Key to sortby data
    descend: bool
        Sort descending flag
    export : str
        Export dataframe data to csv,json,xlsx file
    """

    df = coinbase_model.get_trading_pairs()
    df_data = df.copy()

    for col in [
            "base_min_size",
            "base_max_size",
            "min_market_funds",
            "max_market_funds",
    ]:
        df[col] = df[col].apply(lambda x: lambda_long_number_format(x))

    df = df.sort_values(by=sortby, ascending=descend).head(top)

    print_rich_table(
        df,
        headers=list(df.columns),
        show_index=False,
        title="Available Pairs for Trading",
    )
    console.print("")

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "pairs",
        df_data,
    )
Exemple #20
0
def get_info(ticker: str) -> pd.DataFrame:
    """Gets ticker info

    Parameters
    ----------
    ticker : str
        Stock ticker

    Returns
    -------
    pd.DataFrame
        DataFrame of yfinance information
    """
    stock = yf.Ticker(ticker)
    df_info = pd.DataFrame(stock.info.items(), columns=["Metric", "Value"])
    df_info = df_info.set_index("Metric")

    clean_df_index(df_info)

    if "Last split date" in df_info.index and df_info.loc[
            "Last split date"].values[0]:
        df_info.loc["Last split date"].values[0] = datetime.fromtimestamp(
            df_info.loc["Last split date"].values[0]).strftime("%Y-%m-%d")

    df_info = df_info.mask(df_info["Value"].astype(str).eq("[]")).dropna()
    df_info[df_info.index != "Zip"] = df_info[df_info.index != "Zip"].applymap(
        lambda x: lambda_long_number_format(x))

    df_info = df_info.rename(
        index={
            "Address1":
            "Address",
            "Average daily volume10 day":
            "Average daily volume 10 day",
            "Average volume10days":
            "Average volume 10 days",
            "Price to sales trailing12 months":
            "Price to sales trailing 12 months",
        })
    df_info.index = df_info.index.str.replace("eps", "EPS")
    df_info.index = df_info.index.str.replace("p e", "PE")
    df_info.index = df_info.index.str.replace("Peg", "PEG")
    return df_info
Exemple #21
0
def get_balance_sheet(
    ticker: str, number: int, quarterly: bool = False
) -> pd.DataFrame:
    """Get balance sheets for company

    Parameters
    ----------
    ticker : str
        Stock ticker
    number : int
        Number of past to get
    quarterly : bool, optional
        Flag to get quarterly instead of annual, by default False

    Returns
    -------
    pd.DataFrame
        Dataframe of income statements
    """
    url = f"https://www.alphavantage.co/query?function=BALANCE_SHEET&symbol={ticker}&apikey={cfg.API_KEY_ALPHAVANTAGE}"
    r = requests.get(url)
    if r.status_code == 200:
        statements = r.json()
        df_fa = pd.DataFrame()
        if quarterly:
            if "quarterlyReports" in statements:
                df_fa = pd.DataFrame(statements["quarterlyReports"])
        else:
            if "annualReports" in statements:
                df_fa = pd.DataFrame(statements["annualReports"])

        if df_fa.empty:
            return pd.DataFrame()

        df_fa = df_fa.set_index("fiscalDateEnding")
        df_fa = df_fa.head(number)
        df_fa = df_fa.applymap(lambda x: lambda_long_number_format(x))
        return df_fa[::-1].T
    return pd.DataFrame()
def display_defi_vaults(
    chain: Optional[str] = None,
    protocol: Optional[str] = None,
    kind: Optional[str] = None,
    top: int = 10,
    sortby: str = "apy",
    descend: bool = False,
    link: bool = False,
    export: str = "",
) -> None:
    """Display Top DeFi Vaults - pools of funds with an assigned strategy which main goal is to
    maximize returns of its crypto assets. [Source: https://coindix.com/]

    Parameters
    ----------
    chain: str
        Blockchain - one from list [
            'ethereum', 'polygon', 'avalanche', 'bsc', 'terra', 'fantom',
            'moonriver', 'celo', 'heco', 'okex', 'cronos', 'arbitrum', 'eth',
            'harmony', 'fuse', 'defichain', 'solana', 'optimism'
        ]
    protocol: str
        DeFi protocol - one from list: [
            'aave', 'acryptos', 'alpaca', 'anchor', 'autofarm', 'balancer', 'bancor',
            'beefy', 'belt', 'compound', 'convex', 'cream', 'curve', 'defichain', 'geist',
            'lido', 'liquity', 'mirror', 'pancakeswap', 'raydium', 'sushi', 'tarot', 'traderjoe',
            'tulip', 'ubeswap', 'uniswap', 'venus', 'yearn'
        ]
    kind: str
        Kind/type of vault - one from list: ['lp','single','noimploss','stable']
    top: int
        Number of records to display
    sortby: str
        Key by which to sort data
    descend: bool
        Flag to sort data descending
    link: bool
        Flag to show links
    export : str
        Export dataframe data to csv,json,xlsx file
    """

    df = coindix_model.get_defi_vaults(chain=chain,
                                       protocol=protocol,
                                       kind=kind)
    df_data = df.copy()
    if df.empty:
        print(
            f"Couldn't find any vaults for "
            f"{'' if not chain else 'chain: ' + chain}{'' if not protocol else ', protocol: ' + protocol}"
            f"{'' if not kind else ', kind:' + kind}")
        return

    df = df.sort_values(by=sortby, ascending=descend)
    df["tvl"] = df["tvl"].apply(lambda x: lambda_long_number_format(x))
    df["apy"] = df["apy"].apply(lambda x: f"{str(round(x * 100, 2))} %"
                                if isinstance(x, (int, float)) else x)
    df.columns = [x.title() for x in df.columns]
    df.rename(columns={"Apy": "APY (%)", "Tvl": "TVL ($)"}, inplace=True)

    if link is True:
        df.drop("Link", axis=1, inplace=True)

    print_rich_table(
        df.head(top),
        headers=list(df.columns),
        show_index=False,
        title="Top DeFi Vaults",
    )
    console.print("")

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "vaults",
        df_data,
    )
Exemple #23
0
def ownership_command(
    preset: str = "template", sort: str = "", limit: int = 5, ascend: bool = False
):
    """Displays stocks based on own share float and ownership data [Finviz]"""

    # Check for argument
    if preset == "template" or preset not in so.all_presets:
        raise Exception("Invalid preset selected!")

    # Debug
    if imps.DEBUG:
        logger.debug("scr-ownership %s %s %s %s", preset, sort, limit, ascend)

    # Check for argument
    if limit < 0:
        raise Exception("Number has to be above 0")

    # Output Data
    df_screen = get_screener_data(
        preset,
        "ownership",
        limit,
        ascend,
    )

    title = "Stocks: [Finviz] Ownership Screener"
    if isinstance(df_screen, pd.DataFrame):
        if df_screen.empty:
            raise Exception("No data found.")

        df_screen = df_screen.dropna(axis="columns", how="all")

        if sort:
            if sort in so.d_cols_to_sort["ownership"]:
                df_screen = df_screen.sort_values(
                    by=sort,
                    ascending=ascend,
                    na_position="last",
                )
            else:
                similar_cmd = difflib.get_close_matches(
                    " ".join(sort),
                    so.d_cols_to_sort["ownership"],
                    n=1,
                    cutoff=0.7,
                )
                if similar_cmd:
                    df_screen = df_screen.sort_values(
                        by=[similar_cmd[0]],
                        ascending=ascend,
                        na_position="last",
                    )
                else:
                    raise ValueError(
                        f"Wrong sort column provided! Select from: {', '.join(so.d_cols_to_sort['ownership'])}"
                    )

    df_screen.set_index("Ticker", inplace=True)
    df_screen = df_screen.head(n=limit)
    df_screen = df_screen.fillna("-")
    dindex = len(df_screen.index)
    df_screen = df_screen.applymap(lambda x: lambda_long_number_format(x, 2))

    if dindex > 5:
        embeds: list = []
        # Output
        i, i2, end = 0, 0, 5
        df_pg, embeds_img, images_list = pd.DataFrame(), [], []
        while i < dindex:
            df_pg = df_screen.iloc[i:end]
            df_pg.append(df_pg)
            fig = imps.plot_df(
                df_pg.transpose(),
                fig_size=(800, 720),
                col_width=[2, 1.5],
                tbl_header=imps.PLT_TBL_HEADER,
                tbl_cells=imps.PLT_TBL_CELLS,
                font=imps.PLT_TBL_FONT,
                row_fill_color=imps.PLT_TBL_ROW_COLORS,
                paper_bgcolor="rgba(0, 0, 0, 0)",
            )
            fig.update_traces(cells=(dict(align=["center", "right"])))
            imagefile = "scr_ownership.png"
            imagefile = imps.save_image(imagefile, fig)

            if imps.IMAGES_URL or not imps.IMG_HOST_ACTIVE:
                image_link = imps.multi_image(imagefile)
                images_list.append(imagefile)
            else:
                image_link = imps.multi_image(imagefile)

            embeds_img.append(
                f"{image_link}",
            )
            embeds.append(
                disnake.Embed(
                    title=title,
                    colour=imps.COLOR,
                ),
            )
            i2 += 1
            i += 5
            end += 5

        # Author/Footer
        for i in range(0, i2):
            embeds[i].set_author(
                name=imps.AUTHOR_NAME,
                url=imps.AUTHOR_URL,
                icon_url=imps.AUTHOR_ICON_URL,
            )
            embeds[i].set_footer(
                text=imps.AUTHOR_NAME,
                icon_url=imps.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)}")
        choices = [
            disnake.SelectOption(label="Home", value="0", emoji="🟢"),
        ]

        output = {
            "view": imps.Menu,
            "title": title,
            "embed": embeds,
            "choices": choices,
            "embeds_img": embeds_img,
            "images_list": images_list,
        }
    else:
        fig = imps.plot_df(
            df_screen.transpose(),
            fig_size=(800, 720),
            col_width=[2, 1.5],
            tbl_header=imps.PLT_TBL_HEADER,
            tbl_cells=imps.PLT_TBL_CELLS,
            font=imps.PLT_TBL_FONT,
            row_fill_color=imps.PLT_TBL_ROW_COLORS,
            paper_bgcolor="rgba(0, 0, 0, 0)",
        )
        fig.update_traces(cells=(dict(align=["center", "right"])))
        imagefile = imps.save_image("scr_ownership.png", fig)

        output = {
            "title": title,
            "imagefile": imagefile,
        }

    return output
def display_defi_protocols(top: int,
                           sortby: str,
                           descend: bool,
                           description: bool,
                           export: str = "") -> None:
    """Display information about listed DeFi protocols, their current TVL and changes to it in the last hour/day/week.
    [Source: https://docs.llama.fi/api]

    Parameters
    ----------
    top: int
        Number of records to display
    sortby: str
        Key by which to sort data
    descend: bool
        Flag to sort data descending
    description: bool
        Flag to display description of protocol
    export : str
        Export dataframe data to csv,json,xlsx file
    """

    df = llama_model.get_defi_protocols()
    df_data = df.copy()

    df = df.sort_values(by=sortby, ascending=descend)
    df = df.drop(columns="chain")

    df["tvl"] = df["tvl"].apply(lambda x: lambda_long_number_format(x))

    if not description:
        df.drop(["description", "url"], axis=1, inplace=True)
    else:
        df = df[[
            "name",
            "symbol",
            "category",
            "description",
            "url",
        ]]

    df.columns = [
        lambda_replace_underscores_in_column_names(val) for val in df.columns
    ]
    df.rename(
        columns={
            "Change 1H": "Change 1H (%)",
            "Change 1D": "Change 1D (%)",
            "Change 7D": "Change 7D (%)",
            "Tvl": "TVL ($)",
        },
        inplace=True,
    )

    print_rich_table(df.head(top), headers=list(df.columns), show_index=False)
    console.print("")

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)),
        "ldapps",
        df_data,
    )
def display_bw(
    name: str,
    df: pd.DataFrame,
    target: str,
    yearly: bool,
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Show box and whisker plots

    Parameters
    ----------
    name : str
        Name of dataset
    df : pd.DataFrame
        Dataframe to look at
    target : str
        Data column to look at
    yearly : bool
        Flag to indicate yearly accumulation
    external_axes : Optional[List[plt.Axes]], optional
        External axes (1 axis is expected in the list), by default None
    """
    data = df[target]
    start = df.index[0]

    # 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

    color = theme.get_colors()[0]
    if yearly:
        x_data = data.index.year
    else:
        x_data = data.index.month
    box_plot = sns.boxplot(
        x=x_data,
        y=data,
        ax=ax,
        zorder=3,
        boxprops=dict(edgecolor=color),
        flierprops=dict(
            linestyle="--",
            color=color,
            markerfacecolor=theme.up_color,
            markeredgecolor=theme.up_color,
        ),
        whiskerprops=dict(color=color),
        capprops=dict(color=color),
    )

    box_plot.set(
        xlabel=["Monthly", "Yearly"][yearly],
        ylabel=target,
        title=
        f"{['Monthly','Yearly'][yearly]} box plot of {name} {target} from {start.strftime('%Y-%m-%d')}",
    )
    l_months = [
        "Jan",
        "Feb",
        "Mar",
        "Apr",
        "May",
        "Jun",
        "Jul",
        "Aug",
        "Sep",
        "Oct",
        "Nov",
        "Dec",
    ]
    l_ticks = list()
    if not yearly:
        for val in box_plot.get_xticklabels():
            l_ticks.append(l_months[int(val.get_text()) - 1])
        box_plot.set_xticklabels(l_ticks)

    # remove the scientific notion on the left hand side
    ax.ticklabel_format(style="plain", axis="y")
    ax.get_yaxis().set_major_formatter(
        matplotlib.ticker.FuncFormatter(
            lambda x, _: lambda_long_number_format(x)))

    theme.style_primary_axis(ax)

    if external_axes is None:
        theme.visualize_output()
Exemple #26
0
def performance_command(economy_group="sector"):
    """Performance of sectors, industry, country [Finviz]"""

    d_economy_group = {
        "sector": "Sector",
        "industry": "Industry",
        "basic_materials": "Industry (Basic Materials)",
        "communication_services": "Industry (Communication Services)",
        "consumer_cyclical": "Industry (Consumer Cyclical)",
        "consumer_defensive": "Industry (Consumer Defensive)",
        "energy": "Industry (Energy)",
        "financial": "Industry (Financial)",
        "healthcare": "Industry (Healthcare)",
        "industrials": "Industry (Industrials)",
        "real_estate": "Industry (Real Estate)",
        "technology": "Industry (Technology)",
        "utilities": "Industry (Utilities)",
        "country": "Country (U.S. listed stocks only)",
        "capitalization": "Capitalization",
    }

    # Debug user input
    if imps.DEBUG:
        logger.debug("econ-performance %s", economy_group)

    # Select default group
    if not economy_group:
        if imps.DEBUG:
            logger.debug("Use default economy_group: 'sector'")
        economy_group = "sector"

    # Check for argument
    possible_groups = list(d_economy_group.keys())

    if economy_group not in possible_groups:
        possible_group_list = ", ".join(possible_groups)
        raise Exception(f"Select a valid group from {possible_group_list}")  # nosec

    group = d_economy_group[economy_group]

    # Retrieve data
    df_group = finviz_model.get_valuation_performance_data(group, "performance")

    # Check for argument
    if df_group.empty:
        raise Exception("No available data found")

    # Output data
    df = pd.DataFrame(df_group)

    df["Volume"] = df["Volume"] / 1_000_000
    df["Avg Volume"] = df["Avg Volume"] / 1_000_000

    formats = {
        "Perf Month": "{:.2f}",
        "Perf Quart": "{:.2f}%",
        "Perf Half": "{:.2f}%",
        "Perf Year": "{:.2f}%",
        "Perf YTD": "{:.2f}%",
        "Avg Volume": "{:.0f}M",
        "Change": "{:.2f}%",
        "Volume": "{:.0f}M",
    }
    for col, value in formats.items():
        df[col] = df[col].map(lambda x: value.format(x))  # pylint: disable=W0640

    df = df.set_axis(
        [
            "Name",
            "Week",
            "Month",
            "3 Mouth",
            "6 Mouth",
            "1 Year",
            "YTD",
            "Recom",
            "Avg Volume",
            "Rel Volume",
            "Change",
            "Volume",
        ],
        axis="columns",
    )
    df.set_index("Name", inplace=True)
    df = df.fillna("-")
    df = df.applymap(lambda x: lambda_long_number_format(x, 2))

    title = f"Economy: [WSJ] Performance {group}"

    dindex = len(df.index)
    if dindex > 2:
        embeds: list = []
        # Output
        i, i2, end = 0, 0, 2
        df_pg, embeds_img, images_list = pd.DataFrame(), [], []
        while i < dindex:
            df_pg = df.iloc[i:end]
            df_pg.append(df_pg)
            fig = imps.plot_df(
                df_pg.transpose(),
                fig_size=(800, 720),
                col_width=[6, 10],
                tbl_header=imps.PLT_TBL_HEADER,
                tbl_cells=imps.PLT_TBL_CELLS,
                font=imps.PLT_TBL_FONT,
                row_fill_color=imps.PLT_TBL_ROW_COLORS,
                paper_bgcolor="rgba(0, 0, 0, 0)",
            )
            fig.update_traces(cells=(dict(align=["center", "right"])))
            imagefile = "econ_performance.png"
            imagefile = imps.save_image(imagefile, fig)

            if imps.IMAGES_URL or not imps.IMG_HOST_ACTIVE:
                image_link = imps.multi_image(imagefile)
                images_list.append(imagefile)
            else:
                image_link = imps.multi_image(imagefile)

            embeds_img.append(
                f"{image_link}",
            )
            embeds.append(
                disnake.Embed(
                    title=title,
                    colour=imps.COLOR,
                ),
            )
            i2 += 1
            i += 2
            end += 2

        # Author/Footer
        for i in range(0, i2):
            embeds[i].set_author(
                name=imps.AUTHOR_NAME,
                url=imps.AUTHOR_URL,
                icon_url=imps.AUTHOR_ICON_URL,
            )
            embeds[i].set_footer(
                text=imps.AUTHOR_NAME,
                icon_url=imps.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)}")
        choices = [
            disnake.SelectOption(label="Home", value="0", emoji="🟢"),
        ]

        output = {
            "view": imps.Menu,
            "title": title,
            "embed": embeds,
            "choices": choices,
            "embeds_img": embeds_img,
            "images_list": images_list,
        }
    else:
        fig = imps.plot_df(
            df.transpose(),
            fig_size=(800, 720),
            col_width=[6, 10],
            tbl_header=imps.PLT_TBL_HEADER,
            tbl_cells=imps.PLT_TBL_CELLS,
            font=imps.PLT_TBL_FONT,
            row_fill_color=imps.PLT_TBL_ROW_COLORS,
            paper_bgcolor="rgba(0, 0, 0, 0)",
        )
        fig.update_traces(cells=(dict(align=["center", "right"])))
        imagefile = imps.save_image("econ_performance.png", fig)

        output = {
            "title": title,
            "imagefile": imagefile,
        }

    return output
Exemple #27
0
def display_line(
    data: pd.Series,
    title: str = "",
    log_y: bool = True,
    draw: bool = False,
    markers_lines: Optional[List[datetime]] = None,
    markers_scatter: Optional[List[datetime]] = None,
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
):
    """Display line plot of data

    Parameters
    ----------
    data: pd.Series
        Data to plot
    title: str
        Title for plot
    log_y: bool
        Flag for showing y on log scale
    draw: bool
        Flag for drawing lines and annotating on the plot
    markers_lines: Optional[List[datetime]]
        List of dates to highlight using vertical lines
    markers_scatter: Optional[List[datetime]]
        List of dates to highlight using scatter
    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
    """
    # 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

    if log_y:
        ax.semilogy(data.index, data.values)
        ax.yaxis.set_major_formatter(matplotlib.ticker.ScalarFormatter())
        ax.yaxis.set_major_locator(
            matplotlib.ticker.LogLocator(base=100, subs=[1.0, 2.0, 5.0, 10.0]))
        ax.ticklabel_format(style="plain", axis="y")

    else:
        ax.plot(data.index, data.values)

        if markers_lines:
            ymin, ymax = ax.get_ylim()
            ax.vlines(markers_lines, ymin, ymax, color="#00AAFF")

        if markers_scatter:
            for n, marker_date in enumerate(markers_scatter):
                price_location_idx = data.index.get_loc(marker_date,
                                                        method="nearest")
                # algo to improve text placement of highlight event number
                if (0 < price_location_idx < (len(data) - 1)
                        and data.iloc[price_location_idx - 1] >
                        data.iloc[price_location_idx]
                        and data.iloc[price_location_idx + 1] >
                        data.iloc[price_location_idx]):
                    text_loc = (0, -20)
                else:
                    text_loc = (0, 10)
                ax.annotate(
                    str(n + 1),
                    (mdates.date2num(marker_date),
                     data.iloc[price_location_idx]),
                    xytext=text_loc,
                    textcoords="offset points",
                )
                ax.scatter(
                    marker_date,
                    data.iloc[price_location_idx],
                    color="#00AAFF",
                    s=100,
                )

    data_type = data.name
    ax.set_ylabel(data_type)
    ax.set_xlim(data.index[0], data.index[-1])
    ax.ticklabel_format(style="plain", axis="y")
    ax.get_yaxis().set_major_formatter(
        matplotlib.ticker.FuncFormatter(
            lambda x, _: lambda_long_number_format(x)))

    if title:
        ax.set_title(title)
    if draw:
        LineAnnotateDrawer(ax).draw_lines_and_annotate()

    theme.style_primary_axis(ax)

    if external_axes is None:
        theme.visualize_output()

    export_data(
        export,
        os.path.dirname(os.path.abspath(__file__)).replace("common", "stocks"),
        "line",
    )
def screener(
    loaded_preset: str,
    data_type: str,
    limit: int = 10,
    ascend: bool = False,
    sort: str = "",
    export: str = "",
) -> List[str]:
    """Screener one of the following: overview, valuation, financial, ownership, performance, technical.

    Parameters
    ----------
    loaded_preset: str
        Preset loaded to filter for tickers
    data_type : str
        Data type string between: overview, valuation, financial, ownership, performance, technical
    limit : int
        Limit of stocks to display
    ascend : bool
        Order of table to ascend or descend
    sort: str
        Column to sort table by
    export : str
        Export dataframe data to csv,json,xlsx file

    Returns
    -------
    List[str]
        List of stocks that meet preset criteria
    """
    with suppress_stdout():
        df_screen = get_screener_data(
            preset_loaded=loaded_preset,
            data_type=data_type,
            limit=10,
            ascend=ascend,
        )

    if isinstance(df_screen, pd.DataFrame):
        if df_screen.empty:
            return []

        df_screen = df_screen.dropna(axis="columns", how="all")

        if sort:
            if sort in d_cols_to_sort[data_type]:
                df_screen = df_screen.sort_values(
                    by=[sort],
                    ascending=ascend,
                    na_position="last",
                )
            else:
                similar_cmd = difflib.get_close_matches(
                    sort,
                    d_cols_to_sort[data_type],
                    n=1,
                    cutoff=0.7,
                )
                if similar_cmd:
                    console.print(
                        f"Replacing '{' '.join(sort)}' by '{similar_cmd[0]}' so table can be sorted."
                    )
                    df_screen = df_screen.sort_values(
                        by=[similar_cmd[0]],
                        ascending=ascend,
                        na_position="last",
                    )
                else:
                    console.print(
                        f"Wrong sort column provided! Provide one of these: {', '.join(d_cols_to_sort[data_type])}"
                    )

        df_screen = df_screen.fillna("")

        if data_type == "ownership":
            cols = [
                "Market Cap", "Outstanding", "Float", "Avg Volume", "Volume"
            ]
            df_screen[cols] = df_screen[cols].applymap(
                lambda x: lambda_long_number_format(x, 1))
        elif data_type == "overview":
            cols = ["Market Cap", "Volume"]
            df_screen[cols] = df_screen[cols].applymap(
                lambda x: lambda_long_number_format(x, 1))
        elif data_type == "technical":
            cols = ["Volume"]
            df_screen[cols] = df_screen[cols].applymap(
                lambda x: lambda_long_number_format(x, 1))
        elif data_type == "valuation":
            cols = ["Market Cap", "Volume"]
            df_screen[cols] = df_screen[cols].applymap(
                lambda x: lambda_long_number_format(x, 1))
        elif data_type == "financial":
            cols = ["Market Cap", "Volume"]
            df_screen[cols] = df_screen[cols].applymap(
                lambda x: lambda_long_number_format(x, 1))
        elif data_type == "performance":
            cols = ["Avg Volume", "Volume"]
            df_screen[cols] = df_screen[cols].applymap(
                lambda x: lambda_long_number_format(x, 1))
        elif data_type == "technical":
            cols = ["Volume"]
            df_screen[cols] = df_screen[cols].applymap(
                lambda x: lambda_long_number_format(x, 1))

        print_rich_table(
            df_screen.head(n=limit),
            headers=list(df_screen.columns),
            show_index=False,
            title="Finviz Screener",
        )
        console.print("")

        export_data(
            export,
            os.path.dirname(os.path.abspath(__file__)),
            data_type,
            df_screen,
        )

        return list(df_screen.head(n=limit)["Ticker"].values)

    console.print("")
    return []
Exemple #29
0
def pos_command(sort="dpp_dollar", ascending: bool = False, num: int = 10):
    """Dark pool short position [Stockgrid]"""

    # Debug user input
    if imps.DEBUG:
        logger.debug("dps-pos %s %s", sort, num)

    # Check for argument
    possible_sorts = ("sv", "sv_pct", "nsv", "nsv_dollar", "dpp", "dpp_dollar")

    if sort not in possible_sorts:
        raise Exception(f"The possible sorts are: {', '.join(possible_sorts)}")

    if num < 0:
        raise Exception("Number has to be above 0")

    # Retrieve data
    df = stockgrid_model.get_dark_pool_short_positions(sort, ascending)

    if df.empty:
        raise Exception("No available data found")

    df = df.iloc[:num]

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

    # Output data
    title = "Stocks: [Stockgrid] Dark Pool Short Position"
    df = df.applymap(lambda x: lambda_long_number_format(x, 2))
    df = df.drop(columns=["Date"])
    formats = {
        "Short Volume %": "{}%",
        "Net Short Volume $": "${}",
        "Dark Pools Position $": "${}",
    }
    for col, f in formats.items():
        df[col] = df[col].map(lambda x: f.format(x))  # pylint: disable=W0640

    df["Short Volume"] = df.apply(
        lambda x: f"{x['Short Volume']}  (<b>{x['Short Volume %']}</b>)",
        axis=1)
    df["Net Short Volume"] = df.apply(
        lambda x:
        f"{x['Net Short Volume']:>9} (<b>{x['Net Short Volume $']:>9}</b>)",
        axis=1,
    )
    df["Dark Pools Position"] = df.apply(
        lambda x:
        f"{x['Dark Pools Position']:>9}  (<b>{x['Dark Pools Position $']:>9}</b>)",
        axis=1,
    )
    df = df.drop(columns=[
        "Short Volume %", "Net Short Volume $", "Dark Pools Position $"
    ])
    df.columns = [
        "Ticker",
        "Short Vol.",
        "Net Short Vol.",
        "DP Position",
    ]
    df.set_index("Ticker", inplace=True)
    dindex = len(df.index)
    if dindex > 15:
        embeds: list = []
        # Output
        i, i2, end = 0, 0, 15
        df_pg, embeds_img, images_list = [], [], []
        while i < dindex:
            df_pg = df.iloc[i:end]
            df_pg.append(df_pg)
            fig = imps.plot_df(
                df_pg,
                fig_size=(720, (40 * dindex)),
                col_width=[2, 4, 4, 4],
                tbl_header=imps.PLT_TBL_HEADER,
                tbl_cells=imps.PLT_TBL_CELLS,
                font=imps.PLT_TBL_FONT,
                row_fill_color=imps.PLT_TBL_ROW_COLORS,
                paper_bgcolor="rgba(0, 0, 0, 0)",
            )
            fig.update_traces(cells=(dict(align=["center", "right"])))
            imagefile = "dps-pos.png"
            imagefile = imps.save_image(imagefile, fig)

            if imps.IMAGES_URL or not imps.IMG_HOST_ACTIVE:
                image_link = imps.multi_image(imagefile)
                images_list.append(imagefile)
            else:
                image_link = imps.multi_image(imagefile)

            embeds_img.append(f"{image_link}", )
            embeds.append(disnake.Embed(
                title=title,
                colour=imps.COLOR,
            ), )
            i2 += 1
            i += 15
            end += 15

        # Author/Footer
        for i in range(0, i2):
            embeds[i].set_author(
                name=imps.AUTHOR_NAME,
                url=imps.AUTHOR_URL,
                icon_url=imps.AUTHOR_ICON_URL,
            )
            embeds[i].set_footer(
                text=imps.AUTHOR_NAME,
                icon_url=imps.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)}")
        choices = [
            disnake.SelectOption(label="Home", value="0", emoji="🟢"),
        ]

        output = {
            "view": imps.Menu,
            "title": title,
            "embed": embeds,
            "choices": choices,
            "embeds_img": embeds_img,
            "images_list": images_list,
        }
    else:
        fig = imps.plot_df(
            df,
            fig_size=(720, (40 * dindex)),
            col_width=[2, 4, 4, 4],
            tbl_header=imps.PLT_TBL_HEADER,
            tbl_cells=imps.PLT_TBL_CELLS,
            font=imps.PLT_TBL_FONT,
            row_fill_color=imps.PLT_TBL_ROW_COLORS,
            paper_bgcolor="rgba(0, 0, 0, 0)",
        )
        fig.update_traces(cells=(dict(align=["center", "right"])))
        imagefile = imps.save_image("dps-pos.png", fig)

        output = {
            "title": title,
            "imagefile": imagefile,
        }

    return output
def display_account_growth(
    kind: str = "total",
    cumulative: bool = False,
    top: int = 90,
    export: str = "",
    external_axes: Optional[List[plt.Axes]] = None,
) -> None:
    """Display terra blockchain account growth history [Source: https://fcd.terra.dev/swagger]

    Parameters
    ----------
    top: int
        Number of records to display
    kind: str
        display total account count or active account count. One from list [active, total]
    cumulative: bool
        Flag to show cumulative or discrete values. For active accounts only discrete value are available.
    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 = terramoney_fcd_model.get_account_growth(cumulative)
    if kind not in ["active", "total"]:
        kind = "total"
    options = {"total": "Total accounts", "active": "Active accounts"}

    opt = options[kind]
    label = "Cumulative" if cumulative and opt == "total" else "Daily"

    # 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 = df.sort_values("date", ascending=False).head(top)
    df = df.set_index("date")

    start, end = df.index[-1], df.index[0]

    if cumulative:
        ax.plot(df[opt], label=df[opt])
    else:
        ax.bar(x=df.index, height=df[opt], label=df[opt])

    ax.set_ylabel(f"{opt}")
    ax.get_yaxis().set_major_formatter(
        ticker.FuncFormatter(lambda x, _: lambda_long_number_format(x)))
    ax.set_title(
        f"{label} number of {opt.lower()} in period from {start} to {end}")
    cfg.theme.style_primary_axis(ax)

    if not external_axes:
        cfg.theme.visualize_output()

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