Skip to content

キャッシュフローを考慮して賃貸と分譲を比較する

キャッシュフローを考慮……?

例えばなのだが「1000 万円を〇〇に投資したら、10 年後に 1300 万円になりました! 300 万円、つまり 30%も儲かりました!」というような話をしている人がいる。これは儲かったと言えるのだろうか?これを年利に換算すると、2.6%程度の利益になる。これはインフレ率が 2-3%という前提で考えると、実質的にはほとんど儲からなかったもしくは損をした、 ということになる。S&P500 の平均リターンは 10%程度ということを考えると、ちょっと分が悪い投資だな、という感想になるだろう。これが逆に 1 年で 1300 万円になった場合は、 30%のリターンになるので、これはかなりいい投資だった、ということになる。

このように、投資の成果を評価するときには、単純に金額だけでなく、キャッシュフローを考慮することが重要になる。賃貸と不動産購入を比較するときに、「購入の場合はコレぐらいのコストがかかって、コレぐらいのリターンがあるので、差額でコレぐらい儲かる」というような比較をしている場合がままある。こういった比較だとキャッシュフローが考慮されていない、つまり時間軸を無視しているので、もうちょっとそれっぽい比較を行いたい。

ついでにいうと、比較も大抵の場合、賃貸の場合は家賃を払っただけで、比較対象となる不動産購入のシナリオと比べた場合の余剰資金の運用について考慮されていない。これも含めて考慮したい。

計算する方法

途中まで Google Spreadsheet で計算していたのだが、途中でめんどくさくなってしまったので Python で適当なライブラリを探していたら pyxirrという名前そのまんまなライブラリを見つけたので、それでそのまま計算してみることにする。

MORTGAGE_RATE = 0.005
MORTGAGE_PERIODS = 35

def Y(n: int) -> date:
    return date(2020 + n, 1, 1)

def annual_mortgage_payment(*, buy_price: int, downpayment: int) -> float:
    return -1 * pmt(MORTGAGE_RATE, MORTGAGE_PERIODS, buy_price - downpayment)


def mortgage_left(*, buy_price: int, downpayment: int, years: int) -> int:
    return (
        buy_price
        - downpayment
        + cumprinc(MORTGAGE_RATE, MORTGAGE_PERIODS, buy_price - downpayment, 1, years)
    )

35 年固定ローンで、金利が 0.5%の場合の年間のローン支払いと、ある年におけるローン残高を計算できるようになったので、もろもろのキャッシュフローを出してみる。ここでは次の動画にある設定を使ってみる。

def mortgage_payments(
    *, buy_price: int, downpayment: int, hoa_monthly: int, sell_price: int, years: int
) -> list[tuple[date, float]]:
    payment = annual_mortgage_payment(buy_price=buy_price, downpayment=downpayment)
    ret = [
        (Y(0), -downpayment),
        (Y(0), -0.03 * buy_price),
        (Y(0), -6),
        (Y(0), -0.03 * buy_price * 0.1),
        # 楽天銀行は定額
        # (Y(0), -0.022 * (buy_price - downpayment)),
        (Y(0), -33),
        (Y(0), -40),
        (Y(0), -15),
        (Y(0), -3),
        # ここは変わるけど……
        (Y(0), -40),
        (Y(0), -2),
        (Y(0), -8),
    ]
    for i in range(1, years + 1):
        ret.extend(
            [
                (Y(i), -payment),
                (Y(i), -12 * hoa_monthly),
                (Y(i), -10),
                (Y(i), 15),
            ]
        )
    left = mortgage_left(buy_price=buy_price, downpayment=downpayment, years=years)
    ret.extend(
        [
            (Y(years), -left),
            (Y(years), -7),
            (Y(years), -6),
            (Y(years), -0.03 * sell_price),
            (Y(years), sell_price),
        ]
    )
    return ret

動画にでている設定をほとんど流用している。いくつかの値は物件によって変わるのだが、たぶん大体同じぐらいのレベルの物件だったらあまり変わらないかなと思って、そのまま流用している。本当に本当に正確に計算したいならここらへんも変える必要があるけど、誤差の範囲のレベル(例えば数千万円規模の話の中の数万円程度の誤差)なので、 あまり気にしないことにする。

RENT_INITIAL_COST = 4
RENT_RETURN_COST = 0.5

def rent_payments(*, monthly: int, years: int) -> list[tuple[date, float]]:
    ret = [(Y(0), -monthly * RENT_INITIAL_COST)]
    for i in range(1, years + 1):
        ret.append((Y(i), -12 * monthly))
        if i % 2 == 0 and i != years:
            ret.append((Y(i), -monthly))
    ret.append((Y(years), monthly * RENT_RETURN_COST))
    return ret

賃貸の場合も同様に動画を参考にして値を出している。ここでの初期費用は家賃の 4 ヶ月分で、退去時に家賃の 0.5 ヶ月分が返ってくるという設定になっている。

実際にこの計算がある程度妥当な値を出すかということを確認するために、参考にした動画と同様の設定で N 年目にどれぐらいの値段で売れると、賃貸と購入のどちらが特になるのかという計算をしてみる。

buy_price = 7700
downpayment_ratio = 0
for years in range(1, 11):
    rent_flow = rent_payments(monthly=34, years=years)
    for sell_price in range(1000, 25000, 10):
        buy_flow = mortgage_payments(
            buy_price=buy_price,
            downpayment=buy_price * downpayment_ratio,
            hoa_monthly=3,
            sell_price=sell_price,
            years=years,
        )
        rent_npv = xnpv(0.02, rent_flow)
        buy_npv = xnpv(0.02, buy_flow)

        if buy_npv > rent_npv:
            appreciation = sell_price / buy_price
            print(f"Year {years}: {sell_price} {appreciation:.2f}")
            break

実行結果は次のようになる。

Year 1: 7900 1.03
Year 2: 7560 0.98
Year 3: 7170 0.93
Year 4: 6810 0.88
Year 5: 6420 0.83
Year 6: 6050 0.79
Year 7: 5650 0.73
Year 8: 5280 0.69
Year 9: 4860 0.63
Year 10: 4480 0.58

この値は多少購入の方が有利ではあるものの、概ね動画の結果と一致しているので、このコードである程度妥当な値がでると言えるだろう。これをベースにして、もうちょっと設定を変えて計算してみる。

頭金を払うとどうなるか

「頭金を払うと払う金利が減りますよ」といい感じに話されていることがままあるのだが、これが本当のところどうなのかを計算してみる。

# downpayment_ratio = 0.1 の場合
Year 1: 7920 1.03
Year 2: 7580 0.98
Year 3: 7210 0.94
Year 4: 6860 0.89
Year 5: 6480 0.84
Year 6: 6120 0.79
Year 7: 5730 0.74
Year 8: 5370 0.70
Year 9: 4970 0.65
Year 10: 4600 0.60

# downpayment_ratio = 0.2 の場合
Year 1: 7930 1.03
Year 2: 7600 0.99
Year 3: 7240 0.94
Year 4: 6910 0.90
Year 5: 6540 0.85
Year 6: 6200 0.81
Year 7: 5810 0.75
Year 8: 5460 0.71
Year 9: 5070 0.66
Year 10: 4710 0.61

やはり多少収益性が悪化するものの、そこまで大きく動くことはない。ここから更に現実的な設定を加えていく。

余剰資金を投資するとどうなるか

賃貸と購入の比較をするときに、ざっくりいうとつぎのようなパターンを比較していることが多い。

  • 頭金 2000 万円を払って不動産を購入する
  • おなじ 2000 万円をタンス預金して、家賃を払い続けて、最後の比較ではなぜか 2000 万円 はなかったことになっている。

この比較はおかしい。普通に考えて 2000 万円とかあったら投資する。ということで、賃貸と購入のそれぞれのベースのキャッシュフローを計算した上で、同時期にかかるキャッシュフローを比較、その上で差額部分を S&P500 に投資するという変形を行う。これにより比較シナリオは次のようになる。

  • 頭金 2000 万円を払って不動産を購入する。その後賃貸で家賃を払い続けるよりもラン ニングコストが低い場合は、その差額を S&P500 に投資する。
  • 2000 万円を S&P500 に投資する。その後購入したときと比べてランニングコストが低い 場合は、その差額を S&P500 に投資する。

この比較を行うために、2 つのキャッシュフローを受け取って、余剰資金投資を行った場合の新しいキャッシュフローを返す関数を作成する。

def free_cash_investment(
    flow1: list[tuple[date, float]], flow2: list[tuple[date, float]]
) -> (list[tuple[date, float]], list[tuple[date, float]]):
    agg1 = defaultdict(float)
    agg2 = defaultdict(float)
    for d, amount in flow1:
        agg1[d] += amount
    for d, amount in flow2:
        agg2[d] += amount

    dates = set(agg1.keys()) | set(agg2.keys())
    final_date = max(dates)

    free_cash1 = []
    free_cash2 = []
    ret1 = []
    ret2 = []
    for d in sorted(dates):
        am1 = agg1[d]
        am2 = agg2[d]
        if d == final_date:
            ret1.append((d, am1))
            ret2.append((d, am2))
            continue
        if am1 > am2:
            free_cash1.append((d, abs(am2 - am1)))
            ret1.append((d, am2))
            ret2.append((d, am2))
        else:
            free_cash2.append((d, abs(am2 - am1)))
            ret1.append((d, am1))
            ret2.append((d, am1))
    inv_result1 = 0
    inv_result2 = 0
    for d, amount in free_cash1:
        inv_result1 += amount * pow(1.1, final_date.year - d.year)
    for d, amount in free_cash2:
        inv_result2 += amount * pow(1.1, final_date.year - d.year)
    if inv_result1 == 0:
        inv_result1 = 0.001
    if inv_result2 == 0:
        inv_result2 = 0.001
    ret1.append((final_date, inv_result1))
    ret2.append((final_date, inv_result2))
    return (ret1, ret2)

S&P500 の歴史的な平均的なリターンがインフレ調整前で 10%程度なので、ここでは 10%のリターンを仮定している。NPV を使って計算しているので、ここでインフレ調整をしている。

buy_price = 7700
downpayment_ratio = 0
for years in range(1, 11):
    rent_flow = rent_payments(monthly=34, years=years)
    for sell_price in range(1000, 25000, 10):
        buy_flow = mortgage_payments(
            buy_price=buy_price,
            downpayment=buy_price * downpayment_ratio,
            hoa_monthly=3,
            sell_price=sell_price,
            years=years,
        )
        rent_flow, buy_flow = free_cash_investment(rent_flow, buy_flow)
        rent_npv = xnpv(0.02, rent_flow)
        buy_npv = xnpv(0.02, buy_flow)

        if buy_npv > rent_npv:
            appreciation = sell_price / buy_price
            print(f"Year {years}: {sell_price} {appreciation:.2f}")
            break

実行結果は次のようになる。

# downpayment_ratio = 0 の場合
Year 1: 7930 1.03
Year 2: 7590 0.99
Year 3: 7210 0.94
Year 4: 6840 0.89
Year 5: 6420 0.83
Year 6: 6010 0.78
Year 7: 5550 0.72
Year 8: 5100 0.66
Year 9: 4590 0.60
Year 10: 4080 0.53

# downpayment_ratio = 0.1 の場合
Year 1: 8000 1.04
Year 2: 7750 1.01
Year 3: 7450 0.97
Year 4: 7180 0.93
Year 5: 6860 0.89
Year 6: 6560 0.85
Year 7: 6220 0.81
Year 8: 5890 0.76
Year 9: 5520 0.72
Year 10: 5160 0.67

