Caricamento del file di dati

data_file = read.csv(“realestate_texas.csv”)

str(data_file)

Tipologia di variabili e analisi associate

city: qualitativa nominale; indica la città di riferimento; analisi della

frequenza con barplot e confronti tra variabili

year: quantitativa discreta; indica l’anno corrispondente; analisi del trend

con linechart

month: quantitativa discreta; indica il mese corrispondente; analisi della

stagionalità delle vendite con boxplot

sales: quantitativa discreta; indica il numero di vendite totali; analisi

della distribuzione e misura degli indici relativi

volume: quantitativa continua; indica il valore totale delle vendite; analisi

del trend e misura degli indici relativi

median_price: quantitativa continua; indica il prezzo mediano degli immobili

venduti; analisi del trend e misura degli indici relativi

listings: quantitativa discreta; indica il numero totale degli annunci attivi;

confronto con la variabile sales e misura degli indici relativi

months_inventory: quantitativa continua; indica la quantità di tempo

necessaria per vendere tutte le inserzioni correnti; analisi del trend e

misura degli indici relativi

Gestione delle variabili temporali (raggruppamento in unica variabile)

data_file\(date = as.Date(paste(data_file\)year, data_file$month, “01”, sep = “-”))

str(data_file$date)

Calcolo indici di posizione, variabilità e forma

library(moments)

quant_var = c(“sales”, “volume”, “median_price”, “listings”, “months_inventory”)

summary(data_file[quant_var]) # minimo, massimo, quartili, mediana, media

apply(data_file[quant_var], 2, function(x){any(x) <= 0}) # controllo zeri

apply(data_file[quant_var], 2, function(x){exp(mean(log(x)))}) # media geometrica

apply(data_file[quant_var], 2, var) # varianza

apply(data_file[quant_var], 2, sd) # deviazione standard

apply(data_file[quant_var], 2, function(x){(sd(x)/mean(x))*100}) # coefficiente di variazione

apply(data_file[quant_var], 2, function(x){max(x)-min(x)}) # range

apply(data_file[quant_var], 2, IQR) # differenza interquartile

apply(data_file[quant_var], 2, skewness) # asimmetria

apply(data_file[quant_var], 2, kurtosis) # curtosi (centrata sul 3)

Variabile sales: il range delle vendite è compreso tra 79 e 423 vendite

mensili, con media maggiore rispetto alla mediana.

La variabilità è del 41.4%, mentre l’asimmetria risulta essere positiva

(valori e modalità più basse maggiormente frequenti).

Variabile volume: range non particolarmente ampio, con marcata variabilità

(del 53.7%), e distribuzione asimmetrica positiva.

L’unica variabile con curtosi maggiore di zero (leptocurtica), e dunque una

forma della distribuzione più allungata.

Variabile median_price: media e mediana sono molto simili, e il range è il

più ampio, diversamente dalla variabilità che risulta essere la più ridotta

(cioè del 17.1%).

In ultimo si osserva asimmetria negativa, con valori e modalità più alte

maggiormente frequenti (mediana > media).

Variabile listings: variabilità del 43,3% (piuttosto alta), asimmetria

positiva e curtosi platicurtica (distribuzione appiattita).

Variabile months_inventory: variabile con il range più basso, caratterizzata

da una distribuzione quasi simmetrica, curtosi negativa (ma prossima allo

zero), e variabilità del 25,1%.

Distribuzioni di frequenza

cat_var = c(“city”, “date”)

