diff --git a/bpfin/financials/financial_lib.py b/bpfin/financials/financial_lib.py index 4479bcfd1dfbe3050972add924cbf8d778e80c59..d452d45f457bb937a5ca45cfda101406d9df666a 100644 --- a/bpfin/financials/financial_lib.py +++ b/bpfin/financials/financial_lib.py @@ -148,34 +148,21 @@ class Income_Statement(): self.total_opex = self.energy_opex + self.net_non_energy_opex self.noi = self.revenue - self.total_opex - def assign_next(self, income_statement_characters, - bill_overview_organized): - """ - !!! this function will be deleted in the next version!! - """ - self.electricity_opex = bill_overview_organized['electricity'][ - self.year] - self.gas_opex = bill_overview_organized['gas'][self.year] - self.oil_opex = bill_overview_organized['oil'][self.year] - self.water_opex = bill_overview_organized['water'][self.year] - self.energy_opex = self.electricity_opex + self.gas_opex + self.oil_opex + self.water_opex - self.other_utility = self.revenue * income_statement_characters[ - 'other_utility_percent'] - self.non_utility_expense = self.revenue * income_statement_characters[ - 'non_utility_expense_percent'] - self.utility_expense = self.energy_opex + self.other_utility - self.net_non_energy_opex = self.other_utility + self.non_utility_expense - self.total_opex = self.energy_opex + self.net_non_energy_opex - self.noi = self.revenue - self.total_opex - - # def assign_next_year(self, other_utility_percent, non_utility_expense_percent): - # # print('\n other_utility_percent',other_utility_percent) - # # print('\n non_utility_expense_percent',non_utility_expense_percent) + # def assign_next(self, income_statement_characters, + # bill_overview_organized): + # """ + # !!! this function will be deleted in the next version!! + # """ + # self.electricity_opex = bill_overview_organized['electricity'][ + # self.year] + # self.gas_opex = bill_overview_organized['gas'][self.year] + # self.oil_opex = bill_overview_organized['oil'][self.year] + # self.water_opex = bill_overview_organized['water'][self.year] # self.energy_opex = self.electricity_opex + self.gas_opex + self.oil_opex + self.water_opex - # # print('\n',self.energy_opex) - # # print('\n revenue', self.revenue) - # self.other_utility = self.revenue * other_utility_percent - # self.non_utility_expense = self.revenue * non_utility_expense_percent + # self.other_utility = self.revenue * income_statement_characters[ + # 'other_utility_percent'] + # self.non_utility_expense = self.revenue * income_statement_characters[ + # 'non_utility_expense_percent'] # self.utility_expense = self.energy_opex + self.other_utility # self.net_non_energy_opex = self.other_utility + self.non_utility_expense # self.total_opex = self.energy_opex + self.net_non_energy_opex @@ -289,7 +276,7 @@ class Income_Statement_Table(): Description: raw_income_input = {2014: {'revenue': 90.0, 'utility_expense': 55.0, 'non_utility_expense': 35.0}, 2015:{},} annual_bill_table = {'electricity': electricity_bill, 'oil': oil_bill, 'gas': gas_bill, 'water': water_bill} - electricity_bill = {2014: 100, 2015:200, ...} + electricity_bill = {2014: 100, 2015:200, ...} characters = { 'start_year': (int) 2014, 'end_year': (int) 2016, @@ -372,7 +359,7 @@ class Income_Statement_Table(): annual_bill_table) current_table.append(current_income_statement) self.table = current_table - return current_table + # return current_table def get_hist_table(self): """ @@ -515,6 +502,13 @@ class Income_Statement_Table(): if current_income_statement.year == first_year: return current_income_statement.noi + def get_total_energy_dict(self): + total_energy_dict = {} + for current_income_statement in self.table: + total_energy_dict[ + current_income_statement.year] = current_income_statement.energy_opex + return total_energy_dict + class Balance_Sheet(): def __init__(self): @@ -615,7 +609,7 @@ class Balance_Sheet_Table(): current_net_income) current_table.append(current_balance_sheet) self.bs_table = current_table - return current_table + # return current_table def get_hist_balance_sheet_table(self): hist_balance_sheet_dict = {} diff --git a/bpfin/financials/loan.py b/bpfin/financials/loan.py index 7b3489718d0d8880e0981c376d7a9d1c0c470cc2..966ed128b2529cc00343d656a915c9632f2fbfbc 100644 --- a/bpfin/financials/loan.py +++ b/bpfin/financials/loan.py @@ -133,7 +133,7 @@ class Loan_List(): temp_loan = Loan(current_loan) self.loan_list.append(temp_loan) - def allocate(self, customer_preference, scenario, req_dscr, first_year_saving, first_year_noi, first_year_cash): + def allocate(self, customer_preference, cost, req_dscr, first_year_saving, first_year_noi, first_year_cash): """ Allocate loan amount based on project cost, loan terms, income statements, scenario, other requirements. Apply linear programming method to allocate loan amount among loans, create financing plan. @@ -143,10 +143,7 @@ class Loan_List(): 'expected_payback': int, months that customer expect the project can payback, 'cust_saving_dscr': float, customer required lower limit of (saving / debt service) ratio } - scenario (dictionary): dict of project economics and saving scenario, { - 'cost_estimation': float, estimated project cost - 'post_income_statement': objective of Income_Statement_Table , projected income_statement with savings - } + cost (float): construction cost, can be estimated or quoted req_dscr (dictionary): dict of required debt service coverage ratios, { 'req_noi_dscr': 1.15, 'req_cash_dscr': 1.15, @@ -160,13 +157,13 @@ class Loan_List(): """ current_loan_list = copy.deepcopy(self.loan_list) allocation = loan_allocation(current_loan_list, customer_preference, - scenario, req_dscr, first_year_saving, + cost, req_dscr, first_year_saving, first_year_noi, first_year_cash) for current_loan, current_amount in zip(current_loan_list, allocation): current_loan.put_amount(current_amount) return current_loan_list - def get_schedule(self, customer_preference, scenario, req_dscr, + def get_schedule(self, customer_preference, cost, req_dscr, loan_start_date, first_year_saving, first_year_noi, first_year_cash): """ @@ -177,10 +174,7 @@ class Loan_List(): 'expected_payback': int, months that customer expect the project can payback, 'cust_saving_dscr': float, customer required lower limit of (saving / debt service) ratio } - scenario (dictionary): dict of project economics and saving scenario, { - 'cost_estimation': float, estimated project cost - 'post_income_statement': objective of Income_Statement_Table , projected income_statement with savings - } + cost (float): construction cost, can be estimated or quoted req_dscr (dictionary): dict of required debt service coverage ratios, { 'req_noi_dscr': 1.15, 'req_cash_dscr': 1.15, @@ -194,7 +188,7 @@ class Loan_List(): Returns: list: list of Loan objects, with amounts and schedules assigned """ - allocated_loan_list = self.allocate(customer_preference, scenario, + allocated_loan_list = self.allocate(customer_preference, cost, req_dscr, first_year_saving, first_year_noi, first_year_cash) for current_loan in allocated_loan_list: diff --git a/bpfin/financials/loan_allocation.py b/bpfin/financials/loan_allocation.py index c0d8149dcc89d032fb05e701ee8f1e8e183a1c8f..5bcc9d140f7a5d045a454be81c754d2618387a7c 100644 --- a/bpfin/financials/loan_allocation.py +++ b/bpfin/financials/loan_allocation.py @@ -4,7 +4,7 @@ from scipy.optimize import linprog def loan_allocation( loan_list, customer_preference, - scenario, + cost, req_dscr, first_year_saving, first_year_noi, @@ -34,12 +34,13 @@ def loan_allocation( loan_list (list): list of objectives of loans customer_preference (dictionary): customer preference for financing plan req_dscr(dictionary): required dscr - scenario (dictionary): package of energy conservation measures (ECMs) + cost (float): construction cost, can be estimated or quoted first_year_saving (float): first year saving. # maybe it can be min_annual_saving first_year_noi (float): first year noi, after commissioning date. # maybe it can be min_noi first_year_cash (float): first year cash, after commissioning date # liability: do we need this? it's already calculated in balance sheet # commissioning_date (date): construction finish date. Saving start at NEXT month + # scenario (dictionary): package of energy conservation measures (ECMs) Return: list: list of loan amount that borrowed from each lender @@ -49,15 +50,15 @@ def loan_allocation( 'expected_payback': int, months that customer expect the project can payback, 'cust_saving_dscr': float, customer required lower limit of (saving / debt service) ratio } - scenario (dictionary): dict of project economics and saving scenario, { - 'cost_estimation': float, estimated project cost - 'post_income_statement': objective of Income_Statement_Table , projected income_statement with savings - } req_dscr (dictionary): dict of required debt service coverage ratios, { 'req_noi_dscr': 1.15, 'req_cash_dscr': 1.15, 'req_saving_dscr': 1.10 } + # scenario (dictionary): dict of project economics and saving scenario, { + # 'cost_estimation': float, estimated project cost + # 'post_income_statement': objective of Income_Statement_Table , projected income_statement with savings + # } Note: noi == net operating income dscr == debt service coverage ratio @@ -67,12 +68,10 @@ def loan_allocation( if customer wants to S-F, but SF first -> max(xi) = cost - SF_max """ sum_loan_max_amount = sum(list(current_loan.max_amount for current_loan in loan_list)) - print('\n sum_loan_max_amount=', sum_loan_max_amount) # pre-request judge: project cost should be lower than total available financing - if (sum_loan_max_amount + customer_preference['downpayment_max']) <= scenario['cost_estimation']: - print('alert: not financiable') - return None - + if (sum_loan_max_amount + customer_preference['downpayment_max']) <= cost: + # print('alert: not financiable') + return [0] * len(loan_list) # linear programming (LP) # Set LP constrains. # objective function: x1/payback1, x2/payback2, x3/payback3 = minimum @@ -83,7 +82,7 @@ def loan_allocation( A.append([-1] * len(loan_list)) # -x1 -x2 -x3 <= -max b = [] b.append( - 0 - scenario['cost_estimation'] + 0 - cost # 0 - sum_loan_max_amount, ) A.append(c) # sum(x_i/payback_i) <= required. aka. sum(debt_service) <= min_required_debt_service @@ -95,8 +94,12 @@ def loan_allocation( )) # x variables bounds, 0 <= x[i] <= loan[i]_max_amount bound_list = list((0, current_loan.max_amount) for current_loan in loan_list) + # print('req_dscr', first_year_saving / req_dscr['req_saving_dscr'], first_year_noi / req_dscr['req_noi_dscr'], first_year_cash / req_dscr['req_cash_dscr']) + # print('\nLP constraints =', A, b, bound_list) # LP calculation. x[i] == loan amount from loan[i] res = linprog(c, A_ub=A, b_ub=b, bounds=bound_list, options={'disp': False}) + if res.success is False: + return [0] * len(loan_list) return res.x diff --git a/bpfin/financials/saving.py b/bpfin/financials/saving.py index befb92a217b967b934179108348b6ab6a5ff53fd..0acaff96322ac46e8279ba5ad07316aefe8fa255 100644 --- a/bpfin/financials/saving.py +++ b/bpfin/financials/saving.py @@ -4,9 +4,8 @@ from bpfin.utilbills.bill_lib import cal_last_day from bpfin.utilbills.bill_lib import annualizing_projection from bpfin.utilbills.bill_lib import form_year_calendar from bpfin.utilbills.bill_lib import form_bill_calendar -# from bpfin.tests.testdata import sample_data as db from bpfin.utilbills.bill_post_proj_rough import bill_post_proj_rough - +from bpfin.tests.testdata import sample_data as db class Saving(): """ @@ -220,7 +219,7 @@ class Saving_Overview(): self, bill_overview, prior_annual_bill_table, - analysis_date, + analysis_date, # consider to replace it with proforma_date commissioning_date): """ Initiate Saving_Overview. @@ -337,10 +336,22 @@ class Saving_Overview(): """ return self.total_saving_percent - def get_total_annual_saving_charge(self): + def get_post_annual_bill_table(self): """ + Generate annual bill table for pro-forma, consiering commission date. + Return: + dictionary: dict of dict of annual charges, for 4 utility types + Description: + output = {'electricity': electricity_bill, 'oil': oil_bill, 'gas': gas_bill, 'water': water_bill} + electricity_bill = {2014: 100, 2015:200, ...} + } """ - pass + post_annual_bill_table = {} + utility_type_list = ['electricity', 'gas', 'oil', 'water'] + for utility_type in utility_type_list: + post_annual_bill_table[utility_type] = copy.deepcopy( + self.utility_saving_dict[utility_type].get_annual_proforma_charge()) + return post_annual_bill_table def get_utility_annual_saving_charge(self, utility_type): """ @@ -358,6 +369,9 @@ class Saving_Overview(): return saving_dict + + + # **** ugly test **** # so = Saving_Overview(db.bill_overview, db.bill_overview_organized, db.analysis_date, datetime.date(2017, 3, 14)) # so.put_saving(db.prior_month_bill, db.percent_saving_dict, db.full_saving_dict) @@ -366,4 +380,4 @@ class Saving_Overview(): # print('\n simple payback =', so.get_simple_payback(50000)) # print('\n total saving percent =', so.get_total_saving_percent()) # print('\n electricity_annual_saving_charge', so.get_utility_annual_saving_charge('electricity')) - +# print(so.get_post_annual_bill_table()) diff --git a/bpfin/financials/scenario.py b/bpfin/financials/scenario.py new file mode 100644 index 0000000000000000000000000000000000000000..c606285b081660a6db2d696bcada46cbd584d331 --- /dev/null +++ b/bpfin/financials/scenario.py @@ -0,0 +1,182 @@ +import copy +# from bpfin.utilbills.bill_lib import form_bill_calendar +from bpfin.financials.saving import Saving_Overview +from bpfin.financials.loan import Loan_List +from bpfin.tests.testdata import sample_data as db +from bpfin.financials.financial_lib import Income_Statement_Table, Balance_Sheet_Table +from bpfin.utilbills.bill_lib import form_bill_year, annualizing_projection + + +class Scenario(): + def __init__(self, + analysis_date, + commission_date, + construction_cost, + bill_overview, + prior_annual_bill_table, + other_debt_service, + prior_income_statement_table, + prior_balance_sheet_table, + loan_input_list): + """ + other_debt_service (dict): dictionary of debt service values per year + """ + self.analysis_date = analysis_date + self.commission_date = copy.deepcopy(commission_date) + self.construction_cost = copy.deepcopy(construction_cost) + + self.prior_annual_bill_table = copy.deepcopy(prior_annual_bill_table) + self.other_debt_service = copy.deepcopy(other_debt_service) + + self.prior_income_statement_table = copy.deepcopy(prior_income_statement_table) + self.prior_balance_sheet_table = copy.deepcopy(prior_balance_sheet_table) + self.post_income_statement_table = None + self.post_balance_sheet_table = None + + self.loan_list = Loan_List(loan_input_list) + self.saving_overview = Saving_Overview( + bill_overview=copy.deepcopy(bill_overview), + prior_annual_bill_table=copy.deepcopy(prior_annual_bill_table), + analysis_date=copy.deepcopy(analysis_date), + commissioning_date=copy.deepcopy(commission_date) + ) + self.scheduled_loan_list = None + + def prelim_anlaysis(self, + prior_month_bill, + percent_saving_dict, + full_saving_dict, + growth_rate_flag, + req_dscr, + customer_preference): + """ + growth_rate_flag (float): indicating assumed growth rate, -2.0 == cagr, -1.0 == historical average + + To Do: clarify commission date and loan start date + """ + # calculate saving, by generating saving_overview object + self.saving_overview.put_saving( + prior_month_bill=prior_month_bill, + percent_saving_dict=percent_saving_dict, + full_saving_dict=full_saving_dict) + + # generate post_saving income_statement_table object + post_annual_bill_table = copy.deepcopy(self.saving_overview.get_post_annual_bill_table()) + post_income_statement_table = copy.deepcopy(self.prior_income_statement_table) + post_income_statement_table.project(growth_rate_flag, self.analysis_date, post_annual_bill_table) + self.post_income_statement_table = post_income_statement_table + + # generate post_saving balance_sheet_table object + post_saving_noi_dict = copy.deepcopy(self.post_income_statement_table.get_noi_dict()) + post_balance_sheet_table = copy.deepcopy(self.prior_balance_sheet_table) + post_balance_sheet_table.project_balance_sheet( + self.analysis_date, self.other_debt_service, post_saving_noi_dict) + self.post_balance_sheet_table = post_balance_sheet_table + + # allocate loan and get loan schedules + first_year_saving = copy.deepcopy(self.saving_overview.get_total_first_year_saving()) + first_year_noi = copy.deepcopy(self.post_income_statement_table.get_first_year_noi(self.commission_date)) + first_year_cash = copy.deepcopy(self.post_balance_sheet_table.get_first_year_cash(self.commission_date)) + + # print('first year =', first_year_saving, first_year_noi, first_year_cash) + # print(self.loan_list.loan_list[0].institute) + scheduled_loan_list = self.loan_list.get_schedule( + customer_preference=customer_preference, + cost=self.construction_cost, + req_dscr=req_dscr, + loan_start_date=self.commission_date, + first_year_saving=first_year_saving, + first_year_noi=first_year_noi, + first_year_cash=first_year_cash) + self.scheduled_loan_list = scheduled_loan_list + + def get_post_energy_bill(self): + proforma_year = form_bill_year(self.analysis_date['proforma_start'], + self.analysis_date['proforma_duration']) + post_annual_bill_table = copy.deepcopy(self.saving_overview.get_post_annual_bill_table()) + utility_type_list = ['electricity', 'gas', 'oil', 'water'] + + post_energy_bill = {} + for year in proforma_year: + current_total_energy_bill = 0 + for utility_type in utility_type_list: + current_total_energy_bill += post_annual_bill_table[utility_type][year] + post_energy_bill[year] = current_total_energy_bill + return post_energy_bill + + def get_annual_debt_service(self): + proforma_year = form_bill_year(self.analysis_date['proforma_start'], + self.analysis_date['proforma_duration']) + annual_debt_service_dict = {} + for year in proforma_year: + annual_debt_service_dict[year] = 0 + + for current_loan in self.scheduled_loan_list: + current_loan_annual = annualizing_projection( + current_loan.terms, current_loan.debt_service_due) + for year in proforma_year: + if year in current_loan_annual: + annual_debt_service_dict[year] += current_loan_annual[year] + return annual_debt_service_dict + + def get_graph_dict(self): + """ + Return: + dictionary: dict of dict of total pro-forma items + Description: + graph_dict = { + 'energy_expenses': {year: float} + 'total_loan': {year: float} + 'net_savings': {year: float} + } + # """ + graph_dict = {} + proforma_bill = self.get_post_energy_bill() + annual_debt_service = self.get_annual_debt_service() + prior_annual_bill = self.prior_income_statement_table.get_total_energy_dict() + net_saving_dict = {} + print(prior_annual_bill) + for year in prior_annual_bill: + net_saving_dict[year] = prior_annual_bill[year] - proforma_bill[year] - annual_debt_service[year] + graph_dict = { + 'energy_expenses': proforma_bill, + 'total_loan': annual_debt_service, + 'net_savings': net_saving_dict} + return graph_dict + + +# ***** ugly test that can be a guide for front end dev ***** +# growth_toggle = 0.01 +# prior_IS_table = Income_Statement_Table( +# db.raw_income_input, +# db.bill_overview_organized) +# prior_IS_table.project(growth_toggle, db.analysis_date, db.bill_overview_organized) +# prior_BS_table = Balance_Sheet_Table(db.raw_balance_sheet) +# prior_BS_table.project_balance_sheet( +# db.analysis_date, +# db.liability_dictionary, +# prior_IS_table.get_noi_dict()) + +# scenario = Scenario( +# analysis_date=db.analysis_date, +# commission_date=db.commission_date, +# construction_cost=50000, +# bill_overview=db.bill_overview, +# prior_annual_bill_table=db.bill_overview_organized, +# other_debt_service=db.liability_dictionary, +# prior_income_statement_table=prior_IS_table, +# prior_balance_sheet_table=prior_BS_table, +# loan_input_list=db.loan_input_list +# ) + +# scenario.prelim_anlaysis( +# prior_month_bill=db.prior_month_bill, +# percent_saving_dict=db.percent_saving_dict, +# full_saving_dict=db.full_saving_dict, +# growth_rate_flag=growth_toggle, +# req_dscr=db.req_dscr, +# customer_preference=db.customer_preference) + +# print(scenario.get_annual_debt_service()) +# print(scenario.get_graph_dict()) +# print(scenario.get_graph_dict()) diff --git a/bpfin/tests/test_financials/test_financial_lib.py b/bpfin/tests/test_financials/test_financial_lib.py index f853cc71bf43acfecc55b9409217bcb0b3245f5d..0799fdb84f7dfcb843c1e04f40ec170bae9be874 100644 --- a/bpfin/tests/test_financials/test_financial_lib.py +++ b/bpfin/tests/test_financials/test_financial_lib.py @@ -1,7 +1,6 @@ import datetime import bpfin.financials.financial_lib as fl from bpfin.tests.testdata import sample_data as db -from bpfin.financials.loan import Loan_List from bpfin.financials.financial_lib import Income_Statement_Table from bpfin.financials.financial_lib import Balance_Sheet_Table @@ -39,29 +38,6 @@ def test_Income_Statement_Table(): assert IS_table.get_first_year_noi(datetime.date(2017, 3, 14)) == output_first_year_noi -def test_Loan_List(): - """ - test Loan and Loan_List classes. - by calling Loan_List.get_schedule(), all calculation functions are called and tested. - """ - input_loan_input_list = db.loan_input_list - input_customer_preference = db.customer_preference - input_scenario = db.scenario - input_req_dscr = db.req_dscr - input_loan_start_date = datetime.date(2017, 1, 12) - output_loan1_end_balance = db.loan1_end_balance - sample_loan_list = Loan_List(input_loan_input_list) - result_loan_list = sample_loan_list.get_schedule( - input_customer_preference, - input_scenario, - input_req_dscr, - input_loan_start_date, - 28000.0, - 28000.0, - 100000.0) - assert output_loan1_end_balance == result_loan_list[0].principal_end_balance - - def test_Balance_Sheet_Table(): input_raw_balance_sheet = db.raw_balance_sheet output_hist_balance_sheet_table = db.hist_balance_sheet diff --git a/bpfin/tests/test_financials/test_loan.py b/bpfin/tests/test_financials/test_loan.py new file mode 100644 index 0000000000000000000000000000000000000000..cbfa0a0a5f73569d999fd3926b3e830fa937e825 --- /dev/null +++ b/bpfin/tests/test_financials/test_loan.py @@ -0,0 +1,26 @@ +import datetime +from bpfin.tests.testdata import sample_data as db +from bpfin.financials.loan import Loan_List + + +def test_Loan_List(): + """ + test Loan and Loan_List classes. + by calling Loan_List.get_schedule(), all calculation functions are called and tested. + """ + input_loan_input_list = db.loan_input_list + input_customer_preference = db.customer_preference + input_cost = db.cost_estimation + input_req_dscr = db.req_dscr + input_loan_start_date = db.commission_date + output_loan1_end_balance = db.loan1_end_balance + sample_loan_list = Loan_List(input_loan_input_list) + result_loan_list = sample_loan_list.get_schedule( + input_customer_preference, + input_cost, + input_req_dscr, + input_loan_start_date, + 28000.0, + 28000.0, + 100000.0) + assert output_loan1_end_balance == result_loan_list[0].principal_end_balance diff --git a/bpfin/tests/test_financials/test_saving.py b/bpfin/tests/test_financials/test_saving.py index bc1c48ca8525fefdd2f6d8fa0d8e4d71cac245ae..042a2e9f7a8a00102f4710c6210f58c6d5347eb8 100644 --- a/bpfin/tests/test_financials/test_saving.py +++ b/bpfin/tests/test_financials/test_saving.py @@ -124,6 +124,7 @@ def test_Saving_Overview(): 2035: 12430.56386264111, 2036: 12679.70824604718 } + output_post_annual_bill_table = db.bill_overview_post saving_overview = Saving_Overview( input_bill_overview, input_prior_annual_bill_table, input_analysis_date, input_commissioning_date) @@ -133,8 +134,10 @@ def test_Saving_Overview(): result_simple_payback = saving_overview.get_simple_payback(50000) result_total_saving_percent = saving_overview.get_total_saving_percent() result_electricity_annual_saving_charge = saving_overview.get_utility_annual_saving_charge('electricity') + result_post_annual_bill_table = saving_overview.get_post_annual_bill_table() assert result_first_year_saving == output_first_year_saving assert result_simple_payback == output_simple_payback assert result_total_saving_percent == output_total_saving_percent assert result_electricity_annual_saving_charge == output_electricity_annual_saving_charge + assert result_post_annual_bill_table == output_post_annual_bill_table diff --git a/bpfin/tests/testdata/sample_data.py b/bpfin/tests/testdata/sample_data.py index 1f1c41fa36a566f93a783bcb1eb1f914476fdf11..25b1038d454925047cd0b615ca95156dd2a85474 100644 --- a/bpfin/tests/testdata/sample_data.py +++ b/bpfin/tests/testdata/sample_data.py @@ -134,6 +134,118 @@ bill_overview_organized = { 2031: 0.0, 2032: 0.0, 2033: 0.0, 2034: 0.0, 2035: 0.0, 2036: 0.0} } +bill_overview_post = { + 'electricity': { + 2012: 32220.590596217822, + 2013: 32782.518348207, + 2014: 33293.10053024947, + 2015: 33546.76158045131, + 2016: 33844.501703633454, + 2017: 27765.310595972387, + 2018: 26538.724712295312, + 2019: 27188.618071137025, + 2020: 27825.148026928808, + 2021: 28415.31151022465, + 2022: 28952.82377820487, + 2023: 29480.94391241407, + 2024: 30021.058259530582, + 2025: 30579.321946790835, + 2026: 31181.75023905945, + 2027: 31829.938943047797, + 2028: 32493.926597686295, + 2029: 33158.47409684726, + 2030: 33823.25084758239, + 2031: 34489.99899723802, + 2032: 35164.72907151292, + 2033: 35854.93418165298, + 2034: 36563.663320523345, + 2035: 37291.69158792331, + 2036: 38039.124738141574 + }, + 'gas': { + 2012: 1253.3333333333333, + 2013: 1253.3333333333333, + 2014: 1253.3333333333333, + 2015: 1020, + 2016: 1220, + 2017: 1406.0, + 2018: 1128.0, + 2019: 1128.0, + 2020: 1128.0, + 2021: 1128.0, + 2022: 1128.0, + 2023: 1128.0, + 2024: 1128.0, + 2025: 1128.0, + 2026: 1128.0, + 2027: 1128.0, + 2028: 1128.0, + 2029: 1128.0, + 2030: 1128.0, + 2031: 1128.0, + 2032: 1128.0, + 2033: 1128.0, + 2034: 1128.0, + 2035: 1128.0, + 2036: 1128.0 + }, + 'oil': { + 2012: 1243.3333333333333, + 2013: 1243.3333333333333, + 2014: 1243.3333333333333, + 2015: 1010, + 2016: 1210, + 2017: 603.9999999999999, + 2018: 248.6666666666666, + 2019: 248.6666666666666, + 2020: 248.6666666666666, + 2021: 248.6666666666666, + 2022: 248.6666666666666, + 2023: 248.6666666666666, + 2024: 248.6666666666666, + 2025: 248.6666666666666, + 2026: 248.6666666666666, + 2027: 248.6666666666666, + 2028: 248.6666666666666, + 2029: 248.6666666666666, + 2030: 248.6666666666666, + 2031: 248.6666666666666, + 2032: 248.6666666666666, + 2033: 248.6666666666666, + 2034: 248.6666666666666, + 2035: 248.6666666666666, + 2036: 248.6666666666666 + }, + 'water': { + 2012: 0.0, + 2013: 0.0, + 2014: 0.0, + 2015: 0, + 2016: 0, + 2017: 0.0, + 2018: 0.0, + 2019: 0.0, + 2020: 0.0, + 2021: 0.0, + 2022: 0.0, + 2023: 0.0, + 2024: 0.0, + 2025: 0.0, + 2026: 0.0, + 2027: 0.0, + 2028: 0.0, + 2029: 0.0, + 2030: 0.0, + 2031: 0.0, + 2032: 0.0, + 2033: 0.0, + 2034: 0.0, + 2035: 0.0, + 2036: 0.0 + } +} + + # income statement test income_input_2016 = { 'revenue': 100000, @@ -548,13 +660,14 @@ customer_preference = { 'cust_saving_dscr': 1.15 } -# Engineering Scenarios -scenario = { - 'cost_estimation': 150000.00, - # 'saving': saving_dict, - # 'post_income_statement': post_income_statement -} +# loan_requirement = { +# 'dscr': req_dscr, +# 'customer': customer_preference +# } +# Engineering Scenarios and project economics +cost_estimation = 150000.00 +commission_date = datetime.date(2017, 3, 14) # Financing plan loan1_end_balance = [ diff --git a/bpfin/utilbills/data_generation.py b/bpfin/utilbills/data_generation.py index d3a2bdeb0135c1accb4945e6e3458cdc948340a5..dd81a5a94abaf1cf4cd9417b2bdf4d471af78af5 100644 --- a/bpfin/utilbills/data_generation.py +++ b/bpfin/utilbills/data_generation.py @@ -33,3 +33,6 @@ # print(lib.sublist(post_noi, prior_noi)) # # print(bl.annualizing_projection(saving.proforma_date, saving.get_proforma_saving())) + + +