def net_working_capital(stock: str, date: datetime = datetime.now(), lookback_period: timedelta = timedelta(days=0),
                        period: str = '',
                        exclude_current_portion_cash_and_debt=False,
                        only_include_payables_receivables_inventory=False):
    # broadest (as it includes all accounts)
    if not (exclude_current_portion_cash_and_debt or only_include_payables_receivables_inventory):
        return fi.current_total_assets(stock=stock, date=date, lookback_period=lookback_period, period=period) \
               - fi.current_total_liabilities(stock=stock, date=date, lookback_period=lookback_period, period=period)

    if exclude_current_portion_cash_and_debt:  # more narrow
        return (fi.current_total_assets(stock=stock, date=date, lookback_period=lookback_period, period=period) -
                fi.cash_and_cash_equivalents(stock=stock, date=date, lookback_period=lookback_period, period=period)) \
               - (fi.current_total_liabilities(stock=stock, date=date, lookback_period=lookback_period, period=period)
                  - fi.long_term_debt_current_maturities(stock=stock, date=date, lookback_period=lookback_period,
                                                         period=period))

    if only_include_payables_receivables_inventory:  # most narrow
        return fi.net_accounts_receivable(stock=stock, date=date, lookback_period=lookback_period, period=period) \
               + fi.net_inventory(stock=stock, date=date, lookback_period=lookback_period, period=period) \
               - fi.accounts_payable(stock=stock, date=date, lookback_period=lookback_period, period=period)
def invested_capital(stock: str, date: datetime = datetime.now(), lookback_period: timedelta = timedelta(days=0),
                     period: str = '', operating_approach=True):
    if operating_approach:
        return net_working_capital(stock=stock, date=date, lookback_period=lookback_period, period=period,
                                   exclude_current_portion_cash_and_debt=True) \
               + fi.net_property_plant_equipment(stock=stock, date=date, lookback_period=lookback_period, period=period) \
               + fi.total_intangible_assets(stock=stock, date=date, lookback_period=lookback_period, period=period)
    else:  # investing approach
        return fi.current_total_liabilities(stock=stock, date=date, lookback_period=lookback_period, period=period) \
               + fi.long_term_debt_excluding_current_portion(stock, date, lookback_period=timedelta(days=0),
                                                             period=period) \
               + fi.total_shareholders_equity(stock=stock, date=date, lookback_period=lookback_period, period=period) \
               + fi.cash_flow_financing_activities(stock=stock, date=date, lookback_period=lookback_period,
                                                   period=period) \
               + fi.cash_flow_investing_activities(stock=stock, date=date, lookback_period=lookback_period,
                                                   period=period)
def ohlson_o_score(stock: str,
                   date: datetime = datetime.now(),
                   lookback_period: timedelta = timedelta(days=0),
                   period: str = 'TTM'):
    TA = financials.total_assets(stock=stock,
                                 date=date,
                                 lookback_period=lookback_period,
                                 period=period)
    GNP = macroeconomic_analysis.gross_national_product_price_index(date)
    TL = financials.total_liabilities(stock=stock,
                                      date=date,
                                      lookback_period=lookback_period,
                                      period=period)
    WC = metrics.net_working_capital(stock=stock,
                                     date=date,
                                     lookback_period=lookback_period,
                                     period=period)
    CL = financials.current_total_liabilities(stock=stock,
                                              date=date,
                                              lookback_period=lookback_period,
                                              period=period)
    CA = financials.current_total_assets(stock=stock,
                                         date=date,
                                         lookback_period=lookback_period,
                                         period=period)
    X = 1 if TL > TA else 0
    NI = financials.net_income(stock=stock,
                               date=date,
                               lookback_period=lookback_period,
                               period=period)
    NI_prev = financials.net_income(stock=stock,
                                    date=date,
                                    lookback_period=lookback_period,
                                    period=period)
    FFO = financials.cash_flow_operating_activities(
        stock=stock, date=date, lookback_period=lookback_period, period=period)
    Y = 1 if (NI < 0 and NI_prev < 0) else 0
    return -1.32 - 0.407 * np.log(TA / GNP) + 6.03 * (TL / TA) - 1.43 * (WC / TA) + 0.0757 * (CL / CA) - 1.72 * X \
           - 2.37 * (NI / TA) - 1.83 * (FFO / TL) + 0.285 * Y - 0.521 * ((NI - NI_prev) / (abs(NI) + abs(NI_prev)))
def capital_employed(stock: str, date: datetime = datetime.now(), lookback_period: timedelta = timedelta(days=0),
                     period: str = ''):
    return fi.total_assets(stock=stock, date=date, lookback_period=lookback_period, period=period) \
           - fi.current_total_liabilities(stock=stock, date=date, lookback_period=lookback_period, period=period)