date_city_freq_dist = lapply(cat_var, function(x){ n = table(data_file[[x]]) # frequenza assoluta f = prop.table(n) # frequenza relativa data_file_out = data.frame( variable_name = names(n), ni = as.vector(n), fi = as.vector(f) ) data_file_out\(Ni = cumsum(data_file_out\)ni) # frequenza cumulata data_file_out\(Fi = cumsum(data_file_out\)fi) # frequenza relativa cumulata return(data_file_out) })

Variabile city: la distribuzione è uniforme, con stesse frequenze assolute

e relative per ciascuna città.

Le frequenze cumulate crescono in modo lineare, e la variabile presa

singolarmente non risulta essere informativa.

L’unica informazione ottenibile è che non ci sono dati mancanti per città.

Variabile date: anche in questo caso frequenza assoluta e relativa sono

costanti (e le frequenze cumulate crescono linearmente).

Come per la variabile city, anche la variabile date non fornisce delle

informazioni aggiuntive, ma conferma il fatto che non ci sono dati mancanti.

Variabili con maggior variabilità e asimmetria

La variabile con maggior variabilità è “volume”, come si può evincere dal

coefficiente di variazione (indice ottimale per confrontare variabili in

su scale differenti).

In altre parole la variabile volume è caratterizzata da valori che si

discostano maggiormente dal suo valor medio (elevato grado di dispersione).

La variabile con maggior asimmetria è “volume”, proprietà osservabile

dal risultato dell’indice skewness.

Ciò indica la possibile presenza di outlier, o comunque la possibilità che

i valori siano sbilanciati verso una delle due parti della distribuzione.

Nel caso specifico della variabile volume, l’indice misurato risulta essere

positivo, per cui la distribuzione è asimmetrica positiva (valori più bassi

più frequenti, media > mediana > moda).

Suddivisione in classi della variabile sales

sales_classes = cut(data_file$sales, breaks = c(1,100,200,300,400,500), labels = c(“1-100”, “101-200”, “201-300”, “301-400”, “401-500”), right = TRUE, include.lowest = TRUE)

s_ni = table(sales_classes) s_fi = prop.table(s_ni) s_Ni = cumsum(s_ni) s_Fi = cumsum(s_fi)

sales_freq_dist = data.frame(Class = names(s_ni), ni = as.numeric(s_ni), fi = round(as.numeric(s_fi), 4), Ni = as.numeric(s_Ni), Fi = round(as.numeric(s_Fi), 4) )

sales_barplot = barplot(height = sales_freq_dist\(fi, names.arg = sales_freq_dist\)Class, col = “lightblue”, main = “Distribuzione delle vendite per classe”, xlab = “Classi”, ylab = “Frequenza relativa”, border = “black”, ylim = c(0,0.6) )

text(x = sales_barplot, y = sales_freq_dist\(fi, label = round(sales_freq_dist\)fi, 3), pos = 3 )

Gini.index = function(x){ ni = table(x) fi = table(x)/length(x) fi2 = fi^2 J = length(table(x)) Gini = 1-sum(fi2) norm_Gini = Gini/((J-1)/J) return(norm_Gini) }

Gini.index(data_file$sales)

Gini.index(sales_classes)

Discussione risultati

Distribuzione di frequenze: mostra che la classe 101-200 registra (in termini

di frequenza assoluta e frequenza relativa) i valori più alti, seguita poi

dalla classe 201-300.

Da ciò si evince che mensilmente il numero delle vendite si concentra nelle

classi intermedie, e sono meno frequenti le classi agli estremi della

distribuzione (infatti sono rari i casi in cui si registrano più di 400

vendite per mese)

Indice di Gini: il risultato dell’indice di Gini calcolato sulla variabile

sales è 0.78, ovvero prossimo a 1.

Tale valore indica una disuguaglianza significativa tra le varie classi

(eterogeneità elevata), in accordo con ciò che si osserva dalla distribuzione

di frequenze.

Calcolo probabilità

p_Beaumont = sum(data_file$city == “Beaumont”)/nrow(data_file)

p_July = sum(data_file$month == “7”)/nrow(data_file)

p_Dec2012 = sum(data_file$date == “2012-12-01”)/nrow(data_file)

I risultati sono in accordo con le distribuzioni di frequenze

Prezzo medio immobili ed efficacia annunci

data_file\(average_price = (data_file\)volume*10^6)/data_file$sales

sales_listings_ratio = data_file\(sales/data_file\)listings

price_score = data_file\(median_price/max(data_file\)median_price)

time_score = 1/data_file$months_inventory

data_file$efficacy = (sales_listings_ratio + price_score + time_score)/3

La variabile efficacy misura l’efficacia degli annunci tenendo conto di

alcune variabili del data set, e producendo un risultato compreso tra 0 e 1

(per cui 0 rappresenta la totale inefficacia degli annunci, mentre 1

l’efficacia del 100%).

Le variabili tenute in considerazione sono sales, listings, median_price e

months_inventory.

La variabile sales tiene conto del numero di immobili venduti, per cui un

maggior numero di immobili rappresenta una maggior efficacia, tuttavia è

necessario rapportarlo alla variabile listings (numero di annunci attivi in

quell’intervallo temporale) dal momento in cui un rapporto più elevato

suggerisce che la maggior parte degli immobili presenti sul mercato sono

stati venduti.

La variabile median_price invece rappresenta una sorta di grado di difficoltà

di vendita, infatti se il rapporto tra annunci venduti e annunci disponibili

è pari, l’efficacia può considerarsi maggiore per un prezzo mediano maggiore.

In ultimo la quantità di mesi trascorsi per vendere tutti gli annunci attivi,

ossia la variabile months_inventory, per la quale si ha che un valore minore

rappresenta una maggior efficienza di vendita.

summary(data_file$efficacy)

var(data_file$efficacy)

sd(data_file$efficacy)

(sd(data_file\(efficacy)/mean(data_file\)efficacy))*100

skewness(data_file$efficacy)

kurtosis(data_file$efficacy)

Dai risultati si evince che in media l’efficacia è del 34.4% (molto simile

alla mediana), con un’efficacia minima del 20.8% e massima del 53.0%.

La variabilità dei dati relativi a tale variabile è del 16,6% (piuttosto

contenuta), e la distribuzione risulta essere asimmetrica positiva

leptocurtica.

Analisi condizionata

library(dplyr)

city_summary = data_file %>% group_by(city) %>% summarise(sales_mean = mean(sales), sales_sd = sd(sales), volume_mean = mean(volume), volume_sd = sd(volume), median_price_mean = mean(median_price), median_price_sd = sd(median_price), listings_mean = mean(listings), listings_sd = sd(listings), months_inventory_mean = mean(months_inventory), months_inventory_sd = sd(months_inventory))

year_summary = data_file %>% group_by(year) %>% summarise(sales_mean = mean(sales), sales_sd = sd(sales), volume_mean = mean(volume), volume_sd = sd(volume), median_price_mean = mean(median_price), median_price_sd = sd(median_price), listings_mean = mean(listings), listings_sd = sd(listings), months_inventory_mean = mean(months_inventory), months_inventory_sd = sd(months_inventory))

month_summary = data_file %>% group_by(month) %>% summarise(sales_mean = mean(sales), sales_sd = sd(sales), volume_mean = mean(volume), volume_sd = sd(volume), median_price_mean = mean(median_price), median_price_sd = sd(median_price), listings_mean = mean(listings), listings_sd = sd(listings), months_inventory_mean = mean(months_inventory), months_inventory_sd = sd(months_inventory))

library(ggplot2)

library(tidyr)

s_l_city_plot = city_summary %>% select(city, sales_mean, listings_mean) %>% pivot_longer(cols = c(sales_mean, listings_mean), names_to = “variable”, values_to = “value”)

ggplot(s_l_city_plot, aes(x = city, y = value, fill = variable)) + geom_col(position = position_dodge(width = 0.8)) + geom_text(aes(label = round(value, 1)), position = position_dodge(width = 0.8), vjust = -0.3, size = 3.5) + labs(title = “Vendite/Annunci per città”, x = “Città”, y = “Media di Vendite/Annunci”) + scale_fill_manual(values = c(“sales_mean” = “lightblue”, “listings_mean” = “darkred”), labels = c(“Annunci”, “Vendite”)) + theme_classic(base_size = 10) + theme( axis.text.x = element_text(angle = 0, vjust = 0.5), legend.title = element_blank(), plot.title = element_text(face = “bold”) )

ggplot(city_summary, aes(x = city, y = median_price_mean, fill = median_price_mean)) + geom_col() + geom_errorbar(aes(ymin = median_price_mean - median_price_sd, ymax = median_price_mean + median_price_sd), width = 0.2, color = “black”) + geom_text(aes(label = round(median_price_mean, 0)), vjust = -3, size = 3.5) + scale_fill_gradient(low = “lightgreen”, high = “darkgreen”) + labs(title = “Prezzo Mediano per città”, x = “Città”, y = “Prezzo Mediano Medio”) + scale_y_continuous(breaks = seq(0, 160000, by=40000), limits = c(0, 180000)) + theme_classic(base_size = 10) + theme( axis.text.x = element_text(angle = 0, vjust = 0.5), legend.position = “none”, plot.title = element_text(face = “bold”) )

ggplot(city_summary, aes(x = city, y = months_inventory_mean, fill = months_inventory_mean)) + geom_col() + geom_errorbar(aes(ymin = months_inventory_mean - months_inventory_sd, ymax = months_inventory_mean + months_inventory_sd), width = 0.2, color = “black”) + geom_text(aes(label = round(months_inventory_mean, 1)), vjust = -0.5, size = 5) + scale_fill_gradient(low = “lightpink”, high = “darkred”) + scale_y_continuous(breaks = seq(0, 14, by=2), limits = c(0, 14)) + labs(title = “Tempistiche di Vendita per città”, x = “Città”, y = “Mesi impiegati per vendere totale immobili”) + theme_classic(base_size = 10) + theme( axis.text.x = element_text(angle = 0, vjust = 0.5), legend.position = “none”, plot.title = element_text(face = “bold”) )

ggplot(year_summary, aes(x = year, y = sales_mean)) + geom_line(color = “red”, size = 0.8) + geom_point(color = “darkred”, size = 3) + geom_text(aes(label = round(sales_mean, 0)), vjust = -2, size = 3.5) + labs(title = “Andamento temporale delle Vendite”, x = “Anno”, y = “Media delle Vendite”) + scale_y_continuous(breaks = seq(100, 250, by=50), limits = c(100, 260)) + theme_bw(base_size = 12) + theme( plot.title = element_text(face = “bold”), axis.text.x = element_text(angle = 0, vjust = 0.5) )

ggplot(year_summary, aes(x = year, y = median_price_mean)) + geom_line(color = “lightblue”, size = 0.8) + geom_point(color = “darkblue”, size = 3) + geom_text(aes(label = round(median_price_mean, 0)), vjust = -2, size = 3.5) + labs(title = “Andamento temporale del Prezzo Mediano”, x = “Anno”, y = “Media del Prezzo Mediano”) + scale_y_continuous(breaks = seq(100000, 160000, by=20000), limits = c(100000, 160000)) + theme_bw(base_size = 12) + theme( plot.title = element_text(face = “bold”), axis.text.x = element_text(angle = 0, vjust = 0.5) )

ggplot(month_summary, aes(x = month, y = sales_mean)) + geom_line(color = “violet”, size = 1) + geom_point(color = “darkviolet”, size = 3) + geom_text(aes(label = round(sales_mean, 1)), vjust = -2, size = 3) + labs( title = “Vendite Mensili”, x = “Mese”, y = “Media delle Vendite” ) + scale_x_continuous(breaks = seq(0, 12, by=1), limits = c(1, 12)) + scale_y_continuous(breaks = seq(100, 250, by=50), limits = c(100, 280)) + theme_bw(base_size = 12) + theme( plot.title = element_text(face = “bold”), axis.text.x = element_text(angle = 0, vjust = 0.5) )

ggplot(month_summary, aes(x = month)) + geom_line(aes(y = median_price_mean, color = “Prezzo Mediano Medio”), size = 1) + geom_line(aes(y = sales_mean * 1000, color = “Media Vendite”), size = 1) + geom_text(aes(y = median_price_mean, label = round(median_price_mean, 0), color = “Prezzo Mediano Medio”), vjust = -0.5, size = 3) + geom_text(aes(y = sales_mean * 1000, label = round(sales_mean, 0), color = “Media Vendite”), vjust = -0.5, size = 3) + scale_color_manual( name = “Variabili:”, values = c(“Prezzo Mediano Medio” = “blue”, “Media Vendite” = “red”)) + scale_y_continuous( name = “Media del Prezzo Mediano”, breaks = seq(125000, 250000, 50000), limits = c(120000, 250000), sec.axis = sec_axis(~ . / 1000, name = “Media delle Vendite”)) + labs( title = “Prezzi vs Vendite”, x = “Mese”) + scale_x_continuous(breaks = seq(1, 12, 1), limits = c(1, 13)) + theme_bw(base_size = 12) + theme(plot.title = element_text(face = “bold”), axis.text.x = element_text(angle = 0, vjust = 0.5), legend.position = “bottom”)

month_plot = month_summary %>% select(month, median_price_mean, volume_mean) %>% pivot_longer(cols = c(median_price_mean, volume_mean), names_to = “variable”, values_to = “value”)

max_price = max(month_summary\(median_price_mean) max_volume = max(month_summary\)volume_mean) scale_factor = max_price / max_volume

ggplot(month_plot, aes(x = month)) + geom_line(aes(y = ifelse(variable == “volume_mean”, value * scale_factor, value), color = variable), size = 1) + geom_point(aes(y = ifelse(variable == “volume_mean”, value * scale_factor, value), color = variable), size = 3) + geom_text(aes(y = ifelse(variable == “volume_mean”, value * scale_factor, value), label = round(value, 1), color = variable), vjust = -1, size = 3, check_overlap = FALSE) + scale_color_manual( name = “Variabili”, values = c(“median_price_mean” = “blue”, “volume_mean” = “red”), labels = c(“Prezzo Mediano Medio”, “Ricavato Totale Medio delle Vendite (Milioni USD)”)) + scale_y_continuous( name = “Prezzo Mediano Medio (USD)”, sec.axis = sec_axis(~ . / scale_factor, name = “Ricavato Totale Medio delle Vendite (Milioni USD)”)) + scale_x_continuous(breaks = 1:12) + labs(title = “Prezzo Mediano vs Ricavato Totale delle Vendite Mensili”, x = “Mese”) + theme_bw(base_size = 12) + theme( plot.title = element_text(face = “bold”), axis.text.x = element_text(angle = 0, vjust = 0.5), legend.position = “bottom”)

Visualizzazioni con ggplot2

ggplot(data_file, aes(x = city, y = median_price, fill = city)) + geom_boxplot() + labs( title = “Distribuzione del Prezzo Mediano per Città”, x = “Città”, y = “Prezzo Mediano (USD)”) + theme_classic(base_size = 10) + theme( axis.text.x = element_text(angle = 0, hjust = 0.5), legend.position = “none”, plot.title = element_text(face = “bold”))

Le città presentano livelli del prezzo mediano differenti.

Alcune città mostrano box più compatti (maggior omogeneità del mercato),

mentre altre sono caratterizzate da outlier e una più ampia dispersione

(indice di maggiore variabilità del prezzo).

ggplot(data_file, aes(x = city, y = volume, fill = city)) + geom_boxplot(outlier.colour = “black”, outlier.size = 1.5) + labs( title = “Distribuzione del Ricavato Totale delle Vendite per Città”, x = “Città”, y = “Ricavato delle Vendite (Milioni USD)”) + theme_classic(base_size = 10) + theme( legend.position = “none”, plot.title = element_text(face = “bold”), axis.text.x = element_text(angle = 0, vjust = 0.5))

Le marcate differenze tra le distribuzioni evidenziano come in alcune città

si concentri una quota maggiore del ricavato totale, non necessariamente per

prezzi più alti, ma anche per numero di vendite (o viceversa).

Inoltre box più lunghi indicano maggior volatilità del fatturato.

ggplot(data_file, aes(x = factor(year), y = volume)) + geom_boxplot(fill = “lightblue”, outlier.colour = “black”, outlier.size = 1.5) + labs( title = “Distribuzione del Ricavato Totale delle Vendite per Anno”, x = “Anno”, y = “Ricavato delle Vendite (Milioni USD)”) + theme_classic(base_size = 10) + theme( plot.title = element_text(face = “bold”), axis.text.x = element_text(angle = 0, hjust = 0.5))

Nel tempo si osserva un progressivo allungamento delle distribuzioni, infatti

la dispersione del ricavato totale è più ampia, e uno spostamento verso

l’alto (anche la mediana aumenta).

Questi risultati sono indici di espansione disomogenea e crescita strutturale

del mercato.

ggplot(data_file, aes(x = month, y = sales, fill = city)) + geom_col(position = position_dodge(width = 0.8)) + scale_x_continuous(breaks = 1:12) + labs( title = “Totale Vendite Mensili per Città”, x = “Mese”, y = “Numero di Vendite”, fill = “Città”) + theme_classic(base_size = 10) + theme( plot.title = element_text(face = “bold”), axis.text.x = element_text(angle = 0, vjust = 0.5))

sales_month_city = data_file %>% group_by(month, city) %>% summarise(total_sales = sum(sales), .groups = “drop”)

ggplot(sales_month_city, aes(x = factor(month), y = total_sales, fill = city)) + geom_col() + scale_x_discrete(drop = FALSE) + labs( title = “Totale delle Vendite Mensili per Città”, x = “Mese”, y = “Numero Totale di Vendite”, fill = “Città”) + theme_classic(base_size = 10) + theme( plot.title = element_text(face = “bold”), axis.text.x = element_text(angle = 0))

Per ciascuna città è possibile osservare andamenti stagionali simili, con

un aumento delle vendite durante il periodo primaverile/estivo, e un

decremento nel periodo autunnale/invernale.

In alcuni casi la variazione è più marcata, mentre in altre città il livello

delle vendite si mantiene pressoché costante.

ggplot(sales_month_city, aes(x = factor(month), y = total_sales, fill = city)) + geom_col(position = “fill”) + scale_y_continuous(labels = scales::percent) + scale_x_discrete(drop = FALSE) + labs( title = “Distribuzione Percentuale delle Vendite Mensili per Città”, x = “Mese”, y = “Quota Percentuale delle Vendite”, fill = “Città”) + theme_classic(base_size = 10) + theme( plot.title = element_text(face = “bold”), axis.text.x = element_text(angle = 0))

Tramite normalizzazione si può verificare con quale peso incidono le

variazioni stagionali per ciascuna città sul totale delle vendite,

indipendentemente dalla crescita del numero.

Si osserva infatti come alcune città contribuiscano in particolar modo alla

crescita del numero totale di vendite in funzione del mese, mentre altre

risultano essere meno soggette a tale fenomeno.

ggplot(data_file, aes(x = date, y = sales, color = city)) + geom_line(size = 1) + labs( title = “Andamento Storico delle Vendite Immobiliari in Texas”, x = “Data”, y = “Numero di Vendite”, color = “Città”) + scale_x_date(date_labels = “%Y-%m”, date_breaks = “3 months”, limits = as.Date(c(“2010-01-01”, max(data_file$date)))) + theme_bw(base_size = 10) + theme( plot.title = element_text(face = “bold”, hjust = 0.5), axis.text.x = element_text(angle = 60, hjust = 1), legend.position = “bottom”)

Il confronto temporale mostra che le città non seguono traiettorie identiche

nel tempo, bensì alcune sono caratterizzate da una crescita più regolare e

continua, mentre altre presentano fasi di accelerazione più marcata.

Questo risultato indica che il ciclo immobiliare non è perfettamente

sincronizzato a livello geografico, ma risente delle dinamiche locali.

SINTESI DEI RISULTATI E CONSIDERAZIONI STATISTICHE SULL’ANALISI DEL DATASET

==============================================================================

Il mercato immobiliare analizzato mostra un quadro generalmente espansivo.

Le vendite crescono in modo piuttosto costante nel tempo, sia in senso

stretto (numero di transazioni), sia in senso lato (totale del ricavato),

suggerendo un settore con domanda sostenuta e senza evidenti shock recessivi

nel periodo coperto dal dataset.

La stagionalità risulta evidente: i volumi di vendita tendono a concentrarsi

nel periodo primaverile ed estivo, con attenuazioni dell’attività nei mesi

più freddi.

Questo pattern stagionale orienta le imprese a pianificare pricing e

promozioni tenendo conto dei picchi annuali.

Le città invece si differenziano sia per intensità delle vendite, che per

livelli di prezzo, infatti alcune piazze mostrano medie di vendita più alte,

mentre altre si distinguono per prezzi mediani superiori.

La combinazione tra volume e prezzo mediano non è uniforme tra le città,

di fatto è possibile osservare come in alcuni casi il volume sia alto, ma il

prezzo mediano risulti basso (tante vendite, ma a prezzi ridotti), mentre in

altri casi è il volume a risultare basso, con un prezzo mediano più elevato

(poche vendite, ma con prezzi alti).

Questo suggerisce che le strategie di mercato efficaci non siano trasferibili

da una città all’altra, a meno che non si effettuino degli adattamenti.

Inoltre, la relazione tra prezzi e numero di vendite non appare inversa; al

contrario le due variabili si muovono in modo tendenzialmente concorde nel

medio periodo, come evidenziato dai grafici mensili e annuali.

Tale dinamica suggerisce che la domanda sia sufficientemente forte da

assorbire livelli di prezzo crescenti, evitando compressioni del volume.

La variabile listings e l’indicatore months_inventory confermano un mercato

relativamente attivo.

Le tempistiche di vendita non risultano eccessivamente lunghe e non seguono

trend di deterioramento.

La stabilità della variabie inventory indica l’esistenza di un equilibrio tra

domanda e offerta (nonostante i prezzi crescenti): l’offerta non appare

strutturalmente insufficiente, né sovrabbondante, e contribuisce a

consolidare la crescita del mercato.

Nel lungo periodo è possibile osservare un’evoluzione più robusta del prezzo

mediano rispetto al numero di vendite.

Ciò è coerente con il ciclo espansivo immobiliare: prima la domanda aumenta

in quantità, poi i prezzi seguono e si consolidano.

Non emergono crolli o inversioni, e le città che partono da livelli di prezzo

inferiori mostrano recuperi più marcati nel tempo, riducendo il divario con

le città storicamente più care.

Una lettura congiunta dei risultati supporta quindi tre punti chiave.

Primo: il mercato del periodo analizzato non sembra essere soggetto ad alcuna

speculazione, in quanto volumi, prezzi e inventory si muovono coerentemente e

senza segnali di stress.

Secondo: la stagionalità ha un ruolo non trascurabile e può essere sfruttata

in termini di ottimizzazione dei tempi di immissione dell’offerta.

Terzo: la segmentazione geografica è determinante per comprendere le

performance del mercato immobiliare; trattare il “Texas” come un unico

mercato porterebbe a perdite di informazione e alla definizione di strategie

non ottimali.

Alla luce di quanto sopra, si formulano alcune raccomandazioni operative.

Nel breve periodo conviene pianificare annunci e campagne di vendita in

prossimità della stagione più attiva.

Nel medio periodo invece ha senso concentrare l’interesse di investimento

nelle città in cui la crescita combinata di prezzo e volume è più marcata,

segnale di domanda resiliente.

Infine, nel lungo periodo, monitorare attentamente l’indicatore inventory

potrà fornire segnali anticipatori di cambiamento del ciclo: un aumento

persistente dei tempi di vendita senza crescita dell’offerta indicherebbe

indebolimento della domanda, mentre una compressione dei tempi con offerta

stagnante potrebbe anticipare nuove spinte al rialzo dei prezzi.

==============================================================================