يقارن عقد الإيجار الذي تُعدَّل أجرته وفق مؤشر أسعار المستهلك بين مؤشر شهرين مرجعيين، ثم يطبّق التغيّر ضمن حد أدنى وحد أقصى. توفّر Narwhal المؤشر الشهري لأسعار المستهلك لكل دولة، ويتولى سكربت قصير الباقي.
جلب المؤشر لكل شهر مرجعي
يقارن بند الإيجار المرتبط بمؤشر أسعار المستهلك بين مؤشر شهرين مرجعيين، وغالبًا هما الشهر التقويمي نفسه بفارق سنة. يستخدم هذا المثال شهر سبتمبر والمملكة المتحدة. يعيد طلب واحد المؤشر لكل شهر من سبتمبر 2022 إلى سبتمبر 2026، وتُبقي الاستجابة أدناه على الأول والأخير فقط.
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.
حساب الزيادة مع تطبيق الحد الأدنى والحد الأقصى
نسبة الزيادة لسنة هي المؤشر الجديد مقسومًا على المؤشر القديم ناقص واحد. يحدد الحد الأدنى أقل ارتفاع للإيجار، ويحدد الحد الأقصى أعلاه. النسبة المطبّقة هي نسبة الزيادة محصورة بين الحدّين، والإيجار الجديد هو الإيجار القديم مضروبًا في واحد زائد النسبة المطبّقة.
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 في المئة. وفي كل ذكرى سنوية يقارن العقد شهر سبتمبر بسبتمبر السابق. يطبع السكربت سطرًا لكل سنة، مثل 2023: CPI 123.8 -> 132.0, change 6.62%, applied 5.00%, rent 2100.00. يعمل بـ Decimal طوال الوقت ويقرّب الإيجار إلى أقرب سنت مرة واحدة كل سنة، لذا فإن عقدًا يقرّب النسبة أولًا، أو يقرّب الإيجار بطريقة مختلفة، سيختلف ببضعة سنتات.
| السنة | التغيّر في المؤشر | النسبة المطبّقة | الإيجار |
|---|---|---|---|
| 2023 | من 123.8 إلى 132.0، 6.62% | 5.00% (بلغ الحد الأقصى) | 2,100.00 |
| 2024 | من 132.0 إلى 134.2، 1.67% | 2.00% (رُفع إلى الحد الأدنى) | 2,142.00 |
| 2025 | من 134.2 إلى 139.3، 3.80% | 3.80% | 2,223.40 |
| 2026 | من 139.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، وتتبع السنتان التاليتان المؤشر. يتراكم الإيجار تراكمًا مركّبًا لأن كل سنة تبدأ من إيجار السنة السابقة. أما العقد الذي يطبّق كل نسبة على الإيجار الابتدائي دون تركيب فيحتاج إلى حفظ الإيجار الابتدائي في متغير منفصل.
ما توفّره الواجهة وما يحدده العقد
| البند | المصدر |
|---|---|
| قيمة المؤشر لكل شهر | قراءات مؤشر أسعار المستهلك في Narwhal |
| أي مؤشر يسمّيه العقد | العقد |
| الأشهر المرجعية | العقد |
| الحد الأدنى والحد الأقصى | العقد |
| التقريب والتركيب | العقد |
توفّر Narwhal الرقم القياسي العام لأسعار المستهلك لكل دولة. وإذا سمّى العقد مؤشرًا آخر، مثل المؤشر الأساسي أو مؤشرًا إقليميًا أو مؤشرًا من جهة نشر مختلفة، فقد لا تكون الأرقام هنا هي التي يستخدمها العقد. اقرأ البند قبل تشغيل السكربت.
أي شهر يجب أن تستخدم الزيادة مؤشره؟
الأشهر التي يسمّيها العقد. يستخدم المثال سبتمبر لأن البند هنا يقارن سبتمبر بسبتمبر السابق، ولأن أحدث مؤشر للمملكة المتحدة هو لسبتمبر 2026. اطلب الشهرين بـ start وend، أو اقرأ شهرًا ماضيًا واحدًا بـ /v1/economics/{country}/cpi?period=YYYY-MM.
ماذا لو لم يُنشر الشهر الجديد عند الذكرى السنوية؟
يعيد طلب شهر لا توجد له قيمة منشورة استجابة مشكلة 404 بالرمز series_not_found. أما نقطة CPI دون period فتعيد أحدث شهر وتاريخ released_on الخاص به. وإذا حلّت الذكرى السنوية قبل صدور الشهر المرجعي، فأبقِ الإيجار دون تغيير وأعد تشغيل السكربت عند ظهور الشهر، أو اتبع البديل الذي ينص عليه العقد.
ماذا يحدث إذا انخفضت الأسعار؟
يصبح التغيّر سالبًا، ويقرر الحصر النتيجة. مع حد أدنى 0 في المئة تكون النسبة المطبّقة 0 في المئة ويبقى الإيجار كما هو. ومع حد أدنى 2 في المئة كما في المثال أعلاه يرتفع الإيجار 2 في المئة رغم ذلك. أما العقد بلا حد أدنى فيدع الإيجار ينخفض بنسبة التغيّر، وتعالج الدالة نفسها هذه الحالة بحد أدنى -1.
هل أستطيع إجراء الفحص نفسه لدولة أخرى؟
غيّر رمز الدولة في المسار. تعيد النقطة المؤشر العام للدولة، لذا يجب أن يسمّي البند هذا المؤشر. تقبل start وend الصيغ YYYY وYYYY-MM وYYYY-QN، ويدلّك شكل نصوص period في الاستجابة على أن السلسلة شهرية أو ربعية. ويتناول دليل حساب التضخم السنوي والشهري لمؤشر أسعار المستهلك نسبة التغيّر بمزيد من التفصيل.
نُشر في .