MODELLO DI SIMULAZIONE AD AGENTI
4.1 La simulazione in ambito economico
4.2.2 I dettagli del modello
L’ambiente.
Nel mercato finanziario sono presenti quattro titoli, diversi per variabilità e rischio: due obbligazioni e due azioni. La prima obbligazione è un titolo a rendimento
basso, con cedola fissa (2%) e nessun rischio; la seconda ha una cedola fissa alta (7%) e un elevato rischio di insolvenza da parte del debitore (10%). Per quanto riguarda le azioni, invece, una di esse ha una forte variabilità (valore random tra -10% e +10%); la seconda ha una variabilità più bassa e, quindi, un minor rischio (valore random tra -5% e +5%). I ricavi e le perdite sono dati dall’aumento o dalla diminuzione del valore del titolo dell’azione, non è infatti distribuito alcun dividendo.
Figura 4.3. Andamento del valore dei titoli: la linea gialla rappresenta l’obbligazione ad alto rischio, e evidenzia i casi di insolvenza del debitore.
I titoli finanziari sono rappresentati da vettori, in cui vengono memorizzate le proprietà fondamentali. Nel vettore sono indicati il tipo di titolo, il suo valore – nella codice sottostante esso non è definito (None), perché il suo valore è stabilito successivamente, la cedola delle obbligazioni o la variazione delle azioni e il grado di rischio di ciascun titolo. Poiché il rischio delle azioni dipende dalla variazione del corso del titolo, il quarto termine delle azioni non è valutato. Nel codice del programma sono costruiti così:
# obbligations values = [name of title, value, cedola, risk] self.TitleObbligation1 = [‘obbligation1’, None, 2./100, 0] self.TitleObbligation2 = [‘obbligation2’, None, 7./100, 10] # share values = [name of title, value , variation, risk]
self.TitleShare1 = [‘share1’, None, (random.random()- 0.5)/10, None]
self.TitleShare2 = [‘share2’, None, (random.random()- 0.5)*2/10 , None]
Gli agenti.
Il valore delle azioni e la loro variazione nel tempo sono le uniche variabili ambientali del modello. La parte più complessa della simulazione è l’organizzazione delle azioni degli agenti. Ogni livello del programma, come detto prima, ha una propria gestione del tempo e delle azioni del modello. Il ruolo centrale è, in questo caso, svolto al livello de Model. Qui i ‘passi’ della simulazione sono organizzati in sottogruppi o Actiongroup. Questa struttura permette di suddividere tutte le operazioni in gruppi specifici, ciascuno contenente azioni simili tra loro per significato. Essi sono ordinati in una lista e richiamati uno alla volta dal programma:
self.actionGroupList = [‘move’, ‘talk’, ‘ buy or sell’, ‘distribute money’]
Il più importante è il terzo gruppo, il quale gestisce le operazioni finanziare degli agenti. Dal punto di vista della programmazione, la differenza tra le due fasi della simulazione è limitata a questo gruppo di azioni. La differenza tra le due fasi è quindi minima: la struttura del modello permette infatti di sostituire singole componenti del programma e mantenere allo stesso tempo stabile la struttura generale. Un considerevole vantaggio consiste infatti nel dover modificare solo un numero minimo di elementi: questo favorisce il confronto fra le diverse fasi della simulazione, evitando di distorcere i risultati modificando fattori diversi da quelli studiati.
Il ruolo degli intermediari finanziati è quello di suggerire ai risparmiatori su quale titolo operare e quale operazione effettuare (comprare o vendere). Una volta ottenuto il suggerimento, i risparmiatori operano in base ai loro risparmi e ai titoli che possiedono. Se l’operazione consigliata è economicamente possibile (ci sono sufficienti risparmi per acquistare, o ci sono titoli che possono essere venduti), allora viene realizzata.
def step(self, n, length, learnGlobalCycles, globalLearnedCycles): for s in self.actionGroupListFirst:
if s == ‘move’‘move’‘move’‘move’:
self.actionGroup1.do(self)
if s == ‘talk’‘talk’‘talk’‘talk’:
self.actionGroup2.do(self,n)
if s == ‘buy or sell’‘buy or sell’‘buy or sell’‘buy or sell’: if globalLearnedCycles == learnGlobalCycles - 1: self.actionGroup6self.actionGroup6self.actionGroup6self.actionGroup6.do(self, n)
else:
if n % length > 11:
self.actionGroup3self.actionGroup3self.actionGroup3self.actionGroup3.do(self, n)
else:
print ‘don't act’
if s == ‘distribute money’‘distribute money’‘distribute money’‘distribute money’:
self.actionGroup4.do(self, n) if globalLearnedCycles == learnGlobalCycles-1: if n % length == 0:
# apprendimento degli agenti self.actionGroup5.do(self, n)
# azzeramento dei valori, in modo da vedere la differenza con # i tempi precedenti. Qui inizia il grafico...
if n % length == 0:
self.actionGroup7.do(self)
Figura 4.4. È mostrato la parte del codice che gestisce le azioni al livello del Model. La variabile
n indica il tempo della simulazione, length la durata complessiva. Le altre due variabili in alto tra
parentesi, invece, identificano il numero delle simulazioni parziali. Ogni passo della simulazione è organizzato in Actiongroups, richiamati uno alla volta dal programma in base al loro ordine nel vettore delle azioni. Gli Actiongroups numero 3 e 6 – evidenziati in grassetto – corrispondono alle azioni degli agenti: la differenze tra le due fasi della simulazione è in questo scambio di componenti del programma.
1. La simulazione è divisa in simulazioni parziali. Se essa dura troppo, il valore dei titoli cresce in misura eccessiva e rende più difficile l’elaborazione delle informazioni da parte della rete.
2. Ogni simulazione parziale incomincia da valori di base dei titoli e della ricchezza degli agenti. All’inizio di ciascuna prova, i valori delle variabili ambientali sono ristabiliti da capo. Il processo di azione e memorizzazione degli agenti non è interrotto; essi continuano ad accumulare esperienza14. 3. Non sono invece modificati, all’inizio di ogni simulazione, i valori delle reti
neurali. Nel caso in cui l’azione ‘esperta’ dovesse durare molti cicli, azzerare i valori della rete significherebbe rinunciare alle informazioni apprese dagli agenti.
Nei grafici successivi (figura 4.5) è mostrato lo sviluppo della ricchezza dei singoli risparmiatori nella prima fase della simulazione, dove gli agenti agiscono a caso. Si suppone che ogni famiglia possegga un’attività che produca un reddito minimo, che ad ogni ciclo incrementa il patrimonio. Quest’ultimo può essere dunque trattenuto in forma liquida o essere impiegato per acquistare titoli. La ricchezza di un risparmiatore dipende soprattutto dai titoli acquistati o venduti e dal loro valore al tempo.
Figura 4.5. Ricchezza dei risparmiatori con suggerimenti casuali, nella prima fase della simulazione.
L’azione.
Questa fase ha un ruolo fondamentale perché fornisce i dati necessari sui quali basare l’apprendimento. Ogni operazione è infatti ‘memorizzata’ in un vettore: in esso sono contenute tutte le informazioni necessarie per le operazioni successive – giudizio e pagamento della cedola. Questo vettore contiene informazioni che indicano il tipo di titolo, il suo valore al tempo dell’operazione, il tipo di operazione, la quantità di titoli acquistata o venduta, il tempo dell’operazione e il risparmiatore che ha impiegato il denaro. Il giudizio sull’operazione corrisponde al quarto elemento del vettore, la
# lastOperation = [ titleType, absolute value, operation, quantity, Judge, Fee, time, householder]
Dopo un certo numero di cicli, gli agenti sono in grado di confrontare il valore del titolo (secondo elemento del vettore) al tempo dell’operazione (settimo elemento), con il valore del titolo al momento del giudizio, facilmente ottenibile perché corrisponde ad una variabile ambientale. Il giudizio è positivo se il valore del titolo è aumentato, negativo in caso contrario – nel caso della vendita, il giudizio è invertito; esso è uguale a 1 o -1, moltiplicato per la quota pagata dal risparmiatore all’intermediario. Il pagamento avviene nel momento in cui un’operazione è giudicata positivamente e la somma corrisponde ad una percentuale fissa, moltiplicata per il valore del titolo e la quantità (quarto elemento) di titoli scambiati.
4.2.3 L’apprendimento.
L’apprendimento degli agenti, avviene in base all’esperienza maturata durante i cicli casuali. Le operazioni sono state giudicate e l’intermediario ha a disposizione tutte le informazioni necessarie per esaminare il suo operato. Egli è in grado di rivedere la situazione in cui ha dato un consiglio e di capire gli effetti del suo suggerimento; considera il valore di tutti i titoli nel periodo precedente all’operazione e li confronta con il giudizio ottenuto. In questo modo la rete associata all’azione impara ad associare, al corso dei titoli, un giudizio adeguato sulla bontà dell’azione.
Ogni agente ha due reti per ogni titolo: una per l’acquisto e una per la vendita. I titoli sono quattro e quindi il numero di reti per ogni agente è pari a otto. I valori di input di ciascuna rete corrispondono al valore di ogni titolo nel periodo (t-10) che precede l’operazione al tempo t. Ogni rete ha dunque quaranta nodi di input. Il numero di nodi nascosti, in questo caso venti, è stabilito dal programmatore. Per ottenere i valori di input desiderati, è costruito durante la simulazione un file nel quale è registrato il
valore di ogni titolo in ogni momento. Questi file sono a disposizione degli agenti, i quali possono ottenere tutte le informazioni che desiderano in qualsiasi momento.
Il nodo di output, invece, indica la bontà dell'azione. Il valore in base al quale regolare l’apprendimento è dato dal giudizio dato sul risultato dell’azione, che è stato memorizzato nel vettore dell’operazione, moltiplicato per quota versata all’intermediario. La rete ha quindi a disposizione un valore in base al quale stimare i propri parametri è ciò permette di usare l’algoritmo della backpropagation.
Ogni intermediario finanziario riesce in media a memorizzare 250 azioni (30 per ogni rete) e il relativo giudizio. Per evitare che la rete memorizzi in maniera esaustiva i primi casi esaminati e non sia in grado di apprendere dagli ultimi esempi, in questa simulazione la rete esamina più volte (20) i dati disponibili. Ad ogni ciclo di apprendimento, essa compie un numero di cicli di backpropagation molto basso (10). L’apprendimento è quindi di 6 000 cicli totali per ogni rete di ciascun agente.