計算有下限與上限的 CPI 租金調整

依 CPI 調整租金的租約,會比較兩個基準月份的指數,再把變動率限制在下限與上限之間套用。Narwhal 提供各國的月度 CPI 指數,其餘由一支簡短的腳本完成。

取得每個基準月份的指數

CPI 租金條款會比較兩個基準月份的指數,通常是相隔一年的同一個曆月。本例使用 9 月與英國。一次請求就回傳 2022 年 9 月到 2026 年 9 月每個月的指數,下面的回應只保留了第一個與最後一個。

curl,租約基準月份的 CPI
curl -s -H "Authorization: Bearer $NARWHAL_API_KEY" \
  "https://api.narwhalapi.com/v1/economics/GBR/cpi/observations?start=2022-09&end=2026-09&limit=100"
回應,已精簡
{
  "country": "GBR",
  "as_of": "2026-10-21T00:00:00Z",
  "index_base": "2015=100",
  "observations": [
    {
      "period": "2022-09",
      "value": "123.8"
    },
    {
      "period": "2026-09",
      "value": "144.1"
    }
  ],
  "next_cursor": null
}

observations 依由舊到新的順序列出每個 period 及其 value。英國的 index_base 是 2015=100,對百分比變動沒有影響。as_of 是該序列所反映的日期。這個請求回傳 49 個月度值,全部在一頁之內,next_cursor 為 null。

用下限與上限計算調整幅度

一年的調整幅度等於新指數除以舊指數再減一。下限設定租金至少上漲多少,上限設定最多上漲多少。實際適用的比率是把調整幅度限制在兩者之間的結果,新租金等於舊租金乘以一加適用比率。

python,有下限與上限的年度租金調整
import json
import os
import urllib.request
from decimal import Decimal, ROUND_HALF_UP

def get(path):
    req = urllib.request.Request(
        "https://api.narwhalapi.com" + path,
        headers={"Authorization": "Bearer " + os.environ["NARWHAL_API_KEY"]},
    )
    with urllib.request.urlopen(req, timeout=30) as r:
        return json.load(r)

def escalate(rent, cpi_old, cpi_new, floor, cap):
    change = cpi_new / cpi_old - 1
    applied = min(max(change, floor), cap)
    return (rent * (1 + applied)).quantize(Decimal("0.01"), ROUND_HALF_UP), change, applied

data = get("/v1/economics/GBR/cpi/observations?start=2022-09&end=2026-09&limit=100")
cpi = {o["period"]: Decimal(o["value"]) for o in data["observations"]}

rent, floor, cap = Decimal("2000.00"), Decimal("0.02"), Decimal("0.05")
for year in (2023, 2024, 2025, 2026):
    old, new = cpi[f"{year - 1}-09"], cpi[f"{year}-09"]
    rent, change, applied = escalate(rent, old, new, floor, cap)
    print(f"{year}: CPI {old} -> {new}, change {change:.2%}, applied {applied:.2%}, rent {rent}")

本例的租約起始租金為每月 2,000.00,下限為 2%,上限為 5%。每個週年日都用 9 月與上一年的 9 月比較。腳本每年列印一行,例如 2023: CPI 123.8 -> 132.0, change 6.62%, applied 5.00%, rent 2100.00。它全程使用 Decimal 計算,並且每年只把租金四捨五入到分一次,所以如果租約先對比率取整,或是用別的方式對租金取整,結果會相差幾分。

年份指數變動適用比率租金
2023123.8 到 132.0,6.62%5.00%(觸及上限)2,100.00
2024132.0 到 134.2,1.67%2.00%(觸及下限)2,142.00
2025134.2 到 139.3,3.80%3.80%2,223.40
2026139.3 到 144.1,3.45%3.45%2,300.01

手動驗證第一年。132.0 除以 123.8 等於 1.0662,所以指數上漲了 6.62%。這高於上限,因此適用比率是 5%,2,000.00 乘以 1.05 得 2,100.00。2024 年,134.2 除以 132.0 等於 1.0167,低於 2% 的下限,所以租金上漲 2%,變為 2,142.00。

2023 年觸及上限,2024 年被下限拉高,後面兩年則跟隨指數。租金是複利成長的,因為每一年都從上一年的租金出發。如果租約把每年的比率都套用在起始租金、不做複利,就需要把起始租金放在單獨的變數裡。

API 提供什麼,租約規定什麼

項目來源
每個月的指數值Narwhal 的 CPI 觀測值
租約指定了哪個指數租約
基準月份租約
下限與上限租約
取整與複利租約

Narwhal 提供的是各國的整體消費者物價指數。如果合約指定了其他指數,例如核心指數、地區指數或另一家公布機構的指數,這裡的數字可能就不是合約所用的數字。執行腳本前請先讀懂條款。

租金調整應該用哪個月的指數?

用租約指定的月份。本例用的是 9 月,因為這裡的條款是把 9 月與上一年的 9 月比較,而且英國的最新指數是 2026 年 9 月的。用 start 與 end 請求這兩個月,或是用 /v1/economics/{country}/cpi?period=YYYY-MM 讀取過去的某一個月。

如果週年日時新的月份還沒有公布怎麼辦?

請求一個尚無公布數值的月份,會回傳代碼為 series_not_found 的 404 問題回應。不帶 period 的 CPI 端點回傳最新的月份及其 released_on 日期。如果週年日早於基準月份的公布時間,請先維持租金不變,等該月份出來後再執行腳本,或是依租約規定的替代辦法處理。

如果物價下降會怎樣?

變動率為負時,結果由上下限的限制來決定。下限為 0% 時,適用比率為 0%,租金維持不變。像上面那樣下限為 2% 時,租金仍然上漲 2%。沒有下限的租約會讓租金依變動率下降,同一個函式把下限設為 -1 就能處理這種情況。

其他國家也能做同樣的檢查嗎?

改一下路徑裡的國家代碼即可。端點回傳該國的整體指數,所以條款也必須指定這個指數。start 與 end 接受 YYYY、YYYY-MM 或 YYYY-QN,回應中 period 字串的格式會告訴你該序列是月度還是季度。百分比變動的更多細節見計算 CPI 年增率的指南。

發布於 。

後續步驟