Last active
January 23, 2026 07:38
-
-
Save arssher/68560ba0d588a20fcdeb23f81db3effc to your computer and use it in GitHub Desktop.
vovsu donimaet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ars@nonlibrem ~ $ mortage.py -y 30 --mortage-payment 71946 -i 6 -r 60000 -s 1 --renovation 2000000 --down-payment 3000000 --loan 12000000 | |
| 30 | |
| inflation factor: 0.0600, skip years: 1, loan: 12000000, down_payment: 3000000, renovation: 2000000 | |
| year 0: monthly payment_i_a=71946.00, payment_sum_i_a=863352.00, payment_sum=863352.00, debt=11852639.37, debt_i_a=11181735.26, monthly rental=60000.00, rental_sum=0.00, yearly b=-863352.00, b=-863352.00, full_b=-2863352.00, rental profit=0.00, investments=5863352.00, owned_value=3818264.74, assets=3818264.74, CAGR=-34.88% | |
| year 1: monthly payment_i_a=67873.58, payment_sum_i_a=1677835.02, payment_sum=1726704.00, debt=11696189.86, debt_i_a=10409567.34, monthly rental=60000.00, rental_sum=720000.00, yearly b=-94483.02, b=-957835.02, full_b=-2957835.02, rental profit=0.00, investments=5957835.02, owned_value=4590432.66, assets=4590432.66, CAGR=-12.22% | |
| year 2: monthly payment_i_a=64031.68, payment_sum_i_a=2446215.23, payment_sum=2590056.00, debt=11530090.89, debt_i_a=9680886.65, monthly rental=60000.00, rental_sum=1440000.00, yearly b=-48380.21, b=-1006215.23, full_b=-3006215.23, rental profit=0.00, investments=6006215.23, owned_value=5319113.35, assets=5319113.35, CAGR=-3.97% | |
| year 3: monthly payment_i_a=60407.25, payment_sum_i_a=3171102.21, payment_sum=3453408.00, debt=11353747.30, debt_i_a=8993231.29, monthly rental=60000.00, rental_sum=2160000.00, yearly b=-4886.99, b=-1011102.21, full_b=-3011102.21, rental profit=0.00, investments=6011102.21, owned_value=6006768.71, assets=6006768.71, CAGR=-0.02% | |
| year 4: monthly payment_i_a=56987.97, payment_sum_i_a=3854957.86, payment_sum=4316760.00, debt=11166527.22, debt_i_a=8344278.72, monthly rental=60000.00, rental_sum=2880000.00, yearly b=36144.35, b=-974957.86, full_b=-2974957.86, rental profit=36144.35, investments=6011102.21, owned_value=6655721.28, assets=6691865.63, CAGR=2.17% | |
| year 5: monthly payment_i_a=53762.24, payment_sum_i_a=4500104.70, payment_sum=5180112.00, debt=10967759.81, debt_i_a=7731837.88, monthly rental=60000.00, rental_sum=3600000.00, yearly b=74853.16, b=-900104.70, full_b=-2900104.70, rental profit=110997.51, investments=6011102.21, owned_value=7268162.12, assets=7379159.63, CAGR=3.48% | |
| year 6: monthly payment_i_a=50719.09, payment_sum_i_a=5108733.79, payment_sum=6043464.00, debt=10756732.87, debt_i_a=7153841.71, monthly rental=60000.00, rental_sum=4320000.00, yearly b=111370.91, b=-788733.79, full_b=-2788733.79, rental profit=222368.42, investments=6011102.21, owned_value=7846158.29, assets=8068526.71, CAGR=4.29% | |
| year 7: monthly payment_i_a=47848.20, payment_sum_i_a=5682912.18, payment_sum=6906816.00, debt=10532690.24, debt_i_a=6608340.16, monthly rental=60000.00, rental_sum=5040000.00, yearly b=145821.61, b=-642912.18, full_b=-2642912.18, rental profit=368190.03, investments=6011102.21, owned_value=8391659.84, assets=8759849.87, CAGR=4.82% | |
| year 8: monthly payment_i_a=45139.81, payment_sum_i_a=6224589.91, payment_sum=7770168.00, debt=10294829.16, debt_i_a=6093493.56, monthly rental=60000.00, rental_sum=5760000.00, yearly b=178322.27, b=-464589.91, full_b=-2464589.91, rental profit=546512.31, investments=6011102.21, owned_value=8906506.44, assets=9453018.75, CAGR=5.16% | |
| year 9: monthly payment_i_a=42584.73, payment_sum_i_a=6735606.63, payment_sum=8633520.00, debt=10042297.32, debt_i_a=5607566.37, monthly rental=60000.00, rental_sum=6480000.00, yearly b=208983.28, b=-255606.63, full_b=-2255606.63, rental profit=755495.58, investments=6011102.21, owned_value=9392433.63, assets=10147929.21, CAGR=5.38% | |
| year 10: monthly payment_i_a=40174.27, payment_sum_i_a=7217697.88, payment_sum=9496872.00, debt=9774189.88, debt_i_a=5148921.30, monthly rental=60000.00, rental_sum=7200000.00, yearly b=237908.75, b=-17697.88, full_b=-2017697.88, rental profit=993404.34, investments=6011102.21, owned_value=9851078.70, assets=10844483.04, CAGR=5.51% | |
| year 11: monthly payment_i_a=37900.26, payment_sum_i_a=7672500.94, payment_sum=10360224.00, debt=9489546.15, debt_i_a=4716013.71, monthly rental=60000.00, rental_sum=7920000.00, yearly b=265196.94, b=247499.06, full_b=-1752500.94, rental profit=1258601.27, investments=6011102.21, owned_value=10283986.29, assets=11542587.56, CAGR=5.59% | |
| year 12: monthly payment_i_a=35754.96, payment_sum_i_a=8101560.43, payment_sum=11223576.00, debt=9187346.22, debt_i_a=4307386.42, monthly rental=60000.00, rental_sum=8640000.00, yearly b=290940.51, b=538439.57, full_b=-1461560.43, rental profit=1549541.78, investments=6011102.21, owned_value=10692613.58, assets=12242155.36, CAGR=5.62% | |
| year 13: monthly payment_i_a=33731.09, payment_sum_i_a=8506333.54, payment_sum=12086928.00, debt=8866507.26, debt_i_a=3921664.71, monthly rental=60000.00, rental_sum=9360000.00, yearly b=315226.89, b=853666.46, full_b=-1146333.54, rental profit=1864768.67, investments=6011102.21, owned_value=11078335.29, assets=12943103.96, CAGR=5.63% | |
| year 14: monthly payment_i_a=31821.79, payment_sum_i_a=8888194.96, payment_sum=12950280.00, debt=8525879.66, debt_i_a=3557551.69, monthly rental=60000.00, rental_sum=10080000.00, yearly b=338138.58, b=1191805.04, full_b=-808194.96, rental profit=2202907.25, investments=6011102.21, owned_value=11442448.31, assets=13645355.55, CAGR=5.62% | |
| year 15: monthly payment_i_a=30020.55, payment_sum_i_a=9248441.59, payment_sum=13813632.00, debt=8164242.89, debt_i_a=3213823.87, monthly rental=60000.00, rental_sum=10800000.00, yearly b=359753.38, b=1551558.41, full_b=-448441.59, rental profit=2562660.62, investments=6011102.21, owned_value=11786176.13, assets=14348836.75, CAGR=5.59% | |
| year 16: monthly payment_i_a=28321.28, payment_sum_i_a=9588296.89, payment_sum=14676984.00, debt=7780301.16, debt_i_a=2889327.02, monthly rental=60000.00, rental_sum=11520000.00, yearly b=380144.69, b=1931703.11, full_b=-68296.89, rental profit=2942805.32, investments=6011102.21, owned_value=12110672.98, assets=15053478.30, CAGR=5.55% | |
| year 17: monthly payment_i_a=26718.18, payment_sum_i_a=9908915.11, payment_sum=15540336.00, debt=7372678.74, debt_i_a=2582972.22, monthly rental=60000.00, rental_sum=12240000.00, yearly b=399381.79, b=2331084.89, full_b=331084.89, rental profit=3342187.10, investments=6011102.21, owned_value=12417027.78, assets=15759214.88, CAGR=5.50% | |
| year 18: monthly payment_i_a=25205.83, payment_sum_i_a=10211385.12, payment_sum=16403688.00, debt=6939915.06, debt_i_a=2293732.22, monthly rental=60000.00, rental_sum=12960000.00, yearly b=417529.99, b=2748614.88, full_b=748614.88, rental profit=3759717.09, investments=6011102.21, owned_value=12706267.78, assets=16465984.87, CAGR=5.45% | |
| year 19: monthly payment_i_a=23779.09, payment_sum_i_a=10496734.19, payment_sum=17267040.00, debt=6480459.47, debt_i_a=2020637.89, monthly rental=60000.00, rental_sum=13680000.00, yearly b=434650.93, b=3183265.81, full_b=1183265.81, rental profit=4194368.02, investments=6011102.21, owned_value=12979362.11, assets=17173730.13, CAGR=5.39% | |
| year 20: monthly payment_i_a=22433.10, payment_sum_i_a=10765931.42, payment_sum=18130392.00, debt=5992665.66, debt_i_a=1762774.98, monthly rental=60000.00, rental_sum=14400000.00, yearly b=450802.77, b=3634068.58, full_b=1634068.58, rental profit=4645170.79, investments=6011102.21, owned_value=13237225.02, assets=17882395.81, CAGR=5.33% | |
| year 21: monthly payment_i_a=21163.30, payment_sum_i_a=11019891.08, payment_sum=18993744.00, debt=5474785.79, debt_i_a=1519280.96, monthly rental=60000.00, rental_sum=15120000.00, yearly b=466040.34, b=4100108.92, full_b=2100108.92, rental profit=5111211.13, investments=6011102.21, owned_value=13480719.04, assets=18591930.17, CAGR=5.27% | |
| year 22: monthly payment_i_a=19965.38, payment_sum_i_a=11259475.66, payment_sum=19857096.00, debt=4924964.23, debt_i_a=1289342.15, monthly rental=60000.00, rental_sum=15840000.00, yearly b=480415.42, b=4580524.34, full_b=2580524.34, rental profit=5591626.55, investments=6011102.21, owned_value=13710657.85, assets=19302284.41, CAGR=5.20% | |
| year 23: monthly payment_i_a=18835.27, payment_sum_i_a=11485498.85, payment_sum=20720448.00, debt=4341230.87, debt_i_a=1072190.90, monthly rental=60000.00, rental_sum=16560000.00, yearly b=493976.81, b=5074501.15, full_b=3074501.15, rental profit=6085603.36, investments=6011102.21, owned_value=13927809.10, assets=20013412.46, CAGR=5.14% | |
| year 24: monthly payment_i_a=17769.12, payment_sum_i_a=11698728.27, payment_sum=21583800.00, debt=3721494.12, debt_i_a=867103.03, monthly rental=60000.00, rental_sum=17280000.00, yearly b=506770.58, b=5581271.73, full_b=3581271.73, rental profit=6592373.94, investments=6011102.21, owned_value=14132896.97, assets=20725270.91, CAGR=5.08% | |
| year 25: monthly payment_i_a=16763.32, payment_sum_i_a=11899888.11, payment_sum=22447152.00, debt=3063533.37, debt_i_a=673395.36, monthly rental=60000.00, rental_sum=18000000.00, yearly b=518840.17, b=6100111.89, full_b=4100111.89, rental profit=7111214.11, investments=6011102.21, owned_value=14326604.64, assets=21437818.75, CAGR=5.01% | |
| year 26: monthly payment_i_a=15814.45, payment_sum_i_a=12089661.53, payment_sum=23310504.00, debt=2364991.03, debt_i_a=490423.35, monthly rental=60000.00, rental_sum=18720000.00, yearly b=530226.57, b=6630338.47, full_b=4630338.47, rental profit=7641440.68, investments=6011102.21, owned_value=14509576.65, assets=22151017.33, CAGR=4.95% | |
| year 27: monthly payment_i_a=14919.29, payment_sum_i_a=12268693.07, payment_sum=24173856.00, debt=1623364.13, debt_i_a=317578.96, monthly rental=60000.00, rental_sum=19440000.00, yearly b=540968.46, b=7171306.93, full_b=5171306.93, rental profit=8182409.14, investments=6011102.21, owned_value=14682421.04, assets=22864830.18, CAGR=4.89% | |
| year 28: monthly payment_i_a=14074.81, payment_sum_i_a=12437590.75, payment_sum=25037208.00, debt=835995.31, debt_i_a=154288.57, monthly rental=60000.00, rental_sum=20160000.00, yearly b=551102.32, b=7722409.25, full_b=5722409.25, rental profit=8733511.47, investments=6011102.21, owned_value=14845711.43, assets=23579222.90, CAGR=4.83% | |
| year 29: monthly payment_i_a=13278.12, payment_sum_i_a=12596928.17, payment_sum=25900560.00, debt=63.30, debt_i_a=11.02, monthly rental=60000.00, rental_sum=20880000.00, yearly b=560662.57, b=8283071.83, full_b=6283071.83, rental profit=9294174.04, investments=6011102.21, owned_value=14999988.98, assets=24294163.02, CAGR=4.77% |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| import argparse | |
| import sys | |
| # Calculate lost of purchasing power of value after 1 year of inflation with rate inflation_f. | |
| def lpp(value, inflation_f): | |
| return value * (1 / (1 + inflation_f)) | |
| def lpp_n_years(value, inflation_f, n_years): | |
| return value * (1 / (1 + inflation_f))**n_years | |
| def lpp_test(): | |
| v1 = lpp(100, 0.03) | |
| print(f"lpp test: {v1:.2f}") | |
| v2 = lpp_n_years(100, 0.03, 5) | |
| print(f"lpp_n_years test: {v2:.2f}") | |
| # cagrs as a fraction | |
| def CAGR(initial, end, n_years): | |
| # print(f"calculating cagr: initial={initial}, end={end}, n_years={n_years}") | |
| return (end / initial)**(1 / n_years) - 1 | |
| def cagr_test(): | |
| c1 = CAGR(100, 200, 1) | |
| c2 = CAGR(1000.0, 1980, 6) | |
| print(f"cagr test: {c1:.2%}") | |
| print(f"cagr test: {c2:.2%}") | |
| c3 = CAGR(863352.00, 863352.00 + 720000.00, 1) | |
| print(f"cagr test: {c3:.2%}") | |
| ''' | |
| Notes: | |
| - Mortage conf is assumed to be calculated elsewhere, here we just take monthly | |
| payment, years and loan size as input. Defaults are for 12m for 30 years at 6% | |
| interest. We still need rate to calculate payments interest / body parts. | |
| - Inflation is used to calculate mortage payment reduction over time. Default 6% is | |
| conservative I'd say. | |
| - Realty price is assumed to grow exactly with inflation, so we assume no | |
| profit/loss here and so no calculations are done. Which is also conservative. | |
| - Rental is assumed to grow with exactly inflation too, again we don't do anything here. | |
| - Amortization, taxes etc are assumed to be included into rental. | |
| - if you think mortage is a typo, it is not | |
| ''' | |
| if __name__ == '__main__': | |
| parser = argparse.ArgumentParser(description=""" | |
| calculate some vovsu donimaet | |
| """) | |
| parser.add_argument("-y", help="years", type=int) | |
| parser.add_argument("--mortage-payment", help="monthly mortage payment", type=int, default=71946) | |
| parser.add_argument("--mortage-rate", help="mortage rate", type=float, default=6.0) | |
| parser.add_argument("-r", help="monthly rental", type=int) | |
| parser.add_argument("-i", help="inflation in %", type=float, default=6.0) | |
| parser.add_argument("-s", help="how many years to skip before rental starts", type=int, default=3) | |
| parser.add_argument("-d", "--down-payment", help="down payment", type=int, default=3000000) | |
| parser.add_argument("-l", "--loan", help="loan size", type=int, default=12000000) | |
| parser.add_argument("--renovation", help="renovation cost. 50k per 1m2 seems reasonable. Unlike down payment, not assumed to be returned when sold, which is not clear actually", type=int, default=2000000) | |
| args = parser.parse_args() | |
| print(args.y) | |
| years = args.y | |
| payment = args.mortage_payment | |
| mortage_rate_f = args.mortage_rate / 100.0 | |
| rental = args.r | |
| inflation_f = args.i / 100.0 | |
| skip_years = args.s | |
| down_payment = args.down_payment | |
| loan = args.loan | |
| price = down_payment + loan | |
| remaining_debt = loan | |
| # initial | |
| renovation = args.renovation | |
| print(f"inflation factor: {inflation_f:.4f}, skip years: {skip_years}, loan: {loan}, down_payment: {down_payment}, renovation: {renovation}") | |
| payment_inf_adjusted = payment | |
| # sum of loan payed out | |
| payment_sum_inf_adjusted = 0 | |
| payment_sum = 0 | |
| # sum of investments to cover payment while rental is not enough | |
| payment_investments = 0 | |
| rental_sum = 0 | |
| # part of rental left after covering payments | |
| rental_profit = 0 | |
| for i in range(0, years): | |
| for m in range(0, 12): | |
| monthly_bank_interest = remaining_debt * (mortage_rate_f / 12) | |
| monthly_body = payment - monthly_bank_interest | |
| remaining_debt -= monthly_body | |
| # print(f"year {i} month {m}: interest={monthly_bank_interest:.2f}, body={monthly_body:.2f}, remaining_loan={remaining_loan:.2f}") | |
| remaining_debt_inf_adjusted = lpp_n_years(remaining_debt, inflation_f, i + 1) | |
| payment_yearly_inf_adjusted = payment_inf_adjusted * 12 | |
| payment_sum_inf_adjusted += payment_yearly_inf_adjusted | |
| payment_sum += payment * 12 | |
| # Pure this year rental income not broke up into payment and profit parts | |
| if i >= skip_years: | |
| yearly_rental = rental * 12 | |
| else: | |
| yearly_rental = 0 | |
| # Pure rental income not broke up into payment and profit parts | |
| rental_sum += yearly_rental | |
| # Break rental into payment and profit because putting it into payment reduces investments. | |
| if yearly_rental <= payment_yearly_inf_adjusted: | |
| # all rental goes to payment + we need investments to cover the rest | |
| payment_investments += payment_yearly_inf_adjusted - yearly_rental | |
| else: | |
| # rental covers payment, the rest is profit | |
| rental_profit += yearly_rental - payment_yearly_inf_adjusted | |
| # Total (cumulative) rental minus payment balance. Note that these | |
| # balances describe what you have on hands while the realty is not sold; | |
| # IOW, they ignore accumulating owned part of the property and thus look | |
| # a bit sad. | |
| balance = rental_sum - payment_sum_inf_adjusted | |
| # current year rental minus payment balance | |
| yearly_balance = yearly_rental - payment_yearly_inf_adjusted | |
| # takes into account renovation but not down payment because the latter is assumed to be returned when selling | |
| full_balance = balance - args.renovation | |
| investments = down_payment + renovation + payment_investments | |
| # note: again, renovation is not included in assets as not assumed to be | |
| # returned when selling | |
| # Models payoff & sell. | |
| owned_value = price - remaining_debt_inf_adjusted | |
| assets = owned_value + rental_profit | |
| # You might want to compare with non existing linear payout model | |
| # owned_value_lm = down_payment + (i + 1) / years * loan + rental_profit | |
| # Note that in this basic model with mortage % == inflation % (free | |
| # loan) and realty price changing exactly with inflation (buying + | |
| # selling gives zero), if you ignore renovation & down payment, profit | |
| # just equals rental_sum. | |
| cagr = CAGR(investments, assets, i + 1) | |
| # Interesting points: | |
| # - when payment_inf_adjusted gets to rental, i.e. thing becomes self sustainable | |
| # - when accumulated the rest of rental - payment_inf_adjusted buys back the initial investments | |
| # - total (mostly initial) investments size | |
| print(f"year {i}: monthly payment_i_a={payment_inf_adjusted:.2f}, payment_sum_i_a={payment_sum_inf_adjusted:.2f}, payment_sum={payment_sum:.2f}, debt={remaining_debt:.2f}, debt_i_a={remaining_debt_inf_adjusted:.2f}, monthly rental={rental:.2f}, rental_sum={rental_sum:.2f}, yearly b={yearly_balance:.2f}, b={balance:.2f}, full_b={full_balance:.2f}, rental profit={rental_profit:.2f}, investments={investments:.2f}, owned_value={owned_value:.2f}, assets={assets:.2f}, CAGR={cagr:.2%}") | |
| payment_inf_adjusted = lpp(payment_inf_adjusted, inflation_f) | |
| # not changing rental assumes it changes with inflation |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment