Housing Market

Housing Market preview image

This model is seeking new collaborators — would you please help?

3 collaborators

Default-person Anamaria Berea (Author)
Default-person Matthew McMahon (Author)
Hoda Osman (Team member)

Tags

housing market 

Tagged by Anamaria Berea almost 5 years ago

interest rate 

Tagged by Anamaria Berea almost 5 years ago

mortgage 

Tagged by Anamaria Berea almost 5 years ago

renter ownership 

Tagged by Anamaria Berea almost 5 years ago

Visible to everyone | Changeable by the author
Model was written in NetLogo 5.0.4 • Viewed 986 times • Downloaded 71 times • Run 0 times
Download the 'Housing Market' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


## WHAT IS IT?

This model is an implementation of a simple, abstract housing market, with an adjustable interest rate.

The goal is to look for the emergence of a “bubble” when a shock is introduced into the system and to understand how housing bubbles and foreclosures emerge. In this model, the shock is introduced via the interest rate variable.

The hypothesis is that exogenous interest rate adjustments contribute to the rise in foreclosures and emergence of the housing “bubble”.

## HOW TO USE IT

The main components of the model are People, Houses, Banks, and Mortgages.

The ‘People’ agents are either renters or owners of one or more houses. Each house is associated with zero or one mortgage that is owned by a bank. As the principal agents in the model, people have annual fixed income that follows a uniform random distribution ranging between 5-15 K. The gradient green color of people reflects the differences in income level—the darker the shade, the wealthier the agent. At the initialization of the model, an agent evaluates whether it can buy a house as a primary residence. If the available investment capital is insufficient, it evaluates for renting a house instead. If it can afford to rent, it relocates to a random affordable rental, otherwise it exits the system. If the agent can afford to buy a primary residence house, it relocates to one. If a house owner can not afford paying mortgages on the house, it evaluates for renting. House owner systematically evaluate whether they can afford buying an extra house for investment (renting out for other agents). Moreover, if an agent owns more than one house and can no longer afford paying the mortgages, it randomly picks a house from the list of houses it owns and sells it. Lastly, the expected time for staying in the same house is set at 7 years (84 ticks during the run of simulation); i.e. agents move every 7 years on average.

The ‘House’ agents have prices that follow a random uniform distribution within the range of 75-150K. Red patches indicate rental houses, while blue ones are for ownership. Again, darker shades of either color indicate higher mortgage cost or rent. Black patches are assigned as empty. A house put on sale turns into pink as an indication of foreclosure.

‘Mortgages’ are formulated as agents to capture object-oriented notion that a mortgage is an entity unto itself: the mortgage is owned by (and housed within) a bank, yet is associated with a particular person and also with a particular house.

‘Banks’ are agents that own balance sheets, introduced to keep track of their assets and liabilities. The liabilities side of the balance sheets comprises the whole mortgage value of the houses owned by a bank. Banks assets, on the other hand, include monthly mortgage payments investments returns that are assumed to be exogenous to the model (for simplicity). Consequently, in case of a house foreclosure, the owner bank is negatively affected on the side of its assets.

The model is initiated by creating houses at a specified density on the map (using ‘Initial density of patches’ parameter). Each house is then assigned a price within the specified range. Based on the ‘Rental House Density’ parameter, a fraction of houses are assigned as rentals. ‘Percent occupied’ parameter determines the number of initialized people on landscape. Each person is then assigned an income level within the specified range. People are assigned to houses by matching their income and mortgage cost/rent level.

Fluctuate the interest rate and observe the foreclosures - as pink houses - in the landscape. The model can be adjusted for verisimilitude via the calibration parameters.

The average house price, the mortgage and the balance sheets are the most important plots. Their variations relative to each other (one high, the other low) show whether a crisis emerges or not.

## THINGS TO NOTICE

At default, the people move between houses, houses are being bought and sold and renters become owners and vice-versa. There are some foreclosures, but not too many. By keeping the interest rate parameter constant, the system stabilizes until no house is being sold any more and there is only movement of people between the houses.

The only parameter in this model is the interest rate. By increasing or decreasing the interest rate based on real time values (1 tick = 1 month), the system shows a spike in foreclosures followed by adjustments. The model shows, through the rental/ownership ratio, that less people afford more houses and the people with higher income that afford more houses and offer them for rent.

## NETLOGO FEATURES

