قائمة وثائق المطورين

تحليل مجموعة المنافسين

متوسط

ابنِ مجموعة منافسين حول عقارك من جميع العقارات المجمّعة، واعرف موقع سعرك بينها.

الإعداد

يستخدم هذا الدرس الأداة المساعدة jokerprice.py من درس البدء السريع. احفظها بجوار نصك البرمجي واضبط JOKERPRICE_API_KEY.

عرّف عقارك

Python
mine = {"latitude": 24.8094, "longitude": 46.6112, "bedrooms": 2, "typeId": "6", "nightly": 450}
CITY, RADIUS_KM = "riyadh", 2.0

اجلب عقارات المدينة

تتبع الدالة all_listings قيمة nextCursor بواقع 500 عقار لكل طلب. احفظ النتيجة لتعيد التحليل دون استهلاك طلبات.

Python
import json, os
from jokerprice import all_listings

cache = f"{CITY}-listings.json"
if os.path.exists(cache):
    listings = json.load(open(cache))
else:
    listings = all_listings(CITY)
    json.dump(listings, open(cache, "w"))
print(len(listings), "listings")

صفِّ المنافسين الفعليين

Python
from math import radians, sin, cos, asin, sqrt

def km(a_lat, a_lng, b_lat, b_lng):
    d_lat, d_lng = radians(b_lat - a_lat), radians(b_lng - a_lng)
    h = sin(d_lat / 2) ** 2 + cos(radians(a_lat)) * cos(radians(b_lat)) * sin(d_lng / 2) ** 2
    return 6371 * 2 * asin(sqrt(h))

comps = []
for l in listings:
    if l.get("latitude") is None or not l.get("nightly"):
        continue
    if l.get("bedrooms") != mine["bedrooms"] or str(l.get("typeId")) != mine["typeId"]:
        continue
    d = km(mine["latitude"], mine["longitude"], l["latitude"], l["longitude"])
    if d <= RADIUS_KM:
        comps.append({**l, "km": d})
print(len(comps), "comparables")

اعرف موقعك

Python
from statistics import quantiles, median

rates = sorted(c["nightly"] for c in comps)
p25, p50, p75 = quantiles(rates, n=4)
below = sum(r < mine["nightly"] for r in rates)
print(f"Comp set: 25th SAR {p25:.0f} | median SAR {p50:.0f} | 75th SAR {p75:.0f}")
print(f"Your SAR {mine['nightly']} is above {below / len(rates):.0%} of comparables")

rated = [c for c in comps if c.get("rating")]
top = [c["nightly"] for c in rated if c["rating"] >= 9.5]
if top:
    print(f"Median rate of comps rated 9.5+: SAR {median(top):.0f} ({len(top)} listings)")

تحتاج quantiles إلى عقارين مماثلين على الأقل؛ وسّع نصف القطر إن كان العدد أقل.

راجع أقرب المنافسين

Python
for c in sorted(comps, key=lambda c: c["km"])[:15]:
    print(f"{c['km']:.2f} km  SAR {c['nightly']:>5}  rating {c.get('rating') or '-':>4}  reviews {c.get('reviews') or 0:>4}  {c['source']:<7} {c.get('district') or ''}")

أضف أداء الحجوزات

لا تكشف الأسعار المعروضة ما يُحجز فعلًا. وتقبل /api/v1/metrics النطاق نفسه على هيئة مستطيل على الخريطة، فتستطيع قراءة الإشغال ومتوسط السعر اليومي للمنطقة المحيطة بعقارك.

Python
from jokerprice import api
d = 0.02   # about 2 km
m = api("GET", "/api/v1/metrics", params={"north": mine["latitude"] + d, "south": mine["latitude"] - d,
                                          "east": mine["longitude"] + d, "west": mine["longitude"] - d, "past_days": 60})["metrics"]
print(m["maturity"], "occupancy", m["past"]["occupancy"], "ADR", m["past"]["adr"], "tracked", m["listings"]["tracked"])