def market_capitalization(stock: str, diluted_shares: bool = False, date: datetime = datetime.now(), lookback_period: timedelta = timedelta(days=0), period: str = 'Q'): shares_outstanding = fi.total_shares_outstanding(stock=stock, date=date, lookback_period=lookback_period, period=period, diluted_shares=diluted_shares) output = market_price(stock, date, lookback_period) * shares_outstanding * 1000000 # TODO hotfix! print('Market Capitalization for {} on the {} is: {}'.format(stock, date, output)) return output
def dividend_per_share(stock: str, date: datetime = datetime.now(), lookback_period: timedelta = timedelta(days=0), period: str = '', diluted_shares: bool = True, deduct_preferred_dividends: bool = False): dividends_paid = fi.payments_for_dividends(stock=stock, date=date, lookback_period=lookback_period, period=period) dividends_paid -= abs(fi.preferred_dividends(stock=stock, date=date, lookback_period=lookback_period, period=period)) if deduct_preferred_dividends else 0 shares_outstanding = fi.total_shares_outstanding(stock=stock, diluted_shares=diluted_shares, date=date, lookback_period=lookback_period, period=period) return abs(dividends_paid) / shares_outstanding
def cash_flow_per_share(cash_flow_metric, stock, date=datetime.today(), lookback_period=timedelta(days=0), period: str = '', diluted_shares=True): cash_flow = cash_flow_metric(stock=stock, date=date, lookback_period=lookback_period, period=period) shares_outstanding = fi.total_shares_outstanding( stock=stock, date=date, lookback_period=lookback_period, period=period, diluted_shares=diluted_shares) return cash_flow / shares_outstanding
def piotroski_f_score(stock: str, date: datetime = datetime.now(), lookback_period: timedelta = timedelta(days=0), period: str = 'TTM', diluted_shares=True): piotroski_dictio = { 'Profitability': {}, 'Financial Leverage, Liquidity, and Source of Funds': {}, 'Operating Efficiency': {}, 'Piotroski F-Score': { ' ': { ' ': {0} } } } # Return on Assets (1 point if it is positive in the current year, 0 otherwise) return_on_assets_current_year = ratios.return_on_assets( stock=stock, date=date, lookback_period=lookback_period, period=period) piotroski_dictio['Profitability']['Return on Assets'] = { 'Return on Assets Current Year': '{:.4f}'.format(return_on_assets_current_year), 'ROA Positive in the Current Year ?': return_on_assets_current_year > 0 } # Operating Cash Flow (1 point if it is positive in the current year, 0 otherwise) operating_cash_flow_current_year = financials.cash_flow_operating_activities( stock=stock, date=date, lookback_period=lookback_period, period=period) piotroski_dictio['Profitability']['Operating Cash Flow'] = { 'Operating Cash Flow Current Year': '{:.2f}'.format(operating_cash_flow_current_year), 'OCF Positive in the Current Year ?': operating_cash_flow_current_year > 0 } # Change in Return of Assets (ROA) (1 point if ROA is higher in the current year compared to the previous one, # 0 otherwise) return_on_assets_previous_year = ratios.return_on_assets( stock=stock, date=date, lookback_period=timedelta(days=365), period=period) piotroski_dictio['Profitability']['Change in Return of Assets'] = { 'Return on Assets Current Year': '{:.4f}'.format(return_on_assets_current_year), 'Return on Assets Previous Year': '{:.4f}'.format(return_on_assets_previous_year), 'ROA Current Year > ROA Previous Year ?': return_on_assets_current_year > return_on_assets_previous_year } # Accruals (1 point if Operating Cash Flow/Total Assets is higher than ROA in the current year, 0 otherwise) total_assets_current_year = financials.total_assets( stock=stock, date=date, lookback_period=lookback_period, period=period) accruals = operating_cash_flow_current_year / total_assets_current_year piotroski_dictio['Profitability']['Accruals'] = { 'Operating Cash Flow Current Year': '{}'.format(operating_cash_flow_current_year), 'Total Assets Current Year': '{}'.format(total_assets_current_year), 'Accruals Current Year': '{:.4f}'.format(accruals), 'ROA Current Year': '{:.4f}'.format(return_on_assets_current_year), 'Accruals Current Year > ROA Current Year ?': accruals > return_on_assets_current_year } # Change in Leverage (long-term) ratio (1 point if the ratio is lower this year compared to the previous one, # 0 otherwise) debt_to_assets_current_year = ratios.debt_ratio( stock=stock, date=date, lookback_period=lookback_period, period=period) debt_to_assets_previous_year = ratios.debt_ratio( stock=stock, date=date, lookback_period=timedelta(days=365), period=period) piotroski_dictio['Financial Leverage, Liquidity, and Source of Funds'][ 'Change in Leverage Ratio'] = { 'Debt to Assets Current Year': '{:.4f}'.format(debt_to_assets_current_year), 'Debt to Assets Previous Year': '{:.4f}'.format(debt_to_assets_current_year), 'D/A Current Year < D/A Previous Year ?': debt_to_assets_current_year < debt_to_assets_previous_year } # Change in Current ratio (1 point if it is higher in the current year compared to the previous one, 0 otherwise) current_ratio_current_year = ratios.current_ratio( stock=stock, date=date, lookback_period=lookback_period, period=period) current_ratio_previous_year = ratios.current_ratio( stock=stock, date=date, lookback_period=timedelta(days=365), period=period) piotroski_dictio['Financial Leverage, Liquidity, and Source of Funds'][ 'Change in Current Ratio'] = { 'Current Ratio Current Year': '{:.4f}'.format(current_ratio_current_year), 'Current Ratio Previous Year': '{:.4f}'.format(current_ratio_previous_year), 'CR Current Year > CR Previous Year ?': current_ratio_current_year > current_ratio_previous_year } shares_current_year = financials.total_shares_outstanding( stock=stock, date=date, lookback_period=lookback_period, diluted_shares=diluted_shares, period=period) shares_previous_year = financials.total_shares_outstanding( stock=stock, date=date, lookback_period=timedelta(days=365), diluted_shares=diluted_shares, period=period) # Change in the number of shares (1 point if no new shares were issued during the last year) piotroski_dictio['Financial Leverage, Liquidity, and Source of Funds'][ 'Change in Number of Shares'] = { 'Shares Outstanding Current Year': shares_current_year, 'Shares Outstanding Previous Year': shares_previous_year, 'No New Shares Issued ?': shares_current_year <= shares_previous_year } # Change in Gross Margin (1 point if it is higher in the current year compared to the previous one, 0 otherwise) gross_margin_current_year = ratios.gross_profit_margin( stock=stock, date=date, lookback_period=lookback_period, period=period) gross_margin_previous_year = ratios.gross_profit_margin( stock=stock, date=date, lookback_period=timedelta(days=365), period=period) piotroski_dictio['Operating Efficiency']['Gross Margin'] = { 'Gross Margin Current Year': '{:.4f}'.format(gross_margin_current_year), 'Gross Margin Previous Year': '{:.4f}'.format(gross_margin_previous_year), 'GM Current Year > GM Previous Year ?': gross_margin_current_year > gross_margin_previous_year } # Change in Asset Turnover ratio (1 point if it is higher in the current year compared to the previous one, # 0 otherwise) asset_turnover_current_year = ratios.asset_turnover_ratio( stock=stock, date=date, lookback_period=lookback_period, period=period) asset_turnover_previous_year = ratios.asset_turnover_ratio( stock=stock, date=date, lookback_period=timedelta(days=365), period=period) piotroski_dictio['Operating Efficiency']['Asset Turnover Ratio'] = { 'Asset Turnover Ratio Current Year': '{:.4f}'.format(asset_turnover_current_year), 'Asset Turnover Ratio Previous Year': '{:.4f}'.format(asset_turnover_previous_year), 'ATO Current Year > ATO Previous Year ?': asset_turnover_current_year > asset_turnover_previous_year } number_of_trues = 0 for k, v in piotroski_dictio.items(): for kk, vv in v.items(): for kkk, vvv in vv.items(): if isinstance(vvv, np.bool_) and vvv: number_of_trues = number_of_trues + 1 piotroski_dictio['Piotroski F-Score'][' '][' '] = number_of_trues return piotroski_dictio
def valuation_wrapper( model_type: partial, # Gordon Growth, Two Stage, H Model, Three Stage # For Three-Stage Model, specify transitionary growth periods (5 by default) # For all models except GGM, specify initial growth periods (5 by default) model_metric: Callable, # Dividend, EBITDA, OCF... stock: str, date: datetime = datetime.now(), lookback_period: timedelta = timedelta(days=0), period: str = 'FY', diluted_shares: bool = False): shares_outstanding = fi.total_shares_outstanding( stock=stock, date=date, lookback_period=lookback_period, period=period, diluted_shares=diluted_shares) discount_rate = weighted_average_cost_of_capital( stock=stock, date=date, lookback_period=lookback_period, period=period) print('WACC is {}'.format(discount_rate)) if model_metric == me.dividend_per_share: current_cash_flow = me.dividend_per_share( stock=stock, date=date, lookback_period=lookback_period, period=period, diluted_shares=diluted_shares) else: current_cash_flow = me.cash_flow_per_share( cash_flow_metric=model_metric, stock=stock, date=date, lookback_period=lookback_period, period=period, diluted_shares=diluted_shares) initial_growth_rate = cash_flow_growth_rate( cash_flow_type=partial(me.cash_flow_per_share, model_metric), stock=stock, date=date, lookback_period=lookback_period, period=period) print('Initial Growth Rate is {}'.format(initial_growth_rate)) terminal_growth_rate = growth_rate_PRAT_model( stock, date=datetime.now(), lookback_period=timedelta(days=0), period=period) print('PRAT Terminal Growth Rate is {}'.format(terminal_growth_rate)) # The perpetuity growth rate is typically between the historical inflation rate of 2-3% and the historical GDP growth rate of 4-5%. # If you assume a perpetuity growth rate in excess of 5%, you are basically saying that you expect the company's growth to outpace the economy's growth forever. terminal_growth_rate = min(terminal_growth_rate, HISTORICAL_GDP_GROWTH_RATE) terminal_growth_rate = max(terminal_growth_rate, HISTORICAL_INFLATION_RATE) print('Adujsted Terminal Growth Rate is {}'.format(terminal_growth_rate)) partial_function = partial(model_type, current_cash_flow=current_cash_flow, discount_rate=discount_rate, terminal_growth_rate=terminal_growth_rate) if model_type.func == gordon_growth_model: if model_metric == me.dividend_per_share: return partial_function() else: return partial_function() / shares_outstanding else: if model_metric == me.dividend_per_share: return partial_function(initial_growth_rate=initial_growth_rate) else: return partial_function(initial_growth_rate=initial_growth_rate) \ / shares_outstanding