-
Notifications
You must be signed in to change notification settings - Fork 0
/
BAMERS.nlogo
3210 lines (2915 loc) · 83 KB
/
BAMERS.nlogo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
; Bottom-up Adaptive Macroeconomics
extensions [palette array] ; arrays are used to enhance performance.
breed[firms firm] ; the firms in the simulation, 500 by default.
breed[workers worker] ; the workers or households, 5 * number of firms by default.
breed[banks bank] ; the banks, max of credit-market-h + 1 and number of firms / 10 by default.
globals [
quarters-average-price ; an array storing the average price for the last 4 quarters.
quarters-inflation ; an array storing the inflation for the last 4 quarters.
confiscated-money
gini-index-reserve
lorenz-points
; current stats recorded of incumbent firms used to replace bankrupt ones
new-firms-production-Y
new-firms-minimum-wage-W-hat
new-firms-wage-offered-Wb
new-firms-net-worth-A
new-firms-individual-price-P
]
firms-own[
production-Y ; labor * labor productiviy
labor-productivity-alpha ; labor productivity > 0
desired-production-Yd
expected-demand-De
desired-labor-force-Ld ; desired production / labor productivity
my-employees ; an agent set of current employees.
current-numbers-employees-L0 ; number of current employees.
number-of-vacancies-offered-V ; max of desired labor force - current labor force and 0.
minimum-wage-W-hat ; mandatory minimum wage set by law
wage-offered-Wb ; contractual wage: if no vacancies the max of previous wage
; and minimum wage; otherwise previous wage is also pondered
; by an idiosyncratic shock, e.g., 1 + wage-shock-xi
net-worth-A ; previous net worth + profits - dividends (profits * 1 - profits-delta)
total-payroll-W ; the desired wage bill
loan-B ; max of desired wage bill - net worth and 0
my-potential-banks ; credit-market-H < number of banks (less than firms/10)
my-bank ; the current bank of the firm
my-interest-rate
amount-of-Interest-to-pay
inventory-S ; inventory of unsold goods
individual-price-P
revenue-R
gross-profits
net-profits
retained-profits-pi
; for visual representation
x-position
y-position
; extortion variables
being-extorted?
being-punished?
amount-of-pizzo
amount-of-punish
]
workers-own[
employed? ; a boolean, true iff the agent is employed.
my-potential-firms
my-firm ; the current firm if employed.
contract
my-wage ; current wage
income
savings
wealth
propensity-to-consume-c
my-stores
my-large-store
; extortion variables
extorter?
firms-to-extort
firms-to-punish
in-jail?
time-in-jail
]
banks-own[
; Repayment schedule (eq. 3.6, p. 53) is represented in firms-pay procedure as in p.50:
; "If gross profits are high enough, they “validate” debt commitments, i.e. firms pay back both the principal and the interest to the bank"
; r-bar (instead r-hat) (eq. 3.7, p. 53) is represented as a reporter (interest-rate-policy-rbar)
total-amount-of-credit-C ; a multiple of its equity base in terms of capital req. coeff (buy default v= 0.23).
patrimonial-base-E
operational-interest-rate
my-borrowing-firms
interest-rate-r
bad-debt-BD
bankrupt?
]
; Setup procedures
to setup
clear-all
;reset-timer
start-firms number-of-firms
start-workers round (number-of-firms * 5)
start-banks max (list (credit-market-H + 1) round (number-of-firms / 10))
initialize-variables
reset-ticks
end
to initialize-variables
ask firms [
set production-Y 1
set labor-productivity-alpha 1
set desired-production-Yd 0
set expected-demand-De 1
set desired-labor-force-Ld 0
set my-employees no-turtles
set current-numbers-employees-L0 0
set number-of-vacancies-offered-V 0
set minimum-wage-W-hat 1
set wage-offered-Wb minimum-wage-W-hat
set net-worth-A 10
set total-payroll-W 0
set loan-B 0
set my-potential-banks no-turtles
set my-bank no-turtles
set inventory-S 0
set individual-price-P base-price
set revenue-R 0
set retained-profits-pi 0
set being-extorted? false
set being-punished? false
]
ask workers [
set employed? false
set my-potential-firms no-turtles
set my-firm nobody
set contract 0
set income 0
set savings 1 + random-poisson base-savings
set wealth 0
set propensity-to-consume-c 1
set my-stores no-turtles
set my-large-store no-turtles
set extorter? false
set firms-to-extort no-turtles
set firms-to-punish no-turtles
set in-jail? false
set time-in-jail 0
]
ask banks [
set total-amount-of-credit-C 0
set patrimonial-base-E random-poisson 10000 + 10
set operational-interest-rate 0
set interest-rate-r 0
set my-borrowing-firms no-turtles
set bankrupt? false
]
set quarters-average-price array:from-list n-values (ifelse-value (quarterly-time-scale?)[4][12]) [base-price]
set quarters-inflation array:from-list n-values (ifelse-value (quarterly-time-scale?)[4][12]) [0]
end
to start-firms [#firms]
create-firms #firms [
set x-position random-pxcor * 0.9
set y-position random-pycor * 0.9
setxy x-position y-position
set color blue
set size 1.2
set shape "factory"
]
ask firms [
move-to one-of patches with [not any? firms-here ]
]
end
to start-workers [#workers]
create-workers #workers [
setxy random-pxcor random-pycor
set color yellow
set size 1 / log number-of-firms 10
set shape "person"
]
end
to start-banks [#banks]
create-banks #banks[
setxy random-pxcor * 0.9 random-pycor * 0.9
set color red
set size 1.5
set shape "house"
]
end
to go
;if (ticks mod 100 = 0)[
; export-view (word "view_" (ticks / 100) ".png")
; export-interface (word "inte_" (ticks / 100) ".png")
;]
if (ticks >= 1000
;or (ticks > 600 and fn-unemployment-rate > 0.5)
;or (ticks > 600 and abs annualized-inflation > 0.25)
) [stop]
; Process overview and scheduling
firms-calculate-production
labor-market
credit-market
firms-produce
goods-market
extortion
firms-pay
firms-banks-survive
replace-bankrupt
update-lorenz-and-gini
tick
end
;;;;;;;;;; to firms-calculate production ;;;;;;;;;;
to firms-calculate-production
adapt-expected-demand-or-price
ask firms [
set desired-production-Yd expected-demand-De; submodel 2
]
array:set quarters-average-price (ticks mod (ifelse-value (quarterly-time-scale?)[4][12])) mean [individual-price-P] of firms
let actual-price array:item quarters-average-price (ticks mod (ifelse-value (quarterly-time-scale?)[4][12]))
let previous-price array:item quarters-average-price ((ticks - 1) mod (ifelse-value (quarterly-time-scale?)[4][12]))
let quarter-inflation ((actual-price - previous-price) / ifelse-value previous-price = 0 [0.00001][previous-price]) * 100 ; with safe division
array:set quarters-inflation (ticks mod (ifelse-value (quarterly-time-scale?)[4][12])) quarter-inflation
end
to adapt-expected-demand-or-price
let avg-market-price average-market-price
ask firms [
let minimum-price-Pl ifelse-value (production-Y > 0)[( total-payroll-W + amount-of-Interest-to-pay ) / production-Y] [avg-market-price]
(ifelse
(inventory-S = 0 and individual-price-P >= avg-market-price and production-Y > 0)
[ set expected-demand-De max (list 1 ceiling (production-Y * (1 + production-shock-rho)))]
(inventory-S > 0 and individual-price-P < avg-market-price)
[ set expected-demand-De max (list 1 ceiling (production-Y * (1 - production-shock-rho)))]
(inventory-S = 0 and individual-price-P < avg-market-price)
[ set individual-price-P max(list minimum-price-Pl (individual-price-P * (1 + price-shock-eta)))]
(inventory-S > 0 and individual-price-P >= avg-market-price)
[ set individual-price-P max(list minimum-price-Pl (individual-price-P * (1 - price-shock-eta)))]
[ show (word "No selected strategies ")]
)
]
end
;;;;;;;;;; to labor-market ;;;;;;;;;;
to labor-market
let law-minimum-wage ifelse-value (ticks > 0 and ticks mod (ifelse-value (quarterly-time-scale?)[4][12]) = 0 )[fn-minimum-wage-W-hat][[minimum-wage-W-hat] of firms]
ask firms [
set desired-labor-force-Ld ceiling (desired-production-Yd / ifelse-value labor-productivity-alpha = 0 [0.00001][labor-productivity-alpha]); submodel 3
set current-numbers-employees-L0 count my-employees; summodel 4
set number-of-vacancies-offered-V max(list (desired-labor-force-Ld - current-numbers-employees-L0) 0 ); submodel 5
if (ticks > 0 and ticks mod (ifelse-value (quarterly-time-scale?)[4][12]) = 0 )
[
set minimum-wage-W-hat law-minimum-wage; submodel 6
]
ifelse (number-of-vacancies-offered-V = 0)
[
set wage-offered-Wb max(list minimum-wage-W-hat wage-offered-Wb); submodel 7
]
[
set wage-offered-Wb max(list minimum-wage-W-hat (wage-offered-Wb * (1 + wages-shock-xi))); submodels 8 and 9
]
]
labor-market-opens
end
to labor-market-opens
if (sum [number-of-vacancies-offered-V] of firms > 0) [
let potential-firms firms with [number-of-vacancies-offered-V > 0]
ask workers with [not employed? and not extorter? and not in-jail?][
ifelse (not empty? [my-firm] of my-potential-firms)
[set my-potential-firms (turtle-set my-firm n-of (labor-market-M - 1 ) potential-firms)]
[set my-potential-firms n-of (min (list labor-market-M count potential-firms)) potential-firms]
]
]
hiring-step labor-market-M
ask workers with [not employed?][
set my-wage 0
set income 0
rt random 360
fd (random 4) + 1
]
ask firms [
set label count my-employees
set color palette:scale-gradient [[68 1 84] [33 144 140] [253 231 37]] net-worth-A 0 max [net-worth-A] of firms
]
end
to hiring-step [trials]
while [trials > 0]
[
ask workers with [not employed? and any? my-potential-firms and not in-jail?][
move-to max-one-of my-potential-firms [wage-offered-Wb]
]
ask firms with [number-of-vacancies-offered-V > 0 ][
let potential-workers workers-here with [not employed?]
let quantity count potential-workers
let workers-hired n-of (min list quantity number-of-vacancies-offered-V) potential-workers
let wage-employees wage-offered-Wb
set my-employees (turtle-set my-employees workers-hired)
set number-of-vacancies-offered-V number-of-vacancies-offered-V - count workers-hired
set total-payroll-W total-payroll-W + (count workers-hired * wage-offered-Wb)
ask my-employees with [not employed?] [
set color green
set employed? true
set my-wage wage-employees
set contract 8 + random-poisson 10
set my-firm firms-here
set my-potential-firms no-turtles
]
]
set trials trials - 1
ask workers with [not employed? and any? my-potential-firms][
set my-potential-firms min-n-of min (list trials count my-potential-firms) my-potential-firms [wage-offered-Wb]
]
]
end
;;;;;;;;;; to credit-market ;;;;;;;;;;
to credit-market; observer-procedure
ask banks [
set total-amount-of-credit-C patrimonial-base-E / v; submodel 12
set operational-interest-rate random-float interest-shock-phi; part of submodel 14
]
ask firms with [production-Y > 0][
if (total-payroll-W > net-worth-A)[
let leverage desired-production-Yd * wage-offered-Wb
set loan-B max (list (leverage - net-worth-A) 0); submodel 10
if (loan-B > 0)[
set shape "person business"
]
]
]
credit-market-opens
firing-step
end
to credit-market-opens; observer procedure
ask firms with [loan-B > 0][
set my-potential-banks n-of credit-market-H banks
]
borrowing-step credit-market-H
end
to borrowing-step [trials]; observer procedure
while [trials > 0][ ; submodel 20
ask firms with [loan-B > 0][
move-to min-one-of my-potential-banks [operational-interest-rate]
]
ask banks [
set my-borrowing-firms firms-here
if any? my-borrowing-firms
[
lending-step my-borrowing-firms
]
]
set trials trials - 1
]
end
to lending-step [#borrowing-firms]; banks procedure
while [any? #borrowing-firms and total-amount-of-credit-C > 0][
let my-best-borrower max-one-of #borrowing-firms [net-worth-A]
let networth max (list [net-worth-A] of my-best-borrower 1)
let leverage-of-borrower [loan-B] of my-best-borrower / networth; submodel 19
;submodel 17
let contractual-interest interest-rate-policy-rbar * (1 + ([operational-interest-rate] of self * leverage-of-borrower));
let the-lender-bank self
let loan min (list [loan-B] of my-best-borrower total-amount-of-credit-C); part of submodel 14
ask my-best-borrower [
set my-bank the-lender-bank
set my-interest-rate contractual-interest
set amount-of-Interest-to-pay loan * ( 1 + contractual-interest )
set net-worth-A net-worth-A + loan
set loan-B loan-B - loan
setxy [x-position] of my-best-borrower [y-position] of my-best-borrower
set shape "factory"
]
let count-borrowers count #borrowing-firms
set #borrowing-firms min-n-of (count-borrowers - 1) #borrowing-firms [net-worth-A]
]
end
to firing-step
ask firms with [loan-B > 0][
while [total-payroll-W > net-worth-A and count my-employees > 1][
let expensive-worker max-one-of my-employees [my-wage]
set my-employees min-n-of (count my-employees - 1) my-employees [my-wage]
set total-payroll-W total-payroll-W - [my-wage] of expensive-worker
ask expensive-worker[
set color yellow
set employed? false
set my-wage 0
set income 0
set contract 0
set my-firm no-turtles
rt random 360
fd (random 4) + 1
]
]
]
end
;;;;;;;;;; to firms-produce ;;;;;;;;;;
to firms-produce
ask firms [
set production-Y labor-productivity-alpha * count my-employees; submodel 1
set inventory-S production-Y * individual-price-P
set net-worth-A net-worth-A - total-payroll-W
]
ask workers with [employed?][
set income my-wage
set contract contract - 1
if (contract = 0)[
set employed? false
set color yellow
set my-wage 0
rt random 360
fd (random 4) + 1
]
]
; firing employees with expired contract
ask firms [
set my-employees my-employees with [contract > 0]
]
end
;;;;;;;;;; to goods-market ;;;;;;;;;;
to goods-market ;; an observer procedure
let average-savings mean [savings] of workers with [not in-jail?]
ask workers with [not in-jail?][
set wealth income + savings
set propensity-to-consume-c 1 / (1 + (fn-tanh (savings / average-savings)) ^ beta)
let money-to-consume propensity-to-consume-c * wealth
set savings ((1 - propensity-to-consume-c) * wealth)
ifelse (any? turtle-set my-large-store)
[
let id-store [who] of my-large-store
set my-stores (turtle-set my-large-store n-of ( min list (goods-market-Z - 1) count firms with [who != id-store] ) firms with [who != id-store]) ; safe n-of: n-of ( min list NNN count ASET ) ASET
]
[
set my-stores n-of ( min list goods-market-Z count firms ) firms
]
set my-large-store max-one-of my-stores [production-Y]
if (count my-stores != goods-market-Z) [show (word "Number of my stores " count my-stores " who " who)]
buying-step goods-market-Z money-to-consume
]
end
to buying-step [trials money]; workers procedure
while [trials > 0 and money > 0][
let my-cheapest-store min-one-of my-stores [individual-price-P]
let possible-goods-to-buy min list money [inventory-S] of my-cheapest-store
set money money - possible-goods-to-buy
ask my-cheapest-store [
; goods are fractional e.g. liters or pounds, so its possible to buy a fraction
set inventory-S inventory-S - possible-goods-to-buy
]
ask [patch-here] of my-cheapest-store [
set pcolor green
]
set trials trials - 1
set my-stores max-n-of trials my-stores [individual-price-P]; eliminate cheap-store of my-stores with sets
]
if (money > 0)[
set savings savings + money
]
end
;;;;;;;;;; to extortion ;;;;;;;;;;
to extortion
if (propensity-to-be-extorter-epsilon > 0)[
become-extortionists
]
if (any? workers with [extorter? and time-in-jail < 1])[
extortion-search
execute-extortion
jail-or-punishment
]
if (any? workers with [time-in-jail > 0])[
in-jail
]
end
to become-extortionists
let Q1 lower-quartile [savings] of workers with [not extorter? and not in-jail?] ;; The extorters have already decided.
ask workers with [not employed? and savings < Q1 ][
if (random 100 < propensity-to-be-extorter-epsilon)[
set extorter? true
set color red
]
]
end
to extortion-search
let trials firms-to-extort-X
while [trials > 0][
ask workers with [extorter?][
let my-extorted-firms firms-to-extort
; extorter/worker goes randomly to a company (not already extorted by himself) to extort
ifelse (type-of-search = "random-search")[
let potential-firm-to-extort one-of firms with [not member? self my-extorted-firms]
; if the randomly selected company has already been extorted by someone else who provides "protection", the worker loses his chance to extort
if ([not being-extorted? or not being-punished?] of potential-firm-to-extort)[
; How many of the observable firms are being extorted?
let closest-firms 3
let around-firms min-n-of closest-firms other firms [distance potential-firm-to-extort]
let expected-risk 100 * (count around-firms with [being-extorted? or being-punished?] / closest-firms)
ifelse (expected-risk >= rejection-threshold); If the expected risk is high, firm accept to pay the pizzo
[; A threshold of 0% represents that the company at the slightest hint of extortion in the area will choose to pay the pizzo
set firms-to-extort (turtle-set firms-to-extort potential-firm-to-extort); succesful extortion
ask potential-firm-to-extort [ set being-extorted? true]
]; If the expected risk is low, firm do not accept to pay the pizzo and go to the list of potential punished
[set firms-to-punish (turtle-set potential-firm-to-extort)];
]
][
; extorter/worker goes to a nearest firm (not already extorted by himself) to extort
let potential-firm-to-extort min-one-of firms with [not member? self my-extorted-firms] [distance myself]
; if the selected firm has already been extorted by someone else who provides "protection", the worker loses his chance to extort
if ([not being-extorted? or not being-punished?] of potential-firm-to-extort)[
; How many of the observable firms are being extorted?
let closest-firms closest-observable-firms
let around-firms min-n-of closest-firms other firms [distance potential-firm-to-extort]
let expected-risk 100 * (count around-firms with [being-extorted? or being-punished?] / closest-firms)
ifelse (expected-risk >= rejection-threshold); If the expected risk is high, firm accept to pay the pizzo
[; A threshold of 0% represents that the company at the slightest hint of extortion in the area will choose to pay the pizzo
set firms-to-extort (turtle-set firms-to-extort potential-firm-to-extort); succesful extortion
ask potential-firm-to-extort [ set being-extorted? true]
]; If the expected risk is low, firm do not accept to pay the pizzo and go to the list of potential punished
[set firms-to-punish (turtle-set potential-firm-to-extort)];
]
]
]
set trials trials - 1
]
end
to execute-extortion
ask workers with [any? firms-to-extort][
ask firms-to-extort [
ifelse (type-of-pizzo = "proportion")[
set amount-of-pizzo max (list 0 (net-worth-A * (proportion-of-pizzo / 100)))
set net-worth-A net-worth-A - amount-of-pizzo
]
[
set amount-of-pizzo ifelse-value (net-worth-A > 0) [min (list net-worth-A constant-pizzo)][0]
set net-worth-A net-worth-A - amount-of-pizzo
]
]
set wealth wealth + sum [amount-of-pizzo] of firms-to-extort
]
end
to jail-or-punishment
; The companies that refused to pay pizzo, call the police, and with a probability of being caught, extortionists are imprisoned
set confiscated-money 0; reset confiscated money each tick
let needy-shops no-turtles
ask workers with [any? firms-to-punish][
; greater the number of extorted firms, greater the probability of being imprisoned
let caught? n-values (count firms-to-punish) [random 100 < probability-of-being-caught-lambda]
ifelse ( length filter [i -> i = TRUE] caught? > 0 )[
; extortionists are imprisoned
set in-jail? true
set extorter? false
set time-in-jail 6
ask firms-to-extort [set being-extorted? false] ;; These firms are no longer extorted.
set firms-to-extort no-turtles
ask firms-to-punish [set being-punished? false] ;; These firms are no longer punished.
set firms-to-punish no-turtles
let amount-confiscated max (list 0 (wealth * (percent-transfer-fondo / 100)))
set confiscated-money confiscated-money + amount-confiscated
set wealth wealth - amount-confiscated
][
; Extorters punish firms!
ask firms-to-punish [
set being-punished? true
set amount-of-punish max (list 0 (net-worth-A * ((proportion-of-punish) / 100)))
set net-worth-A net-worth-A - amount-of-punish
set needy-shops (turtle-set [firms-to-punish] of workers with [any? firms-to-punish])
]
set wealth sum [amount-of-punish] of firms-to-punish
]
]
if (count needy-shops > 0)[
ifelse (proportional-refund?)[; Refund is proportional
ask needy-shops [
set net-worth-A net-worth-A + ( confiscated-money / count needy-shops )
]
][; Refund "First to come" instead proportional
while [confiscated-money > 0 and count needy-shops > 0][
let first-firm-to-come one-of needy-shops
ask first-firm-to-come [
set net-worth-A net-worth-A + min (list amount-of-punish confiscated-money)
set needy-shops other needy-shops
]
set confiscated-money confiscated-money - [amount-of-punish] of first-firm-to-come
]
]
]
end
to in-jail
ask workers with [time-in-jail > 0][
set time-in-jail time-in-jail - 1
]
ask workers with [in-jail? and time-in-jail < 1][
set in-jail? false ;; They are being realeased
set color yellow
]
end
;;;;;;;;;; to firms-pay ;;;;;;;;;;
to firms-pay
ask firms [
set revenue-R individual-price-P * ( production-Y - inventory-S)
set gross-profits revenue-R - total-payroll-W
let principal-and-Interest amount-of-Interest-to-pay
if (amount-of-Interest-to-pay > 0)[
ifelse (gross-profits > amount-of-Interest-to-pay)[; submodel 42
ask my-bank [
set patrimonial-base-E patrimonial-base-E + principal-and-Interest
]
][
let bank-financing ifelse-value (net-worth-A != 0 ) [loan-B / net-worth-A][1]
let bad-debt-amount bank-financing * net-worth-A
ask my-bank [
set patrimonial-base-E patrimonial-base-E - bad-debt-amount
]
]
]
set net-profits gross-profits - amount-of-Interest-to-pay
set amount-of-Interest-to-pay 0
if (net-profits > 0)[
set retained-profits-pi (1 - dividends-delta ) * net-profits
]
]
end
;;;;;;;;;; to firms-banks-survive ;;;;;;;;;;
to firms-banks-survive
ask firms [
set net-worth-A net-worth-A + retained-profits-pi
if (net-worth-A <= 0
or production-Y <= 0
)[
ask my-bank [
set bad-debt-BD bad-debt-BD + 1
]
ask my-employees [
set color yellow
set employed? false
set my-wage 0
set contract 0
set my-firm no-turtles
rt random 360
fd (random 4) + 1
]
die
]
]
ask banks with [patrimonial-base-E < 0][
ask my-borrowing-firms [
set my-potential-banks no-turtles
set my-bank no-turtles
]
set bankrupt? true
]
end
to replace-bankrupt
if (count firms < number-of-firms)[
let incumbent-firms fn-incumbent-firms
if (any? incumbent-firms) [
set new-firms-production-Y ceiling mean [production-Y] of incumbent-firms
set new-firms-minimum-wage-W-hat min [minimum-wage-W-hat] of incumbent-firms
set new-firms-wage-offered-Wb (1 - size-replacing-firms) * mean [wage-offered-Wb] of incumbent-firms
set new-firms-net-worth-A (1 - size-replacing-firms) * mean [net-worth-A] of incumbent-firms
set new-firms-individual-price-P average-market-price
]
create-firms (number-of-firms - count firms) [
set x-position random-pxcor * 0.9
set y-position random-pycor * 0.9
setxy x-position y-position
move-to one-of patches with [not any? firms-here ]
set color blue
set size 1.2
set shape "factory"
;-----------------
set production-Y new-firms-production-Y
set labor-productivity-alpha 1
set my-employees no-turtles
set minimum-wage-W-hat new-firms-minimum-wage-W-hat
set wage-offered-Wb new-firms-wage-offered-Wb
set net-worth-A new-firms-net-worth-A
set my-potential-banks no-turtles
set my-bank no-turtles
set inventory-S 0
set individual-price-P new-firms-individual-price-P
;-----------------
set being-extorted? false
set being-punished? false
set amount-of-pizzo 0
]
]
ask banks with [bankrupt?][
set total-amount-of-credit-C 0
set patrimonial-base-E random-poisson 10000 + 10
set operational-interest-rate 0
set interest-rate-r 0
set my-borrowing-firms no-turtles
set bankrupt? false
]
; re-paint patches
ask patches [
set pcolor black
]
end
;;;;;;;;;; utilities ;;;;;;;;;;
;; this procedure recomputes the value of gini-index-reserve
;; and the points in lorenz-points for the Lorenz and Gini-Index plots
;; Code adapted from:
;; Wilensky, U. (1998). NetLogo Wealth Distribution model.
;; http://ccl.northwestern.edu/netlogo/models/WealthDistribution.
;; Center for Connected Learning and Computer-Based Modeling,
;; Northwestern University, Evanston, IL.
to update-lorenz-and-gini
let sorted-wealths sort [wealth] of workers
let total-wealth sum sorted-wealths
let wealth-sum-so-far 0
let index 0
let number-of-workers round (number-of-firms * 5)
set gini-index-reserve 0
set lorenz-points []
repeat number-of-workers [
set wealth-sum-so-far (wealth-sum-so-far + item index sorted-wealths)
set lorenz-points lput ((wealth-sum-so-far / total-wealth) * 100) lorenz-points
set index (index + 1)
set gini-index-reserve
gini-index-reserve +
(index / number-of-workers) -
(wealth-sum-so-far / total-wealth)
]
end
to-report gini-index
report (gini-index-reserve / round (number-of-firms * 5)) / 0.5
end
; b_1 skewness is calculated following:
; Joanes, D.N. and Gill, C.A. (1998). Comparing measures of sample skewness and kurtosis.
; The Statistician, 47, 183–189.
to-report skewness-of-wealth-regular-worker
ifelse (ticks > 0)[
let wealths [wealth] of workers with [not extorter? and not in-jail?]
let n round (number-of-firms * 5)
let x-bar mean wealths
let first-part ((n - 1 ) / n)^ (3 / 2)
let m-3-part ( reduce + map [i -> ( i - x-bar ) ^ 3] wealths ) / n
let m-2-part ( reduce + map [i -> ( i - x-bar ) ^ 2] wealths ) / n
report first-part * (m-3-part / (m-2-part) ^ (3 / 2 ))
][
report 0
]
end
to-report fn-truncated-normal [ m sd ]
let normal-value random-normal m sd
report ifelse-value (normal-value > (m - sd)) [normal-value][max list 1 (m - sd)]
end
to-report lower-quartile [ xs ]
let med median xs
let lower filter [ x -> x < med ] xs
report ifelse-value (empty? lower) [ med ] [ median lower ]
end
to-report tiempo
report timer
end
to-report CPI
let base base-price
let current array:item quarters-average-price (ticks mod (ifelse-value (quarterly-time-scale?)[4][12]))
report (current / base) * 100
end
to-report ln-hopital [number]
report ifelse-value (number > 0)[ln number][0]
end
to-report base-price
report 1.5
end
to-report base-savings
report 2
end
;;;;;;;;;; firm related reporters ;;;;;;;;;;
to-report average-market-price
report mean [individual-price-P] of firms
end
to-report fn-minimum-wage-W-hat
let currently-minimum-w min [minimum-wage-W-hat] of firms
report annualized-inflation * currently-minimum-w
end
to-report fn-incumbent-firms
let lower count firms * 0.05
let upper count firms * 0.95
let ordered-firms sort-on [net-worth-A] firms
let list-incumbent-firms sublist ordered-firms lower upper
report (turtle-set list-incumbent-firms)
end
to-report avg-firm-production
report mean [production-Y] of fn-incumbent-firms
end
to plot-size-of-firms
histogram map ln-hopital [production-Y] of fn-incumbent-firms
end
to-report avg-interest-rate
report 100 * mean [my-interest-rate] of firms
end
to-report avg-wage-offered
report ln mean [wage-offered-Wb] of firms
end
to-report avg-net-worth
report mean [net-worth-A] of fn-incumbent-firms
end
to-report net-worth-of-firms-to-gdp-ratio
let sum-net-worth sum [net-worth-A] of firms
report sum-net-worth / nominal-GDP
end
to-report skewness-of-networth
ifelse (ticks > 0 and any? firms)[
let networth [net-worth-A] of fn-incumbent-firms
let n number-of-firms
let x-bar mean networth
let first-part ((n - 1 ) / n)^ (3 / 2)
let m-3-part ( reduce + map [i -> ( i - x-bar ) ^ 3] networth ) / n
let m-2-part ( reduce + map [i -> ( i - x-bar ) ^ 2] networth ) / n
report first-part * (m-3-part / (m-2-part) ^ (3 / 2 ))
][
report 0
]
end
;;;;;;;;;; regular worker related reporters ;;;;;;;;;;
to-report fn-tanh [a]
report ifelse-value (a < 354.391)[(exp (2 * a) - 1) / (exp (2 * a) + 1)][0.135335283]
end
to-report avg-propensity-to-consume
report mean [propensity-to-consume-c] of workers
end
to-report avg-propensity-to-consume-regular-worker
ifelse (any? workers with [not extorter? and not in-jail?])[
report mean [propensity-to-consume-c] of workers with [not extorter? and not in-jail?]
][
report 0
]
end
to-report fn-wealth-of-regular-worker
ifelse (any? workers with [not extorter? and not in-jail?])[
report ln-hopital mean [wealth] of workers with [not extorter? and not in-jail?]
][
report 0
]
end
to-report wealth-of-regular-worker-to-gdp-ratio
let sum-wealth sum [wealth] of workers with [not extorter? and not in-jail?]
report sum-wealth / nominal-GDP
end
;;;;;;;;;; bank related reporters ;;;;;;;;;;
to-report interest-rate-policy-rbar
report 0.07
end
to-report patrimonial-bank-to-gdp-ratio
let bank-capital sum [patrimonial-base-E] of banks
report bank-capital / nominal-GDP
end
;;;;;;;;;; economic variables reporters ;;;;;;;;;;
to-report nominal-GDP
let output sum [production-Y * individual-price-P] of firms
report output
end
to plot-nominal-GDP
plot ln-hopital nominal-GDP
end
to-report real-GDP
report nominal-GDP / CPI
end
to plot-real-GDP
plot ln-hopital real-GDP
end
to-report fn-unemployment-rate
report count workers with [not employed? and time-in-jail < 1] / count workers with [time-in-jail < 1]
end
to plot-unemployment-rate
plot fn-unemployment-rate
end
to-report logarithm-of-households-consumption
let output sum [production-Y * individual-price-P] of firms
let consumption output - sum [inventory-S] of firms
report ln-hopital consumption
end
to-report households-consumption-to-gdp-ratio
let output sum [production-Y * individual-price-P] of firms
let consumption output - sum [inventory-S] of firms
report consumption / nominal-GDP
end
to-report inventory-to-gdp-ratio
let stock sum [inventory-S] of firms
report stock / nominal-GDP
end
to-report quarterly-inflation
let q-inflation array:item quarters-inflation (ticks mod (ifelse-value (quarterly-time-scale?)[4][12]))
report q-inflation
end
to-report annualized-inflation
report reduce * map [i -> (i / 100) + 1] array:to-list quarters-inflation
end
to-report yearly-inflation
report (annualized-inflation - 1) * 100
end
to plot-annualized-inflation
plot yearly-inflation
end
;;;;;;;;;; Reporters for extortion variables ;;;;;;;;;;
to-report fn-wealth-of-extorters
ifelse (any? workers with [extorter?])[
report ln-hopital mean [wealth] of workers with [extorter?]
][
report 0
]
end
to-report wealth-of-extorters-to-gdp-ratio
let sum-wealth sum [wealth] of workers with [extorter?]
report sum-wealth / nominal-GDP
end
to-report avg-wealth-of-extorters-to-gdp-ratio
ifelse (any? workers with [extorter?])[
let sum-wealth sum [wealth] of workers with [extorter?]
let extorters count workers with [extorter?]
let avg-wealth sum-wealth / extorters
report avg-wealth / nominal-GDP
][
report 0
]
end
to-report skewness-of-wealth-extorter
ifelse (ticks > 0 and any? workers with [extorter?])[