Analyser un marché local
Combinez stats, tendances et activité pour un tableau de bord marché complet.
Une analyse de marché efficace combine trois dimensions : l'état actuel (statistiques agrégées), l'évolution temporelle (tendances), et la dynamique (activité, saisonnalité). Normi propose un endpoint dédié à chaque dimension.
1. Statistiques actuelles
Commencez par une vue d'ensemble : volume de transactions, prix médian, prix au m².
import requests
API_KEY = "normi_votre_token"
BASE_URL = "https://mcp.normi.fr/v1"
HEADERS = {"X-API-Key": API_KEY}
# 1. Statistiques agrégées — état actuel du marché
stats = requests.get(
f"{BASE_URL}/stats/market",
params={"code_postal": "33000", "type_local": "Appartement"},
headers=HEADERS,
).json()
print(f"=== Marché Appartements — Bordeaux Centre (33000) ===")
print(f"Transactions (3 ans) : {stats['count']:,}")
print(f"Prix médian : {stats['price']['median']:,} €")
print(f"Prix médian au m² : {stats['price_per_m2']['median']:,} €/m²")
print(f"Surface médiane : {stats['surface']['median']} m²")2. Tendances temporelles
/v1/stats/trends retourne l'évolution par période avec les variations year-over-year (YoY). Résultats mis en cache 24h.
# 2. Évolution trimestrielle sur 5 ans
trends = requests.get(
f"{BASE_URL}/stats/trends",
params={
"code_postal": "33000",
"type_local": "Appartement",
"granularity": "quarter",
},
headers=HEADERS,
).json()
print(f"\n=== Tendances trimestrielles ===")
print(f"Tendance globale : {trends['summary']['overall_trend']}")
print(f"Variation totale : {trends['summary']['total_change_pct']:+.1f}%")
# Afficher les 4 derniers trimestres
for t in trends["trends"][-4:]:
yoy = t["yoy_change"]["price_median_pct"]
print(f" {t['period']} : {t['price']['median']:,} € ({yoy:+.1f}% YoY)")3. Saisonnalité et activité
Utilisez la granularité mensuelle pour identifier les pics d'activité saisonniers.
# 3. Activité et saisonnalité (24 derniers mois)
activity = requests.get(
f"{BASE_URL}/stats/trends",
params={
"code_postal": "33000",
"granularity": "month",
"date_debut": "2024-01-01",
},
headers=HEADERS,
).json()
# Identifier les mois les plus actifs
monthly = sorted(
activity["trends"],
key=lambda t: t["transaction_count"],
reverse=True,
)
print("\n=== Top 3 mois les plus actifs ===")
for m in monthly[:3]:
print(f" {m['period']} : {m['transaction_count']} transactions, {m['price']['median']:,} € médiane")4. Comparer plusieurs zones
Comparez plusieurs codes postaux ou communes pour identifier les zones premium et abordables.
# 4. Comparaison de quartiers — Bordeaux vs Mériadeck vs Chartrons
compare = requests.get(
f"{BASE_URL}/stats/market",
params={"commune": "BORDEAUX", "type_local": "Appartement"},
headers=HEADERS,
).json()
# Requêtes par code postal pour granularité quartier
QUARTIERS = {
"Centre (33000)": "33000",
"Caudéran (33200)": "33200",
"Bacalan (33300)": "33300",
}
print("\n=== Comparaison par quartier ===")
print(f"{'Quartier':<25} {'Médiane/m²':>12} {'Transactions':>14}")
print("-" * 55)
for name, cp in QUARTIERS.items():
r = requests.get(
f"{BASE_URL}/stats/market",
params={"code_postal": cp, "type_local": "Appartement"},
headers=HEADERS,
).json()
print(f"{name:<25} {r['price_per_m2']['median']:>10,} €/m² {r['count']:>12,}")/v1/stats/market coûte 5 crédits. Comparer 4 zones = 20 crédits. Pensez à mettre en cache les résultats si vous construisez un tableau de bord.Visualisation avec Chart.js
Les données de tendances sont directement compatibles avec Chart.js pour des graphiques d'évolution des prix.
// Préparer les données pour Chart.js
const trends = await fetchTrends("33000", "Appartement", "quarter");
const chartData = {
labels: trends.trends.map((t) => t.period),
datasets: [
{
label: "Prix médian au m² (€)",
data: trends.trends.map((t) => t.price_per_m2.median),
borderColor: "rgb(37, 99, 235)",
backgroundColor: "rgba(37, 99, 235, 0.1)",
tension: 0.3,
fill: true,
},
],
};
const config = {
type: "line",
data: chartData,
options: {
responsive: true,
plugins: {
legend: { position: "top" },
title: { display: true, text: "Évolution du prix au m² — Bordeaux 33000" },
},
scales: {
y: {
ticks: {
callback: (value) => `${value.toLocaleString("fr-FR")} €`,
},
},
},
},
};
// new Chart(document.getElementById("myChart"), config);Avec Claude (MCP)
Claude peut réaliser toute l'analyse en une seule instruction :