# downpayment_ratio = 0.2 の場合
Year 1: 8080 1.05
Year 2: 7910 1.03
Year 3: 7690 1.00
Year 4: 7510 0.98
Year 5: 7300 0.95
Year 6: 7110 0.92
Year 7: 6880 0.89
Year 8: 6690 0.87
Year 9: 6450 0.84
Year 10: 6250 0.81

このように頭金を払い、かつ賃貸の場合できちんと余剰資金を投資することを考慮すると 10 年後の損益分岐点がかなり変わることがわかる。参考にしている動画では 40%下落することはまずない、という前提で購入の方が有利だと言っているが、頭金・手付金を 20%払うという前提だと、この損益分岐点が 10 年後で 20%程度の下落率になる。

金利が 1%になった場合

ここまででは住宅ローン金利が 35 年固定で 0.5%だと仮定していたが、最近は金利が上昇する流れになってきているので、仮に 1%になった場合にどうなるかを計算してみる。

# downpayment_ratio = 0 の場合
Year 1: 7970 1.04
Year 2: 7670 1.00
Year 3: 7330 0.95
Year 4: 7010 0.91
Year 5: 6630 0.86
Year 6: 6280 0.82
Year 7: 5860 0.76
Year 8: 5470 0.71
Year 9: 5010 0.65
Year 10: 4570 0.59

# downpayment_ratio = 0.1 の場合
Year 1: 8040 1.04
Year 2: 7820 1.02
Year 3: 7560 0.98
Year 4: 7330 0.95
Year 5: 7050 0.92
Year 6: 6800 0.88
Year 7: 6500 0.84
Year 8: 6230 0.81
Year 9: 5900 0.77
Year 10: 5600 0.73

# downpayment_ratio = 0.2 の場合
Year 1: 8110 1.05
Year 2: 7970 1.04
Year 3: 7790 1.01
Year 4: 7650 0.99
Year 5: 7470 0.97
Year 6: 7320 0.95
Year 7: 7130 0.93
Year 8: 6980 0.91
Year 9: 6790 0.88
Year 10: 6640 0.86

金利が 0.5%から 1%に上昇した場合、損益分岐点がそこそこ上昇してくることがわかる。

購入価格を変えた場合

2024 年 6 月時点で、ドゥ・トゥールの 70 平米の物件価格が 1.25 億円ほど。それに対して家賃が 31 万円ほどに下落している。この価格で購入するとどうなるかを計算してみる。

# downpayment_ratio = 0 の場合
Year 1: 13190 1.06
Year 2: 13030 1.04
Year 3: 12830 1.03
Year 4: 12690 1.02
Year 5: 12520 1.00
Year 6: 12400 0.99
Year 7: 12260 0.98
Year 8: 12170 0.97
Year 9: 12070 0.97
Year 10: 12020 0.96

# downpayment_ratio = 0.1 の場合
Year 1: 13310 1.06
Year 2: 13270 1.06
Year 3: 13210 1.06
Year 4: 13210 1.06
Year 5: 13200 1.06
Year 6: 13240 1.06
Year 7: 13290 1.06
Year 8: 13400 1.07
Year 9: 13510 1.08
Year 10: 13700 1.10

# downpayment_ratio = 0.2 の場合
Year 1: 13430 1.07
Year 2: 13510 1.08
Year 3: 13580 1.09
Year 4: 13730 1.10
Year 5: 13870 1.11
Year 6: 14090 1.13
Year 7: 14320 1.15
Year 8: 14630 1.17
Year 9: 14960 1.20
Year 10: 15380 1.23

このように購入価格が上昇すると、損益分岐点がかなり上昇してくることがわかる。現状の価格で 20%の頭金を払うと、10 年後には 1.23 倍程度の価格で売却できない限りは賃貸の方が有利になる。

