ICEACE Model: Closed Economy  1.0.0
Design Documentation of ICEACE Model
 All Data Structures Files Functions Variables Typedefs Macros Pages
firm_functions_credit.c
Go to the documentation of this file.
1 #include "../header.h"
2 #include "../firm_agent_header.h"
3 
4 /*
5  * \fn: int firm_credit_check_interest_rate()
6  * \brief: it receives interest rate from the central bank and updates interest to be paid on loans.
7  */
9 {
10  double rcb;
12  /* The 1 percent increase is determined by the model. */
14  LOANS_INTEREST_RATE = rcb + 0.01;
15 
17 
18  return 0; /* Returning zero means the agent is not removed */
19 }
20 
21 
22 /*
23  * \fn: int firm_credit_check_tax_rate()
24  * \brief: Recieved from the government.
25  */
27 {
28 
32 
33  return 0; /* Returning zero means the agent is not removed */
34 }
35 
36 /*
37  * \fn: int firm_credit_compute_income_statement()
38  * \brief: Firm computes its income statement.
39  */
41 {
42  int bank;
43  double to_be_paid;
44 
45 
47 
48  for (int i = 0; i < 2; i++) {
49  bank = LOAN_LIST[i].bank_id;
50  to_be_paid = LOAN_LIST[i].amount * (LOANS_INTEREST_RATE / 4);
51  LOAN_LIST[i].to_be_paid = to_be_paid;
52  TOTAL_INTEREST_PAYMENTS += to_be_paid;
53  }
54 
55  /* Labour cost is decremented from liquidity on a monthly basis.
56  Costs (wages) and revenues (from sales) are updated incrementally.
57  */
58 
62 
64  char * filename;
65  FILE * file1;
66  filename = malloc(100*sizeof(char));
67  filename[0]=0;
68  if (ISCONSTRUCTOR) {
69  strcpy(filename, "./outputs/data/Constructor_Firm_Quarterly_IncomeStatement.txt");
70  file1 = fopen(filename,"a");
71  fprintf(file1,"%d %d %f %f %f %f %f %f\n", IT_NO, ID, REVENUES, OPERATING_COSTS, LABOUR_COSTS, TOTAL_INTEREST_PAYMENTS, EBIT, NET_EARNINGS);
72  } else {
73  strcpy(filename, "./outputs/data/Firm_Quarterly_IncomeStatement.txt");
74  file1 = fopen(filename,"a");
75  fprintf(file1,"%d %d %f %f %f %f %f %f\n", IT_NO, ID, REVENUES, OPERATING_COSTS, LABOUR_COSTS, TOTAL_INTEREST_PAYMENTS, EBIT, NET_EARNINGS);
76  }
77 
78  /*** Balancesheet Verification.
79  file1 = fopen(filename,"a");
80  fprintf("%d %d %f %f %f\n",IT_NO, ID, DEBT, LOAN_LIST[0].amount, LOAN_LIST[1].amount);
81  */
82 
83  fclose(file1);
84  free(filename);
85  }
86 
87  REVENUES = 0;
88  OPERATING_COSTS = 0;
89  LABOUR_COSTS = 0;
90 
91  return 0; /* Returning zero means the agent is not removed */
92 }
93 
94 /*
95  * \fn: int firm_credit_investment_decisions()
96  * \brief:
97  */
99 {
100  RETAINED_EARNINGS = 0;
102 
103  return 0; /* Returning zero means the agent is not removed */
104 }
105 
106 /*
107  * \fn: int firm_credit_compute_dividends()
108  * \brief: Within this implementation the firm sends all of net income
109  * to the Fund Equity to be distributed equally to households.
110  */
112 {
114  DIVIDENDS_PAID = 0;
115  RETAINED_EARNINGS = 0;
116  if (DIVIDENDS_TO_BE_PAID < 0) {
117  if (PRINT_DEBUG_MODE) {
118  printf("Firm ID = %d, has no positive earnings to send out to share holders. \n", ID);
119  }
121  }
122 
123  return 0; /* Returning zero means the agent is not removed */
124 }
125 
126 /*
127  * \fn: int firm_credit_check_liquidity_need()
128  * \brief: Firm checks its liquidity need. The information will be used for the decisio
129  * to enter the credit market or not.
130  */
132 {
133 
135 
136  /*The variable is used for statistics as state variables. */
137  ISLIQUIDSHORT = 0;
138  HASLOAN = 0;
139  HASINVESTMENT = 0;
140  ISILLIQUID = 0;
141  ISINSOLVENT = 0;
142 
143  if (LIQUIDITY_NEED > 0.1) {
144  ISLIQUIDSHORT = 1;
145  }
146  else{LIQUIDITY_NEED = 0;}
147 
148  return 0; /* Returning zero means the agent is not removed */
149 }
150 
151 /*
152  * \fn: int firm_credit_demand_loans_1()
153  * \brief: Firm goes to its own bank for the loan request.
154  */
156 {
157  if (LIQUIDITY_NEED > 0){
159  //printf("Firm Stage 1: Firm ID = %d --> Bank ID = %d R = %f, Current D = %f \n", ID, BANK_ID, LIQUIDITY_NEED, DEBT);
160  }
161 
162 
163 
164 
165  return 0; /* Returning zero means the agent is not removed */
166 }
167 
168 /*
169  * \fn: int firm_credit_borrow_loans_1()
170  * \brief: The function is run when there is liquidity need.
171  */
173 {
174  double amount = 0;
175 
178  LIQUIDITY += amount;
179  DEBT += amount;
180  LOAN_LIST[0].amount += amount;
181  //printf("Firm ID = %d @ Loan Stage 1 received %f of loans. Updated Debt = %f \n", ID, amount, DEBT);
183 
184 
185 
186  if (PRINT_DEBUG_MODE){
187  printf("Firm ID = %d @ Loan Stage 1 received %f of loans. \n", ID, amount);
188  }
189 
190  if (amount >= LIQUIDITY_NEED){
191  LIQUIDITY_NEED = 0;
192  HASLOAN = 1;
193  }
194  /* Shall we allow partial loans?
195  If so at bank side partial loan should be processed.
196  */
197  else{
198  LIQUIDITY_NEED -= amount;
200  //printf("Firm Stage 2: Firm ID = %d --> Bank ID = %d R = %f, Current D = %f \n", ID, LOAN_LIST[1].bank_id, LIQUIDITY_NEED, DEBT);
201  }
202 
203  return 0; /* Returning zero means the agent is not removed */
204 }
205 
206 /*
207  * \fn: int firm_credit_borrow_loans_2()
208  * \brief:
209  */
211 {
212  double amount = 0;
213 
216  LIQUIDITY += amount;
217  DEBT += amount;
218  LOAN_LIST[1].amount += amount;
219  //printf("Firm ID = %d @ Loan Stage 2 received %f of loans. Updated Debt = %f \n", ID, amount, DEBT);
221 
222 
223  if (PRINT_DEBUG_MODE){
224  printf("Firm ID = %d @ Loan Stage 2 received %f of loans. \n", ID, amount);
225  }
226 
227  if (amount >= LIQUIDITY_NEED){
228  LIQUIDITY_NEED = 0;
229  HASLOAN = 1;
230  }
231 
232  return 0; /* Returning zero means the agent is not removed */
233 }
234 
235 /*
236  * \fn: int firm_credit_request_equityfund_investment()
237  * \brief: Firm goes to equity fund to get the required amount of liquidity it needs. Dividend payments are
238  * deferred.
239  */
241 {
242  /* New liquidity need is computed. */
244 
245  if (LIQUIDITY_NEED <= 0) {
248  LIQUIDITY_NEED = 0 ;
249  }
250  else {
251  if (TOTAL_ASSETS == 0) {
252  if (DEBT <= 0) {
254  }
255  return 0;
256  }
257 
260  }
261  }
262 
263  return 0; /* Returning zero means the agent is not removed */
264 }
265 
266 /*
267  * \fn: int firm_credit_check_equityfund_investment()
268  * \brief: Firms check if they are invested by Equity Fund for their liquidity need.
269  */
271 {
272  double amount = 0;
273 
277 
278  if (amount > 0) {
279  LIQUIDITY += amount;
280  HASINVESTMENT = 1;
281  EQUITY += amount;
282  LIQUIDITY_NEED = 0;
283  if (PRINT_DEBUG_MODE){
284  printf("Firm ID = %d @ Loan - Equity Fund received %f amount of funding investment. \n", ID, amount);
285  }
286  }
287  return 0; /* Returning zero means the agent is not removed */
288 }
289 
290 
291 /*
292  * \fn: int firm_credit_illiquidity_bankrupt()
293  * \brief: Firm debt is restructured.
294  */
296 {
297  ISILLIQUID = 1;
298  if (PRINT_DEBUG_MODE) {
299  printf("Firm ID = %d is illiquidity bankrupt!\n", ID);
300  }
301 
302  double new_loans;
303  double ratio, current_amount, new_amount, delta_amount;
304  int bank;
305 
306 
307  /* Maximum amount of debts that can be paid.
308  */
309  if (EBIT < 0){
310  new_loans = 0;}
311  else {
312  new_loans = EBIT / (LOANS_INTEREST_RATE / 4);
313  }
314 
315  if (DEBT > 0){
316  ratio = new_loans / DEBT;}
317  else {
318  ratio = 0;
319  }
320 
321  if (ratio >= 1) { return 0;}
322 
323  DEBT = 0;
324  for (int i = 0; i < 2; i++) {
325  bank = LOAN_LIST[i].bank_id;
326  current_amount = LOAN_LIST[i].amount;
327  new_amount = current_amount * ratio;
328  LOAN_LIST[i].amount = new_amount;
329  DEBT += new_amount;
330  delta_amount = current_amount - new_amount;
331 
332  if (delta_amount > 0.1) {
333  add_loan_writeoff_message(bank, delta_amount);
334  if (WARNING_MODE) {
335  if (delta_amount < 0) {
336  printf("Warning @firm_credit_illiquidity_bankrupt(): The illiquid Firm ID = %d new loan request is higher than its existing loan to Bank ID = %d, The difference is = %f \n", ID, bank, delta_amount);
337  }
338  }
339 
340  //printf("Illiquidity: Firm ID = %d, Bank = %d Writeoff = %f \n",ID,bank, delta_amount);
341 
342  if (PRINT_DEBUG_MODE) {
343  printf("Firm ID = %d illiquidity bankrupt burden on Bank = %d is = %f \n",ID,bank, delta_amount);
344  }
345 
346  if (DATA_COLLECTION_MODE) {
347  char * filename;
348  FILE * file1;
349  filename = malloc(100*sizeof(char));
350  filename[0]=0;
351  strcpy(filename, "./outputs/data/BankruptcyInspection.txt");
352  file1 = fopen(filename,"a");
353  fprintf(file1,"%d %d %s %s %d %f\n",IT_NO, ID, "Firm", "Illiquidity", bank, delta_amount);
354  fclose(file1);
355  free(filename);
356  }
357  }
358  }
359 
360  return 0; /* Returning zero means the agent is not removed */
361 }
362 
363 /*
364  * \fn: int firm_credit_pay_interest_on_loans()
365  * \brief:
366  */
368 {
369 
370  int bank;
371  double to_be_paid;
372 
373  for (int i = 0; i < 2; i++) {
374  bank = LOAN_LIST[i].bank_id;
375  to_be_paid = LOAN_LIST[i].to_be_paid;
376  LIQUIDITY -= to_be_paid;
377  add_firm_bank_interest_on_loan_message(bank, to_be_paid);
378  }
379 
380  return 0; /* Returning zero means the agent is not removed */
381 }
382 
383 
384 /*
385  * \fn: int firm_credit_pay_dividends()
386  * \brief: Firm send dividends to to the Fund Equity to be distributed
387  * to households.
388  */
390 {
392 
393  if (DIVIDENDS_PAID > 0) {
396  }
397 
399  char * filename;
400  FILE * file1;
401  filename = malloc(100*sizeof(char));
402  filename[0]=0;
403  if (ISCONSTRUCTOR) {
404  strcpy(filename, "./outputs/data/Constructor_Firm_Quarterly_Dividends.txt");
405  file1 = fopen(filename,"a");
406  fprintf(file1,"%d %d %f %f\n", IT_NO, ID, DIVIDENDS_PAID, DIVIDENDS_TO_BE_PAID);
407  } else {
408  strcpy(filename, "./outputs/data/Firm_Quarterly_Dividends.txt");
409  file1 = fopen(filename,"a");
410  fprintf(file1,"%d %d %f %f\n", IT_NO, ID, DIVIDENDS_PAID, DIVIDENDS_TO_BE_PAID);
411  }
412  fclose(file1);
413  free(filename);
414  }
415 
417 
418  return 0; /* Returning zero means the agent is not removed */
419 }
420 
421 
422 /*
423  * \fn: int firm_credit_do_balance_sheet()
424  * \brief: Firm does the balance sheet accounting.
425  */
427 {
428 
429  if (ISCONSTRUCTOR) {
431 
432  } else {
434  }
436 
438 
439  if (EQUITY < 0) {
440  ISINSOLVENT = 1; }
441 
443 
444  char * filename;
445  FILE * file1;
446  filename = malloc(100*sizeof(char));
447  filename[0]=0;
448  if (ISCONSTRUCTOR) {
449  strcpy(filename, "./outputs/data/Constructor_Firm_Quarterly_BalanceSheet.txt");
450  file1 = fopen(filename,"a");
451  fprintf(file1,"%d %d %d %d %d %f %d %d %f %f %d %f %f %d %f %f\n",IT_NO, ID, ISLIQUIDSHORT, HASLOAN, HASINVESTMENT, LIQUIDITY_NEED, ISINSOLVENT, ISILLIQUID, TOTAL_ASSETS, LIQUIDITY, INVENTORY, UNIT_HOUSE_PRICE, CAPITAL_GOODS_PRICE, CAPITAL_GOODS, DEBT, EQUITY);
452  } else {
453  strcpy(filename, "./outputs/data/Firm_Quarterly_BalanceSheet.txt");
454  file1 = fopen(filename,"a");
455  fprintf(file1,"%d %d %d %d %d %f %d %d %f %f %d %f %f %d %f %f\n",IT_NO, ID, ISLIQUIDSHORT, HASLOAN, HASINVESTMENT, LIQUIDITY_NEED, ISINSOLVENT, ISILLIQUID, TOTAL_ASSETS, LIQUIDITY, INVENTORY, UNIT_GOODS_PRICE, CAPITAL_GOODS_PRICE, CAPITAL_GOODS, DEBT, EQUITY);
456  }
457  fclose(file1);
458  free(filename);
459  }
460 
461  return 0; /* Returning zero means the agent is not removed */
462 }
463 
464 /*
465  * \fn: int firm_credit_insolvency_bankruptcy()
466  * \brief:
467  */
469 {
470 
471  /* The firm will skip production for the first time and enters the labour market.
472  The variable below is used for that purpose in production and labour markets.
473  */
474 
475  /* Writeoff debts.
476  */
477  int bank;
478  double amount;
479 
480 
481  //printf("Firm ID = %d is insolvent bankrupt!! Amount = %f \n", ID, DEBT);
482 
483  if (PRINT_DEBUG_MODE) {
484  printf("Firm ID = %d is insolvent bankrupt!! \n", ID);
485  }
486 
487 
489  LIQUIDITY = 0;
490 
491  DEBT = 0;
492  SALES = 0;
493  REVENUES = 0;
494  OPERATING_COSTS = 0;
495  LABOUR_COSTS = 0;
497  /* Physical capital etc are kept the same.
498  */
499 
500 
501  if (ISCONSTRUCTOR == 0) {
505  /* UNIT_COST is inherited. */
506  } else {
507  INVENTORY = 0;
509  /* Constructor firms keep the averega house prices, current projects, etc */
510  }
511 
512  for (int i = 0; i < 2; i++) {
513  bank = LOAN_LIST[i].bank_id;
514  amount = LOAN_LIST[i].amount;
515  if (amount > 0.001) {
516  add_loan_writeoff_message(bank, amount);
517 
518  //printf("Insolvency: Firm ID = %d, Bank = %d Writeoff = %f, Updated \n",ID,bank, amount);
519 
520  if (DATA_COLLECTION_MODE) {
521  char * filename;
522  FILE * file1;
523  filename = malloc(100*sizeof(char));
524  filename[0]=0;
525  strcpy(filename, "./outputs/data/BankruptcyInspection.txt");
526  file1 = fopen(filename,"a");
527  fprintf(file1,"%d %d %s %s %d %f\n",IT_NO, ID, "Firm", "Insolvency", bank, amount);
528  fclose(file1);
529  free(filename);
530  }
531  }
532  LOAN_LIST[i].amount = 0;
533  }
534 
535  /* Getting initial loan */
539 
540  //printf("Newentrant Loan: Firm ID = %d, Bank = %d New loan = %f\n",ID,bank, DEBT);
541 
542  LOAN_LIST[0].amount = DEBT;
544 
545 
546  return 0; /* Returning zero means the agent is not removed */
547 }
548