Housing Market
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;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 about 12 years ago by Anamaria Berea.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
Housing Market.png | preview | Preview for 'Housing Market' | about 12 years ago, by Anamaria Berea | Download |
This model does not have any ancestors.
This model does not have any descendants.
Isabel S
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 9 years ago