ICEACE Model: Closed Economy  1.0.0
Design Documentation of ICEACE Model
 All Data Structures Files Functions Variables Typedefs Macros Pages
reagency_functions_housing.c
Go to the documentation of this file.
1 #include "../header.h"
2 #include "../reagency_agent_header.h"
3 #include "../library_header.h"
4 #include <math.h>
5 
6 
7 /*
8  * \fn: int reagency_housing_process()
9  * \brief:
10  */
12 {
13  /* Initialize **
14  */
15 
16  /* Allocate housing buyer queues and seller listss.
17  */
18  hseller_array sellers_list;
19  hbuyer_array buyers_list;
20  hbank_array banks_list;
21 
22 
23  /* Initialize */
24  init_hseller_array(&sellers_list);
25  init_hbuyer_array(&buyers_list);
26  init_hbank_array(&banks_list);
27 
28 
29  /* Collect sellers */
30  int id, type;
31  double price, quantity;
32  int fire_seller_attempts = 0;
33  int regular_seller_attempts = 0;
34  int firm_seller_attempts = 0;
36  type = sell_housing_message->type;
37  if (type == 0){firm_seller_attempts++;}
38  else if (type == 2){regular_seller_attempts++;}
39  else if (type == 1){fire_seller_attempts++;}
40  else {
41  if (WARNING_MODE) {
42  printf("Warning @reagency_housing_process(): Unidentifed seller type is dtected! \n");
43  }
44  type = -1;
45  }
47  price = sell_housing_message->price;
48  quantity = sell_housing_message->quantity;
49  add_hseller(&sellers_list, id, price, quantity, type);
51 
52  /* Queue the households */
53  int bank, mortgage_choice;
54  double cash, income, mortgage;
61  mortgage_choice = buy_housing_message->mortgage_choice;
62  add_hbuyer(&buyers_list,id,bank,cash,income,mortgage,mortgage_choice);
64 
65  /* Queue the banks */
66  double risk;
71  add_hbank(&banks_list, id, cash, risk, 0);
73 
74  if (sellers_list.size == 0 || buyers_list.size == 0) {
75  /* Free seller list */
76  free_hseller_array(&sellers_list);
77  /* Free buyer queues */
78  free_hbuyer_array(&buyers_list);
79  /* Free bank list */
80  free_hbank_array(&banks_list);
81  return 0;
82  }
83 
84  if (PRINT_DEBUG_MODE) {
85  printf("\nReal Estate Agency Reports: Day= %d, Buyers = %d, Sellers = %d, Banks = %d \n", IT_NO, buyers_list.size, sellers_list.size, banks_list.size);
86  }
87 
88  /* Do the matching *
89  * Input assumptions:
90  * - sellers are sorted ascendingly by price.
91  * - buyers are randomly queued
92  * These are arranged at message filtering stage.
93  */
94 
95 
96  /* Compute annuity for possible mortgages. */
97  double annuity;
98  double d1, d2;
99  /* Not needed after implementing code for each mortgage type */
100  //d1 = MORTGAGES_INTEREST_RATE/4;
101  //d2 = d1 * pow((1 + d1), 160);
102  //annuity = 1/d1 - 1/d2;
103 
104  int nsold = 0;
105  int transaction_quantity = 0;
106  double transaction_volume = 0;
107  int fire_sales = 0;
108  int regular_sales = 0;
109  int firm_sales = 0;
110  do {
111  if (sellers_list.size == 0 ){break;}
112  if (buyers_list.size == 0 ){break;}
113 
114  quantity = sellers_list.array[0].quantity;
115  id = sellers_list.array[0].seller_id;
116  price = sellers_list.array[0].price;
117  type = sellers_list.array[0].type;
118 
119  if (nsold == quantity){
120  add_sold_housing_message(id, nsold, price);
121  remove_hseller(&sellers_list, 0);
122  transaction_quantity += nsold;
123  transaction_volume += nsold * price;
124  nsold = 0;
125  if (type == 0) { firm_sales++;}
126  if (type == 2) { regular_sales++;}
127  if (type == 1) { fire_sales++;}
128  continue;
129  }
130  id = buyers_list.array[0].buyer_id;
131  cash = buyers_list.array[0].liquidity;
132  if (cash >= price) {
133  add_bought_housing_message(id, price, 0, 0);
134  nsold++;
135 
136  if (PRINT_DEBUG_MODE) {
137  printf("Real Estate Agency Reports: Buyer ID = %d, bought a housing unit for %f right away! \n", id, price);
138  }
139  remove_hbuyer(&buyers_list, 0);
140  continue;
141  }
142 
143  /* The household needs mortgage.
144  */
145 
146  /* No banks in the market is able to give mortgage credit. */
147  if (banks_list.size == 0 ){
148  if (PRINT_DEBUG_MODE) {
149  printf("Real Estate Agency Reports: No more more banks is available to offer mortgage! \n");
150  }
151  remove_hbuyer(&buyers_list, 0);
152  /* It is possible that some other buyers are able to buy without any credit. */
153  continue;
154  }
155 
156  /* Check available mortgaging capacity of the bank. */
157  bank = buyers_list.array[0].bank_id;
158  int i = 0;
159  int flag = 0;
160  do {
161  if (banks_list.array[i].id == bank){
162  flag = 1;
163  break;
164  }
165  i++;
166  } while (i < banks_list.size);
167  if (flag == 0){
168  remove_hbuyer(&buyers_list, 0);
169  if (PRINT_DEBUG_MODE) {
170  printf("Bank of Household ID = %d is not available any more for crediting the mortgage.\n", id);
171  }
172  continue;
173  }
174 
175  double equity = banks_list.array[i].equity;
176 
177  /* Risky asssets before the market has opened. */
178  risk = banks_list.array[i].risky_assets;
179  /* Risk of bank is evalauted incrementally. */
180  risk += banks_list.array[i].amount_mortgaged;
181 
182  if (equity < CAPITAL_ADEQUECY_RATIO * risk) {
183  remove_hbuyer(&buyers_list, 0);
184  remove_hbank(&banks_list, i);
185  if (PRINT_DEBUG_MODE) {
186  printf("Bank ID = %d, was not allowed to give mortgages any more.\n", banks_list.array[i].id);
187  }
188  continue;
189  }
190 
191  double mortgage_request = 0;
192  if (cash > 0) {
193  mortgage_request = price - cash;
194  } else {
195  mortgage_request = price;
196  }
197 
198  /* Risk of the bank is updated temporally/locally and evaluated including the new requested mortgage. */
199  risk += mortgage_request;
200 
201  /* The bank cannot mortgage this buyer. But the bank may be able to credit
202  some others waiting in the queue. */
203  if (equity < CAPITAL_ADEQUECY_RATIO * risk) {
204  remove_hbuyer(&buyers_list, 0);
205  if (PRINT_DEBUG_MODE) {
206  printf("Bank ID = %d, was not allowed to give mortgages to Household ID = %d. \n", banks_list.array[i].id, id);
207  }
208  continue;
209  }
210  /* Here mortgage choice of household could be adopted according to crediting conditions in an endogenous manner.*/
211 
212 
213  /* Check credibility of the household */
214  mortgage_choice = buyers_list.array[0].choice;
215  income = buyers_list.array[0].quarterly_income;
216  mortgage = buyers_list.array[0].quarterly_mortgage_paid;
217  double new_mortgage_cost = 0; // = mortgage_request / annuity;
218 
219  if (mortgage_choice == 1) {
221  d2 = d1 * pow((1 + d1), 160);
222  annuity = 1/d1 - 1/d2;
223  new_mortgage_cost = mortgage_request / annuity;
224  }
225  else if (mortgage_choice == 2){
226  new_mortgage_cost = (mortgage_request / 160) + (mortgage_request*MORTGAGES_INTEREST_RATE/4);
227  }
228  else if (mortgage_choice == 3){
229  /* Should we incorporate an expectation of inflation, we could use the inflation target of CB, 0.02? */
230  d1 = 0.02/4;
231  d2 = d1 * pow((1 + d1), 160);
232  annuity = 1/d1 - 1/d2;
233  new_mortgage_cost = mortgage_request / annuity;
234  }
235  else if (mortgage_choice == 4){
236  /* Should we incorporate an expectation of inflation, we could use the inflation target of CB, 0.02? */
237  new_mortgage_cost = (mortgage_request / 160) + (mortgage_request*0.02/4);
238  }
239  else if (mortgage_choice == 5){
240  d1 = (MORTGAGES_INTEREST_RATE + 0.01)/4;
241  d2 = d1 * pow((1 + d1), 160);
242  annuity = 1/d1 - 1/d2;
243  new_mortgage_cost = mortgage_request / annuity;
244  }
245  else if (mortgage_choice == 6){
246  new_mortgage_cost = (mortgage_request / 160) + (mortgage_request*(MORTGAGES_INTEREST_RATE+0.01)/4);
247  }
248  else if (mortgage_choice == 7){
249  /* Should we incorporate an expectation of inflation, we could use the inflation target of CB, 0.02? */
250  d1 = 0.02/4;
251  d2 = d1 * pow((1 + d1), 160);
252  annuity = 1/d1 - 1/d2;
253  new_mortgage_cost = mortgage_request / annuity;
254  }
255  else {
256  if (WARNING_MODE) {
257  printf("Warning @household_housing_debt_writeoff(): Unexpected mortgage choice = %d \n", mortgage_choice);
258  }
259 
260  }
261 
262 
263  mortgage += new_mortgage_cost;
264 
265  if (mortgage > HOUSEHOLD_BUDGET_CONSTRAINT * income) {
266  remove_hbuyer(&buyers_list, 0);
267  if (PRINT_DEBUG_MODE) {
268  printf("Household ID = %d mortgage request is denied by Bank ID = %d \n", id, banks_list.array[i].id);
269  }
270  continue;
271  }
272 
273  /* Mortgage is used. Cash at hand by household while enetering the market
274  assumed to be non-negative.
275  */
276  add_bought_housing_message(id, cash, mortgage_request, annuity);
277  if (PRINT_DEBUG_MODE) {
278  printf("Household ID = %d has gotten %f from Bank ID = %d along with her own %f amount of cash. \n", id, mortgage_request, banks_list.array[i].id, cash);
279  }
280  remove_hbuyer(&buyers_list, 0);
281  nsold++;
282  /* The mortgage amount of the bank is increased incrementally. */
283  banks_list.array[i].amount_mortgaged += mortgage_request;
284  } while (1);
285 
286  if (nsold > 0 && sellers_list.size > 0) {
287  id = sellers_list.array[0].seller_id;
288  type = sellers_list.array[0].type;
289  add_sold_housing_message(id, nsold, price);
290  transaction_quantity += nsold;
291  transaction_volume += nsold * price;
292  if (type == 0) { firm_sales++;}
293  if (type == 2) { regular_sales++;}
294  if (type == 1) { fire_sales++;}
295  }
296 
297 
298  for (int i = 0; i < banks_list.size; i++) {
299  add_mortgage_requests_message(banks_list.array[i].id, banks_list.array[i].amount_mortgaged);
300  }
301 
302  HOUSING_TRANSACTIONS.quantity = transaction_quantity;
303  if (transaction_quantity > 0) {
304  HOUSING_TRANSACTIONS.avg_price = transaction_volume / transaction_quantity;
305  }
306 
307 
308  if (DATA_COLLECTION_MODE) {
309  char * filename;
310  FILE * file1;
311  filename = malloc(100*sizeof(char));
312  filename[0]=0;
313  strcpy(filename, "./outputs/data/REAgency_sales.txt");
314 
315  file1 = fopen(filename,"a");
316  fprintf(file1,"%d %d %d %d %d %d %d\n",IT_NO, fire_seller_attempts, regular_seller_attempts, firm_seller_attempts, fire_sales, regular_sales, firm_sales);
317  fclose(file1);
318  free(filename);
319  }
320 
321 
322  /* Garbage Collection */
323  free_hseller_array(&sellers_list);
324  free_hbuyer_array(&buyers_list);
325  free_hbank_array(&banks_list);
326  return 0; /* Returning zero means the agent is not removed */
327 }
328 
329 /*
330  * \fn: int reagency_housing_summary()
331  * \brief:
332  */
334 {
335  double price;
336  int quantity;
337 
338  price = HOUSING_TRANSACTIONS.avg_price;
339  quantity = HOUSING_TRANSACTIONS.quantity;
340 
343 
344  if (DATA_COLLECTION_MODE) {
345  char * filename;
346  FILE * file1;
347  filename = malloc(40*sizeof(char));
348  filename[0]=0;
349  strcpy(filename, "./outputs/data/REAgency_snapshot.txt");
350 
351  file1 = fopen(filename,"a");
352  fprintf(file1,"%d %d %f\n",IT_NO, quantity, price);
353  fclose(file1);
354  free(filename);
355  }
356  return 0; /* Returning zero means the agent is not removed */
357 }