def beneish_m_score(stock: str,
                    date: datetime = datetime.now(),
                    lookback_period: timedelta = timedelta(days=0),
                    period: str = 'TTM',
                    describe=False):
    current_net_accounts_receivable = fi.net_accounts_receivable(
        stock=stock, date=date, lookback_period=lookback_period, period=period)
    current_net_sales = fi.net_sales(stock=stock,
                                     date=date,
                                     lookback_period=lookback_period,
                                     period=period)
    current_receivables_to_sales = current_net_accounts_receivable / current_net_sales

    previous_net_accounts_receivable = fi.net_accounts_receivable(
        stock=stock,
        date=date - timedelta(days=365 if period == 'FY' else 90),
        lookback_period=lookback_period,
        period=period)
    previous_net_sales = fi.net_sales(
        stock=stock,
        date=date - timedelta(days=365 if period == 'FY' else 90),
        lookback_period=lookback_period,
        period=period)
    previous_receivables_to_sales = previous_net_accounts_receivable / previous_net_sales

    DSRI = current_receivables_to_sales / previous_receivables_to_sales

    previous_gross_profit_margin = ratios.gross_profit_margin(
        stock=stock,
        date=date - timedelta(days=365 if period == 'FY' else 90),
        lookback_period=lookback_period,
        period=period)
    current_gross_profit_margin = ratios.gross_profit_margin(
        stock=stock, date=date, lookback_period=lookback_period, period=period)

    GMI = previous_gross_profit_margin / current_gross_profit_margin

    current_asset_quality = 1 - (fi.current_total_assets(
        stock=stock, date=date, lookback_period=lookback_period, period=period
    ) + fi.net_property_plant_equipment(
        stock=stock, date=date, lookback_period=lookback_period, period=period
    ) + fi.current_marketable_securities(
        stock=stock, date=date, lookback_period=lookback_period,
        period=period))
    previous_asset_quality = 1 - (fi.current_total_assets(
        stock=stock,
        date=date - timedelta(days=365 if period == 'FY' else 90),
        lookback_period=lookback_period,
        period=period) + fi.net_property_plant_equipment(
            stock=stock,
            date=date - timedelta(days=365 if period == 'FY' else 90),
            lookback_period=lookback_period,
            period=period) + fi.current_marketable_securities(
                stock=stock,
                date=date - timedelta(days=365 if period == 'FY' else 90),
                lookback_period=lookback_period,
                period=period))
    AQI = current_asset_quality / previous_asset_quality

    SGI = fi.net_sales(stock=stock, date=date, lookback_period=lookback_period, period=period) \
          / fi.net_sales(stock=stock, date=date - timedelta(days=365 if period == 'FY' else 90),
                         lookback_period=lookback_period, period=period)

    current_depreciation = fi.accumulated_depreciation_amortization(stock=stock, date=date,
                                                                    lookback_period=lookback_period, period=period) \
                           / (fi.net_property_plant_equipment(stock=stock, date=date, lookback_period=lookback_period,
                                                              period=period)
                              + fi.accumulated_depreciation_amortization(stock=stock, date=date,
                                                                         lookback_period=lookback_period,
                                                                         period=period))
    previous_depreciation = fi.accumulated_depreciation_amortization(stock=stock,
                                                                     date=date - timedelta(
                                                                         days=365 if period == 'FY' else 90),
                                                                     lookback_period=lookback_period, period=period) \
                            / (fi.net_property_plant_equipment(stock=stock,
                                                               date=date - timedelta(
                                                                   days=365 if period == 'FY' else 90),
                                                               lookback_period=lookback_period, period=period)
                               + fi.accumulated_depreciation_amortization(stock=stock, date=date - timedelta(
                days=365 if period == 'FY' else 90), lookback_period=lookback_period, period=period))

    DEPI = previous_depreciation / current_depreciation

    SGAI = (fi.selling_general_administrative(stock=stock, date=date, lookback_period=lookback_period, period=period)
            / fi.net_sales(stock=stock, date=date, lookback_period=lookback_period, period=period)) \
           / (fi.selling_general_administrative(stock=stock, date=date - timedelta(days=365 if period == 'FY' else 90),
                                                lookback_period=lookback_period, period=period)
              / fi.net_sales(stock=stock, date=date - timedelta(days=365 if period == 'FY' else 90),
                             lookback_period=lookback_period, period=period))

    previous_leverage = (fi.current_total_liabilities(stock=stock,
                                                      date=date - timedelta(days=365 if period == 'FY' else 90),
                                                      lookback_period=lookback_period, period=period) +
                         fi.total_long_term_debt(stock=stock, date=date - timedelta(days=365 if period == 'FY' else 90),
                                                 lookback_period=lookback_period, period=period)) \
                        / fi.total_assets(stock=stock, date=date - timedelta(days=365 if period == 'FY' else 90),
                                          lookback_period=lookback_period, period=period)
    current_leverage = (fi.current_total_liabilities(stock=stock, date=date, lookback_period=lookback_period,
                                                     period=period)
                        + fi.total_long_term_debt(stock=stock, date=date, lookback_period=lookback_period,
                                                  period=period)) \
                       / fi.total_assets(stock=stock, date=date, lookback_period=lookback_period, period=period)
    LVGI = current_leverage / previous_leverage

    TATA = (fi.operating_income(stock=stock, date=date, lookback_period=lookback_period, period=period)
            - fi.cash_flow_operating_activities(stock=stock, date=date, lookback_period=lookback_period, period=period)) \
           / fi.total_assets(stock=stock, date=date, lookback_period=lookback_period, period=period)

    if not describe:
        return -4.84 + 0.92 * DSRI + 0.528 * GMI + 0.404 * AQI + 0.892 * SGI + 0.115 * DEPI - 0.172 * SGAI + 4.679 * TATA - 0.327 * LVGI
    else:
        return {'Inputs': {}}