This code has been updated to comply with Netlogo 5.0.4 (The previous version used deprecated Netlogo 4.0.4 features, per http://ccl.northwestern.edu/netlogo/docs/transition.html)

## CREDITS AND REFERENCES

We thank the Center for Social Complexity at George Mason University, USA.

Model Web Site: http://www.css.gmu.edu/node/81

Paper: http://www.css.gmu.edu/images/HousingMarket_revisited/Housing_Market_revisited.pdf

Comments and Questions

price (Question)

hello dear, I am reading this model and a beginner in netlogo. My question is how price of house are working becuase bubble is via an exogenous shock? THanksss

Posted over 2 years ago

Click to Run Model

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;A Housing Market Model
;;Anamaria Berea, Hoda Osman, Matt McMahon
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

globals 
[
housingDemand
]

; agents
breed [banks bank]
banks-own
[
myMortgages
incomeFromHouses
]

breed [people person]
people-own
[
  income    ; period income
  myHouses   ; which houses do I own; first in the list is the own I occupy. the rest are the ones I own and perhaps rent.
  timeInHouse ;
  investmentCapital
]

breed [houses house]
houses-own 
[
  has-owner
  updateMortgage
  is-occupied    ; does someone live here
  is-rental      ; am I a rental
  
  price  ; house price
  purchase-price;
  is-owned;todo keep track if house is owned or not
  mortgageCost  ; tick mortgage cost
  rent      ; tick rent cost
  
  missedPaymentCount ; count number of missed payments
]

breed [mortgages mortgage]
mortgages-own
[
  which-owner
  which-house
  which-bank
  
  purchasePrice
]

;initialization

to initialize
  ;; (for this model to work with NetLogo's new plotting features,
  ;; __clear-all-and-reset-ticks should be replaced with clear-all at
  ;; the beginning of your setup procedure and reset-ticks at the end
  ;; of the procedure.)
  __clear-all-and-reset-ticks
  random-seed 8675309      
  ;agents
  setup-houses
  setup-people 
  
  setup-banks
  setup-mortgages
  
  ;plots
  setup-average-house-price-plot
  update-average-house-price-plot
end 

to go
   
   update-housing-price-info    
   update-available-capital
   update-people
   buy-investment-houses
   update-available-capital   
   ;update-people
   update-mortgages   
   sell-investment-houses    
   tick
   
   update-average-house-price-plot
   update-mortgage-plot
   update-ownership-plot
   update-mortgageHousePrice-plot

   
   ;ask links [set hidden? not show-links]
   ;print [investmentCapital] of people 
   
    update-average-location
   ;update-housing-stats
   compute-bank-balances
   update-interest-rate-plot
   update-bankrupt-people-plot
   update-balance-sheet-plot
end 


; procedures

to update-housing-price-info
  
    let tmpList []
    ask people
    [
      let tmpCount length myHouses 
      set tmpList fput tmpCount tmpList             
    ] 
    
    let multiplier 1 + 3 * (mean tmpList - housingDemand) / 10
   
    set housingDemand mean tmpList
    print word "housing multipler" multiplier
   
  
  ask houses
  [
    if random 100 < 5
    [ 
      ;if is-occupied = 0 ; todo: do this but make the adjustment only for un-owned houses.
      ;[
        set mortgageCost 0.01 +  price * interest-rate / 60
        set rent  price * rental-fraction
      ;]
    ]
       
    if random 100 < 20
    [  
        ;print word "1 " price
        set price (price * multiplier * multiplier * multiplier)
        ;print word "2 " price
    ]
   
  ifelse is-rental = 1
    [  
      set color rgb (55 + (200 * (price - min-price) / (max-price - min-price))) 0 0
    ]
    [
      set color rgb 0 0 (55 + (200 * (price - min-price) / (max-price - min-price)))
    ]  
  
  ifelse missedPaymentCount > 3
     [
         set size 2.0
         set color pink
         
     ]
     [
        ifelse is-rental = 1
       [  
         set color rgb (55 + (200 * (price - min-price) / (max-price - min-price))) 0 0
       ]
       [
         set color rgb 0 0 (55 + (200 * (price - min-price) / (max-price - min-price)))
       ]      
        set size 1.0
     ]
  ]
end 

to sell-investment-houses
 ;ask people whose investment capital is negative to sell a house
 ask people with [investmentCapital < 0 and length myHouses > 1]
 [
   if random 100 < 50
   [
     ;sell a house 
     ;print "Selling a house"
     let tmpHouses but-first myHouses
     let listToSell houses with [member? self tmpHouses]   ; find houses that are in the person's list
     ;print listToSell
     ;print count houses with [updateMortgage = 1]
     let tmpMyHouses []
     set tmpMyHouses myHouses
     let foreclosedHouses  listToSell with [missedPaymentCount > 3]
     ifelse count foreclosedHouses > 0
     [
       if random-float 1.0 < 0.2
       [
        ask one-of foreclosedHouses
        [
         ;find my mortgage and sell me
         let myMortgage one-of mortgages with [which-house = myself] ; find my mortgage
         
         ;print myMortgage
         ;print tmpMyHouses
         set tmpMyHouses remove-item (position self  tmpMyHouses) tmpMyHouses
         ;set is-rental 0
         ;print tmpMyHouses
         ;some mortgages get asked to die which don't exist ...     
         ;ask myMortgage
         ;[
         ;die
         ;]        
         set missedPaymentCount 0   
         ]
       ]
     ]
     [
      ask one-of listToSell
      [
        ;find my mortgage and sell me
        let myMortgage one-of mortgages with [which-house = myself] ; find my mortgage
        
        ;print myMortgage
        ;print tmpMyHouses
        set tmpMyHouses remove-item (position self  tmpMyHouses) tmpMyHouses
        ;set is-rental 0
        ;print tmpMyHouses
        ;some mortgages get asked to die which don't exist ...     
        ;ask myMortgage
        ;[
        ;die
        ;]           
      ]
     ]
        ;print "Done Selling a house"
     set myHouses tmpMyHouses
   ]
 ]
end 

to update-people
;ask people with [investmentCapital < 0]
;[
;set color pink
;set size 2 
;]
ask people with [investmentCapital >= 0]
[
set color rgb 0 (100 + (155 * (income - min-income ) / (max-income - min-income))) 0     
set size 1.0
]

  ask people
  [
    
    set timeInHouse (timeInHouse + 1)
    ;randomly move to a new house
    if (random mobility = 1 or ; check to see if it's time to move to a new hosue
          (investmentCapital < 0 and (length myHouses = 1))) ; or if house has become too expensive
    [
    ;;begin move to new house
      ;sell-house
      set timeInHouse 0
      let myHouse item 0 myHouses
  
      if ([is-rental] of myHouse = 0)
      [
        ;set [has-owner] of myHouse 0
        ask myHouse [set has-owner 0]
      ]
      ;set [is-occupied] of myHouse 0
      ask myHouse [set is-occupied 0]
      set myHouses remove-item 0 myHouses
      
      ;buy new house
          let housingList houses  with 
          [
            count people-here = 0         
          ];; assign a house to occupy

       let tmpHouse []
 
       let myRentalList housingList with [is-rental = 1 and rent < [income] of myself]
       let myPurchaseList housingList with [is-rental = 0 and mortgageCost < [income] of myself]
       
       ;print count myRentalList 
       ;print count myPurchaseList      
       
       
       ifelse (count myPurchaseList > 0)
       [
         set tmpHouse one-of myPurchaseList
       ]
       [
         if (count myRentalList > 0)
         [
            set tmpHouse one-of myRentalList
         ]     
       ]
       
      ;;occupy tmpHouse
      move-to tmpHouse     
      ;;create-link-with  tmpHouse          
      set myHouses  fput tmpHouse myHouses           ; add it to my list of houses. most people will have one house.      
 
      ask item 0 myHouses
      [
        set is-occupied 1
      ]      
    
     ;exchange mortgage

       ask mortgages with [which-owner = myself and which-house = myHouse]       
       [         
         set which-owner myself
        set which-house item 0 [myHouses] of which-owner
        set which-bank one-of banks
        move-to which-bank       
       ]  
    ]
    
    ;;end move to a new house
  ]  
end 

to update-mortgages
  
  let tmpMortgageCount count houses with [updateMortgage = 1]
  create-mortgages tmpMortgageCount  
  [
    set which-house one-of houses with     
    [
      updateMortgage = 1
       ;member? self myHouses = true
    ]
    set which-owner one-of people with
    [
      member? [which-house] of myself myHouses = true
    ]       
    set which-bank one-of banks
    set purchasePrice [price] of which-house
    ;set [purchase-price] of which-house purchasePrice
    let newpp purchasePrice
    ask which-house [set purchase-price newpp]
    move-to which-bank
    ;set [updateMortgage] of which-house 0  ; finished updating
    ask which-house [set updateMortgage 0]
  ]
end 

to update-available-capital
  ; update available capital
  ask people
  [
    let tmpCapital income
    let tmpHouse item 0 myHouses
    ifelse ([is-rental] of tmpHouse = 0)
    [
      set tmpCapital tmpCapital - [mortgagecost] of tmpHouse
    ]     
    [ 
     set tmpCapital tmpCapital - [rent] of tmpHouse
    ]
    if (length myHouses > 1)
    [
      let tmpHouses but-first myHouses
      ask houses with [member? self tmpHouses]   ; find houses that are in the person's list, and subtract cost
      [
        set tmpCapital tmpCapital - mortgageCost
        ifelse tmpCapital < 0
        [
          set missedPaymentCount (missedPaymentCount + 1)
        ]
        [
          set missedPaymentCount 0
        ]
      ]      
    ]
    set investmentCapital tmpCapital
  ]    
end 

to buy-investment-houses
  ask people
  [    
    ;randomly choose a new house to buy
    if random-float 1.0 < 0.1
    [       
      ;print "buying an investment house" 
      ;buy new house
          let housingList houses  with 
          [
            count people-here = 0 and
            mortgagecost < [investmentCapital] of myself
          ];; assign a house to buy
       ;print [mortgagecost] of houses
       ;print investmentCapital
       let tmpHouse []
        
       ;let myPurchaseList housingList with [is-rental = 0 and mortgageCost < [income] of myself]      
       
       if (count housingList > 0)
       [
         set tmpHouse one-of housingList ;if there are houses available, choose one to buy
         ;;add house to my list
         ;print "tmpHouse"
         ;print tmpHouse
         set myHouses  lput tmpHouse myHouses           ; add it to my list of houses. most people will have one house.      
 
         ;adjust capital 
         ;set [is-rental] of tmpHouse 1    
         ask tmpHouse [set is-rental 1]     
         set investmentCapital (income - [mortgageCost] of tmpHouse)         
         
       ]
        ;print "done buying an investment house" 
    ]
  ]  
end 

to setup-mortgages
  set-default-shape mortgages "circle"
  create-mortgages count houses with [is-occupied = 1]
  ask mortgages
  [
   let myHouse one-of houses with [is-occupied = 1 and updateMortgage = 1]
   set which-owner one-of people with     
   [
     item 0 myHouses = myHouse
   ]

    set which-house item 0 [myHouses] of which-owner
    set which-bank one-of banks
    set purchasePrice [price] of which-house
    ;set [updateMortgage] of which-house 0
    ask which-house [set updateMortgage 0]
    move-to which-bank
    set color green
  ]  
end 

to setup-houses
 ask patches 
 [ 
   set pcolor black
 ]
 set-default-shape houses "house"
 ;set-default-shape patches "house"
 
  let houseCount ceiling (initial-density * world-width * world-height / 100)
  ;print houseCount
  create-houses houseCount
  ask houses 
  [
       set price (min-price + random (max-price - min-price))
       set is-occupied 0
       set mortgageCost 0.01 + price * interest-rate / 50
   
   if random-float 100.0 < rental-density
     [
       set is-rental 1
       set rent  price * rental-fraction
      
     ]
     let tmpPrice price
     move-to one-of patches with [count (houses-here) = 0 and abs (pycor / world-height - ((tmpPrice - min-price) / (max-price - min-price))) < .1]
     ;move-to one-of patches with [count (houses-here) = 0 ]
    ifelse is-rental = 1
    [  
      set color rgb (55 + (200 * (price - min-price) / (max-price - min-price))) 0 0
    ]
    [
      set color rgb 0 0 (55 + (200 * (price - min-price) / (max-price - min-price)))
    ]      
    set size 1 ; dont draw the house agent
    set updateMortgage 1
  ]
end 

to setup-people 
  set-default-shape people "person"

  let num-people (count houses * percent-occupied / 100); 
  create-people num-people
    [ 
      set income (random (max-income - min-income) + min-income)
      set myHouses []
 
      
      let housingList houses  with 
          [
            count people-here = 0         
          ];; assign a house to occupy

      let tmpHouse []

      let myRentalList housingList with [is-rental = 1 and rent < [income] of myself]
      let myPurchaseList housingList with [is-rental = 0 and mortgageCost < [income] of myself]
      
      ;print count myRentalList 
      ;print count myPurchaseList      
      
      ifelse (count myPurchaseList > 0)
      [
        set tmpHouse one-of myPurchaseList
      ]
      [
        if (count myRentalList > 0)
        [
           set tmpHouse one-of myRentalList
        ]     
      ]
      
     ;;occupy tmpHouse
     move-to tmpHouse  ; here is where we should deal with homeless people  
     set timeInHouse random mobility
     ;;create-link-with  tmpHouse          
     set myHouses  lput tmpHouse myHouses           ; add it to my list of houses. most people will have one house.      

     ask item 0 myHouses
     [
       set is-occupied 1
     ]      
    ;adjust capital 
    let houseType [is-rental] of tmpHouse
    ifelse houseType = 1
    [
      set investmentCapital (income - [rent] of tmpHouse)
    ]
    [
      set investmentCapital (income - [mortgageCost] of tmpHouse)
    ]
    ;give self a color
    ;set color rgb 0 (100 + (155 * (income - min-income ) / (max-income - min-income))) 0     
    set color green
    ;set color scale-color green income min-income max-income
    ]    
end 

to setup-banks
  set-default-shape banks "box"
  create-banks num-banks
    [
      set color yellow
      move-to one-of patches with 
        [count (turtles-here) = 0]
        set size 2
    ]
end 

to compute-bank-balances
  ask banks
  [
  let delta 0
  ask mortgages with [which-bank = myself]
    [
     if [missedPaymentCount] of which-house > 0
     [
     set delta (delta + (([price] of which-house) - purchasePrice))
     ]
    ]
  print delta
  set incomeFromHouses delta
  ifelse (delta < 0)
   [
   set color red
   ] ; else
   [
   set color yellow
   ]
  ]
end 
    





;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;plots

to setup-average-house-price-plot
  set-current-plot "average house price"
  set-plot-y-range  0 (ceiling max [mortgageCost] of houses)
end 

to update-average-house-price-plot 
  set-plot-y-range 50 150
  set-current-plot "average house price"
  let myMean mean [price] of houses with [is-occupied = 1]
  set-current-plot-pen "myMean"
  plot myMean
  print "mean house price" 
  print myMean
end 

to update-mortgage-plot
  set-current-plot "average mortgage"
  let myMean mean [mortgageCost] of houses with [is-occupied = 1]
  set-current-plot-pen "myMean"
  plot myMean
  print "mean house price" 
  print myMean
end 

to update-mortgageHousePrice-plot
  set-current-plot "Average House Price vs Average Mortgage"
  set-current-plot-pen "AverageHousePrice"
  plot mean [price] of houses with [is-occupied = 1] 
  set-current-plot-pen "AverageMortgage"
  plot mean [mortgageCost] of houses with [is-occupied = 1]
  
  ;print "mean house price" 
  ;print myMean
end 

to update-average-location
  set-current-plot "average loc"
  let myMean mean [ycor] of people
  set-current-plot-pen "myLoc"
  plot myMean
end 

to update-ownership-plot
   set-current-plot "owner occupied and rental homes"
   let myOwnedHouses count houses with [is-occupied = 1 and is-rental = 0]
   set-current-plot-pen "myOwnedHouses"
   plot myOwnedHouses
   let myRentedHouses count houses with [is-occupied = 1 and is-rental = 1]
   set-current-plot-pen "myRentedHouses"
   ;print "owned and rented"
   ;print word myOwnedHouses myRentedHouses
   plot myRentedHouses
end 

to update-housing-stats
   set-current-plot "mean number of investment houses owned"
   set-plot-y-range  0 15
   let tmpList []
   ask people
    [
      let tmpCount length myHouses 
      set tmpList fput tmpCount tmpList 
    ] 
   print word "average houses owned:" mean tmpList
   set-current-plot-pen "count"
   plot (mean tmpList - housingDemand) * 10 
   ;plot (mean tmpList)
end 

to update-interest-rate-plot
   set-current-plot "Interest Rate"
   set-plot-y-range  0 15

   plot interest-rate
end 

to update-bankrupt-people-plot
   set-current-plot "percentage of people bankrupt"
   let bankruptPeopleCount (count people with [investmentCapital < 0]) / count people
  
   plot bankruptPeopleCount
    set-plot-y-range  0 11
end 

to update-balance-sheet-plot
   set-current-plot "balance sheet plot"
   let solventBankCount count banks with [incomeFromHouses > 0]
  
   plot solventBankCount
    set-plot-y-range  0 50
end 
   
   
   
   
     

There is only one version of this model, created almost 5 years ago by Anamaria Berea.

Attached files

File Type Description Last updated
Housing Market.png preview Preview for 'Housing Market' almost 5 years ago, by Anamaria Berea Download

This model does not have any ancestors.

This model does not have any descendants.