家賃固定で 10 年住んだ場合と比較した損益平衡購入価格

35 年固定金利 1%の環境で、家賃を 34 万円で固定して 10 年住んだ場合と比較して、果たしていくらぐらいの物件を買うのであれば賃貸よりも有利になるのかを計算してみる。

rent_flow = rent_payments(monthly=34, years=10)
for downpayment_ratio in (0, 0.05, 0.1, 0.15, 0.2):
    print(f"Downpayment Ratio: {downpayment_ratio}")
    for buy_price in range(20000, 7000, -1000):
        for sell_price in range(1000, 25000, 10):
            buy_flow = mortgage_payments(
                buy_price=buy_price,
                downpayment=buy_price * downpayment_ratio,
                hoa_monthly=3,
                sell_price=sell_price,
                years=10,
            )
            rent_flow, buy_flow = free_cash_investment(rent_flow, buy_flow)
            rent_npv = xnpv(0.02, rent_flow)
            buy_npv = xnpv(0.02, buy_flow)

            if buy_npv > rent_npv:
                appreciation = sell_price / buy_price
                print(f"\t{buy_price} -> {sell_price} {appreciation:.2f}")
                break

計算結果が次のようになる。

Downpayment Ratio: 0
        20000 -> 22020 1.10
        19000 -> 20600 1.08
        18000 -> 19190 1.07
        17000 -> 17770 1.05
        16000 -> 16350 1.02
        15000 -> 14940 1.00
        14000 -> 13520 0.97
        13000 -> 12100 0.93
        12000 -> 10680 0.89
        11000 -> 9260 0.84
        10000 -> 7850 0.79
        9000 -> 6430 0.71
        8000 -> 5010 0.63
Downpayment Ratio: 0.05
        20000 -> 23380 1.17
        19000 -> 21900 1.15
        18000 -> 20410 1.13
        17000 -> 18930 1.11
        16000 -> 17440 1.09
        15000 -> 15960 1.06
        14000 -> 14480 1.03
        13000 -> 12990 1.00
        12000 -> 11510 0.96
        11000 -> 10020 0.91
        10000 -> 8540 0.85
        9000 -> 7050 0.78
        8000 -> 5560 0.69
Downpayment Ratio: 0.1
        20000 -> 24740 1.24
        19000 -> 23190 1.22
        18000 -> 21640 1.20
        17000 -> 20090 1.18
        16000 -> 18540 1.16
        15000 -> 16990 1.13
        14000 -> 15430 1.10
        13000 -> 13880 1.07
        12000 -> 12330 1.03
        11000 -> 10780 0.98
        10000 -> 9230 0.92
        9000 -> 7670 0.85
        8000 -> 6120 0.77
Downpayment Ratio: 0.15
        19000 -> 24490 1.29
        18000 -> 22870 1.27
        17000 -> 21250 1.25
        16000 -> 19630 1.23
        15000 -> 18010 1.20
        14000 -> 16400 1.17
        13000 -> 14780 1.14
        12000 -> 13160 1.10
        11000 -> 11540 1.05
        10000 -> 9920 0.99
        9000 -> 8300 0.92
        8000 -> 6680 0.83
Downpayment Ratio: 0.2
        18000 -> 24100 1.34
        17000 -> 22410 1.32
        16000 -> 20730 1.30
        15000 -> 19040 1.27
        14000 -> 17360 1.24
        13000 -> 15670 1.21
        12000 -> 13980 1.17
        11000 -> 12300 1.12
        10000 -> 10610 1.06
        9000 -> 8920 0.99
        8000 -> 7240 0.91

こうしてみると、頭金が 0 の場合は価格の下落率についてそこそこ余裕ができるが、頭金を払えば払うほど、価格が上昇しない限り S&P500 に投資しながら賃貸に住むほうが有利になってくることわかる。

雑感・その他の要素について

