def annual_capiq_stmts(annual_capiq_income_stmt, annual_capiq_bs_stmt) -> FinancialStatements: try: stmts = FinancialStatements(annual_capiq_income_stmt, annual_capiq_bs_stmt) except MismatchingDatesException: pass else: assert False dates = annual_capiq_income_stmt.dates stmts = FinancialStatements(annual_capiq_income_stmt, annual_capiq_bs_stmt[dates]) return stmts
def test_quarterly(self, quarterly_stockrow_stmts_mar: FinancialStatements): stmts = quarterly_stockrow_stmts_mar.copy() stmts.config.update('cash', ['forecast_config', 'plug'], False) stmts.config.update('cash_and_st_invest', ['forecast_config', 'plug'], True) super().test_quarterly(stmts, ignore_keys=['gross_ppe', 'dep'])
def test_annual_change_make_forecast_and_plug( self, annual_stockrow_stmts_cat: FinancialStatements): stmts = annual_stockrow_stmts_cat.copy() stmts.config.update('total_debt', ['forecast_config', 'make_forecast'], True) stmts.config.update('st_debt', ['forecast_config', 'make_forecast'], False) stmts.config.update('def_tax_lt', ['forecast_config', 'method'], 'manual') stmts.config.update('def_tax_lt', ['forecast_config', 'manual_forecasts'], { 'levels': [], 'growth': [4, 5] }) try: super().test_annual(stmts) except BalanceSheetNotBalancedException: pass else: assert False stmts.config.update("total_debt", ["forecast_config", "plug"], True) stmts.config.update("lt_debt", ["forecast_config", "plug"], False) super().test_annual( stmts, data=FCST_STOCKROW_CAT_PLUG_MAKE_FORECAST_A_INDEX_DATA_DICT, name='fcst_stockrow_cat_plug_make_forecast', ignore_keys=['gross_ppe', 'dep'])
def test_config_load_cat_annual_stockrow_no_adjust( annual_stockrow_income_stmt_cat: IncomeStatements, annual_stockrow_bs_stmt_cat: BalanceSheets ): stmts = FinancialStatements(annual_stockrow_income_stmt_cat, annual_stockrow_bs_stmt_cat, auto_adjust_config=False) json_path = EXPECT_CONFIG_PATH / 'no-adjust-cat-annual-stockrow.json' check_config(stmts.config, json_path)
def test_config_load_cat_annual_capiq_no_adjust( annual_capiq_income_stmt: IncomeStatements, annual_capiq_bs_stmt: BalanceSheets ): dates = annual_capiq_income_stmt.dates stmts = FinancialStatements(annual_capiq_income_stmt, annual_capiq_bs_stmt[dates], auto_adjust_config=False) json_path = EXPECT_CONFIG_PATH / 'no-adjust-cat-annual-capiq.json' check_config(stmts.config, json_path)
def test_multi_forecast_changing_assumptions( self, annual_stockrow_stmts_cat: FinancialStatements): stmts = annual_stockrow_stmts_cat.copy() stmts.config.update_all(['forecast_config', 'method'], 'cagr') fcst = stmts.forecast() stmts.config.update('revenue', ['forecast_config', 'method'], 'trend') stmts.config.update('cogs', ['forecast_config', 'method'], 'mean') fcst = stmts.forecast()
def test_quarterly(self, stmts: FinancialStatements, data: Optional[Dict[str, pd.Series]] = None, name: Optional[str] = None, ignore_keys: Optional[Sequence[str]] = None, **kwargs): if name is None: name = self.name fcst_kwargs = FORECAST_KWARGS.copy() fcst_kwargs.update(kwargs) adjust_forecast_methods(stmts, self.q_adjust_dict) fcst = stmts.forecast(**fcst_kwargs) if DEVELOPMENT_MODE: fig = fcst.plot() out_path = os.path.join(GENERATED_PATH, f'{name}_quarterly.pdf') fig.savefig(out_path) super().test_quarterly(fcst, data=data, name=name, ignore_keys=ignore_keys)
def quarterly_stockrow_stmts_cat(quarterly_stockrow_income_stmt_cat, quarterly_stockrow_bs_stmt_cat) -> FinancialStatements: stmts = FinancialStatements(quarterly_stockrow_income_stmt_cat, quarterly_stockrow_bs_stmt_cat) return stmts
def annual_stockrow_stmts_cat(annual_stockrow_income_stmt_cat, annual_stockrow_bs_stmt_cat) -> FinancialStatements: stmts = FinancialStatements(annual_stockrow_income_stmt_cat, annual_stockrow_bs_stmt_cat) return stmts
def quarterly_capiq_stmts(quarterly_capiq_income_stmt, quarterly_capiq_bs_stmt) -> FinancialStatements: stmts = FinancialStatements(quarterly_capiq_income_stmt, quarterly_capiq_bs_stmt) return stmts
def get_dcf_fcf_calculation_exercise() -> LabExercise: lab_1_inputs = dict(adjustments=100, change_ar=1000, change_inventory=500, change_ap=800, change_ppe=2000, dep_amort=200, net_income=300) lab_1_nwc = lab_1_inputs['change_ar'] + lab_1_inputs[ 'change_inventory'] - lab_1_inputs['change_ap'] lab_1_capex = lab_1_inputs['change_ppe'] + lab_1_inputs['dep_amort'] lab_1_fcf = lab_1_inputs['net_income'] + lab_1_inputs[ 'adjustments'] - lab_1_nwc - lab_1_capex stmt_folder = LAB_EXERCISES_PATH / 'DCF' / 'FCF' bs_path = os.path.join(stmt_folder, 'WMT Balance Sheet.xlsx') inc_path = os.path.join(stmt_folder, 'WMT Income Statement.xlsx') bs_df = pd.read_excel(bs_path, index_col=0) inc_df = pd.read_excel(inc_path, index_col=0) bs_data = BalanceSheets.from_df(bs_df) inc_data = IncomeStatements.from_df(inc_df) stmts = FinancialStatements(inc_data, bs_data) lab_2_date_1 = '2019-04-30' lab_2_date_2 = '2019-07-31' bullet_contents = [ [ 'Calculate free cash flow from the following information:', f"Net income is {lab_1_inputs['net_income']}, the total of non-cash expenditures is " f"{lab_1_inputs['adjustments']}, " f"the changes in accounts receivable, inventory, accounts payable, and PPE are {lab_1_inputs['change_ar']}, " f"{lab_1_inputs['change_inventory']}, {lab_1_inputs['change_ap']}, and {lab_1_inputs['change_ppe']}, " f"and depreciation & amortization is {lab_1_inputs['dep_amort']}." ], [ 'Load in the income statement and balance sheet data associated with Project 3, "WMT Balance Sheet.xlsx" ' 'and "WMT Income Statement.xlsx"', 'Calculate the free cash flows from these data. Note that some items are missing in these data such as ' 'depreciation. You will just need to exclude any missing items from your calculation', f'Get the FCFs for {lab_2_date_1} and {lab_2_date_2}.' ] ] answer_contents = [ [ fr'The NWC is \${lab_1_nwc:,.0f}', fr'The CapEx is \${lab_1_capex:,.0f}', fr'The FCF is \${lab_1_fcf:,.0f}' ], [ fr'The FCF for {lab_2_date_1} is \${stmts.fcf[lab_2_date_1]:,.0f}', fr'The FCF for {lab_2_date_2} is \${stmts.fcf[lab_2_date_2]:,.0f}', ] ] return LabExercise(bullet_contents, 'Calculate FCFs', f"Free Cash Flow Calculation", label='lab:dcf-fcf-calc', answers_content=answer_contents)
def get_fcf_calculation_lab_lecture() -> LabExerciseLecture: title = 'Free Cash Flow Calculation' short_title = 'Calculate FCF Lab' youtube_id = 'zVTkT5p0SHs' week_covered = 12 lab_1_inputs = dict(adjustments=100, change_ar=1000, change_inventory=500, change_ap=800, change_ppe=2000, dep_amort=200, net_income=300) lab_1_nwc = lab_1_inputs['change_ar'] + lab_1_inputs[ 'change_inventory'] - lab_1_inputs['change_ap'] lab_1_capex = lab_1_inputs['change_ppe'] + lab_1_inputs['dep_amort'] lab_1_fcf = lab_1_inputs['net_income'] + lab_1_inputs[ 'adjustments'] - lab_1_nwc - lab_1_capex stmt_folder = LAB_EXERCISES_PATH / 'DCF' / 'FCF' bs_path = os.path.join(stmt_folder, 'WMT Balance Sheet.xlsx') inc_path = os.path.join(stmt_folder, 'WMT Income Statement.xlsx') bs_df = pd.read_excel(bs_path, index_col=0) inc_df = pd.read_excel(inc_path, index_col=0) bs_data = BalanceSheets.from_df(bs_df) inc_data = IncomeStatements.from_df(inc_df) stmts = FinancialStatements(inc_data, bs_data) lab_2_date_1 = '2019-04-30' lab_2_date_2 = '2019-07-31' bullets = [ [ 'Calculate free cash flow from the following information:', f"Net income is {lab_1_inputs['net_income']}, the total of non-cash expenditures is " f"{lab_1_inputs['adjustments']}, " f"the changes in accounts receivable, inventory, accounts payable, and PPE are {lab_1_inputs['change_ar']}, " f"{lab_1_inputs['change_inventory']}, {lab_1_inputs['change_ap']}, and {lab_1_inputs['change_ppe']}, " f"and depreciation & amortization is {lab_1_inputs['dep_amort']}." ], [ 'Load in the income statement and balance sheet data associated with Project 3, "WMT Balance Sheet.xlsx" ' 'and "WMT Income Statement.xlsx"', 'Calculate the free cash flows from these data. Note that some items are missing in these data such as ' 'depreciation. You will just need to exclude any missing items from your calculation', f'Get the FCFs for {lab_2_date_1} and {lab_2_date_2}.' ] ] answers = [ [ fr'The NWC is \${lab_1_nwc:,.0f}', fr'The CapEx is \${lab_1_capex:,.0f}', fr'The FCF is \${lab_1_fcf:,.0f}' ], [ fr'The FCF for {lab_2_date_1} is \${stmts.fcf[lab_2_date_1]:,.0f}', fr'The FCF for {lab_2_date_2} is \${stmts.fcf[lab_2_date_2]:,.0f}', ] ] resources = [ LECTURE_12_SLIDES, RESOURCES.labs.dcf.fcf.wmt_balance_sheet, RESOURCES.labs.dcf.fcf.wmt_income_statement, ] return LabExerciseLecture.from_seq_of_seq( title, bullet_content=bullets, answers_content=answers, short_title=short_title, youtube_id=youtube_id, resources=resources, week_covered=week_covered, )
def quarterly_stockrow_stmts_mar(quarterly_stockrow_income_stmt_mar, quarterly_stockrow_bs_stmt_mar) -> FinancialStatements: stmts = FinancialStatements(quarterly_stockrow_income_stmt_mar, quarterly_stockrow_bs_stmt_mar) return stmts
def annual_stockrow_stmts_mar(annual_stockrow_income_stmt_mar, annual_stockrow_bs_stmt_mar) -> FinancialStatements: stmts = FinancialStatements(annual_stockrow_income_stmt_mar, annual_stockrow_bs_stmt_mar) return stmts