Agent-Based Cognitive Simulation for Financial Stability

No preview image

1 collaborator

Default-person Gianni Di Lernia (Author)

Tags

(This model has yet to be categorized with any tags)
Visible to everyone | Changeable by the author
Model was written in NetLogo 7.0.0-beta0 • Viewed 7 times • Downloaded 0 times • Run 0 times
Download the 'Agent-Based Cognitive Simulation for Financial Stability' 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?

(a general understanding of what the model is trying to show or explain)

HOW IT WORKS

(what rules the agents use to create the overall behavior of the model)

HOW TO USE IT

(how to use the model, including a description of each of the items in the Interface tab)

THINGS TO NOTICE

(suggested things for the user to notice while running the model)

THINGS TO TRY

(suggested things for the user to try to do (move sliders, switches, etc.) with the model)

EXTENDING THE MODEL

(suggested things to add or change in the Code tab to make the model more complicated, detailed, accurate, etc.)

NETLOGO FEATURES

(interesting or unusual features of NetLogo that the model uses, particularly in the Code tab; or where workarounds were needed for missing features)

RELATED MODELS

(models in the NetLogo Models Library and elsewhere which are of related interest)

CREDITS AND REFERENCES

(a reference to the model's URL on the web if it has one, as well as any other necessary credits, citations, and links)

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

;; Modello: Solvibilità dei creditori sotto eventi avversi - Versione Basel III
;; Agent-Based Model con RWA, CET1, prob-default e loss-given-default espliciti
;; NetLogo Web compatible

globals [
  ;; Banca - Equity e Capitale
  bank-equity-tier1              ;; patrimonio netto primario (CET1)
  bank-debt-tier2                ;; debito subordinato (Tier 2)
  bank-total-equity              ;; Tier 1 + Tier 2

  ;; Banca - Esposizioni e Ponderazione
  total-loans-nominal            ;; impieghi lordi (nominale)
  bank-RWA                       ;; Risk-Weighted Assets
  
  ;; Banca - Metriche Basel III
  CET1-ratio                     ;; CET1 / RWA
  total-capital-ratio            ;; (Tier1 + Tier2) / RWA
  leverage-ratio                 ;; Tier1 / Total Exposure (non ponderato)
  
  ;; Banca - Metriche di qualità crediti
  npl-ratio                      ;; crediti in default / totale
  npl-amount                     ;; ammontare assoluto NPL
  total-provisions               ;; accantonamenti per perdite
  
  ;; Regolamentari
  CET1-req                       ;; requisito CET1 (slider)
  Total-Capital-req              ;; requisito capitale totale
  Leverage-req                   ;; requisito leva
  
  ;; Parametri di shock
  growth-rate
  shock-frequency
  shock-severity
  
  ;; Monitor aggregati
  avg-credit-score
  avg-income
  avg-prob-default
  avg-collateral-value
  shock-counter
  
  shock-epicenter-x
shock-epicenter-y
shock-radius
]

turtles-own [
  debtor-type                    ;; "household" / "firm"
  risk-zone                      ;; 1, 2, 3
  
  ;; Variabili microeconomiche
  income                         ;; Y - reddito annuale
  wealth                         ;; A - patrimonio netto
  deposits                       ;; D - liquidità presso banca
  loan-amount                    ;; L_i - prestito nominale
  
  ;; Qualità creditizia
  credit-score                   ;; MC - merito creditizio (0-100)
  prob-default                   ;; Probability of Default (%)
  loss-given-default             ;; Loss Given Default (%)
  collateral-value               ;; valore garanzie
  risk-weight                    ;; peso RWA per questo debitore
  
  ;; Stato
  default?                       ;; boolean
  in-forbearance?                ;; moratoria su pagamenti
]

patches-own [
  patch-risk-zone                ;; zone 1, 2, 3
]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SETUP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to setup
  clear-all
  setup-parameters
  setup-world
  setup-bank
  setup-debtors
  reset-ticks
end 

to setup-parameters
  set CET1-req CET1-req-slider
  set Total-Capital-req Total-Capital-req-slider
  set Leverage-req Leverage-req-slider
  
  set growth-rate growth-rate-slider
  set shock-frequency shock-frequency-slider
  set shock-severity shock-severity-slider
  set shock-counter 0
  
  ;; NUOVO: Parametri spaziali
  set shock-epicenter-x shock-epicenter-x-slider
  set shock-epicenter-y shock-epicenter-y-slider
  set shock-radius shock-radius-slider
end 

; SETUP-WORLD MIGLIORATO (Divisione Concentrica)

to setup-world
  ;; VERSIONE MIGLIORATA: Divisione concentrica attorno all'epicentro
  ask patches [
    ;; Calcola distanza dall'epicentro
    let distance-from-epicenter sqrt ((pxcor - shock-epicenter-x) ^ 2 + (pycor - shock-epicenter-y) ^ 2)
    
    ;; Assegna zone di rischio in base alla distanza
    if distance-from-epicenter <= 5 [
      set patch-risk-zone 3  ;; Zona rossa: rischio MASSIMO (dentro 5 unità)
    ]
    if distance-from-epicenter > 5 and distance-from-epicenter <= 10 [
      set patch-risk-zone 2  ;; Zona arancione: rischio MEDIO (5-10 unità)
    ]
    if distance-from-epicenter > 10 [
      set patch-risk-zone 1  ;; Zona blu: rischio BASSO (oltre 10 unità)
    ]
    
    ;; Colora le patch in base al rischio
    if patch-risk-zone = 1 [ set pcolor blue + 2 ]
    if patch-risk-zone = 2 [ set pcolor orange + 1 ]
    if patch-risk-zone = 3 [ set pcolor red - 1 ]
  ]
  
  ;; OPZIONALE: Disegna cerchi di riferimento per visualizzare le zone
  draw-risk-circles shock-epicenter-x shock-epicenter-y
end 

to draw-risk-circles [center-x center-y]
  ;; Disegna cerchi concentrici per chiarezza visiva
  ask patches [
    let distance-from-epicenter sqrt ((pxcor - center-x) ^ 2 + (pycor - center-y) ^ 2)
    if distance-from-epicenter >= 4.8 and distance-from-epicenter <= 5.2 [
      set pcolor yellow  ;; Confine tra zona 3 e 2
    ]
    if distance-from-epicenter >= 9.8 and distance-from-epicenter <= 10.2 [
      set pcolor gray    ;; Confine tra zona 2 e 1
    ]
  ]
  
  ;; Marker al centro (epicentro)
  ask patch center-x center-y [
    set pcolor black  ;; Epicentro
  ]
end 

to setup-bank
  set bank-equity-tier1 1000
  set bank-debt-tier2 200
  set bank-total-equity bank-equity-tier1 + bank-debt-tier2
  
  set total-loans-nominal 0
  set bank-RWA 0
  set CET1-ratio 0
  set total-capital-ratio 0
  set leverage-ratio 0
  
  set npl-amount 0
  set npl-ratio 0
  set total-provisions 0
end 

to setup-debtors
  let n-households num-households-slider
  let n-firms      num-firms-slider

  crt (n-households + n-firms) [
    set default? false
    set in-forbearance? false
    move-to one-of patches
    set risk-zone [patch-risk-zone] of patch-here

    if who < n-households [
      set debtor-type "household"
      set shape "person"
      set size 1.2
    ]
    if who >= n-households [
      set debtor-type "firm"
      set shape "factory"
      set size 1.4
    ]

    if debtor-type = "household" [
      set income  random-normal 35000 5000
      if income < 10000 [ set income 10000 ]
      set wealth  random-normal 200000 50000
      if wealth < 20000 [ set wealth 20000 ]
      set deposits (income * 0.5)
      set loan-amount (income * 1.0)
      set collateral-value wealth * 0.8
    ]

    if debtor-type = "firm" [
      set income  random-normal 80000 15000
      if income < 30000 [ set income 30000 ]
      set wealth  random-normal 400000 100000
      if wealth < 50000 [ set wealth 50000 ]
      set deposits (income * 0.3)
      set loan-amount (income * 2.0)
      set collateral-value wealth * 0.7
    ]

    set credit-score calc-credit-score
    set prob-default calc-prob-default
    set loss-given-default calc-loss-given-default
    set risk-weight calc-risk-weight
    
    recolor-debtor
  ]

  update-bank-metrics
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; GO
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to go
  if ticks >= max-ticks-slider [ stop ]

  apply-shocks
  update-debtors
  apply-forbearance
  update-bank
  update-aggregates
  update-my-plots

  tick
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SHOCK CLIMATICI / FISICI
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; APPLY-SHOCKS MIGLIORATO (Shock Localizzato)

to apply-shocks
  ;; VERSIONE MIGLIORATA: Shock localizzato per distanza
  ;; Solo gli agenti entro una certa distanza dall'epicentro vengono colpiti
  if random-float 1 < shock-frequency [
    set shock-counter shock-counter + 1
    
    ask turtles with [ not default? ] [
      let distance-from-epicenter sqrt ((xcor - shock-epicenter-x) ^ 2 + (ycor - shock-epicenter-y) ^ 2)
      
      ;; Lo shock colpisce solo gli agenti entro il raggio
      if distance-from-epicenter <= shock-radius [
        ;; La severità dello shock è INVERSAMENTE proporzionale alla distanza
        ;; (più vicino all'epicentro = più danno)
        let attenuation-factor (1 - (distance-from-epicenter / shock-radius))
        let effective-shock shock-severity * attenuation-factor
        
        ;; Combina con la vulnerabilità della zona
        let vuln risk-zone
        let loss-factor effective-shock * vuln
        
        ;; Applica i danni
        set income income * (1 - loss-factor)
        if income < 0 [ set income 0 ]

        set wealth wealth * (1 - loss-factor)
        if wealth < 0 [ set wealth 0 ]

        set deposits deposits * (1 - (loss-factor * 0.5))
        if deposits < 0 [ set deposits 0 ]

        set collateral-value collateral-value * (1 - loss-factor * 1.5)
        if collateral-value < 0 [ set collateral-value 0 ]

        ;; Ricalcola metriche di rischio
        set prob-default calc-prob-default
        set loss-given-default calc-loss-given-default
        set risk-weight calc-risk-weight
      ]
    ]
  ]
end 


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; DEBITORI
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to update-debtors
  ask turtles [
    if not default? and not in-forbearance? [
      set income income * (1 + growth-rate)

      let installment-rate 0.15
      let installment income * installment-rate

      let consumption-rate 0.6
      let consumption income * consumption-rate

      let savings income - consumption - installment
      if savings < 0 [ set savings 0 ]

      set deposits deposits + savings
      set wealth wealth + savings
      set collateral-value collateral-value + (savings * 0.5)

      let amort installment
      set loan-amount loan-amount - amort
      if loan-amount < 0 [ set loan-amount 0 ]

      set credit-score calc-credit-score
      set prob-default calc-prob-default
      set loss-given-default calc-loss-given-default
      set risk-weight calc-risk-weight

      if prob-default > 30 [
        set default? true
        set income 0
        set in-forbearance? false
      ]
    ]

    if in-forbearance? [
      let installment-rate 0.075
      let installment income * installment-rate
      set loan-amount loan-amount - installment
      if loan-amount < 0 [ set loan-amount 0 ]

      set prob-default calc-prob-default
      if prob-default < 20 [ set in-forbearance? false ]
    ]

    recolor-debtor
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SCORING E METRICHE INDIVIDUALI
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to-report calc-credit-score
  let y-norm   (income   / 80000)
  if y-norm > 1 [ set y-norm 1 ]
  if y-norm < 0 [ set y-norm 0 ]

  let a-norm   (wealth   / 500000)
  if a-norm > 1 [ set a-norm 1 ]
  if a-norm < 0 [ set a-norm 0 ]

  let d-norm   (deposits / 100000)
  if d-norm > 1 [ set d-norm 1 ]
  if d-norm < 0 [ set d-norm 0 ]

  let l-norm   (loan-amount / 500000)
  if l-norm > 1 [ set l-norm 1 ]
  if l-norm < 0 [ set l-norm 0 ]

  let wY 0.25
  let wA 0.25
  let wD 0.25
  let wL -0.25

  let score (100 * ( wY * y-norm +
                     wA * a-norm +
                     wD * d-norm +
                     wL * (1 - l-norm) ))

  if score < 0 [ set score 0 ]
  if score > 100 [ set score 100 ]
  report score
end 

to-report calc-prob-default
  let base-prob-default 40.0
  let score-factor credit-score / 100
  let prob-default-result base-prob-default * (1 - score-factor * 0.975)
  
  let collateral-ratio 0
  if loan-amount > 0 [ set collateral-ratio collateral-value / loan-amount ]
  if collateral-ratio < 0.5 [ set prob-default-result prob-default-result * 1.5 ]
  
  if prob-default-result < 0.1 [ set prob-default-result 0.1 ]
  if prob-default-result > 50 [ set prob-default-result 50 ]
  report prob-default-result
end 

to-report calc-loss-given-default
  let lgd-result 0
  if loan-amount > 0 [
    let coverage-ratio collateral-value / loan-amount
    set lgd-result 60 * (1 - coverage-ratio)
    if coverage-ratio > 1 [ set lgd-result 10 ]
  ]
  
  if lgd-result < 10 [ set lgd-result 10 ]
  if lgd-result > 60 [ set lgd-result 60 ]
  report lgd-result
end 

to-report calc-risk-weight
  let RW 0
  let prob-decimal prob-default / 100
  
  let N-inv 1.627
  let correlation 0.12
  let maturity 2.5
  
  let term1 (prob-decimal + (correlation ^ 0.5) * N-inv)
  let term2 (1 - correlation) ^ 0.5
  let arg (term1 / term2) - N-inv
  let prob-conditional 0
  
  if arg > 3 [ set prob-conditional 0.99 ]
  if arg <= 3 and arg > 0 [ set prob-conditional 0.50 + arg / 8 ]
  if arg <= 0 [ set prob-conditional (arg / 5) + 0.1 ]
  if prob-conditional < 0 [ set prob-conditional 0 ]
  if prob-conditional > 1 [ set prob-conditional 1 ]
  
  let lgd-decimal loss-given-default / 100
  set RW (1.06 * (prob-conditional * lgd-decimal + ((1 - prob-decimal) ^ 0.5) * (0.0470 + 0.999 * maturity)) - 0.0147)
  
  if RW < 0.2 [ set RW 0.2 ]
  if RW > 12.5 [ set RW 12.5 ]
  
  report RW
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; FORBEARANCE (MORATORIA)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to apply-forbearance
  ask turtles with [ not default? and credit-score < 35 and not in-forbearance? ] [
    set in-forbearance? true
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; BANCA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to update-bank
  update-bank-metrics
  
  let loss-NPL 0
  ask turtles with [ default? ] [
    if loan-amount > 0 [
      let loss-on-this-loan loan-amount * (loss-given-default / 100)
      set loss-NPL loss-NPL + loss-on-this-loan
    ]
  ]
  
  let interest-margin 0.02
  let interest-income interest-margin * sum [ loan-amount ] of turtles with [ not default? and not in-forbearance? ]
  let interest-forbearance 0.005 * sum [ loan-amount ] of turtles with [ in-forbearance? ]
  let operating-costs-rate 0.01
  let operating-costs operating-costs-rate * total-loans-nominal
  
  let EL 0
  ask turtles [
    if loan-amount > 0 [
      let EL-this (loan-amount * (prob-default / 100) * (loss-given-default / 100))
      set EL EL + EL-this
    ]
  ]
  set total-provisions EL
  
  let profit (interest-income + interest-forbearance - operating-costs - loss-NPL)
  
  set bank-equity-tier1 bank-equity-tier1 + profit
  if bank-equity-tier1 < 0 [ set bank-equity-tier1 0 ]
  
  set bank-total-equity bank-equity-tier1 + bank-debt-tier2
end 

to update-bank-metrics
  set total-loans-nominal sum [ loan-amount ] of turtles
  
  set bank-RWA 0
  ask turtles [
    if loan-amount > 0 [
      set bank-RWA bank-RWA + (loan-amount * (risk-weight / 100))
    ]
  ]
  
  set npl-amount sum [ loan-amount ] of turtles with [ default? ]
  if total-loans-nominal > 0 [
    set npl-ratio npl-amount / total-loans-nominal
  ]
  
  if bank-RWA > 0 [
    set CET1-ratio (bank-equity-tier1 / bank-RWA) * 100
    set total-capital-ratio (bank-total-equity / bank-RWA) * 100
  ]
  
  if total-loans-nominal > 0 [
    set leverage-ratio (bank-equity-tier1 / total-loans-nominal) * 100
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; AGGREGATI
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to update-aggregates
  if count turtles > 0 [
    set avg-credit-score mean [ credit-score ] of turtles
    set avg-income mean [ income ] of turtles
    set avg-prob-default mean [ prob-default ] of turtles
    set avg-collateral-value mean [ collateral-value ] of turtles
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; COLORI
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to recolor-debtor
  if default? [
    set color red
  ]
  if in-forbearance? [
    set color yellow
  ]
  if not default? and not in-forbearance? [
    if credit-score >= 67 [ set color green ]
    if credit-score < 67 and credit-score >= 33 [ set color orange ]
    if credit-score < 33 [ set color gray ]
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PLOT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to update-my-plots
  set-current-plot "Credit Score"
  set-current-plot-pen "Households"
  plot mean [ credit-score ] of turtles with [ debtor-type = "household" ]
  set-current-plot-pen "Firms"
  plot mean [ credit-score ] of turtles with [ debtor-type = "firm" ]

  set-current-plot "Prob Default Average"
  set-current-plot-pen "Prob-Default"
  plot avg-prob-default

  set-current-plot "NPL Ratio"
  set-current-plot-pen "NPL"
  plot npl-ratio * 100

  set-current-plot "CET1 Ratio"
  set-current-plot-pen "CET1"
  plot CET1-ratio
  set-current-plot-pen "CET1_req"
  plot CET1-req

  set-current-plot "Total Capital Ratio"
  set-current-plot-pen "Total Capital"
  plot total-capital-ratio
  set-current-plot-pen "Total_req"
  plot Total-Capital-req

  set-current-plot "Leverage Ratio"
  set-current-plot-pen "Leverage"
  plot leverage-ratio
  set-current-plot-pen "Leverage_req"
  plot Leverage-req

  set-current-plot "Total Loans"
  set-current-plot-pen "Nominal"
  plot total-loans-nominal
  set-current-plot-pen "RWA"
  plot bank-RWA

  set-current-plot "Debtors Status"
  set-current-plot-pen "Active"
  plot count turtles with [ not default? and not in-forbearance? ]
  set-current-plot-pen "Forbearance"
  plot count turtles with [ in-forbearance? ]
  set-current-plot-pen "Default"
  plot count turtles with [ default? ]
end 

There is only one version of this model, created 6 days ago by Gianni Di Lernia.

Attached files

No files

This model does not have any ancestors.

This model does not have any descendants.