def get_stocks_data(stocks: list, finance_key: str, sa_dict: dict,
                    stocks_data: dict, period: str):
    """Get stocks data based on a list of stocks and the finance key. The function searches for the correct
     financial statement automatically. [Source: StockAnalysis]

    Parameters
    ----------
    stocks: list
        A list of tickers that will be used to collect data for.
    finance_key: str
        The finance key used to search within the sa_dict for the correct name of item
        on the financial statement
    sa_dict: dict
        A dictionary that includes BS, IS and CF, the abbreviations and names of items
        on the financial statements. I.e: {"BS": {"ce": "Cash & Equivalents"}}
    stocks_data : dict
        A dictionary that is empty on initialisation but filled once data is collected
        for the first time.
    period : str
        Whether you want annually, quarterly or trailing financial statements.

    Returns
    -------
    dict
        Dictionary of filtered stocks data separated by financial statement
    """
    no_data = []
    for symbol in tqdm(stocks):
        for statement in sa_dict.keys():
            if finance_key in sa_dict[statement]:
                if statement not in stocks_data:
                    stocks_data[statement] = {}
                used_statement = statement
                symbol_statement = create_dataframe(symbol, statement,
                                                    period.lower())

                if symbol_statement[0].empty:
                    no_data.append(symbol)
                    continue

                stocks_data[statement][symbol] = (
                    change_type_dataframes(symbol_statement[0]) *
                    symbol_statement[1])

    if period in ["Quarterly", "Trailing"]:
        for symbol in stocks_data[used_statement]:
            stocks_data[used_statement][symbol].columns = (
                stocks_data[used_statement][symbol].columns.map(
                    lambda x: pd.Period(x, "Q")).astype(str))

    stocks_data[used_statement] = match_length_dataframes(
        stocks_data[used_statement])

    if no_data:
        console.print(
            f"No data available for {', '.join(str(symbol) for symbol in no_data)}"
        )

    return stocks_data
예제 #2
0
    def get_data(self, statement: str, row: int, header: bool) -> pd.DataFrame:
        df, rounding, _ = dcf_model.create_dataframe(self.info["ticker"],
                                                     statement)
        if df.empty:
            raise ValueError("Could generate a dataframe for the ticker")
        self.info["rounding"] = rounding
        if not self.info["len_data"]:
            self.info["len_data"] = len(df.columns)

        self.ws[1][f"A{row}"] = dcf_static.statement_titles[statement]
        self.ws[1][f"A{row}"].font = dcf_static.bold_font

        rowI = row + 1
        names = df.index.values.tolist()

        for name in names:
            self.ws[1][f"A{rowI}"] = name
            if name in dcf_static.sum_rows:
                length = self.info["len_data"] + (self.info["len_pred"]
                                                  if statement != "CF" else 0)
                for i in range(length):
                    if statement == "CF" and name == "Net Income":
                        pass
                    else:
                        self.ws[1][
                            f"{dcf_static.letters[i+1]}{rowI}"].font = dcf_static.bold_font
                        self.ws[1][
                            f"{dcf_static.letters[i+1]}{rowI}"].border = dcf_static.thin_border_top
            rowI += 1

        column = 1

        for key, value in df.iteritems():
            rowI = row
            if header:
                dcf_model.set_cell(
                    self.ws[1],
                    f"{dcf_static.letters[column]}{rowI}",
                    float(key),
                    font=dcf_static.bold_font,
                )
            for item in value:
                rowI += 1
                m = 0 if item is None else float(item.replace(",", ""))
                dcf_model.set_cell(
                    self.ws[1],
                    f"{dcf_static.letters[column]}{rowI}",
                    m,
                    num_form="[$$-409]#,##0.00;[RED]-[$$-409]#,##0.00",
                )
            column += 1

        return df
예제 #3
0
def get_stocks_data(
    stocks: list,
    finance_key: str,
    sa_dict: dict,
    stocks_data: dict,
    period: str,
    convert_currency: str = "USD",
):
    """Get stocks data based on a list of stocks and the finance key. The function searches for the correct
     financial statement automatically. [Source: StockAnalysis]

    Parameters
    ----------
    stocks: list
        A list of tickers that will be used to collect data for.
    finance_key: str
        The finance key used to search within the sa_dict for the correct name of item
        on the financial statement
    sa_dict: dict
        A dictionary that includes BS, IS and CF, the abbreviations and names of items
        on the financial statements. I.e: {"BS": {"ce": "Cash & Equivalents"}}
    stocks_data : dict
        A dictionary that is empty on initialisation but filled once data is collected
        for the first time.
    period : str
        Whether you want annually, quarterly or trailing financial statements.
    convert_currency : str
        Choose in what currency you wish to convert each company's financial statement. Default is USD (US Dollars).

    Returns
    -------
    dict
        Dictionary of filtered stocks data separated by financial statement
    """
    no_data = []
    for symbol in tqdm(stocks):
        for statement in sa_dict.keys():
            if finance_key in sa_dict[statement]:
                if statement not in stocks_data:
                    stocks_data[statement] = {}
                used_statement = statement
                symbol_statement, rounding, currency = create_dataframe(
                    symbol, statement, period.lower())

                if symbol_statement.empty:
                    no_data.append(symbol)
                    continue

                symbol_statement_rounded = (
                    change_type_dataframes(symbol_statement) * rounding)

                if convert_currency and convert_currency != currency:
                    currency_data = yf.download(
                        f"{currency}{convert_currency}=X",
                        start=f"{symbol_statement_rounded.columns[0]}-01-01",
                        end=f"{symbol_statement_rounded.columns[-1]}-12-31",
                        progress=False,
                    )["Adj Close"]

                    for year in symbol_statement_rounded:
                        # Since fiscal year can differ, I take the median of the currency and not the last value
                        # of the year
                        symbol_statement_rounded[year] = (
                            symbol_statement_rounded[year] *
                            currency_data.loc[year].median())

                stocks_data[statement][symbol] = symbol_statement_rounded

    if period in ["Quarterly", "Trailing"]:
        for symbol in stocks_data[used_statement]:
            stocks_data[used_statement][symbol].columns = (
                stocks_data[used_statement][symbol].columns.map(
                    lambda x: pd.Period(x, "Q")).astype(str))

    stocks_data[used_statement] = match_length_dataframes(
        stocks_data[used_statement])

    if no_data:
        console.print(
            f"No data available for {', '.join(str(symbol) for symbol in no_data)}"
        )

    return stocks_data