def __init__(self, loan, r, months, teaserRate, teaserMonths): Mortgage.__init__(self, loan, teaserRate, months) self.teaserMonths = teaserMonths self.teaserRate = teaserRate self.nextRate = r / 12.0 self.legend = str(teaserRate*100)\ + '% for ' + str(self.teaserMonths)\ + ' months, then ' + str(r*100) + '%'
def from_json(cls, json_data: dict): return cls( property_value=PropertyValue(**json_data["property_value"]), renting_capital=RentingCapital(**json_data["renting_capital"]), mortgage=Mortgage(**json_data["mortgage"]), number_of_years=json_data["number_of_years"], rent=Rent(**json_data["rent"]))
def update_data_with_extra_columns(row, currRow): taxesPerMonth = strip_number(row['taxes']) listPrice = strip_number(row['listPr']) mortgageAmount = listPrice * (1 - (MORTGAGE_DOWNPAYMENT_PERCENTAGE / 100)) downpayment = listPrice * MORTGAGE_DOWNPAYMENT_PERCENTAGE / 100 mortgageMonthly = Mortgage( float(MORTGAGE_INTEREST_RATE) / 100, MORTGAGE_LOAN_YEARS * 12, mortgageAmount) row.update({'#': currRow}) row.update({'dateAdded': datetime.now().strftime('%Y-%m-%d')}) row.update({'taxesPerMonth': round(taxesPerMonth / 12, 2)}) row.update({'estMonthlyMortgage': mortgageMonthly.monthly_payment()}) row.update({'downPayment': round(downpayment, 2)}) row.update({'mortgageAmt': round(mortgageAmount, 2)}) return row
def set_new_datetime_index(self, datetime_index): # create a couple of dataframes with the newly created series self.__series_revenues = pd.DataFrame( [i.to_series(datetime_index) for i in self.__revenues]).transpose() self.__series_costs = pd.DataFrame( [i.to_series(datetime_index) for i in self.__costs]).transpose() self.__mortgage = Mortgage(self.__value, self.__mortgage.down, datetime_index, self.__mortgage.apr) self.__mortgage_costs = self.__mortgage.to_costs() self.__series_costs['mortgage'] = self.__mortgage_costs self.appreciation = House.get_appreciation_curve( self.__value, self.__appreciation_rate, self.__mortgage)
def main(): loan_amount = 190000 three_percent = 3.0 three_point_five_percent = 3.5 four_percent = 4.0 zero = 0.00 ten_years = 10 fifteen_years = 15 thirty_years = 30 little_extra = 200.0 my_mortgage = Mortgage(loan_amount, four_percent, fifteen_years) #my_mortgage = Mortgage(loan_amount, four_percent, thirty_years) print my_mortgage my_mortgage.amortize()
class Contract: def __init__(self, signature, value, base): self.signature = signature self.value = value self.borrowers = dict() self.mortgage = None self.data = base.data self.params = base.params def set_borrowers(self, b, percentage): self.borrowers[b] = percentage def set_mortgage(self, interest, months, loan, correction, choice): self.mortgage = Mortgage(interest, months, loan, correction, choice) def gen_schedule(self): for i, payment in enumerate(self.mortgage.monthly_payment_schedule()): self.data.loc[i, 'correction'] = round(self.mortgage.get_monetary_correction(), 2) self.data.loc[i, 'amortization'] = round(payment[0], 2) self.data.loc[i, 'interest'] = round(payment[1], 2) self.data.loc[i, 'balance'] = round(self.mortgage.amount() - payment[0], 2) def complete_schedule(self): self.data.loc[:, 'dfi'] = round(self.dfi(), 2) self.mip() self.data.loc[:, 'payment'] = self.data.amortization + self.data.interest + self.data.dfi + self.data.mip # self.data.to_csv(self.params['DATA'], sep=';', index=False) def dfi(self): return self.value * insurance.DFI def mip(self): keys = list(self.borrowers.keys()) for i in range(len(self.data)): # self.data.to_csv(self.params['DATA'], sep=';', index=False) self.data.loc[i, 'mip'] = insurance.mip(self.data.loc[i, 'balance'], self.signature, keys[0].birth, self.signature + relativedelta(months=i), keys[1].birth if keys[1] else None, self.borrowers[keys[0]], self.borrowers[keys[1]] if keys[1] else None)
def main(): loan_amount = 122028 num_years_left = 9 thirty_years = 30 interest_rate = 3.625 zero = 0.00 ten_years = 10 fifteen_years = 15 little_extra = 200.0 #my_mortgage = Mortgage(loan_amount, interest_rate, num_years_left) my_mortgage = Mortgage(loan_amount, interest_rate) print my_mortgage my_mortgage.amortize() my_mortgage.pay_extra_amortize(200) my_mortgage.recalculate(8 * 12 + 6, 0) my_mortgage.recalculate(8 * 12 + 6, 200)
def check_area_ytp(pickle_name): data = load(pickle_name) n_years = 15 house_cost = data.loc[0].value appreciation = 3.0 n_months = n_years * 12 dates = pd.date_range(data.loc[0].date, periods=n_months, freq="M") rent = Revenue("rent", "monthly payment", 0.011 * house_cost) # costs utilities = Cost("utilities", "hvac", 150) insurance = Cost("insurance", "full coverage", 100) property_tax = Cost("insurance", "full coverage", (house_cost * 0.019) / 12) mortgage = Mortgage(house_cost, 25000, dates, 3.0) # revenue revenues = [rent] costs = [utilities, insurance, property_tax] house = House(revenues, costs, mortgage, dates, appreciation) # house.summary() house.graph_net_profit() portfolio = Portfolio([house]) ytp = portfolio.get_years_to_positive(house) print("years till positive", ytp) exit(0) return ytp
def __init__(self, loan, r, months): Mortgage.__init__(self, loan, r, months) self.legend = 'Fixed, ' + str(r*100) + '%'
def makePayment(self): if len(self.paid) == self.teaserMonths + 1: self.rate = self.nextRate self.payment = findPayment(self.owed[-1], self.rate, self.months - self.teaserMonths) Mortgage.makePayment(self)
def __init__(self): self.m = Mortgage()
def __init__(self, loan, r, months, pts): Mortgage.__init__(self, loan, r, months) self.pts = pts self.paid = [loan*(pts/100.0)] self.legend = 'Fixed, ' + str(r*100) + '%, '\ + str(pts) + ' points'
def gipo_handler(): if request.method == 'POST': msg = request.get_json() parsed = parse_message(msg) if (not parsed['txt']): send_message(parsed['chat_id'], gipo_token, '...') return Response('Ok', status=200) elif parsed['txt'] == '/calc': send_message(parsed['chat_id'], gipo_token, 'Ввведите через разделитель следующие данные') send_message( parsed['chat_id'], gipo_token, 'стоимость объекта / первоначальный взнос в % / процентную ставку в % / количество лет ипотеки' ) send_message(parsed['chat_id'], gipo_token, 'Пример:') send_message(parsed['chat_id'], gipo_token, '3000000 / 20 / 10 / 30') return Response('Ok', status=200) elif len(parsed['txt'].split('/')) == 4: vals = parsed['txt'].split('/') m = Mortgage() m.home_value = int(vals[0]) m.down_payment_percent = float(vals[1]) / 100 vals[2] = vals[2].replace(',', '.') m.mortgage_rate = float(vals[2]) / 100 m.years = int(vals[3]) m.run() send_message(parsed['chat_id'], gipo_token, f'Cтоимость объекта: {m.home_value}') send_message( parsed['chat_id'], gipo_token, f'Первоначальный взнос в % : {m.down_payment_percent * 100}') send_message(parsed['chat_id'], gipo_token, f'Процентная ставка в %: {m.mortgage_rate * 100}') send_message(parsed['chat_id'], gipo_token, f'Первоначальный взнос: {m.down_payment}') send_message(parsed['chat_id'], gipo_token, f'Сумма кредита: {m.mortgage_loan}') send_message( parsed['chat_id'], gipo_token, f'Процентная ставка по кредиту : {m.mortgage_rate * 100}%') send_message(parsed['chat_id'], gipo_token, f'Количество лет кредита: {m.years}') send_message( parsed['chat_id'], gipo_token, f'Количетсво периодов платежей: {m.mortgage_payment_periods}') send_message( parsed['chat_id'], gipo_token, f"Ежемесячный платеж по кредиту: {round(m.periodic_mortgage_payment, 2)}" ) send_message( parsed['chat_id'], gipo_token, f"Первый платеж (проценты): {round(m.initial_interest_payment, 2)}" ) send_message( parsed['chat_id'], gipo_token, f"Первый платеж (основной долг): {round(m.initial_principal_payment, 2)}" ) return Response('Ok', status=200) else: send_message(parsed['chat_id'], gipo_token, '.....') return Response('Ok', status=200)
def update_output( # Rent initial_rent_n_submit, initial_rent_n_blur, inflation_rate_n_submit, inflation_rate_n_blur, # Property property_sale_price_n_submit, property_sale_price_n_blur, property_tax_n_submit, property_tax_n_blur, condo_fee_n_submit, condo_fee_n_blur, insurance_n_submit, insurance_n_blur, utility_cost_n_submit, utility_cost_n_blur, property_appreciation_n_submit, property_appreciation_n_blur, # Mortgage mortgage_load_n_submit, mortgage_load_n_blur, mortgage_interest_rate_n_submit, mortgage_interest_rate_n_blur, mortgage_terms, mortgage_payments_per_year, # Purchase Upfront Cost mortgage_down_payment_n_submit, mortgage_down_payment_n_blur, welcome_tax_n_submit, welcome_tax_n_blur, legal_fee_n_submit, legal_fee_n_blur, # Other investments investment_roi_n_submit, investment_roi_n_blur, initial_rent, inflation_rate, property_tax, condo_fee, insurance, utility_cost, property_appreciation, mortgage_loan, mortgage_interest_rate, mortgage_down_payment, welcome_tax, legal_fee, other_investment_roi, ): logger.log( logging.INFO, msg="Update output: " + f"\n\tinitial_rent={initial_rent}" + f"\n\tinflation_rate={inflation_rate}" + f"\n\tproperty_tax={property_tax}" + f"\n\tcondo_fee={condo_fee}" + f"\n\tinsurance={insurance}" + f"\n\tutility_cost={utility_cost}" + f"\n\tproperty_appreciation={property_appreciation}" + f"\n\tmortgage_loan={mortgage_loan}" + f"\n\tmortgage_interest_rate={mortgage_interest_rate}" + f"\n\tmortgage_terms={mortgage_terms}" + f"\n\tmortgage_payments_per_year={mortgage_payments_per_year}" + f"\n\tmortgage_down_payment={mortgage_down_payment}" + f"\n\twelcome_tax={welcome_tax}" + f"\n\tlegal_fee={legal_fee}" + f"\n\tother_investment_roi={other_investment_roi}") inflation_rate = inflation_rate / 100 mortgage_interest_rate = mortgage_interest_rate / 100 property_appreciation = property_appreciation / 100 other_investment_roi = other_investment_roi / 100 number_of_years = mortgage_terms monthly_property_owning_cost = property_tax + condo_fee + insurance + utility_cost mortgage = Mortgage.create(loan=mortgage_loan, annual_interest_rate=mortgage_interest_rate, amortization_period=number_of_years, annual_payment_count=mortgage_payments_per_year) rent = Rent.create_rent(initial_monthly_rent=initial_rent, inflation_rate=inflation_rate, number_of_years=number_of_years) initial_capital = mortgage_down_payment + welcome_tax + legal_fee renting_capital = RentingCapital.create( initial_capital=initial_capital, return_on_investment=other_investment_roi, monthly_property_owning_cost=monthly_property_owning_cost, mortgage=mortgage, rent=rent, number_of_years=number_of_years) property_initial_value = mortgage_down_payment + mortgage_loan property_value = PropertyValue.create( initial_value=property_initial_value, appreciation_rate=property_appreciation, mortgage=mortgage, number_of_years=number_of_years, real_estate_commission=0.05) cache = AppState(number_of_years=number_of_years, rent=rent, property_value=property_value, renting_capital=renting_capital, mortgage=mortgage) return cache.dump()
class House: def __init__(self, revenues, costs, mortgage, datetime_index, appreciation_rate=3.0): """This blueprint of a house is going to be used for long-term financial forecasting including a large number of arbitrary revenue and cost variables. All of this data is based on a singular pandas time series that indicates the number of months Args: revenues (list): a list of revenues costs (list): the costs mortgage (Mortgage): the mortgage for the house appreciation_rate (float, optional): rate of appreciation. Defaults to 3.0. """ self.__mortgage = mortgage # take a list of series for each and turn them into a df self.__revenues = revenues self.__costs = costs # create a couple of dataframes with the newly created series self.__series_revenues = pd.DataFrame( [i.to_series(datetime_index) for i in revenues]).transpose() self.__series_costs = pd.DataFrame( [i.to_series(datetime_index) for i in costs]).transpose() self.datetime_index = datetime_index self.__appreciation_rate = appreciation_rate / 100 self.__value = self.__mortgage.amount # insert mortgage into the costs self.__mortgage_costs = self.__mortgage.to_costs() self.__series_costs['mortgage'] = self.__mortgage_costs self.appreciation = House.get_appreciation_curve( self.__value, appreciation_rate, mortgage) def set_new_datetime_index(self, datetime_index): # create a couple of dataframes with the newly created series self.__series_revenues = pd.DataFrame( [i.to_series(datetime_index) for i in self.__revenues]).transpose() self.__series_costs = pd.DataFrame( [i.to_series(datetime_index) for i in self.__costs]).transpose() self.__mortgage = Mortgage(self.__value, self.__mortgage.down, datetime_index, self.__mortgage.apr) self.__mortgage_costs = self.__mortgage.to_costs() self.__series_costs['mortgage'] = self.__mortgage_costs self.appreciation = House.get_appreciation_curve( self.__value, self.__appreciation_rate, self.__mortgage) @staticmethod def get_appreciation_curve(value, appreciation_rate, mortgage): # calculate appreciation index = mortgage.amortization appreciation_array = [] # create a time series for the amount the house appreciates for time in index: amount = (value * appreciation_rate) / 12 transfer = Asset("appreciation", "home appreciation", amount) appreciation_array.append(transfer) return pd.Series(appreciation_array, index=index, name="appreciation") def total_cost(self) -> float: total_cost = 0 for index, row in self.__series_costs.iterrows(): for cost in row: total_cost += cost return total_cost def total_revenue(self) -> float: """return the amount of pure revenue coming in every month, not including assets from house appreciation Returns: float: the total revenue """ total_revenue = 0 for index, row in self.__series_revenues.iterrows(): for revenue in row: total_revenue += revenue return total_revenue def total_assets(self) -> float: """the total number of assets from the house. These are considered non-liquidable and are thus kept separate from revenue Returns: float: the total number of assets """ return self.appreciation.sum().amount def total_profit(self) -> float: """the total amount of gains from both revenue and assets Returns: float: total gains """ return self.total_revenue() + self.total_assets() def net_profit(self) -> float: """the total number of gains minus the costs Returns: float: net gain """ return self.total_profit() + self.total_cost() def net_revenue(self) -> float: """the total revenue minus cost. This does not include house assets Returns: float: the net revenue minus costs """ return self.total_revenue() + self.total_cost() def graph_net_profit(self): # sum costs across 1st axis (horizontally) costs = self.__series_costs.sum(axis=1).cumsum() profits = self.__series_revenues.sum(axis=1).cumsum() net = costs + profits # print(net) plt.plot(net.index, net) plt.title("House investment") plt.xlabel("Years") plt.ylabel("Net profit") # plt.axvline(x=2020, color='k', linestyle='--') plt.axhline(y=0, color='k', linestyle='--') plt.show() plt.close() def summary(self) -> float: print('Summary') print('-------------------------------------------') print("total cost ", self.total_cost()) print("total revenue ", self.total_revenue()) print("net revenue ", self.net_revenue()) print("total assets ", self.total_assets()) print("total profit ", self.total_profit()) print("net profit ", self.net_profit())
def set_mortgage(self, interest, months, loan, correction, choice): self.mortgage = Mortgage(interest, months, loan, correction, choice)
from mortgage import Mortgage from decimal import Decimal # avoid floating point conversion # initial loan: $300K at 4% over 5 years (interest charged monthly) principal = 300_000 interest_rate = Decimal('0.04') / 12 # monthly rate = 4% / 12 periods = 60 # 5 years = 60 months m = Mortgage(principal, interest_rate, periods) # pay loan as usual for one year ... m.go(12) # ... then refinance to a better rate principal = 245_000 interest_rate = Decimal('0.03') / 12 periods = 60 m.refinance(principal, interest_rate, periods, other_costs=2_000) # go for two months m.go(2) # make a large one-time payment and go again m.pay_extra_one_time(120_000) m.go(2) # pay extra each month and go until close m.pay_extra_each_time(3_000) m.go() # see details of how much paid each month print(m.format())
import unittest from mortgage import Mortgage new_mortgage_io_false = Mortgage(rate=.04 / 12, loan=400000, term=360, interest_only=False) class MyFirstTests(unittest.TestCase): def test_total_12_pmts_equals_1_pmt_times_12(self): self.assertEqual(new_mortgage_io_false.total_pmts(12), new_mortgage_io_false.get_pmt() * 12) def test_cumulative_interest_pmt_of_new_mortgage_io_false(self): self.assertAlmostEqual(new_mortgage_io_false.get_pmt(), 1910, 0) def test_total_pmts_equals_sum_interest_and_principal(self): for i in range(1, 300, 12): sum_interest_and_principal = new_mortgage_io_false.cumulative_interest_pmt( i) + new_mortgage_io_false.cumulative_principal_pmt(i) total_pmts = new_mortgage_io_false.total_pmts(i) self.assertEqual(sum_interest_and_principal, total_pmts) if __name__ == '__main__': unittest.main()
from mortgage import Mortgage import numpy as np import locale locale.setlocale(locale.LC_ALL, '') import matplotlib.pyplot as plt def money_fmt(num): return locale.currency(num, grouping=True) m = Mortgage(apr=.037, loan_total=500_000, loan_duration=30, monthly_overage=100) def plot_mortage(m): fig, ax = plt.subplots(1, 1) fig.set_size_inches(6, 6) ax = fig.gca() ax.text( 0, 0, 'Principal: {}\nAPR: {:.2}%\nMontly payment: {}\nCost in interest: {}\nTotal cost: {}' .format(money_fmt(m.principal), m.apr * 100, money_fmt(m.monthly_payment), money_fmt(m.cost_interest), money_fmt(m.cost_total)), bbox={ 'facecolor': 'white',