diff --git a/bpfin/financials/balance_sheet_projection.py b/bpfin/financials/balance_sheet_projection.py new file mode 100644 index 0000000000000000000000000000000000000000..60a68dad652094ed97504c252e636b3c87366196 --- /dev/null +++ b/bpfin/financials/balance_sheet_projection.py @@ -0,0 +1,56 @@ +import datetime + + +def balance_sheet_projection(cash_balance, liability, + income_statement_projection, analysis_date): + """Return balance sheet projection. + Args: + cash_balance (dictionary): {year:value}, cash per year + liability (dictionary): {(year):value} value can be mortgage, loan debt, etc + income_statement_projection (dictionary): {year:income statement values - take NOI} + analysis_date (dictionary): proforma's starting date and the years of proforma + Returns: + dictionary: {year: balance sheet cash available} + The future balance sheet cash available = cash balance + NOI - liability for future. + The past balance sheet cash available = None. + The present balance sheet cash available = cash balance from bank statement or balance sheet + + """ + + analysis_years = {} + + for date in analysis_date: + start_year = date.year + duration = analysis_date[date] + for i in range(duration): + analysis_years[start_year + i] = [] + + smallest_year = min(cash_balance) + largest_year = max(cash_balance) + + for an_year in analysis_years: + if an_year in cash_balance: + analysis_years[an_year] = cash_balance[an_year] + # If the cash available value exists (balance sheet, bank statements), cash available = to that value + elif an_year < smallest_year: + analysis_years[an_year] = None + # If the analysis period of time starts before cash info is available, return None. + # Ex: If analysis date starts in 1999, but our starting cash balance info is from 2004, + # Then 1999-2003 will be None. + elif an_year > largest_year: + previous_year = an_year - 1 + cash_b = analysis_years[previous_year] + if an_year in liability: + liability_value = liability[an_year] + else: + liability_value = 0 + if an_year in income_statement_projection: + noi = income_statement_projection[an_year]['noi'] + else: + noi = 0 + analysis_years[an_year] = cash_b - liability_value + noi + # If we are asked to project the cash balance for future values, + # We use the most recent cash info + NOI - Liability. For example, if we only have information to 2016, + # Then 2017 = 2016 cash + 2017 NOI (projected) - 2017 liability (projected) + + return analysis_years diff --git a/bpfin/financials/cash_balance.py b/bpfin/financials/cash_balance.py index f8759ea628447f86aceb1205dedbbfecfac5103f..a73675ddcd9846753020e2c11143c358f7b25cd6 100644 --- a/bpfin/financials/cash_balance.py +++ b/bpfin/financials/cash_balance.py @@ -1,4 +1,10 @@ def cash_balance(cash_dictionary): + """Returns current cash balance + Args: + cash_dictionary (dictionary): {datetime:(cash value,year)} + Returns: + dictionary: {datetime, cash value} + """ cash_balance_dictionary = {} diff --git a/bpfin/tests/test_financials/test_balance_sheet_projection.py b/bpfin/tests/test_financials/test_balance_sheet_projection.py new file mode 100644 index 0000000000000000000000000000000000000000..05c4afe36d838827cc701ef239de45c1e6f1a7c7 --- /dev/null +++ b/bpfin/tests/test_financials/test_balance_sheet_projection.py @@ -0,0 +1,41 @@ +from bpfin.financials.balance_sheet_projection import balance_sheet_projection +from bpfin.tests.testdata import sample_data as db +import datetime + + +def test_balance_sheet_projection(): + input_cash_balance = db.cash_balance + input_liability = db.liability_dictionary + input_noi = db.income_statement_projection_cagr + input_date_years = {datetime.date(2012, 1, 15): 25} + output = { + 2012: None, + 2013: None, + 2014: 5000.0, + 2015: 6000, + 2016: 4500.0, + 2017: 35778.43692755746, + 2018: 75992.72229401008, + 2019: 124835.35357997121, + 2020: 177567.28767315467, + 2021: 234506.6375641261, + 2022: 295993.759336618, + 2023: 362325.94364370033, + 2024: 433787.36982739856, + 2025: 510670.2474431231, + 2026: 593249.2143796427, + 2027: 681814.8219497779, + 2028: 776716.587140195, + 2029: 878344.3914861011, + 2030: 987109.6873789529, + 2031: 1103443.8773919346, + 2032: 1227793.8279146897, + 2033: 1360621.1623494846, + 2034: 1502409.5252755708, + 2035: 1653669.0253920422, + 2036: 1814938.615393169 + } + result = balance_sheet_projection(input_cash_balance, input_liability, + input_noi, input_date_years) + + assert output == result diff --git a/bpfin/tests/testdata/sample_data.py b/bpfin/tests/testdata/sample_data.py index b7a8053a466e0858a5970b982fc59c5081c47844..5b6c106852dee33b66ddecb715d68c518a91da4a 100644 --- a/bpfin/tests/testdata/sample_data.py +++ b/bpfin/tests/testdata/sample_data.py @@ -487,13 +487,19 @@ income_statement_projection_cagr = { 'water_opex': 0.0, 'year': 2036}} - -# liability, mortgage and other debt data liability_dictionary = { - 'debt1': (150, 'NYSERDA', 10, datetime.date(2012, 12, 31)), - 'debt2': (100, 'NYCEEC', 20, datetime.date(2012, 8, 31)) + 2012: 650, + 2013: 2550, + 2014: 100, + 2015: 6000, + 2016: 15000, + 2017: 10000, + 2018: 5000 } - +# {year: value, is_balancesheet (boolean)} +cash_balance = { + 2014: 5000.0, 2015: 6000, 2016: 4500.0 +} # pro-forma date and bill projection - # proforma_date_from, proforma_date_to