東京のマンション価格が 2021 年ぐらいからかなり上昇しているので、それ以前の価格で買った人はかなり利益が出ているだろう。しかし今回の計算結果を見ると、現在の価格で購入する場合は、フルローンで購入する、もしくは今後 10 年の同様の値上がりが見込めると信じるない限り、(S&P500 に投資する)賃貸よりも儲かるかというとそうでもないようにみえる。

一般的に日本の不動産の価値は下落していくと言われている。流石にここ数年のような価格上昇が同様に続いていくとは考えにくいが、適切な物件を選べば緩やかな価格上昇もしくは以前よりも緩やかな価格下落ぐらいは有り得そうな感じがする。例えば、 このページ によると歴史的には 10 年経過後の価格は 20%程度下落しているが、下がるとしてもこれよりも緩いペースで下がるということが考えられる。この場合、頭金を極力抑えることができれば、現状の価格でもそれなりに有利な購入ができるように思われる。

上で行った計算についての細かい考慮事項としては、以下のようなものがある。

  • 家賃の上昇を考慮していない。日本では 2024 年に 17%ほど上昇しているものの、これも恒久的に 17%上がるとは考えにくい。アメリカでは給料も家賃も不動産価格も年々上昇していくのだが、日本では給与も不動産価格も歴史的にはそこまで上昇していない。このトレンドは変わりつつあると言えるかもしれないが、不動産価格の上昇が一部の都心のマンションに限られていることを考えると、全体的に家賃が毎年上がりつつけるかというと、あまりないように思える。仮に想定インフレ率 2%と同じペースで上昇するとすると、例えば頭金 0 円 1.2 億円の 10 年後損益分岐点が 89%から 85%ぐらいになる。
  • 売却時の各種税金を考慮してない。自分が住んでいる不動産を売却した場合は 3000 万円の控除が発生する。他方で S&P500 も NISA 枠を使えば税金がかからないパターンも考えられる。特に賃貸+S&P500 のパターンは、賃貸を乗り換える場合でも株式は売却しなくても良いため、最後の 10 年後にどういう税金がかかるかどうかは、個々人のライフプランによって変わるだろう。例えば 10 年後に賃貸にするのであれば、不動産の方は税金がかかるとした方が良いだろうし、逆に購入するのであれば、S&P500 の方は税金がかかるとしたほうが良いだろう。
  • 雑多な修繕費などは含んでいない。例えば購入した場合は定期的にエアコンや給湯器などの修繕が必要になる。これは賃貸の場合は大家持ちになるので、その分賃貸のほうがお金がかからない。他方で賃貸も数年に一回引っ越しをするということであれば、引越し費用がかかる。これらの支払いはあまり全体の損益に大きな影響を与えないと思われるが、もし細かく計算したいのであれば入れてみればよいだろう。
  • この記事では NPV を用いて、適当に日本のインフレターゲットの 2%を割引率として比較を行った。自分の理解が正しければ、この賃貸と購入の比較を行うにあたって用いた設定及び比較方法においては、どのような割引率を使っても結果は変わらないはずである。同様に、NPV ではなく IRR を使っても単純に同じ式をどちら側から見ているかだけなので、結果は変わらないはずである。というのも、余剰資金を投資するように補正を行った関係で、最終年度を除いてキャッシュフローがどちらのパターンも同一になっているからである。

このようにいくつかの具体的な数値および仮定をおいて、賃貸と購入の比較を行ってみたが、どちらかというと実際にどちらが得かという結果よりも、このような枠組みを作ることで、様々な仮定を追加、変更することによる結果の変化を見ることができたり、変数を変えていったときにどのような結果の変化が出るのかを自分で組むことができるということが重要だと思われる。また、コスト・リターンの計算に様々な要因があるなかで、 どの要素がどれぐらい効いてくるのかという理解も高められる。適当な数値を入れて計算して遊んでみてほしい。