Sei sulla pagina 1di 326

Elementi di Finanza, metodi numerici e loro implementazione.

Marco Airoldi Email: MarcoAiroldi@yahoo.it


Versione documento 7.5 c Marco Airoldi

11 novembre 2009

ii

Indice
1 Elementi di programmazione ad oggetti 5 1.1 Introduzione alla programmazione ad oggetti . . . . . . . . . 6 1.2 Il contesto - Elementi base del C++ . . . . . . . . . . . . . . 7 1.2.1 Programmazione procedurale e ad oggetti . . . . . . . 7 1.2.2 Perch il C++ . . . . . . . . . . . . . . . . . . . . . . e 9 1.2.3 Tipi variabili fondamentali e concetti base . . . . . . . 9 1.2.4 Input output . . . . . . . . . . . . . . . . . . . . . . . 12 1.2.5 Ciclo for . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.2.6 Costrutto while . . . . . . . . . . . . . . . . . . . . . . 18 1.2.7 Condizione if . . . . . . . . . . . . . . . . . . . . . . . 21 1.2.8 Denizione ed utilizzo di una funzione . . . . . . . . . 24 1.2.9 Tipi derivati . . . . . . . . . . . . . . . . . . . . . . . 30 1.2.10 Tipi derivati: i puntatori . . . . . . . . . . . . . . . . 31 1.2.11 Tipi derivati: i vettori . . . . . . . . . . . . . . . . . . 35 1.2.12 Tipi derivati: le strutture . . . . . . . . . . . . . . . . 44 1.2.13 Overloading . . . . . . . . . . . . . . . . . . . . . . . . 48 1.2.14 Compilazione . . . . . . . . . . . . . . . . . . . . . . . 50 1.2.15 Gestione della memoria in C/C++ . . . . . . . . . . . 51 1.3 Programmazione ad oggetti . . . . . . . . . . . . . . . . . . . 52 1.3.1 Denizione di una classe . . . . . . . . . . . . . . . . . 53 1.3.2 Interfaccia di una classe . . . . . . . . . . . . . . . . . 60 1.3.3 Ereditariet di classe . . . . . . . . . . . . . . . . . . . 61 a 1.3.4 Composizione di oggetti vs ereditariet . . . . . . . . 85 a 1.3.5 Ridenizione degli operatori . . . . . . . . . . . . . . . 93 1.3.6 Esempio di utilizzo del polimorsmo, ovvero programmare riferendosi allinterfaccia e non allimplementazione specica. 98 1.3.7 Esempio di utilizzo avanzato del polimorsmo. 125 1.3.8 Design patterns . . . . . . . . . . . . . . . . . . . . . . 130 iii

iv

INDICE

2 Elementi di nanza 133 2.1 Il contesto - Elementi di nanza . . . . . . . . . . . . . . . . . 134 2.1.1 Tasso di interesse . . . . . . . . . . . . . . . . . . . . . 134 2.1.2 Il principio del non arbitraggio . . . . . . . . . . . . . 135 2.1.3 Attualizzazione del denaro . . . . . . . . . . . . . . . . 137 2.1.4 Denizione di bond e sua valutazione . . . . . . . . . . 138 2.1.5 Curva dei tassi di interesse . . . . . . . . . . . . . . . 138 2.1.6 Titoli derivati e opzioni plain vanilla . . . . . . . . . . 139 2.2 Processi stocastici per descrivere le azioni . . . . . . . . . . . 144 2.2.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . 144 2.2.2 Il modello random walk . . . . . . . . . . . . . . . . . 144 2.2.3 Processi di Wiener e di Ito . . . . . . . . . . . . . . . 147 2.2.4 Lemma di Ito . . . . . . . . . . . . . . . . . . . . . . . 148 2.2.5 Processi di Markov . . . . . . . . . . . . . . . . . . . . 150 2.2.6 Il processo log normale come modello per le azioni . . 151 2.3 Analisi di Black Scholes per il pricing delle opzioni . . . . . . 154 2.3.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . 154 2.3.2 Largomento di Black & Scholes . . . . . . . . . . . . 154 2.3.3 Il concetto di valutazione neutrale verso il rischio . . . 157 2.3.4 Alberi binomiali ad uno stadio e valutazione neutrale verso il rischio . . . . . . . . . . . . . . . . . . . . . . 157 2.3.5 Soluzione dellequazione di Black & Scholes . . . . . . 161 2.3.6 Critica allapproccio di Black & Scholes . . . . . . . . 164 2.4 Opzioni esotiche . . . . . . . . . . . . . . . . . . . . . . . . . 166 2.4.1 Opzioni asiatiche . . . . . . . . . . . . . . . . . . . . . 166 2.4.2 Opzioni digitali . . . . . . . . . . . . . . . . . . . . . . 166 2.4.3 Opzioni con barriera . . . . . . . . . . . . . . . . . . . 166 2.4.4 Opzioni cliquet e reverse cliquet . . . . . . . . . . . . 169 2.4.5 Opzioni lookback . . . . . . . . . . . . . . . . . . . . . 170 2.4.6 Opzioni su basket . . . . . . . . . . . . . . . . . . . . 170 2.4.7 Denizione generale di opzione . . . . . . . . . . . . . 172 2.4.8 Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . 173 2.5 Una formula approssimata per la valutazione di opzioni asiatiche174 3 Metodi numerici per il pricing di opzioni 179 3.1 Metodo Monte Carlo . . . . . . . . . . . . . . . . . . . . . . . 180 3.1.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . 180 3.1.2 Il metodo Monte Carlo e . . . . . . . . . . . . . . . 180 3.1.3 Miglioramenti al metodo Monte Carlo . . . . . . . . . 184 3.1.4 Il metodo Monte Carlo nel calcolo del prezzo di unopzione europea . . . . . . . . . . . . . . . . . . . . . . . . . . 186 3.2 Alberi Binomiali . . . . . . . . . . . . . . . . . . . . . . . . . 194 3.2.1 Gli alberi binomiali nel gioco dazzardo - esercitazione 194 3.2.2 Introduzione agli alberi binomiali in nanza . . . . . . 194

INDICE 3.2.3

v Alberi Binomiali per un sottostante - metodo di Cox, Ross e Rubinstein (CRR) . . . . . . . . . . . . . . . . 196 3.2.4 Alberi Binomiali per un sottostante - metodo di Rubinstein . . . . . . . . . . . . . . . . . . . . . . . . . . 196 3.2.5 Estensione al caso di due sottostanti correlati . . . . . 197 3.2.6 Alberi Binomiali a pi stadi . . . . . . . . . . . . . . . 199 u 3.2.7 Alberi Binomiali: vantaggi e svantaggi . . . . . . . . . 200 Dierenze Finite . . . . . . . . . . . . . . . . . . . . . . . . . 202 3.3.1 Introduzione e schemi di discretizzazione . . . . . . . . 202 3.3.2 Schemi di discretizzazione . . . . . . . . . . . . . . . . 202 3.3.3 Discretizzazione dellequazione di BS - metodo esplicito204 3.3.4 Convergenza del metodo . . . . . . . . . . . . . . . . . 207 3.3.5 Esempi di applicazione del metodo delle dierenze nite208 3.3.6 Vantaggi e punti deboli del metodo alle dierenze nite213

3.3

4 Progetto di una libreria in C++ per il pricing 215 4.1 Progetto per una libreria nanziaria in C++ . . . . . . . . . 216 4.1.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . 216 4.1.2 Obiettivi della libreria . . . . . . . . . . . . . . . . . . 216 4.1.3 Avvertenze ed utilizzo delle presenti note . . . . . . . 217 4.1.4 Curva dei tassi . . . . . . . . . . . . . . . . . . . . . . 220 4.1.5 Anagraca bond . . . . . . . . . . . . . . . . . . . . . 227 4.1.6 Metodi per il pricing dei bond . . . . . . . . . . . . . 232 4.1.7 Anagraca e prezzi di azioni . . . . . . . . . . . . . . . 236 4.1.8 Processi stocastici e generazione di cammini . . . . . 244 4.1.9 Anagraca opzioni . . . . . . . . . . . . . . . . . . . . 263 4.1.10 Metodi per il pricing di opzioni . . . . . . . . . . . . . 269 4.1.11 Schema complessivo della libreria (limitatamente al pricing di opzioni su equity) . . . . . . . . . . . . . . . 278 4.1.12 Schema di usso per il pricing di unopzione scritta su di un sottostante azionario) . . . . . . . . . . . . . . . 280 4.2 Link in Excel di una libreria C++ . . . . . . . . . . . . . . . 283 4.2.1 le dll interface.cpp . . . . . . . . . . . . . . . . . . . 285 4.2.2 le module pricing.bas . . . . . . . . . . . . . . . . . . 287 5 Laboratorio ed esercitazioni pratiche 5.1 Esercizio 1 . . . . . . . . . . . . . . . 5.1.1 Introduzione . . . . . . . . . 5.1.2 Denizione del problema . . . 5.1.3 Discussione qualitativa . . . . 5.1.4 Obiettivi dellesercitazione . . 5.2 Esercizio 2 . . . . . . . . . . . . . . . 5.2.1 Introduzione . . . . . . . . . 5.2.2 Denizione del problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289 291 291 291 291 294 297 297 297

vi

INDICE 5.2.3 Alcune considerazioni . . . . . . . . . . . . . . . . . . 298 5.2.4 Obiettivi dellesercitazione . . . . . . . . . . . . . . . . 298 Esercizio 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300 5.3.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . 300 5.3.2 Denizione del problema . . . . . . . . . . . . . . . . . 300 5.3.3 Alcune considerazioni . . . . . . . . . . . . . . . . . . 301 5.3.4 Obiettivi dellesercitazione . . . . . . . . . . . . . . . . 301 Esercizio 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304 5.4.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . 304 5.4.2 Denizione dellopzione Counter Positive Performance304 5.4.3 Alcune considerazioni . . . . . . . . . . . . . . . . . . 305 5.4.4 Obiettivi dellesercitazione . . . . . . . . . . . . . . . . 305 Esercizio 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308 5.5.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . 308 5.5.2 Denizione del problema . . . . . . . . . . . . . . . . . 308 5.5.3 Alcune considerazioni . . . . . . . . . . . . . . . . . . 309 5.5.4 Obiettivi dellesercitazione . . . . . . . . . . . . . . . . 309

5.3

5.4

5.5

Introduzione
Le presenti note sono nate da una serie di lezioni tenute dal sottoscritto presso il: corso di Metodi Numerici - Sottomodulo II: Alberi binomiali e differenze nite - Master in metodologie e modelli per la nanza quantitativa. Universit di Milano (Dipartimento di Fisica); a sottomodulo di Metodi numerici e calcolo stocastico: esempi di applicazione del corso di Metodi Computazionali della Fisica. Universit a di Milano (Dipartimento di Fisica). sottomodulo di Programmazione ad oggetti in C++ del corso di Metodi Computazionali della Fisica. Universit di Milano (Dipartia mento di Fisica). Il materiale presentato comunque ben pi ampio di quanto sarebbe e u richiesto per un corso di metodi numerici applicati alla nanza ed inteso e a dare allo studente una visione globale ed esaustiva dei concetti base della nanza quantitativa e dei principali metodi numerici utilizzati al ne del pricing. Finalit a La nalit delle presenti note quella di dimostrare come alcuni metodi a e sviluppati allinterno della sica abbiano una vasta gamma di applicazioni anche in ambiti apparentemente lontani, quali la nanza. In particolare, le note si focalizzano proprio nellapplicazioni del calcolo stocastico e di alcuni metodi numerici al pricing di opzioni nanziarie esotiche 1 . Lo studio delle presenti note, insieme alla parte di laboratorio, consentir allo a studente di acquisire una buona conoscenza sia dei fondamenti della nanza quantitativa (funzionamento dei titoli derivati pi comunemente trattati sul u mercato, processi stocastici ecc.) sia dei principali metodi numerici utilizzati nella determinazione del prezzo dei derivati e sulla loro implementazione in una libreria nanziaria. Su questultimo punto verr posta particolare enfasi a
1 Uno degli algoritmi numerici su cui si concentrer la nostra attenzione, il metodo a Monte Carlo, largamente utilizzato ed applicato in ambito sico. e

INDICE

in quanto laspetto cruciale nellattivit di un quantitativo consiste spesso a nellimplementazione pratica di algoritmi e tecniche numeriche. Conoscenze necessarie Si presuppone, nei partecipanti, una conoscenza matematica adeguata ai temi trattati, nonch una conoscenza di base dei fondamenti della programe mazione ad oggetti, con particolare attenzione al C++. Struttura delle dispense Il presente volume si compone di cinque sezioni fondamentali: Un capitolo (sezione 1) dedicato ad introdurre i concetti fondamentali della programmazione ad oggetti in C++. Nella parte nale viene anche introdotto il concetto di Design patter, una tematica pi avanu zata nellambito della programmazione ad oggetti e dello sviluppo di software professionale. Tale capitolo pu essere letto in maniera independente dal resto delle o note o pu servire come base di partenza per comprendere lo sviluppo o della libreria descritta nella sezione 4. Una parte teorica (sezione 2) il cui scopo quello di introdurre i cone cetti teorici fondamentali della nanza (tassi di interesse, denizione di opzione, processi stocastici, formula di Black & Scholes, ecc.). Una parte teorica sul calcolo numerico (sezione 3), in cui verranno presentate a livello teorico le principali metodologie numeriche utilizzate nel campo della nanza per il calcolo del prezzo di opzione esotiche (metodo Monte Carlo, alberi binomiali e dierenze nite). Una parte applicativa (sezione 4) in cui viene discusso in dettagli la costruzione di una libreria nanziaria tramite un linguaggio di programmazione ad oggetti. Una sessione di laboratorio (sezione 5) dove vengono proposti diversi esempi ed esercitazioni pratiche al ne di testare su casi concreti quanto presentato nel punto precedente.

Bibliograa Alla ne delle note riportata una breve bibliograa (sia di articoli recene temente pubblicati su riviste, sia di libri di testo) che pu essere utilizzata o per approfondire gli argomenti trattati in queste note. In particolare un buon testo di approfondimento sulla nanza, con un deciso taglio economico/nanziario ed unottima descrizione degli stumenti nanziari principali il volume di Hull [7]. Un testo pi matematico e quantitativo lottimo e u e

INDICE

volume di Wilmott [8], disponibile anche in una versione pi introduttiu va [9]. Una presentazione delle tematiche riguardanti leconosica (ovvero lapplicazione di alcune tecniche e modelli della sica alleconomia) la si pu o trovare in [10].

INDICE

Capitolo 1

Elementi di programmazione ad oggetti

6 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

1.1

Introduzione alla programmazione ad oggetti

Il presente capitolo intende fornire una guida sintetica allapprendimento dei concetti base della programmazione ad oggetti in C++ con particolare riferimento ai problemi di carattere numerico. Conoscenze necessarie Si presuppone, nei partecipanti, una conoscenza matematica adeguata ai temi trattati. Struttura delle dispense La presente sezione si compone di tre capitoli fondamentali: Una parte introduttiva dedicata ai fondamenti del C++ (sezione 1.2), il cui scopo quello di denire i concetti base del C++: tipi variabili, e costrutti fondamentali (if, ciclo for ecc.), utilizzo di funzioni ecc. Una parte dedicata alla programmazione ad oggetti in senso compiuto. (sezione 1.3), in cui verranno presentate le idee alla base della programmazione ad oggetti, ovvero: a) incapsulamento e mascheramento; b) polimorsmo c) ereditariet. a Breve introduzione ai design patterns. Una parte pi applicativa, in cui viene proposto lo sviluppo di una libreu ria per la nanza, presentata nella sezione 4.1). e Bibliograa Alla ne delle note riportata una breve bibliograa di libri di testo sule largomento. In particolare si suggeriscono alcuni testi di riferimento: [1, 2], alcuni testi su argomenti avanzati: [3] e del materiale disponibile su web: [4, 5, 6].

1.2. IL CONTESTO - ELEMENTI BASE DEL C++

1.2

Il contesto - Elementi base del C++

In questo primo capitolo deniremo alcuni elementi base del linguaggio C++. In particolare: Introduzione alla programmazione procedurale e ad oggetti: dierenze e vantaggi. Elementi base del C/C++: tipi variabili fondamentali, condizioni, cicli for, gestione input/output, funzioni ecc. Compilatori e ambienti di compilazione per la gestione di progetti. Strutturazione di una libreria: nomenclatura dei lename e organizzazione dei le. Esempi di scrittura di semplici programmi in C++.

1.2.1

Programmazione procedurale e ad oggetti

Programmazione procedurale: un problema complesso scomposto in e una serie di task pi semplici, per ciascuno di questi viene scritta una u funzione in grado di risolverlo. Assemblando le varie funzioni, dedicate alla risuluzione dei task elementari, si ottiene la risoluzione del task complesso. Caratteristica di questo stile di programmazione il focus sulle procee dure/funzioni. Questo modo di procedere permette una certa riutilizzabilit del softa ware (anche se non paragonabile a quella permessa dalla programmazione ad oggetti). Infatti le singole funzioni, se ben progettate, possono essere utilizzate anche in altri contesti. Si pensi ad esempio ad una funzione per integrare numericamente una funzione reale di variabile reale, su un intervallo denito. Tale funzione pu trovare o applicazione in una miriade di contesti (ovvero di problemi) dierenti. Gli svantaggi della programmazione procedurale sono fondamentalmente i seguenti: (a) lutlizzatore di una funzione che risolve un task elementare, deve sapere quali parametri inviare alla funzione e quale e il loro signicato. In altri termini deve avere una conoscenza specica del funzionamento della funzione. (b) Nella programmazione procedurale le funzioni ed i dati (che vengono passati alle funzioni) sono logicamente e sicamente distinti, questo produce rischi ed errori (se ad es. viene passato un dato nel formato sbagliato ad una funzione). Ricordiamo che nella programmazione procedurale il focus sulle funzioni e non sui e dati.

8 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI (c) La programmazione procedurale non naturale, nel senso che e gli esseri umani tendono a strutturare il proprio ragionamento logico per classi di oggetti tra loro interagenti (vedi punto successivo) e non per strutture di task. Programmazione ad oggetti: il problema viene rappresentato tramite una visione ad oggetti. Ciascun elemento del mondo viene rappresentato da un oggetto. La soluzione del problema si ottiene in modo naturale, facendo interagire opportunamente gli oggetti del mondo. Cio che caratterizza la programmazione ad oggetti : e lincapsulamento di dati e funzioni in ununica classe il polimorsmo (overloading) lereditarieta I vantaggi oerti dalla programmazione ad oggetti sono speculari rispetto ai punti deboli della programmazione procedurale, ovvero: (a) nella programmazione ad oggetti, lutilizzatore di un oggetto non tenuto a sapere come loggetto stato implementato al proprio e e interno. Lutente interagisce con loggetto unicamente attraverso la sua interfaccia. (b) nella programmazione ad oggetti dati e funzioni vengono incapsulate in un unico costrutto, appunto loggetto. Questo impedisce di avere errori o funzionamenti imprevisti causati dal passare un dato errato ad una funzione. (c) la programmazione ad oggetti naturale, nel senso che riproduce e ed basata sullo stesso modo di strutturare il ragionamento degli e esseri umani. (d) come conseguenza dei punti elencati sopra, la programmazione ad oggetti produce del codice estremamente modulare e facilmente riutilizzabile. Questo un punto chiave nella creazione del softe ware. Infatti la riutilizzabilit del codice permette di: i) ridurre a i tempi di sviluppo ed i costi e ii) produrre del software pi siu curo (gli oggetti possono essere manipolati solo attraverso la loro interfaccia, questo riduce drasticamente la possibilit di uso non a consono del codice). Questa tecnica di programmazione stata sviluppata negli anni 80. I e principali linguaggi ad oggetti sono C++ e Java. Nei paragra successivi verranno deniti i concetti fondamentali della programmazione in C (quindi ancora una programmazione di tipo procedurale).

1.2. IL CONTESTO - ELEMENTI BASE DEL C++

1.2.2

Perch il C++ e

I vantaggio oerti dal C++ sono i seguenti: Supporta la programmazione ad oggetti. E compatibili (quasi al 100 Permette un controllo anche a basso livello della macchina (propriet a derivata dal C). Non un linguaggio interpretato (ovvero consente la creazione di un e codice binario per lesecuzione del programma). Va osservato che il C++ presenta alcuni svantaggi: Non vengono fatte veriche dal linguaggio sulleventuale sforamento dei vettori. Non possiede alcune caratteristiche avanzate di alcuni linguaggi ad oggetti (come ad esempio la capacit di introspezione da parte degli a oggetti). Il Java permette ad esempio di superare questi aspetti negativi. In questo senso un linguaggio pi potente, sicuro e moderno del C++. Consente e u anche una maggiore integrazione con il web ed pi facilmente portabile su e u piattaforme dierenti. Paga tutto questo con una minore velocit in fase di a esecuzione ed essendo fortemente astratto rispetto alla macchina sica, non consente alcune operazioni di basso livello che il C++ invece permette.

1.2.3

Tipi variabili fondamentali e concetti base

Terminatore di ne istruzione: ; Commenti: // int - numero intero oat - numero reale in singola precisione double - numero reale in doppia precisione char - carattere alfanumerico In C++ ogni variabile caratterizzata dalle seguenti propriet: e a nome: una stringa (identicatore) che referenzia la variabile in oggetto tipo: la tipologia a cui la variabile appartiene, ad es. int, oat, double ecc.

10 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI scopo: larea di codice allinterno della quale la variabile esiste (scopo di le, scopo di classe ecc.) indirizzo: lindirizzo di memoria dove la variabile allocata e dimensioni: lammontare di memoria (in byte) necessaria per immagazzinare la variabile in oggetto. Si noti che leettiva precisione (ovvero il numero di digit signicativi, ovvero la dimensione della memoria allocata) di un oat o di un double, dipende dalla particolare macchina, ovvero non ssato a priori dal linguaggio. e

1.2. IL CONTESTO - ELEMENTI BASE DEL C++ 1.2.3.a Programma desempio sullutilizzo di variabili

11

Nome le: main.cpp Contenuto: esempio di utilizzo di variabili fondamentali main.cpp


// ------------------ Begin esempio_1 --------------// // Tipi variabili fondamentali

int main(void) { int n ; n = 2 ; int m = 2 ; // n dichiarato // n valorizzato // m dichiarato ed inizializzato

double d = 10.5 ; char c = a ; }

// ------------------ End esempio_1 -----------------

Commenti (1) si noti il carattere di ne istruzione: ;

12 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

1.2.4

Input output

Le funzioni per la gestione dellinput/output sono in C++: cin e cout. Importante: includere sempre allinzio del le listruzione di include: #include < iostream >

1.2. IL CONTESTO - ELEMENTI BASE DEL C++ 1.2.4.a Programma desempio sullutilizzo di cin e cout

13

Nome le: main.cpp Contenuto: esempio di utilizzo delle funzioni cin e cout main.cpp
// ------------------ Begin esempio_2 --------------// // Input e output

#include <iostream> using namespace std; int main(void) { int n ; char str[80] ; // Stampa la frase come un printf() // cout << "Introdurre il numero di cui calcolare il fattoriale: " ; // Legge il valore e lo copia in n come scanf() // cin >> n; cout << "Introdurre una stringa: "; cin >> str; // Legge la stringa copiandola in str cout << "Il numero introdotto e: " << n << " mentre str = " << str << "\n"; }

// ------------------ End esempio_2 -----------------

Commenti (1) Con le funzioni di cin e cout si possono trattare allo stesso modo stringhe, int, double, senza mai preoccuparsi di specicare il tipo e il numero di caratteri da stampare (a dierenza di quanto accade con

14 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI scanf e printf). Loperatore in questo contesto rappresenta un operatore di output. Mentre in questo caso indica linput da tastiera. Da notare che in C++ e sempre possibile usare scanf() e printf(), le funzioni per la gestione dellinput/output native del C.

1.2. IL CONTESTO - ELEMENTI BASE DEL C++

15

1.2.5

Ciclo for

Il costrutto per eettuare un ciclo : for. Questo costrutto permette di e eseguire un certo numero di volte un blocco di istruzioni.

16 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI 1.2.5.a Programma desempio sullutilizzo del for

Nome le: main.cpp Contenuto: esempio di utilizzo di un ciclo for main.cpp


// ------------------ Begin esempio_3 --------------// // Ciclo for

#include <iostream> using namespace std; int main(void) {

// Lettura dati di input // int n ; char str[80] ; // Stampa la frase come un printf() // cout << "Introdurre il numero di cui calcolare il fattoriale: "; // Legge il valore e lo copia in n come scanf() // cin >> n;

cout << "\n"; cout << "Introdurre una stringa: "; cin >> str; // Legge la stringa copiandola in str cout << "\n"; cout << "Il numero introdotto e: " << n << " mentre str = " << str << "\n";

// Calcolo del fattoriale // int fattoriale ; fattoriale = 1 ;

1.2. IL CONTESTO - ELEMENTI BASE DEL C++

17

for(int i=0; i<n; i++) { fattoriale = fattoriale * (i+1) ; }

// Visualizzazione risultato // cout << "Il fattoriale di " << n << " e: " << fattoriale << "\n"; }

// ------------------ End esempio_3 -----------------

18 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

1.2.6

Costrutto while

Questo costrutto permette di ripetere un set di istruzioni no a quando una condizione non risulta vericata. La parola chiaver per utilizzare questo costrutto : while. e

1.2. IL CONTESTO - ELEMENTI BASE DEL C++ 1.2.6.a Programma desempio sullutilizzo del costrutto while

19

Nome le: main.cpp Contenuto: esempio di utilizzo del costrutto while main.cpp
// ------------------ Begin esempio_4 --------------// // Costrutto while

#include <iostream> using namespace std; int main(void) {

// Lettura dati di input // int n ; char str[80] ; // Stampa la frase come un printf() // cout << "Introdurre il numero di cui calcolare il fattoriale: "; // Legge il valore e lo copia in n come scanf() // cin >> n;

cout << "\n"; cout << "Introdurre una stringa: "; cin >> str; // Legge la stringa copiandola in str cout << "\n"; cout << "Il numero introdotto e: " << n << " mentre str = " << str << "\n";

// Calcolo del fattoriale // int i = 1 ; int fattoriale = 1 ;

20 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


while(i<=n) { fattoriale = fattoriale * i ; i ++ ; }

// Visualizzazione risultato // cout << "Il fattoriale di " << n << " e: " << fattoriale << "\n"; }

// ------------------ End esempio_4 -----------------

1.2. IL CONTESTO - ELEMENTI BASE DEL C++

21

1.2.7

Condizione if

Il costrutto per eseguire un set di istruzioni se una certa condizione risulta vericata : if. e La condizione if pu essere seguita da else. In tal modo possibile eso e eguire un certo blocco di istruzioni se (if) vericata una certa condizioni, e diversamente (else) viene eseguito un altro blocco di istruzioni.

22 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI 1.2.7.a Programma desempio sulluso di condizioni

Nome le: main.cpp Contenuto: esempio di utilizzo del costrutto if main.cpp


// ------------------ Begin esempio_5 --------------// // Utilizzo di if

#include <cstdlib> #include <iostream> using namespace std; int main(void) {

// Lettura dati di input // int n ; char str[80] ; // Stampa la frase come un printf() // cout << "Introdurre il numero di cui calcolare il fattoriale: "; // Legge il valore e lo copia in n come scanf() // cin >> n;

cout << "\n"; cout << "Introdurre una stringa: "; cin >> str; // Legge la stringa copiandola in str cout << "\n"; cout << "Il numero introdotto e: " << n << " mentre str = " << str << "\n";

// Controllo dati di input // if(n<0) { // Errore nellinput

1.2. IL CONTESTO - ELEMENTI BASE DEL C++


// cout << "input n deve essere >=0. n = " << n << "\n" ; exit(1) ; }

23

// Calcolo del fattoriale // int i = 1 ; int fattoriale = 1 ; while(i<=n) { fattoriale = fattoriale * i ; i ++ ; }

// Visualizzazione risultato // cout << "Il fattoriale di " << n << " e: " << fattoriale << "\n"; }

// ------------------ End esempio_5 -----------------

24 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

1.2.8

Denizione ed utilizzo di una funzione

Una funzione un insieme di istruzioni elementari, il cui scopo risolvere un e e certo task. Una funzione aratterizzata da un nome, dallinsieme (tipologia) c dei dati di input che necessita e dalloutput che restituisce. Il codice riportato sotto mostra lutilizzo di una funzione.

1.2. IL CONTESTO - ELEMENTI BASE DEL C++ 1.2.8.a Programma desempio sulluso di funzioni

25

Nome le: main.cpp Contenuto: esempio di utilizzo di una funzione main.cpp


// ------------------ Begin esempio_6 --------------// // Utilizzo di una funzione

#include <cstdlib> #include <iostream> using namespace std; int Calcolo_fattoriale(int n) ; int main(void) {

// Lettura dati di input // int n ; char str[80] ; // Stampa la frase come un printf() // cout << "Introdurre il numero di cui calcolare il fattoriale: "; // Legge il valore e lo copia in n come scanf() // cin >> n;

cout << "\n"; cout << "Introdurre una stringa: "; cin >> str; // Legge la stringa copiandola in str cout << "\n"; cout << "Il numero introdotto e: " << n << " mentre str = " << str << "\n";

// Controllo dati di input // if(n<0) {

26 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


// Errore nellinput // cout << "input n deve essere >=0. n = " << n << "\n" ; exit(1) ; }

// Visualizzazione risultato // cout << "Il fattoriale di " << n << " e: " << Calcolo_fattoriale(n) << "\n"; }

int Calcolo_fattoriale(int n) { // Calcolo del fattoriale // int fattoriale ; fattoriale = 1 ; for(int i=0; i<n; i++) { fattoriale = fattoriale * (i+1) ; } return fattoriale ; } // ------------------ End esempio_6 -----------------

Meglio in questi casi separare la funzione in un le distinto da quello che contiene il main.

1.2. IL CONTESTO - ELEMENTI BASE DEL C++ 1.2.8.b Programma desempio sulluso di funzioni II

27

Nome le: main.cpp, calcolo fattoriale.cpp e calcolo fattoriale.hpp Contenuto: esempio di utilizzo di una funzione main.cpp
// ------------------ Begin esempio_7 --------------// // Utilizzo di una funzione

#include <cstdlib> #include <iostream> #include "calcolo_fattoriale.hpp"

using namespace std; int main(void) {

// Lettura dati di input // int n ; char str[80] ; // Stampa la frase come un printf() // cout << "Introdurre il numero di cui calcolare il fattoriale: "; // Legge il valore e lo copia in n come scanf() // cin >> n;

cout << "\n"; cout << "Introdurre una stringa: "; cin >> str; // Legge la stringa copiandola in str cout << "\n"; cout << "Il numero introdotto e: " << n << " mentre str = " << str << "\n";

// Controllo dati di input //

28 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


if(n<0) { // Errore nellinput // cout << "input n deve essere >=0. n = " << n << "\n" ; exit(1) ; }

// Visualizzazione risultato // cout << "Il fattoriale di " << n << " e: " << Calcolo_fattoriale(n) << "\n"; }

// ------------------ End esempio_7 -----------------

calcolo fattoriale.cpp
// ------------------ Begin esempio_7 --------------// // Utilizzo di una funzione

int Calcolo_fattoriale(int n) { // Calcolo del fattoriale // int fattoriale ; fattoriale = 1 ; for(int i=0; i<n; i++) { fattoriale = fattoriale * (i+1) ; } return fattoriale ; } // ------------------ End esempio_7 -----------------

calcolo fattoriale.hpp
// ------------------ Begin esempio_7 ---------------

1.2. IL CONTESTO - ELEMENTI BASE DEL C++


// // Utilizzo di una funzione

29

#ifndef _CALCOLO_FATTORIALE_HPP #define _CALCOLO_FATTORIALE_HPP int Calcolo_fattoriale(int n) ;

#endif

// ------------------ End esempio_7 -----------------

30 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

1.2.9

Tipi derivati

I tipi derivati sono dei tipi ottenuti a partire dai tipi dati predeniti nel linguaggio, attraverso: (a) luso degli operatori: [] (vettori o array), * (pointer) e & (reference) (b) denendo delle strutture (struct) Sono tipi derivati ad esempio: i vettori o le matrici (ad es. double vect[10] o double matrix[10][10]); le stringhe (ad es. char name[10]); i puntatori a variabili (ad es. double *pointer) ; le strutture. I tipi derivati sono quindi ottenuti dai tipi primitivi tramite composizione. Un tipo primitivo non pu essere decomposto in tipi pi elementari. o u I tipi primitivi fondamentali sono stati illustrati nei preedenti paragra (ad. es. double, oat, int, char ecc. ecc.).

1.2. IL CONTESTO - ELEMENTI BASE DEL C++

31

1.2.10

Tipi derivati: i puntatori

Un tipo derivato in C++ molto interessante (e non presente in altri linguaggi come il fortran o il visual basic) dato dai puntatori. e

32 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI 1.2.10.a Programma desempio sullutilizzo dei puntatori

Nome le: main.cpp Contenuto: esempio di utilizzo di un puntatore main.cpp


// ------------------ Begin esempio_8 --------------// // Utilizzo di un puntatore

#include <iostream> using namespace std; int main(void) { // Lettura dati di input // double *pointer ; double a ; a = 10 ; pointer = &a ;

cout << "contenuto area di memoria indirizzata da pointer = " << *pointer << "\n" ; *pointer = 20 ;

// Visualizzazione risultato // cout << "contenuto area di memoria indirizzata da pointer = " << *pointer << "\n" ; cout << "contenuto di a = " << a << "\n" ; } // ------------------ End esempio_8 -----------------

1.2. IL CONTESTO - ELEMENTI BASE DEL C++ 1.2.10.b

33

Programma desempio sulluso dei puntatori nelle funzioni

Nome le: main.cpp Contenuto: esempio di utilizzo di un puntatore in una funzione main.cpp
// ------------------ Begin esempio_9 --------------// // Utilizzo di un puntatore in una funzione

#include <iostream> using namespace std;

int Calcola_perimetro_e_area_quadrato(double lato, double *perimetro, double *area) ; int main(void) {

double lato ; // Lettura dati di input // cout << "Introdurre il lato del quadrato: "; // Stampa la frase come un printf() cin >> lato;

double perimetro = 0 ; double area = 0 ; int stato ; stato = Calcola_perimetro_e_area_quadrato(lato, &perimetro, &area) ; if(stato == 0) { // Visualizzazione risultato // cout << "perimetro = " << perimetro << " area = " << area << "\n" ; } else { cout << "errore nellelaborazione \n" ; }

34 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

int Calcola_perimetro_e_area_quadrato(double lato, double *perimetro, double *area) { if(lato >=0 ) { *perimetro = 4 * lato ; *area = lato * lato ; return 0 ; } else { *perimetro = 0 ; *area = 0 ; return 1 ; }

} // ------------------ End esempio_9 -----------------

Commenti (1) Anche in questo caso pi pulito implementare la funzione in un le e u separato.

1.2. IL CONTESTO - ELEMENTI BASE DEL C++

35

1.2.11

Tipi derivati: i vettori

Un altro tipo derivato costituito dai vettori (array). Un array un insieme e e di dati dello stesso tipo, referenziato tramite un unico identicatore. Lesempio riportato di seguito chiarisce la denizione e lutilizzo degli array. Nellesempio sono riportate due modalit dierenti nella denizione dei a vettori: (1) Allocazione della memoria da parte del sistema operativo. Ad es. double vector[10] ; In questo caso la gestione della memoria viene demandata e gestita in automatico dal programma / sistema operativo. Se ad esempio la denizione del vettore avviene allinterno di una funzione, la memoria verr allocata al momento della denizione nello stack segment (vedi a paragrafo sulla gestione della memoria in C). La memoria verr poi a deallocata in automatico quando la variabile uscir di scopo (ad es. a quando si esce dalla funzione). Lutente non dovr quindi preoccuparsi di gestire lallocazione / deala locazione della memoria. La dimensione del vettore deve per essere nota in fase di compilazione. o (2) Allocazione dinamica della memoria tramite lutilizzo di un puntatore. Ad es. double * pointer ; pointer = new double[n] ; In questo caso la gestione della memoria viene demandata interamente allutente che responsabile dellallocazione della memoria tramite le operatore new e la successiva deallocazione tramite delete. La memoria necessaria ad immagazzinare il vettore viene rieservata allinterno dello heap (vedi paragrafo sulla gestione della memoria in C). Si noti invece come il pointer che contiene lindirizzo del vettore, essendo tipicamente una variabile denita allinterno di una funzione, trova la sua allocazione allinterno dello stak segment ed uscir di scopo (quindi a verr deallocata automaticamente dal sistema operativo) al termine a della funzione. Se lutente non dealloca la memoria prima che la variabile puntatore esca di scopo, tale memoria rimarr residente nella RAM senza pi a u poter essere deallocata.

36 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI 1.2.11.a Programma desempio sullutilizzo dei vettori

Nome le: main.cpp Contenuto: esempio di utilizzo di un vettore main.cpp


// ------------------ Begin esempio_10 --------------// // Utilizzo di un vettore // #include <iostream> using namespace std; int main(void) {

// Lettura dati di input // int n ; cout << "Introdurre la dimensione del vettore: "; // Stampa la frase come un printf() cin >> n;

double vector[n] ; for(int i=0; i<n; i++) { vector[i] = i ; }

// Allocazione dinamica della memoria // double *pointer_vector ; pointer_vector = new double[n] ; for(int i=0; i<n; i++) { pointer_vector[i] = 100+ i ; }

for(int i=0; i<n; i++) { cout << "contenuto di vector[i] = " << vector[i] "\n"

1.2. IL CONTESTO - ELEMENTI BASE DEL C++

37
;

cout << "contenuto di pointer_vector[i] = " << pointer_vector[i] << "\n" }

delete [] pointer_vector ; } // ------------------ End esempio_10 -----------------

Si noti che la dimensione dellarray deve essere unespressione costante (quindi ssata e nota gi in fase di compilazione). Non pu quindi essere una a o grandezza variabile denita in fase di run-time. Lallocazione di memoria viene eseguita dal compilatore prima dellesecuzione del programma.

38 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI Si consideri ora il seguente problema: si deniscano due vettori di uguale lunghezza e si costruisca una funzione che li scambi (ovvero che scambi gli elementi delluno con quelli dellaltro). 1.2.11.b Programma desempio sullo swap di due vettori

Nome le: main.cpp Contenuto: swap tra due vettori main.cpp


// ------------------ Begin esempio_11 --------------// // Swap tra due vettori //

#include <iostream> using namespace std; int main(void) {

// Lettura dati di input // int n ; cout << "Introdurre la dimensione del vettore: "; // Stampa la frase come un printf() cin >> n; double *pointer_vector_a ; double *pointer_vector_b ;

// Alloca vettori // pointer_vector_a = new double[n] ; pointer_vector_b = new double[n] ;

// Inizializza vettori // for(int i=0; i<n; i++) { pointer_vector_a[i] = 100.0 + i ;

1.2. IL CONTESTO - ELEMENTI BASE DEL C++


pointer_vector_b[i] = i ; }

39

// Stampa vettori // cout << "Stampa vettore \n" for(int i=0; i<n; i++) { cout << " contenuto di pointer_vector_a[i] = " << pointer_vector_a[i] << "\n" } cout << "Stampa vettore \n" for(int i=0; i<n; i++) { cout << " contenuto di pointer_vector_b[i] = " << pointer_vector_b[i] << "\n" }

// Scambia vettori // double *pointer_tmp ; pointer_tmp = pointer_vector_a ; pointer_vector_a = pointer_vector_b ; pointer_vector_b = pointer_tmp ;

// Stampa vettori // cout << "Stampa vettore \n" for(int i=0; i<n; i++) { cout << " contenuto di pointer_vector_a[i] = " << pointer_vector_a[i] << "\n" } cout << "Stampa vettore \n" for(int i=0; i<n; i++) { cout << " contenuto di pointer_vector_b[i] = " << pointer_vector_b[i] << "\n" }

// Cancella vettori // delete pointer_vector_a ; delete pointer_vector_b ; }

// ------------------ End esempio_11 -----------------

40 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI Commenti (1) Difetti del codice: il programma e stato scritto con un approccio top down in un blocco unico, senza spezzare il problema in parti pi u semplici. Si noti come alcune parti del codice siano ripetute (la parte relativa alla stampa del vettore ma anche la parte di inizializzazione, seppur in misura minore). Il codice appare a prima vista poco chiaro (nonostante lestrema semplicit del compito svolto dal programma) e a di scarsa leggibilit. Inoltre il codice non pu essere riutilizzato. Se in a o un altro contesto necessario stampare il contenuto del vettore sar e a necessario riscrivere completamente la parte relativa alla stampa.

1.2. IL CONTESTO - ELEMENTI BASE DEL C++

41

Una soluzione rispetto alle critiche dellesempio precedente consiste nellutilizzare la tecnica della programmazione procedurale. In tal caso il task complesso viene spezzato in una serie di task pi semplici (lettura della u dimensione dei vettori, inizializzazione dei vettori, stampa dei vettori ecc.). 1.2.11.c Programma desempio sullo swap di due vettori II

Nome le: main.cpp Contenuto: swap tra due vettori main.cpp


// ------------------ Begin esempio_12 --------------// // Swap tra due vettori // #include <iostream>

// Dichiarazione funzioni // int Inizializza_vettore(double *pointer_vector, int dim, double valore_iniziale) ; int Stampa_vettore(double *pointer_vector, int dim) ; int Leggi_intero(void) ;

using namespace std; int main(void) {

// Lettura dati di input // int n ; n = Leggi_intero() ;

double *pointer_vector_a ; double *pointer_vector_b ;

// Alloca vettori // pointer_vector_a = new double[n] ;

42 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


pointer_vector_b = new double[n] ;

// Inizializza vettori // Inizializza_vettore(pointer_vector_a, n, 100) ; Inizializza_vettore(pointer_vector_b, n, 0) ;

// Stampa vettori // Stampa_vettore(pointer_vector_a, n) ; Stampa_vettore(pointer_vector_b, n) ;

// Scambia vettori // double *pointer_tmp ; pointer_tmp = pointer_vector_a ; pointer_vector_a = pointer_vector_b ; pointer_vector_b = pointer_tmp ;

// Stampa vettori // Stampa_vettore(pointer_vector_a, n) ; Stampa_vettore(pointer_vector_b, n) ;

// Cancella vettori // delete pointer_vector_a ; delete pointer_vector_b ; }

int Leggi_intero(void) { int n ; cout << "Introdurre la dimensione del vettore: "; // Stampa la frase come un printf() cin >> n; return n ; } int Inizializza_vettore(double *pointer_vector, int dim, double valore_iniziale) {

1.2. IL CONTESTO - ELEMENTI BASE DEL C++

43

for(int i=0; i<dim; i++) { pointer_vector[i] = valore_iniziale + i ; } return 0 ; } int Stampa_vettore(double *pointer_vector, int dim) { cout << "Stampa vettore \n" ; for(int i=0; i<dim; i++) { cout << " contenuto di pointer_vector[i] = " << pointer_vector[i] << "\n" } return 0 ; }

// ------------------ End esempio_12 -----------------

Commenti (1) Difetti del codice: le funzioni sono separate dai dati. Come conseguenza la funzione non sa se il programmatore la chiamer nella maniera a corretta (ad es. se dim rappresenta eettivamente la corretta dimene sione del vettore o ancora se pointer vector stato correttamente allocato), rendendo il codice poco sicuro. Al solito, per questioni di chiarezza, bene enucleare limplemene tazione delle funzioni rispetto al le contenente il main.

44 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

1.2.12

Tipi derivati: le strutture

Le strutture sono un altro esempio di tipo derivato. Tramite le strutture il C consente di creare nuovi tipi a partire da tipi di variabili gi esistenti. In a sintesi una struttura non altro che un insieme di tipi gi deniti. e a Questo consente di estendere il linguaggio in modo da gestire situazioni nuove. Se ad esempio abbiamo necessit di denire una nuova struttura di a dati per arontare un certo problema, il linguaggio ci permette di farlo. Un esempio tipico potrebbe essere quello dei numeri complessi. Tipicamente i lunguaggi di programmazione classici non hanno tra i propri tipi di variabili il concetto di numero complesso. Il C tramite le strutture consente di creare un nuovo tipo variabile, dato da una coppia di numeri double, in grado di gestore / rappresentare un numero complesso.

1.2.12.a main.cpp

Programma: complex structure

Nome le: main.cpp Contenuto: main con manipolazione di alcuni numeri complessi complex.hpp Nome le: complex.hpp Contenuto: denizione della strutttura complex complex.cpp Nome le: complex.cpp Contenuto: implementazione delle funzioni per la manipolazione delle strutture di tipo complex. 1.2.12.b Commenti

Il difetto principale delle strutture sta nel fatto che queste consentono di assemblare / impacchettare solo dati, non possibile inserire nelle strutture e funzioni e/o operatori. Questa forte limitazione risulta particolaremente

1.2. IL CONTESTO - ELEMENTI BASE DEL C++

45

evidente nel caso si sia creata una struttura per rappresentare e manipolare numeri complessi. Una volta denita la struttura complex number, data dalla combinazione di due numeri di tipo double, sar possibile rapa presentare un numero complesso ma non sar possibile utilizzare i normali a operatori + / per eseguire le classiche operazioni aritmetiche su tali numeri. Lunica alternativa percorribile quella riportata nellesempio, in cui e cio si deniscono delle funzioni per gestire somme e prodotti di numeri e complesis. Appare per evidente nel main come luso di tali funzioni appaia o poco naturale e poco intuitivo. Risulta quindi evidente come le strutture non rappresentino una reale estensione dei tipi di un linguaggio, in quanto tale costrutto si limita puramente a denire insiemi di tipi senza per permettere una reale denizione o o ridenizione ad esempio degli operatori che agiscono su tali nuove variabili. Quello che invece si vorrebbe per una piena estensibilit di un linguaggio a sarebbe la possibilit di denire nuovi tipi variabili, denendo anche gli a operatori che operano su questi tipi. Questo esattamente quello che un e linguaggio ad oggetti permette di raggiungere. Vedremo successivamente come sar possibile ottenere una piena estensione a nella gestione dei numeri complessi tramite le classi del C++. Un altro esempio di utilizzo del concetto di struttura riportato di see guito. Con questo esempio vengono illustrati due punti: (1) Come sia possibile utilizzare / denire una struttura per trattare un polinomio. (2) Come sia possibile trattare le operazioni tra polinomi in unottica procedurale. Per entrambi i punti verranno discussi i principali difetti e limiti insiti in questa soluzione. 1.2.12.c main.cpp Nome le: main.cpp Contenuto: main con manipolazione di polinomi polinomio.hpp Nome le: polinomio.hpp Contenuto: denizione della strutttura polinomio Programma: polinomio structure

46 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI polinomio.cpp Nome le: polinomio.cpp Contenuto: implementazione delle funzioni per la manipolazione delle strutture di tipo polinomio. 1.2.12.d Commenti

I principali vantaggi di questa soluzione sono i seguenti: (1) La struttura permette di inglobare in un unico costrutto i due dati principali che caratterizzano il polinomio: (i) il suo grado (n) e (ii) il set di coecienti (rappresentato in C da un vettore di dimensione n + 1). In questo modo si ottiene un primo impacchettamento di dati in ununica struttura. Questo permette di passare pi facilmente i dati u alle funzioni, in maniera pi chiara, lineare e con minore rischi. u (2) La denizione delle funzioni: Prod polinomi, Sum polinomi ecc. tipiche di una programmazione procedurale, consente di utilizzare / riutilizzare facilmente queste funzioni allinterno del codice. I limiti di questa impostazione, che verranno superati dalla programmazione ad oggetti, sono: (1) La struttura Polinomio, bench consenta di inserire in un unico costrute to i dati che caratterizzano un polinomio, non permette di denire a tutti gli eetti un nuovo tipo di variabile. Non infatti possibile scrie vere: Polinomio a, b, c; c = a + b ; (2) Le funzioni per la manipolazione dei polinomi, sono separati dai dati. Se ad es. si cambia allinterno della struttura la modalit di gestione a dei dati sar necessario ridenire anche le funzioni, pena la generazione a di errori. Ad es. se si invertisse lordine dei coecienti, le funzioni somma e prodotto continuerebbero a funzionare correttamente ma non la funzione Print polinomio o una eventuale funzione che trovasse le radici dei polinomi di secondo grado, fornirebbe risultati errati. Poich e dati e funzioni sono separati, nulla garantisce che la coerenza tra questi due aspetti venga mantenuta da eventuali modiche future. In denitiva il punto debole di questo tipo di programmazione la e separazione tra dati e funzioni.

1.2. IL CONTESTO - ELEMENTI BASE DEL C++

47

(3) Lutilizzo della struttura e delle funzioni, richiede comunque una certa conoscenza delle modalit seguite per limplementazione. Lutente che a utilizzasse questa struttura dovrebbe ad esempio sapere con quale criterio vengono inseriti i coecienti del polinomio nel vettore allinterno della struttura (dal grado pi basso a quello pi alto? il contrario? u u una scelta diversa?). Questo rende luso della struttura pi dicile, u meno trasperente e potenzialmente pericoloso. In questo caso il punto debole la mancanza di mascheramento sulle e modalit implementative interne della struttura. a

48 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

1.2.13

Overloading

Loverloading di una funzione indica la possibilit di denire funzioni con lo a stesso nome ma argomenti diversi. Si veda lesempio riportato sotto: 1.2.13.a Programma: overloading di funzioni

Nome le: main.cpp Contenuto: overloading di funzioni main.cpp


// ------------------ Begin esempio_13 --------------// // Overloading di una funzione

#include <cstdlib> #include <iostream> int Max(int a, int b) ; double Max(double a, double b) ; using namespace std; int main(void) { int ia = 2 ; int ib = 3 ; double da = 10.2 ; double db = 20.3 ;

// Visualizzazione risultato // cout << "Il primo max e " << Max(ia, ib) << " il secondo max e "<< Max(da, db) << " \ }

int Max(int ia, int ib) { if(ia>ib) { return ia ; }

1.2. IL CONTESTO - ELEMENTI BASE DEL C++


else { return ib ; } } double Max(double da, double db) { if(da>db) { return da ; } else { return db ; } }

49

// ------------------ End esempio_13 -----------------

50 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

1.2.14

Compilazione

La creazione di un eseguibile in C++ avviene in 3 passaggi: 1) precompilazione (direttive precedute da # nei le .cpp) 2) compilazione dei le .cpp e creazione di un codice oggetto .o (uno per ciascun le cpp) g++.exe -c main.cpp -o main.o -Ipath le include 3) linking dei vari moduli oggetto in un eseguibile g++.exe main.o -o prova.exe -Lpath librerie -lmc la ag -l indica lutilizzo della libreria specicata di seguito, nellesempio la libreria libmc.a (come si sar notato, si omette nel nome della a libreria che segue il comando -l il presso lib ed il susso .a). Sono utili i software per la gestione visuale dei progetti. Ad esempio sotto windows un interessante programma freeware : dev-cpp for windows e (http://www.bloodshed.net/dev/). Tale ambiente permette in maniera molto semplice ed intuitiva di: 1) creare un progetto 2) precompilare e compilare i singoli moduli (le .cpp) 3) eettuare loperazione di linking in un eseguibile nale E buona norma separare limplementazione delle funzioni dal le contentente il main. In generale sarebbe utile separare limplementazione delle varie funzioni in diversi le, cercando di assegnare a ciascun le tutte le funzioni che sono fra loro imparentate.

1.2. IL CONTESTO - ELEMENTI BASE DEL C++

51

1.2.15

Gestione della memoria in C/C++

Gestione della memoria 1) Code Segment: larea di memoria dove risiede il codice dellapplie cazione. 2) Data Segment: questa area di memoria contiene le variabili globali o statiche denite nel codice. 3) stack: larea di memoria gestita in automatico dal compilatore. E in e questa area che vengono allocate la variabili locali denite nelle varia funzioni. E il sistema operativo che si preoccupa di gestire tale area di memoria, allocando e deallocando lo spazio necessario quando le variabili vengono denite o escono dal loro scopo (al termine ad es. di una funzione). 4) heap (detta anche free store): questa larea di memoria gestita e dinamicamente dallutente. Ad esempio e questa area dove viene n allocato lo spazio per gestire gli array dinamici.

52 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

1.3

Programmazione ad oggetti

Perch un linguaggio si possa denire ad oggetti, deve possedere le seguenti e propriet: a Incapsulamento e mascheramento Polimorsmo (overloading) Ereditarieta Lincapsulamento dei dati consiste nella possibilit di denire un costruta to unico (classe) in vengono incapsulati sia dati che funzioni. In questo modo si evita il problema presente nella programmazione procedurale in cui dati e funzioni viaggiano separatamente, con la conseguenza che non vi mai la e certezza che i dati inviati ad una funzione siano coerenti con essa. Il mascheramento riguarda il fatto che certi dati siano nascosti allutilizzatore della classe. Questo perch non vogliamo che lutente possa alterare tali e dati senza che la classe ne sia alloscuro. Tipicamente i dati (variabili) presenti in un oggetto sono sempre mascherati, questo per evitare manipolazioni incontrollate da parte dellutente. Verranno poi implementati nelloggetto dei metodi che consentono di accedere (o meno) ai dati ed eventualmente di modicarli (in maniera per controllata). o

1.3. PROGRAMMAZIONE AD OGGETTI

53

1.3.1

Denizione di una classe

Di seguito riportato a titolo di esempio la denizione di una classe in C++ e con cui si denisce il concetto di quadrato in un piano. Per implementare questa classe dobbiamo prima rispondere alle seguenti domande: Cosa caratterizza il concetto di quadrato? Quali sono le sue propriet fondamentali? a La risposta a queste domande : e il quadrato caratterizzato dallessere un poligono regolare di quattro e lati, quindi identici (pari ad l), con i quattro angoli interni pari a /2. Il concetto di lato verr sintetizzato tramite un dato di tipo double. a Insito nel concetto di lato vi poi il fatto che il numero che ne rappree senta la misura sia sempre maggiore o uguale a zero. Ovvero il double che rappresenter il lato dovr sempre essere positivo o al pi nullo. a a u Per langolo interno sar suciente denire una funzione che restitua isca /2. Altra carattieristica del quadrato quella di avere un perimetro (4l) e ed unarea (l2 ). Entrambe queste caratteristiche sono denite tramite una funzione (calcola perimetro e calcola area). Da questa analisi discende limplentazione riportata nel paragrafo successivo.

54 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI 1.3.1.a Programma desempio sulla denizione di una classe (vedi codice libreria 03.01.01)

Contenuto: esempio di denizione di una classe quadrato.hpp


// // Dichiarazione di una classe

#ifndef _QUADRATO_HPP #define _QUADRATO_HPP #define PI_GRECO 3.1415926 class Quadrato { private: double lato ; protected: public: // Costruttore // Quadrato(void) { lato = 0 ; };

// in line

Quadrato(double _lato) { Set_lato(_lato) ; } ; // Distruttore // ~Quadrato() ;

// in line

// Funzioni di input/output // double Get_lato(int indice_lato) { // in line // indice_lato compreso tra 0 e 3 // return lato ; } ;

1.3. PROGRAMMAZIONE AD OGGETTI


int Set_lato(double _lato) ; int Get_numero_lati(void) { return 4 ; } ; // in line

55

int Get_numero_angoli_interni(void) { return 4 ; } ;

// in line

int Get_angolo_interno(int indice_angolo) { // indice_angolo compreso tra 0 e 3 // return PI_GRECO/2 ; } ; double Get_area(void) { return lato * lato ; } ; // in line

// in line

double Get_perimetro(void) { return 4 * lato ; } ; } ; #endif

// in line

Commenti (1) La variabile lato stata dichiarata allinterno della sezione prie vate ed quindi accessibile solo allinterno della classe. Non pu e o essere modicata da un utente esterno (vedi esempio successivo). Tale propriet va sotto il nome di mascheramento dei dati. a (2) Linizializzazione ovvero la costruzione di un oggetto di tipo Quadrato avviene tramite il costruttore (nellesempio ne sono riportati due). (3) La deallocazione di un oggetto di tipo Quadrato avviene tramite il distruttore (ne pu essere denito solamente uno!). o (4) Vi sono poi due funzioni di input/output per gestire la modica di lato. Una funzione per ottenere gli angoli interni ed inne vi sono due funzioni che permettono di calcolare due propriet fondamentali a di questo oggetto: il perimetro e larea.

56 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI (5) Si noti come alcune funzioni siano implementate direttamente nella dichiarazione della classe. Questo signica che le funzioni sono di tipo in line. Linterfaccia della classe denita dallinsieme dei suoi metodi, quindi: e i due costruttori:

Quadrato(void) ; Quadrato(double lato_init) ; il distruttore:

~Quadrato() ; tre funzioni di input/output per il setting dei parametri:

int Set_lato(double lato_init) ; double Get_lato(int indice_lato) ; int Get_numero_lati(void) ; int Get_angolo_interno(int indice_angolo) ; int Get_numero_angoli_interni(void) ; due funzioni di calcolo:

double Get_area(void) ; double Get_perimetro(void) ; per un totale di otto metodi (vedi anche paragrafo successivo). Linsieme di questi metodi lunico punto di congiunzione / interazione tra e la classe ed il mondo. Questo implica che qualunque modica apportata allimplementazione di questi metodi, ovvero qualunque modica eseguita allinterno della classe che lasci inalterate le dichiarazioni dei metodi (ovvero dellinterfaccia) non comporter alcuna necessit di modica al codice che utilizza tale classe. a a quadrato.cpp Limplementazione delle funzioni presenti nella classe Quadrato eete tuata nel corrispondente le .cpp:

1.3. PROGRAMMAZIONE AD OGGETTI


// // Utilizzo di una funzione

57

#include <cstdlib> #include <iostream> #include "quadrato.hpp"

using namespace std;

// ----------> Class: Quadrato // ----------> Function name: ~Quadrato // ----------> Description: Distruttore di Quadrato // Quadrato::~Quadrato(void) { cout << "Distruggo loggetto di tipo Quadrato \n" ; }

// ----------> Class: Quadrato // ----------> Function name: Set_lato // ----------> Description: Setting del lato // int Quadrato::Set_lato(double _lato) { if(_lato>=0) { lato = _lato ; return 0 ; } else { cout << "Warning in Quadrato::Set_lato, _lato = " << _lato << " e negativo \n" ; cout << "Nessun setting effettuato \n" ; return 1 ; } }

main.cpp Un esempio di main che utilizza la classe : e


// ------------------ Begin esempio_14 --------------// // Utilizzo di una funzione

58 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

#include <cstdlib> #include <iostream> #include "quadrato.hpp"

using namespace std; int main(void) { double lato ; // Legge il valore e lo copia in n come scanf() // cout << "Inserire lato del quadrato \n" ; cin >> lato;

// Creo un oggetto (istanza) della classe Quadrato // Quadrato quadrato(lato) ;

// Visualizzazione risultato // cout << "Larea del quadrato di lato " << lato << " e: " << quadrato.Get_area() << "\n

quadrato.Set_lato(20.0) ;

// Visualizzazione risultato // cout << "Larea del quadrato di lato " << quadrato.Get_lato() << " e: " << quadrato.Ge }

// ------------------ End esempio_14 -----------------

Loutput ottenuto a video il seguente: e

Inserire lato del quadrato 10 Larea del quadrato di lato 10 e: 100 Larea del quadrato di lato 20 e: 400 Distruggo loggetto di tipo Quadrato

1.3. PROGRAMMAZIONE AD OGGETTI Commenti

59

(1) Il mascheramento dei dati in questo caso consiste nel fatto che la variabile lato (dichiarata private) contenuta in un oggetto di tipo Quadrato risulta inaccessibile dallesterno (ad es. dalla funzione main). Lunica maniera che lutente ha a disposizione per alterare il contenuto della variabile lato quella di utilizzare lopportuna funzione di e interfaccia Quadrato::Set lato. Anche la semplice interrogazione del contenuto di lato deve necessariamente passare attraverso lutilizzo dellaltra funzione di interfaccia Quadrato::Get lato. In altri termini la variabile Quadrato::lato risulta mascherata ovvero protetta contro le manipolazioni esterne dellutente ed visibile unicae mente allinterno (ovvero nello scopo) della classe Quadrato. Questo obiettivo stato realizzato grazie al fatto di aver dichiarato la variabile e lato allinterno del blocco private.

60 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

1.3.2

Interfaccia di una classe

Una classe contiene dati e funzioni (chiamati anche metodi o operazioni). Tipicamente i dati di una classe non sono mai accedibili dallesterno, ovvero vengono dichiarati privati o protetti. Come conseguenza, lunico modo possibile per interagire con un oggetto attraverso i suoi metodi, le sue opere azioni. Unoperazione, come tutte le funzioni, denita dal suo nome, da e quali variabili prende in ingresso e da quale risultato restituisce. Linsieme di tutte le operazioni/metodi di un oggetto ne denisce linterfaccia. Si pu quindi aermare che esternamente, lunica cosa di cui sappiamo di o un oggetto la sua interfaccia, la sola via che abbiamo per relazionarci e con loggetto stesso. Non sappiamo invece nulla di come linterfaccia sia implementata allinterno delloggetto, ovvero non sappiamo nulla di come loggetto sia costruito al proprio interno. Potrebbe accadere che due oggetti abbiano la stessa interfaccia, ma questa sia implementata in modi dierenti nei due oggetti. Questo signica che i due oggetti possono ricevere gli stessi messaggi dallesterno ma reagire in modi diversi. Il concetto di inferfaccia un punto cardine della programmazione ad e oggetti ed alla base della riutilizzabilit del codice tipico di questo stile di e a programmmazione. Poich un oggetto si relaziona con il mondo circostante e solo tramite la sua interfaccia, qualunque modica o miglioria alle sue procedure interne non impatter luso che ne viene fatto da parte di tutti i proa grammi che lo utilizzano. Sar anche possibile sostituire un oggetto con un a altro avente la stessa interfaccia ma dierente implementazione, senza dover modicare in alcun punto il codice generale che lo utilizza. Questo consente di rendere estremamente modulare la gestione dei programmi e delle librerie, permettendo una riutilizzabilit del codice ad un livello superiore rispetto a a quello ottenibile con lo stile procedurale.

1.3. PROGRAMMAZIONE AD OGGETTI

61

1.3.3

Ereditariet di classe a

Lereditariet di classe consente in C++ di ottenere una nuova classe a para tire da una classe pre-esistente, minimizzando cos la quantit di codice da a scrivere. Di seguito riportiamo un semplice esempio, al ne di mostrare la sintassi.

1.3.3.a

Esempio di base (vedi codice libreria 03.02.01)

main.cpp Nome le: main.cpp Contenuto: classe padre, classe derivata e main.
// ------------------ Begin esempio classe derivata --------------// //

#include <cstdlib> #include <iostream>

using namespace std;

class Classe_base { private: double x ; public: Classe_base(double _x) { cout << "Costruttore classe base \n" ; Set_x(_x) ; } ; ~Classe_base(void) { cout << "Distruttore classe base \n" ; } ; void Set_x(double _x) { x = _x ;

62 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


} ; double Get_x(void) { return x ; } ; void Print(void) { cout << "x = " << x << " \n" ; } ; } ;

class Classe_derivata { private: int y ; public: Classe_derivata(double _x, int _y) : Classe_base(_x) { cout << "Costruttore classe derivata \n" ; Set_y(_y) ; } ; ~Classe_derivata(void) { cout << "Distruttore classe derivata \n" ; } ; void Set_y(int _y) { y = _y ; } ; int Get_y(void) { return y ; } ; void Print(void) { Classe_base::Print() ; cout << "y = " << y << " \n" ; } ; } ;

int main(void) { Classe_derivata obj(10.0, 1) ;

1.3. PROGRAMMAZIONE AD OGGETTI


obj.Print() ; obj.Se_x(2.2) ; obj.Se_y(3) ; obj.Print() ;

63

Classe_derivata *pointer_obj ; pointer_obj = new Classe_derivata(20.0, 2) ; pointer_obj->Print() ; delete pointer_obj ; return 0 ; }

// ------------------ End esempio classe derivata -----------------

1.3.3.b

Ereditariet tra classi: un esempio avanzato a

Come esempio pi sosticato di ereditariet tra classi, consideriamo il probu a lema di rappresentare linsieme dei poligoni (non necessariamente regolari) e allinterno di questo insieme considerare poi i quadrati ed i tringoli. Da un punto di vista logico, il concetto di quadrato e di triangolo pu eso sere ottenuto a partire da quello di poligono, applicando alcune restrizioni (o richiedendo il soddisfacimento di alcune propriet aggiuntive). In particolare a si considerino le seguenti denizioni: Poligono: unarea racchiusa allinterno di una linea spezzata chiusa (tipicamente non intrecciata). Caratteristiche del poligono: possiede n lati ogni lato ha una lunghezza maggiore di zero possiede n angoli interni un angolo rappresentato da un valore compreso tra (0, ). e Quadrato: un poligono con alcune propriet aggiuntive. e a Caratteristiche del quadrato:

64 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI E un poligono Ha quattro lati I lati sono tutti uguali Gli angoli interni sono uguali e pari a /2. Triangolo isoscele: un poligono con alcune propriet aggiuntive. e a Caratteristiche del triangolo isoscele: E un poligono Ha tre lati Due lati sono uguali La programmazione ad oggetti consente di dare una rappresentazione fedele di questo mondo (formato da tre tipologie di elementi: i poligoni, i quadrati ed i triangoli isoscele), ottemperando a tre fondamentali requisiti: Il linguaggio deve consentire di minimizzare la quantit di codice neca essario per descrivere le singole tipologie di oggetti. In altri termini laggiunta di una nuova tipologia di oggetti appartenente al mondo, deve avvenire nella maniera pi rapida, semplice e parsimoniosa u possibile. (Riutilizzabilit del codice). a La denizione di un tipo oggetto evoluto (ad es. un quadrato) andrebbe eettuata in termini di un oggetto pi elementare (un generu ico poligono), consentendo una maggiore purezza e semplicit logica. a (Chiarezza nel codice). La scrittura di codice per la manipolazione ad es. di poligoni non dovrebbe risentire dellaggiunta di una nuova particolare tipologia di poligoni. Ovvero il codice deve risultare perfettamente modulare. (Uso del polimorsmo). La soluzione resa disponibile dalla programmazione ad oggetti quella e dellereditariet di classe. a In particolare di seguito riportato un esempio di implementazione per e il mondo dei poligoni. 1.3.3.c Programma: poligoni, quadrati e triangoli (vedi codice libreria 03.02.02)

main.cpp

1.3. PROGRAMMAZIONE AD OGGETTI Nome le: main.cpp

65

Contenuto: main per la manipolazione di poligoni, quadrati e triangoli isosceli.


// // Esempio di derivazione tra classi e polimorfismo

#include <cstdlib> #include <iostream> #include "figura_triangolo_isoscele.hpp" #include "figura_quadrato.hpp" #include "funzione_stampa_perimetro_e_area.hpp" #include "funzione_leggi_da_tastiera.hpp"

using namespace std;

int main(void) { double lato ; Figura_poligono *poligono ; // Lettura dati di input // Leggi_da_tastiera(&lato) ;

// Creo un quadrato ed un triangolo // Figura_quadrato quadrato(lato) ; Figura_triangolo_isoscele triangolo_isoscele(lato) ; Stampa_perimetro_e_area(&quadrato) ; Stampa_perimetro_e_area(&triangolo_isoscele) ;

funzione stampa perimetro e area.hpp Nome le: funzione stampa perimetro e area.hpp

66 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI Contenuto: Dichiarazione funzione per la stampa del perimetro/area di un poligono.
// ------------------ Begin esempio --------------// //

#ifndef FUNZIONE_STAMPA_PERIMETRO_E_AREA_HPP #define FUNZIONE_STAMPA_PERIMETRO_E_AREA_HPP int Stampa_perimetro_e_area(Figura_poligono *poligono) ; #endif

// ------------------ End esempio -----------------

funzione stampa perimetro e area.cpp Nome le: funzione stampa perimetro e area.cpp Contenuto: Implementazione funzione per la stampa del perimetro/area di un poligono.
// ------------------ Begin esempio --------------// // Utilizzo di una funzione

#include <cstdlib> #include <iostream> #include "figura_poligono.hpp"

using namespace std;

int Stampa_perimetro_e_area(Figura_poligono *poligono) { if(poligono != NULL) { // Visualizzazione risultato // cout << "poligono di " << poligono->Get_numero_lati() << " lati \n" ; cout << " Area = " << poligono->Get_area() << " \n" ; cout << " perimetro = " << poligono->Get_perimetro() << " \n" ;

1.3. PROGRAMMAZIONE AD OGGETTI


return 0 ; } else { return 1 ; } }

67

// ------------------ End esempio -----------------

gura poligono.hpp Nome le: gura poligono.hpp Contenuto: denizione della classe Poligono
// // Dichiarazione di una classe

#ifndef _FIGURA_POLIGONO_HPP #define _FIGURA_POLIGONO_HPP

#include <cstdlib> #include <iostream> #define PI_GRECO 3.1415926 using namespace std;

class Figura_poligono { private: int numero_lati ; double *lati ; double *angoli_interni ;

protected: int Allocazione_iniziale(int _numero_lati) ; // costruttore con solo allocazione della memoria

68 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


// Figura_poligono(int _numero_lati) { Allocazione_iniziale(_numero_lati) ; } ; public: // Costruttori // // costruttore di default // Figura_poligono(void) { // in line Allocazione_iniziale(0) ; }; // costruttore generico // Figura_poligono(int _numero_lati, double *_lati, double *_angoli_interni) { Allocazione_iniziale(_numero_lati) ; for(int i=0; i<_numero_lati; i++) { Set_lato(i, _lati[i]) ; Set_angolo_interno(i, _angoli_interni[i]) ; } } ; // costruttore di un poligono regolare // Figura_poligono(int _numero_lati, double _lato) { Allocazione_iniziale(_numero_lati) ; for(int i=0; i<_numero_lati; i++) { Set_lato(i, _lato) ; Set_angolo_interno(i, PI_GRECO*(double(numero_lati)-2.0)/double(numero_lati)) } } ; // Distruttore // ~Figura_poligono(void) { cout << "Distruggo loggetto di tipo Figura_poligono \n" ; delete lati ; delete angoli_interni ; } ; // Funzioni di input/output // double Get_lato(int indice_lato) {

// in line

1.3. PROGRAMMAZIONE AD OGGETTI


// indice_lato compreso tra 0 e numero_lati // if(indice_lato >=0 && indice_lato <numero_lati) { return lato[indice_lato] ; } else { return 0 ; } } ; double Get_angolo_interno(int indice_angolo) { // in line // indice_lato compreso tra 0 e numero_lati // if(indice_angolo >=0 && indice_angolo <numero_lati) { return angoli_interni[indice_angolo] ; } else { return 0 ; } } ; double Get_numero_lati(void) { return numero_lati ; } ; // in line

69

int Set_lato(int indice_lato, double lato_singolo) ; int Set_angolo_interno(int indice_angolo, double angolo_interno) ;

// Funzioni di calcolo // virtual double Get_area(void) = 0 ; virtual double Get_perimetro(void) { double perimetro = 0 ; for(int i=0; i<_numero_lati; i++) { perimetro = perimetro + Get_lato(i) ; } return perimetro ; }; } ; #endif

70 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI gura poligono.cpp Nome le: gura poligono.cpp Contenuto: implementazione delle funzioni per la classe Poligono
// // Utilizzo di una funzione

#include <cstdlib> #include <iostream> #include "figura_poligono.hpp"

using namespace std;

// ----------> Class: Figura_poligono // ----------> Function name: Allocazione_iniziale // ----------> Description: Setting del numero di lati e della memoria // int Figura_poligono::Allocazione_iniziale(int _numero_lati) { if(_numero_lati >0) { numero_lati = _numero_lati ; lati = new double[numero_lati] ; angoli_interni = new double[numero_lati] ; for(int i=0; i<numero_lati; i++) { lati[i] = 0 ; angoli_interni[i] = 0 ; } return 0 ; } else { numero_lati = 0 ; lati = NULL ; angoli_interni = NULL ; return 1 ; }

1.3. PROGRAMMAZIONE AD OGGETTI


}

71

// ----------> Class: Figura_poligono // ----------> Function name: Set_lato // ----------> Description: Setting del lato // int Figura_poligono::Set_lato(int indice_lato, double lato_singolo) { if(indice_lato>=0 && indice_lato <Get_numero_lati()) { if(lato_singolo > 0) { lati[indice_lato] = lato_singolo ; return 0 ; } else { return 1 ; } } else { return 1 ; } }

// ----------> Class: Figura_poligono // ----------> Function name: Set_angolo_interno // ----------> Description: Setting dellangolo interno // int Figura_poligono::Set_angolo_interno(int indice_angolo, double angolo_interno) { if(indice_angolo>=0 && indice_angolo <Get_numero_lati()) { if(angolo_interno > 0) { angoli_interni[indice_angolo] = angolo_interno ; return 0 ; } else { return 1 ; } } else { return 1 ; } }

gura quadrato.hpp

72 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI Nome le: gura quadrato.hpp Contenuto: denizione della classe Quadrato
// // Dichiarazione di una classe

#ifndef _FIGURA_QUADRATO_HPP #define _FIGURA_QUADRATO_HPP

#include <cstdlib> #include <iostream> #include "figura_poligono.hpp"

using namespace std;

class Figura_quadrato : public Figura_poligono { private: protected: public: // Costruttore // Figura_quadrato(double _lato) : Figura_poligono(4) { for(int i=0; i<Get_numero_lati(); i++) { Set_lato(i, _lato) ; // lati uguali Set_angolo(i, PI/2) ; // angoli uguali } } ;

// 4 lati

// Distruttore // virtual ~Figura_quadrato(void) { cout << "Distruggo loggetto di tipo Figura_quadrato \n" ; } ; // Funzioni di input/output specifici delloggetto // double Get_lato(void) { // in line return Get_lato(0) ; } ;

1.3. PROGRAMMAZIONE AD OGGETTI

73

// Funzioni di calcolo // virtual double Get_area(void) { // in line return Get_lato() * Get_lato() ; } ; } ; #endif

gura triangolo isoscele.hpp Nome le: gura triangolo isoscele.hpp Contenuto: denizione della classe Triangolo
// // Dichiarazione di una classe

#ifndef _FIGURA_TRIANGOLO_ISOSCELE_HPP #define _FIGURA_TRIANGOLO_ISOSCELE_HPP

#include <cstdlib> #include <iostream> #include <math.h> #include "figura_poligono.hpp"

using namespace std;

class Figura_triangolo_isoscele : public Figura_poligono { private: protected: public: // Costruttore // Figura_triangolo_isoscele(void) : Figura_poligono() {

// in line

74 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


}; Figura_triangolo_isoscele(double _lato_base, double _lato_uguale, double _angolo_unico) : Figura_poligono(3) { Set_lato(0, _lato_base) ; // lato alla base Set_lato(1, _lato_uguale) ; // lati uguali Set_lato(2, _lato_uguale) ; // lati uguali Set_angolo(0, (PI-_angolo_unico)/2) ; // angoli uguali alla base Set_angolo(1, (PI-_angolo_unico)/2) ; // angoli uguali alla base Set_angolo(2, _angolo_unico) ; // angolo diverso al vertice } ; // Distruttore // virtual ~Figura_triangolo_isoscele(void) { cout << "Distruggo loggetto di tipo Figura_triangolo_isoscele \n" ; } ;

// in line

// Funzioni di calcolo specifiche della classe // double Get_altezza(void) { // in line return sqrt( Get_lato_uguale()*Get_lato_uguale() - Get_base() * Get_base() / 4.0 ) } ;

// Funzioni di calcolo // virtual double Get_area(void) { // in line return Get_base() * Get_altezza() / 2.0 ; } ;

} ; #endif

1.3.3.d

Commenti

I principali vantaggi di questa soluzione sono i seguenti: (1) La classe padre (Poligono), una classe generale per implementare il e concetto di poligono. Si noti come tutte le propriet elencate per il a

1.3. PROGRAMMAZIONE AD OGGETTI

75

concetto matematico di poligono trovano una corrispondenza precisa allinterno della classe. (2) Le classi glie (Quadrato e Triangolo isoscele), sono derivate dalla classe Poligono. Il codice necessario a descriverle ristretto al minimo e ed implementa unicamente le propriet aggiuntive che caratterizzano a i quadrati o i triangoli isosceli allinterno della famiglia generale dei poligoni. (3) La classe padre (Poligono) stata resa virtuale pura, questo perch le e e funzioni:

double Get_area(void) ; double Get_perimetro(void) ; sono dichiarate virtuali. Questo consente di scrivere del codice (il main nellesempio riportato sopra) in grado di trattare qualunque oggetto del mondo dei poligoni senza preoccuparsi della sua implementazione interna o della sua tipologia (polimorsmo evoluto). Laggiunta di una nuova tipologia di oggetto (ad es. i rettangoli o i pentagoni regolari), non necessit di modicare il codice della funzione: a int Stampa_caratteristiche_poligono(Poligono * oggetto_poligono) ; Questo consente una vera e piena riutilizzabilit del codice. a Un secondo esempio di utilizzo dellereditariet per creare una nuova a classe a partire da una esistente il seguente: e Polinomio di primo grado: un polinomio della forma a + b x. Caratteristiche di un polinomio di primo grado: il coeciente del termine di grado zero (a). il coeciente del termine di grado uno (b). possedere una radice (x = a/b). Polinomio di secondo grado: un polinomio della forma a + b x + c x2 . Caratteristiche di un polinomio di secondo grado: il coeciente del termine di grado zero (a). il coeciente del termine di grado uno (b). il coeciente del termine di grado due (c).

76 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI possedere due radici. In questo caso le tipologie di oggetti del mondo sono due: (a) i polinomi di primo grado e (b) i polinomi di secondo grado. Ovviamente possibile denire due classi indipendenti che caratterizzano e le due tipologie di oggetti. Risulta per pi vantaggioso, sia in termini o u di chiarezza logica sia in termini di economicit nella struttura del codice, a utilizzare la derivazione tra classi. 1.3.3.e Programma: Polinomi di primo e secondo grado tramite ereditariet (vedi codice libreria 03.02.03) a

main.cpp Nome le: main.cpp Contenuto: main per la manipolazione di polinomi di primo e secondo grado.
#include <cstdlib> #include <iostream> #include "polinomio_primo_grado.hpp" #include "polinomio_secondo_grado.hpp" using namespace std; int main(int argc, char *argv[]) { double root_1_grado ; // Costruzione polinomio primo grado // Polinomio_primo_grado p_1_grado(1, 1) ; // Costruzione polinomio primo grado // Polinomio_secondo_grado p_2_grado(1, 1, 2) ;

// Stampa delle info // p_1_grado.Print() ; p_2_grado.Print() ;

1.3. PROGRAMMAZIONE AD OGGETTI


p_1_grado.Get_root(0, root_1_grado) ; cout << "radice polinomio 1 grado " << root_1_grado << " \n" ;

77

return 0 ; }

polinomio primo grado.hpp Nome le: polinomio primo grado.hpp Contenuto: denizione della classe Polinomio primo grado
#ifndef _POLINOMIO_PRIMO_GRADO_HPP #define _POLINOMIO_PRIMO_GRADO_HPP #include <iostream>

using namespace std;

class Polinomio_primo_grado { private: // polinomio = coeff_grado_zero + coeff_grado_uno * x // double coeff_grado_zero ; double coeff_grado_uno ; public:

Polinomio_primo_grado(void) : Punto() { Set_coeff_grado_zero(0) ; Set_coeff_grado_uno(0) ; } ; Polinomio_primo_grado(double _coeff_grado_zero, double _coeff_grado_uno) { Set_coeff_grado_zero(_coeff_grado_zero) ; Set_coeff_grado_uno(_coeff_grado_uno) ; } ; // Lo studente e chiamato ad implementare il costruttore di // copia. // Polinomio_primo_grado( const Polinomio_primo_grado& c ) ;

78 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

~Polinomio_primo_grado(void) { cout << "invoco il distruttore di polinomio di 1 grado << "\n"; } ; int Set_coeff_grado_zero(double _coeff_grado_zero) { coeff_grado_zero = _coeff_grado_zero ; return 0 ; } ; int Set_coeff_grado_uno(double _coeff_grado_uno) { coeff_grado_uno = _coeff_grado_uno ; return 0 ; } ; double Get_coeff_grado_zero(void) ; double Get_coeff_grado_uno(void) ; virtual void Print(void) ; // Fornisce le radici del polinomio di // primo grado (ovvero una sola radice!). // In questo caso root_counter potra // assumere solo il valore 0 (corrispondente // alla prima ed unica radice del polinomio // di primo grado). // Il risultato sara inserito nella variabile // root (passata tramite reference). // virtual int Get_root(int root_counter, double &root) ; } ; #endif

polinomio secondo grado.hpp Nome le: polinomio secondo grado.hpp Contenuto: denizione della classe Polinomio secondo grado
#ifndef _POLINOMIO_SECONDO_GRADO_HPP

1.3. PROGRAMMAZIONE AD OGGETTI


#define _POLINOMIO_SECONDO_GRADO_HPP #include <iostream>

79

using namespace std; #include "polinomio_primo_grado.hpp" class Polinomio_secondo_grado : Polinomio_primo_grado { private: // polinomio = coeff_grado_zero + coeff_grado_uno * x + // + coeff_grado_due * x^2 // double coeff_grado_due ; public:

Polinomio_secondo_grado(void) : Polinomio_primo_grado() { Set_coeff_grado_due(0) ; } ; Polinomio_secondo_grado( double _coeff_grado_zero, double _coeff_grado_uno, double _coeff_grado_due ) : Polinomio_primo_grado(_coeff_grado_zero, _coeff_grado_uno) { Set_coeff_grado_due(_coeff_grado_due) ; } ; // Lo studente e chiamato ad implementare il costruttore di // copia. // Polinomio_secondo_grado( const Polinomio_secondo_grado& obj ) ;

~Polinomio_secondo_grado(void) { cout << "invoco il distruttore di polinomio di 2 grado << "\n"; } ; int Set_coeff_grado_due(double _coeff_grado_due) ; double Get_coeff_grado_due(void) ; virtual void Print(void) ;

80 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


// Fornisce le radici del polinomio di // secondo grado (ovvero due soli radici!). // In questo caso root_counter potra // assumere solo i valori 0 e 1 (corrispondente // alla prima e seconda radice del polinomio // di secondo grado). // Il risultato sara inserito nella variabile // root (passata tramite reference). // virtual int Get_root(int root_counter, double &root) ; } ; #endif

Un terzo esempio di utilizzo dellereditariet per creare una nuova classe a a partire da un classe gi esistente, il seguente: a e Punto in un piano: un punto in un piano cartesiano rappresentato e tramite due coordinate (x, y). Caratteristiche del punto:

avere due coordinate che lo identichino nel piano Cerchio: una gura geometrica nel piano caratterizzata dallinsieme e dei punti equidistanti rispetto ad un punto dato. Caratteristiche del cerchio: E caratterizzato da un centro (un punto nel piano). E denito da un raggio. Le dimensioni del raggio sono positive. In questo caso gli oggetti del mondo sono due: (a) il punto e (b) il cerchio. Ovviamente possibile denire due classi indipendenti che caratterizzano e le due tipologie di oggetti. Risulta per pi vantaggioso sia in termini di o u chiarezza logica sia in termini di economicit nella struttura del codice, a utilizzare la derivazione tra classi.

1.3. PROGRAMMAZIONE AD OGGETTI 1.3.3.f

81

Programma: classe cerchio tramite lereditariet (vedi codice a libreria 03.02.04)

main.cpp Nome le: main.cpp Contenuto: main per la manipolazione di cerchi


#include <cstdlib> #include <iostream> #include "punto.hpp" #include "cerchio_per_derivaz.hpp" using namespace std; int main(int argc, char *argv[]) { // ********************************************************* // ** Costruzione oggetti ** // ********************************************************* Punto p(-1,-1) ;

// // // //

********************************************************* ** Costruzione di un cerchio tramite ** ** lereditarieta di classe ** *********************************************************

// Costruzione di un cerchio tramite // lereditarieta di classe. // Si crea un cerchio di raggio 5 con centro in (1,1) // Cerchio_per_derivaz cerchio_1(5,1,1) ;

// ********************************************************* // ** Stampa delle info del cerchio ** // ********************************************************* cerchio_1.Print() ;

82 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


// ********************************************************* // ** Cambio del centro del cerchio ** // ********************************************************* // Cambio il centro di cerchio_1. // Posso usare direttamente Set_coordinate // cerchio_1.Set_coordinate(-2,-2) ;

// ********************************************************* // ** Stampa delle info del cerchio ** // ********************************************************* cerchio_1.Print() ;

// ********************************************************* // ** End program ** // ********************************************************* return 0 ; }

punto.hpp Nome le: punto.hpp Contenuto: denizione della classe Punto


#ifndef _PUNTO_HPP #define _PUNTO_HPP #include <iostream>

using namespace std;

class Punto { private: double x ; double y ; public:

1.3. PROGRAMMAZIONE AD OGGETTI

83

Punto(void) { x = 0 ; y = 0 ; } ; Punto(double _x, double _y) { Set_coordinate(_x, _y) ; } ; Punto::Punto( const Punto& c ) { x = c.x; y = c.y; } ;

~Punto(void) { cout << "invoco il distruttore " << "\n"; } ;

int Set_coordinate(double _x, double _y) { x = _x ; y = _y ; return 0 ; } ;

void Print(void) { cout << "punto = [" << x << "," << y << "] \n"; } ; } ; #endif

cerchio tramite ereditarieta.hpp

Nome le: cerchio tramite ereditarieta.hpp Contenuto: denizione della classe Cerchio tramite ereditarieta

84 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI 1.3.3.g Commenti

Di seguito alcuni commenti: (1) Nellesempio sulluso dellereditariet riguardante i poligono, avevamo a due insiemi: (a) i poligono e (b) i quadrati. Lereditarie permetteva a di denire i quadrati partendo dai poligono, ovvero applicava una restrizione allinsieme pi generale per ottenere un insieme pi ristretto. u u Nellesempio riguardante i polinomi di primo e secondo grado, avevamo due insiemi: (a) i polinomi di primo grado e (b) i polinomi di secondo grado. Lereditariet permetteva di denire i polinomi di secondo graa do partendo da quelli di primo grado, ovvero applicava una estensione allinsieme pi ristretto per ottenere un insieme pi generale. u u Nellesempio corrente sui cerchi, abbiamo due insiemi: (a) i punti e (b) i cerchi. Lereditariet permette di denire i cerchi a partire dai a punti. In questo caso i due insiemi non sono in un rapporto di inclusione luno rispetto allaltro (a meno di non vedere i punti come casi particolari di cerchi di raggio nullo). Questo per osservare come lereditariet sia estremamente versatile a nelluso.

1.3. PROGRAMMAZIONE AD OGGETTI

85

1.3.4

Composizione di oggetti vs ereditariet a

Vi sono sostanzialmente due modi per estendere e denire nuovi oggetti a partire da oggetti gi esistenti: a (1) Tramite lereditariet tra classi. a (2) Tramite la composizione di oggetti in una nuova classe. Modi ed esempi relativi alla prima metodologia sono stati dati nei paragra precedenti. Occupiamoci ora della tecnica di composizione. La composizione una modalit estremamente intuitiva: una nuova classe e a ottenuta includendo come membri altri oggetti. In tal modo certi compiti e che la nostra classe chiamata a svolgere possono essere delegati ad alcuni e oggetti da essa inclusi, o certe azioni complesse possono essere ottenute coordinando opportunamente gli oggetti in questione. La tecnica di composizione molto intuitiva in quanto prassi corrente in e e qualunque attivit umana, quella di assemblare insieme oggetti semplici per a ottenere un oggetto pi complesso. u Come esempio di composizione riprendiamo il caso del punto e del cerchio, cercando di denire una classe cerchio partendo dalla classe punto, senza ricorrere allereditariet come fatto precedentemente. a 1.3.4.a Programma: classe cerchio tramite composizione (vedi codice libreria 03.03.01)

main.cpp Nome le: main.cpp Contenuto: main per la manipolazione di cerchi


#include <cstdlib> #include <iostream> #include #include #include #include "../Esempio_classe_cerchio/punto.hpp" "../Esempio_classe_cerchio/cerchio_per_ereditarieta.hpp" "cerchio_per_composizione_tramite_aggregazione.hpp" "cerchio_per_composizione_tramite_cognizione.hpp"

using namespace std; int main(int argc, char *argv[]) { // *********************************************************

86 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


// ** Costruzione oggetti ** // ********************************************************* // Costruzione di un punto // Punto p(-1,-1) ; // Costruzione di un cerchio tramite lereditarieta di classe // cerchio di raggio 5 con centro in (1,1) // Cerchio_per_ereditarieta cerchio_1(5,1,1) ;

// // // // //

********************************************************* ** Costruzione di cerchi tramite la composizione di ** ** oggetti: nello specifico un double (raggio) ed un ** ** punto. ** *********************************************************

// cerchio di raggio 5 con centro in (0,0) // il cerchio in questo caso e responsabile // del punto che contiene. // Cerchio_per_composizione_tramite_aggregazione cerchio_2(5,0,0) ;

// cerchio di raggio 5 con centro in p // Cerchio_per_composizione_tramite_cognizione cerchio_3(5, &p) ;

// cerchio di raggio 10 con centro in p // Cerchio_per_composizione_tramite_cognizione cerchio_4(10, &p) ;

// ********************************************************* // ** Stampa delle info sui vari oggetti ** // ********************************************************* cerchio_1.Print() ; cerchio_2.Print() ; cerchio_3.Print() ; cerchio_4.Print() ;

1.3. PROGRAMMAZIONE AD OGGETTI

87

// ********************************************************* // ** Cambio dei centri dei cerchi ** // ********************************************************* // Cambia solo il centro di cerchio_1. // Posso usare direttamente Set_coordinate // cerchio_1.Set_coordinate(-2,-2) ;

// Cambia solo il centro di cerchio_2. // Il cambio del centro passa attraverso la // delegare alloggetto interno di tipo Punto // cerchio_2.Get_centro().Set_coordinate(3,3) ;

// Cambia anche il centro di cerchio_4 // cerchio_3.Get_centro()->Set_coordinate(2,2) ;

// ********************************************************* // ** Stampa delle info sui vari oggetti ** // ********************************************************* cerchio_1.Print() ; cerchio_2.Print() ; cerchio_3.Print() ; cerchio_4.Print() ;

// ********************************************************* // ** End program ** // ********************************************************* return 0 ; }

cerchio per composizione tramite cognizione.hpp Nome le: cerchio per composizione tramite cognizione.hpp

88 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI Contenuto: denizione della classe Cerchio per composizione tramite cognizione
#ifndef _CERCHIO_PER_COMPOSIZIONE_TRAMITE_COGNIZIONE_HPP #define _CERCHIO_PER_COMPOSIZIONE_TRAMITE_COGNIZIONE_HPP #include <iostream>

using namespace std;

class Cerchio_per_composizione_tramite_cognizione { private: Punto *pnt_centro ; double raggio ; public: // Costruttori // Cerchio_per_composizione_tramite_cognizione(void) { raggio = 0 ; } ; Cerchio_per_composizione_tramite_cognizione(double _raggio, Punto *_pnt_centro) { pnt_centro = _pnt_centro ; raggio = _raggio ; } ;

Cerchio_per_composizione_tramite_cognizione( const Cerchio_per_composizione_tramit pnt_centro = c.pnt_centro ; raggio = c.raggio; } ;

// Distruttore // ~Cerchio_per_composizione_tramite_cognizione(void) { cout << "invoco il distruttore di cerchio" << "\n"; } ;

// Funzioni di setting // int Set_raggio(double raggio_init) { raggio = raggio_init ; return 0 ; } ;

1.3. PROGRAMMAZIONE AD OGGETTI

89

// Funzioni di getting // double Get_raggio(void) { return raggio ; } ; Punto *Get_centro(void) { return pnt_centro ; } ;

// Funzioni di printing // void Print(void) { pnt_centro->Print() ; cout << "raggio cerchio = " << raggio << " \n"; } ; } ; #endif

cerchio per composizione tramite aggregazione.hpp Nome le: cerchio per composizione tramite aggregazione.hpp Contenuto: denizione della classe Cerchio per composizione tramite aggregazione
#ifndef _CERCHIO_PER_COMPOSIZIONE_TRAMITE_AGGREGAZIONE_HPP #define _CERCHIO_PER_COMPOSIZIONE_TRAMITE_AGGREGAZIONE_HPP #include <iostream>

using namespace std;

class Cerchio_per_composizione_tramite_aggregazione { private: Punto centro ; double raggio ;

90 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


public:

// Costruttori // Cerchio_per_composizione_tramite_aggregazione(void) { raggio = 0 ; } ;

Cerchio_per_composizione_tramite_aggregazione(double _raggio, double _x, double _y centro.Set_coordinate(_x, _y) ; raggio = _raggio ; } ;

Cerchio_per_composizione_tramite_aggregazione(const Cerchio_per_composizione_trami centro(obj.Get_centro()) ; raggio = obj.raggio; } ;

// Distruttore // ~Cerchio_per_composizione_tramite_aggregazione(void) { cout << "invoco il distruttore di cerchio" << "\n"; } ;

// Funzioni di setting // int Set_raggio(double _raggio) { raggio = _raggio ; return 0 ; } ;

// Funzioni di getting // double Get_raggio(void) { return raggio ; } ; Punto &Get_centro(void) { return centro ; } ;

// Funzioni di printing // void Print(void) {

1.3. PROGRAMMAZIONE AD OGGETTI


centro.Print() ; cout << "raggio cerchio = " << raggio << " \n"; } ; } ; #endif

91

1.3.4.b

Commenti

Di seguito alcuni commenti: (1) Si noti le due possibili declinazione nelluso della composizione di oggetti: (a) tramite aggregazione e (b) tramite cognizione. Nel caso dellaggregazione, loggetto Punto contenuto sicamente e nella classe Cerchio, sar quindi compito della classe Cerchio gestire a loggetto Punto (allocazione e deallocazione). In questo caso ad esempio se si crea un oggetto Cerchio tramite aggregazione, loggetto Punto in esso contenuto, inizier la propria esistenza con la nascita di cerchio a e la terminer con la sua ne. In altri termini loggetto Punto non ha a unesistenza autonoma rispetto al Cerchio. Nel caso della cognizione invece si ha la situazione opposta: il Cerchio ha solo cognizione delloggetto Punto, la cui esistenza per indipenoe dente dal Cerchio. Se si alloca un oggetto Cerchio tramite cognizione, loggetto Punto a cui il cerchio si riferisce, pre-esiste a questultimo e non cesser necessariamente di esistere al momento della deallocazione a del cerchio. Potr anche capitare che loggetto Punto in questione vena ga sostituito da un altro oggetto dello stesso tipo. I due oggetti sono quindi in una relazione reciproca pi debole della precedente. u (2) Ritornando alla questione delle tecniche esistenti per il riutilizzo del codice (ereditariet e composizione), vi sono molto dierenze rilevana ti. Una delle pi signicative sta nel fatto che nella composizione, u la classe complessa (quella che include gli oggetti al proprio interno), necessit unicamente di conoscere la sola interfaccia degli oggetti che a vuole includere. I dettagli implementativi di questi ultimi sono invece irrilevanti. Questo da un lato ha come svantaggio che linterfaccia degli oggetti va stabilita con grande cura e non pi modicata, ma u dallaltro consente un notevole riutilizzo nel codice. Infatti sar possia bile sostituire un oggetti contenuto con un altro, purch questultimo e implementi la stessa interfaccia.

92 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI In generale una delle regole fondamentali per il riutilizzo del codice nella programmazione ad oggetti quella di ricorrere maggiormente e alla composizione di oggetti rispetto allereditariet, di cui spesso si fa a abuso.

1.3. PROGRAMMAZIONE AD OGGETTI

93

1.3.5

Ridenizione degli operatori

Come esempio di ridenizione degli operatori in una classe, ritorniamo sullesempio dei numeri complessi. Avevamo visto come nellambito della programmazione procedurale in C fosse possibile introdurre una rappresentazione dei numeri complessi tramite il concetto di struttura. Avevamo anche esaminato i limiti di questo approccio, fondamentalmente riconducibile allimpossibilit di una piena rappresentazione dei numeri complessi tramite a un nuovo tipo. Tali limiti sono perfettamente superati e risolti nellambito della programmazione ad oggetti. Di seguito viene proposta la riscrittura del codice basato su strutture, in termini di classi. 1.3.5.a Programma: complex class (vedi codice libreria 03.04.01)

main.cpp Nome le: main.cpp Contenuto: main con manipolazione di alcuni numeri complessi
#include <cstdlib> #include <iostream> #include "complex.hpp" using namespace std; int main(int argc, char { Complex a(1,1) ; // Complex b; // viene Complex c; // viene *argv[]) viene invocato il costruttore double, double invocato il costruttore di default invocato il costruttore di default

c = b = a ; // viene invocato loperatore = due volte c= a+b ; // viene invocato loperatore + c.Print() ;

Complex x ; // viene invocato il costruttore di default x = a ; // viene invocato loperatore = Complex y = a ; // viene invocato il cpy constructor

Test_copy_complex(c) ; // viene invocato il copy constructor Test_reference_complex(c) ; // viene passato solo il reference

94 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


return EXIT_SUCCESS; }

complex.hpp Nome le: complex.hpp Contenuto: denizione della strutttura complex


#ifndef _COMPLEX_HPP #define _COMPLEX_HPP #include <iostream>

using namespace std;

class Complex { private: double real ; double img ;

public:

Complex(void) { cout << "invoco il costruttore di default" << "\n"; real = 0 ; img = 0 ; } ; Complex(double real_init, double img_init) { cout << "invoco il costruttore double double" << "\n"; real = real_init ; img = img_init ; } ; Complex::Complex( const Complex& c ) { cout << "invoco il costruttore di copia" << "\n"; real = c.real; img = c.img; } ;

~Complex(void) {

1.3. PROGRAMMAZIONE AD OGGETTI


cout << "invoco il distruttore " << "\n"; } ;

95

inline Complex operator+(const Complex &c) { return Complex(this->real + c.real, this->img + c.img); } ; inline Complex operator+(const double real_number) { return Complex(this->real + real_number, this->img); } ;

Complex &operator=( const Complex &c) { cout << "invoco operatore =" << "\n"; real = c.real ; img = c.img ; return (*this) ; } ;

void Print(void) { cout << "z = [" << real << "," << img << "] \n"; } ; } ; inline Complex operator+(double left_side, Complex &c) ; int Test_copy_complex(Complex input) ; int Test_reference_complex(Complex &input) ; #endif

complex.cpp Nome le: complex.cpp Contenuto: implementazione delle funzioni per la manipolazione delle strutture di tipo complex.
// ------------------ Begin esempio_16 --------------//

96 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


// Utilizzo di una funzione

#include <cstdlib> #include <iostream> #include "complex.hpp"

using namespace std;

inline Complex operator+(double left_side, Complex &c) { return c + left_side; }

int Test_copy_complex(Complex input) { input.Print() ; return 0 ; } int Test_reference_complex(Complex &input) { input.Print() ; return 0 ; }

E utile osservare come nel esempio riportato sopra il signicato di numero complesso, la sua idea, la sua essenza, sia stata trasferita allinterno della classe, a dierenza di quanto accadeva nel caso del C tramite il costrutto struttura, dove il signicato rimaneva al di fuore del codice, nella mente dellutente chiamato ad utilizzare quella struttura, con tutti i limiti ed i problemi che questo comportava. Anche nel caso dei polinomi possibile portare a termine il progetto di e denire un nuovo tipo di variabile che ne consenta la rappresentazione e la gestione. Vedremo che anche in questo caso fondamentale poter ridenire e gli operatori di base +, ecc. Un aspetto da sottolineare come lutente che voglia utilizzare la classe e Polinomio, non debba preoccuparsi delle procedure dallocazione necessarie per la gestione delloggetto. Queste infatti vengono svolte in maniera trasparente dal costruttore delloggetto, senza che lutente ne sia consapevole o se

1.3. PROGRAMMAZIONE AD OGGETTI

97

ne debba curare. Stesse considerazioni valgono per la deallocazione delle strutture soggiacenti loggetto polinomio. Una notevole dierenza rispetto alla programmazione procedurale e allutilizzo delle strutture, dove lutente comunque era coinvolto negli aspetti gesionali (allocazione / inizializzazione /deallocazione) delle strutture. Questo aspetto conferisce alla programmazione ad oggetti una notevole potenza, in quanto permette agli utenti di concentrarsi sul proprio core business, senza doversi preoccupare di aspetti gesionali di basso livello, portando quindi ad una maggiore ecienza ed una maggiore sicurezza.

98 CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

1.3.6

Esempio di utilizzo del polimorsmo, ovvero programmare riferendosi allinterfaccia e non allimplementazione specica.

In questo capitolo abbiamo discusso dei fondamenti della programmazione ad oggetti. Questa si poggia su tre pilastri: lincapsulamento / mascheramento dei dati, lereditariet (di cui si detto nel capitolo [?]) ed il polimora e smo, che sar loggetto del presente capitolo. a Il codice che segue mostra come implementare una classe astratta Vettore, utilizzata poi nel main per calcolare il prodotto scalare tra due vettori. Dalla classe astratta Vettore, vengono derivate due classi relative a due diverse strategie implementative dei vettori: i vettori standard basati su un array interno di tipo double (classe Vettore std). i vettori intesi come liste (classe Vettore lista). In questo caso un singolo vettore ottenuto come una lista di elementi di oggetti di tipo e Elemento lista. Un oggetto Elemento lista contiene un intero che rappresenta la posizione ed un valore double che rappresenta il valore associato a quella posizione. La lista si caratterizza per il fatto che ogni elemento della lista conosce lindirizzo dellelemento precedente e di quello successivo. Una lista cos costruita pu essere utilizzata per o denire un vettore. Partendo da un elemento della lista possibile e percorrerla nelle due direzioni (dal precedente al successivo o dal successivo al precedente), scorrendo in tal modo gli elementi del vettore. Lutilizzo delle liste per denire i vettori risulta particolarmente vantaggioso nel caso di vettori sparsi (vettori di grandissime dimensioni in cui la maggior parte degli elementi sia valorizzata a zero). In questi casi viene denita una lista contenente solo gli elementi non nulli. Gli elementi a zero del vettore non vengono rappresentati tramite alcun elemento nella lista. In questo modo si ha un notevole risparmio di memoria ed una maggiore ecienza computazionale. La struttura dei le organizzata come segue: e a classe Elemento lista in modalit invasiva (.hpp) classe Elemento lista in modalit non invasiva (.hpp) a classe Vettore (.hpp e .cpp) classe Vettore std (.hpp e .cpp) classe Vettore lista (.hpp e .cpp)

1.3. PROGRAMMAZIONE AD OGGETTI

99

main (.cpp) con un esempio di allocazione di due vettori (di tipo standard e di tipo lista) di cui viene calcolato il prodotto interno. 1.3.6.a Programma: classi per la gestione dei vettori (vedi codice libreria 03.05.01)

main.cpp Nome le: main.cpp Contenuto: main per la manipolazione di alcuni vettori
#include <cstdlib> #include <iostream> #include "vettore_std.hpp" #include "vettore_lista.hpp"

using namespace std; extern int run ; int run = 0 ; int Esempio_calcolo_tra_vettori(Vettore &v_1, Vettore &v_2) ;

int main(void) { int dim ; // Legge il valore e lo copia in n come scanf() // cout << "Inserire dim del vettore \n" ; cin >> dim;

// Creo dei vettori utilizzando gli oggetti standard // cout << "standard" ; Vettore_std v_std_1(dim) ; Vettore_std v_std_2(dim); Esempio_calcolo_tra_vettori(v_std_1, v_std_2) ;

// Creo dei vettori utilizzando gli oggetti lista //

100CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


cout << "lista" ; Vettore_lista v_lst_1(dim) ; Vettore_lista v_lst_2(dim); Esempio_calcolo_tra_vettori(v_lst_1, v_lst_2) ;

int Esempio_calcolo_tra_vettori(Vettore &v_1, Vettore &v_2) {

// Modifico dati dei vettori // for(long int i=0; i<v_1.Get_dim(); i++) { v_1.Set_element(i, 0.0 + i*0.000) ; v_2.Set_element(i, 0.0 + i*0.000) ; }

v_1.Set_element(v_1.Get_dim()/2, 2.0) ; v_2.Set_element(v_2.Get_dim()/2, 4.0) ; // Stampa dei vettori // // v_1.Stampa() ; // v_2.Stampa() ; // Prodotto interno dei vettori // for(int k=0; k<100; k++) { v_1 * v_2 ; } cout << " } prodotto interno = " << v_1 * v_2 << " \n" ;

vettore.hpp Nome le: vettore.hpp Contenuto: denizione della classe vettore astratta
// // Dichiarazione della classe Vettore

1.3. PROGRAMMAZIONE AD OGGETTI


#ifndef _VETTORE_HPP #define _VETTORE_HPP

101

# define DEFAULT_DIM 1

class Vettore { private: long int dim ; int Set_dim(long int _dim) ; protected: public: // Costruttori // Vettore(void) { // in line Set_dim(DEFAULT_DIM) ; }; Vettore(long int _dim) { Set_dim(_dim) ; } ; Vettore(const Vettore &obj) { Set_dim(obj.dim) ; } ; // Distruttore // virtual ~Vettore() ; // Funzioni virtuali di input/output // virtual int Set_element(long int posizione, double valore) = 0 ; virtual double Get_element(long int posizione) = 0 ; // funzioni pubbliche varie // long int Get_dim(void) { return dim ; } ; int Stampa(void) ;

102CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


int Reset_vettore_a_zero(void) ; // ridefinizione operatori // virtual double operator*(Vettore &obj) ; } ; #endif

vettore.cpp Nome le: vettore.cpp Contenuto: implementazione funzioni della classe Vettore
// Implementazione metodi della classe Vettore

#include <cstdlib> #include <iostream> #include "vettore.hpp"

using namespace std;

// ----------> Class: Vettore // ----------> Function name: ~Vettore // ----------> Description: Distruttore di Vettore // Vettore::~Vettore(void) { cout << "Distruttore di Vettore \n" ; }

// ----------> Class: Vettore // ----------> Function name: Set_dim // ----------> Description: Set dim del vettore // int Vettore::Set_dim(long int _dim) { if(_dim > 0) { dim = _dim ; return 0 ; }

1.3. PROGRAMMAZIONE AD OGGETTI


else { cout << "Errore _dim = " << _dim << "non ammesso \n" ; dim = DEFAULT_DIM ; return 1 ; } }

103

// ----------> Class: // ----------> Function name: // ----------> Description: // int Vettore::Stampa(void) {

Vettore Stampa Stampa del vettore

cout << "Stampa del vettore \n" ; for(long int i=0; i<Get_dim(); i++) { cout << " Vettore[" << i << "] = " << Get_element(i) << " \n" ; } } // ----------> Class: Vettore // ----------> Function name: Reset_vettore_a_zero // ----------> Description: Resetta tutti gli // elementi del vettore a zero. // int Vettore::Reset_vettore_a_zero(void) { for(int i=0; i<Get_dim(); i++) { Set_element(i, 0) ; } }

// ----------> Class: Vettore // ----------> Function name: operator* // ----------> Description: Prodotto interno // double Vettore::operator*(Vettore &obj) { double result = 0 ; for(int i=0; i<Get_dim(); i++) { result = result + Get_element(i) * obj.Get_element(i) } return result ;

104CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


}

vettore std.hpp Nome le: vettore std.hpp Contenuto: denizione della classe Vettore std (derivata da Vettore)
// // Dichiarazione della classe Vettore_std

#ifndef _VETTORE_STD_HPP #define _VETTORE_STD_HPP #include "vettore.hpp"

class Vettore_std : public Vettore { private: // dati privati // double *pointer_vettore ; // funzioni private // int Alloc_vettore_std() ; protected: public: // Costruttori // Vettore_std(void) : Vettore() { Alloc_vettore_std() ; Reset_vettore_a_zero() ; };

// in line

Vettore_std(long int _dim) : Vettore(_dim) { Alloc_vettore_std() ; Reset_vettore_a_zero() ; };

// in line

Vettore_std(long int _dim, double *_pointer_vettore) ;

1.3. PROGRAMMAZIONE AD OGGETTI


Vettore_std(const Vettore_std &obj) ;

105

// Distruttore // virtual ~Vettore_std() ; // Funzioni virtuali di input/output // virtual int Set_element(long int posizione, double valore) ; virtual double Get_element(long int posizione) ; } ; #endif

vettore std.cpp Nome le: vettore std.cpp Contenuto: implementazione funzioni della classe Vettore std
// // Implementazione metodi della classe Vettore_std

#include <cstdlib> #include <iostream> #include "vettore_std.hpp"

using namespace std;

// ----------> Class: Vettore_std // ----------> Function name: Vettore_std // ----------> Description: Costruttore di Vettore_std // Vettore_std::Vettore_std(long int _dim, double *_pointer_vettore) : Vettore(_dim) { Alloc_vettore_std() ; for(long int i=0; i< Get_dim(); i++) { Set_element(i, _pointer_vettore[i]) ; }

106CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


} // ----------> Class: Vettore_std // ----------> Function name: Vettore_std // ----------> Description: Costruttore di copia per la // classe Vettore_std // Vettore_std::Vettore_std(const Vettore_std &obj) : Vettore( (Vettore &) obj) { Alloc_vettore_std() ; for(long int i=0; i< Get_dim(); i++) { Set_element(i, obj.pointer_vettore[i]) ; } }

// ----------> Class: Vettore_std // ----------> Function name: ~Vettore_std // ----------> Description: Distruttore di Vettore_std // Vettore_std::~Vettore_std(void) { cout << "Distruttore di Vettore_std \n" ; delete pointer_vettore ; }

// ----------> Class: Vettore_std // ----------> Function name: Alloc_init_vettore_std // ----------> Description: Alloca la memoria per // il vettore // int Vettore_std::Alloc_vettore_std(void) { if(Get_dim() > 0) { // Alloco vettore // pointer_vettore = new double[Get_dim()] ; // Fine metodo // return 0 ; } else { // Inizializzo il pointer a NULL // pointer_vettore = NULL ; // Fine metodo

1.3. PROGRAMMAZIONE AD OGGETTI


// return 1 ; } }

107

// ----------> Class: Vettore_std // ----------> Function name: Set_element // ----------> Description: Set di un elemento del vettore_std // int Vettore_std::Set_element(long int numero_elemento, double valore) { if(numero_elemento >= 0 && numero_elemento <Get_dim()) { pointer_vettore[numero_elemento] = valore ; return 0 ; } else { cout << "Error in Vettore_std::Set_elemento, numero_elemento = " << numero_elemento << " e fuori dal range \n" ; return 1 ; } } // ----------> Class: Vettore_std // ----------> Function name: Get_element // ----------> Description: Get di un elemento del vettore_std // double Vettore_std::Get_element(long int numero_elemento) {

if(numero_elemento >= 0 && numero_elemento <Get_dim()) { return pointer_vettore[numero_elemento] ; } else { cout << "Error in Vettore_std::Get_elemento, numero_elemento = " << numero_elemento << " e fu return 0.0 ; } }

elemento lista invasiva.hpp Nome le: elemento lista invasiva.hpp Contenuto: denizione della classe Elemento lista invasiva (classe utilizzata da Vettore lista)
// ------------------ Begin esempio_lista_invasiva --------------// // Dichiarazione di una classe

108CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

#ifndef _ELEMENTO_LISTA_INVASIVA_HPP #define _ELEMENTO_LISTA_INVASIVA_HPP #include <iostream>

using namespace std; // Esempio di lista invasiva doppiamente "linkata" // class Elemento_lista { private: // dati privati // double valore ; long int posizione ; Elemento_lista *next; Elemento_lista *previous;

protected: public: // Costruttore // Elemento_lista(void) { previous = NULL ; next = NULL ; Set_posizione(0) ; Set_valore(0) ; };

// in line

Elemento_lista(long int _posizione, double _valore) { previous = NULL ; next = NULL ; Set_posizione(_posizione) ; Set_valore(_valore) ; } ;

// Distruttore // virtual ~Elemento_lista() {

1.3. PROGRAMMAZIONE AD OGGETTI


// cout << "Elimino elemento: " << posizione << "\n" ; } ;

109

// Funzioni di interrogazione delloggetto // double Get_valore(void) { return valore ; } ; long int Get_posizione(void) { return posizione ; } ;

Elemento_lista *Get_next(void) { return next ; } ;

Elemento_lista *Get_previous(void) { return previous ; };

// Funzioni di setting delloggetto // int Set_valore(double _valore) { valore = _valore ; return 0 ; } ; int Set_posizione(long int _posizione) { if(_posizione >= 0) { posizione = _posizione ; return 0 ; } else { return 1 ; } } ;

int Set_next(Elemento_lista *_next) { next = _next ; if(next != NULL) { next->previous = this ;

110CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


} } ;

int Set_previous(Elemento_lista *_previous) { previous = _previous ; if(previous != NULL) { previous->next = this ; } };

} ; #endif

// ------------------ End esempio_lista_invasiva -----------------

elemento lista non invasiva.hpp Nome le: elemento lista non invasiva.hpp Contenuto: denizione della classe Elemento lista non invasiva (classe utilizzata da Vettore lista)
// ------------------ Begin esempio_lista_non_invasiva --------------// // Dichiarazione di una classe

#ifndef _ELEMENTO_LISTA_NON_INVASIVA_HPP #define _ELEMENTO_LISTA_NON_INVASIVA_HPP class Contenitore { private: // dati privati // double valore ; long int posizione ; protected: public:

1.3. PROGRAMMAZIONE AD OGGETTI


// Costruttore // Contenitore(void) { valore = 0 ; posizione = 0 ; };

111

// in line

// Distruttore // virtual ~Contenitore() { } ;

// Funzioni di interrogazione delloggetto // double Get_valore(void) { return valore ; } ; long int Get_posizione(void) { return posizione ; } ;

// Funzioni di setting delloggetto // int Set_valore(double _valore) { valore = _valore ; return 0 ; } ; int Set_posizione(long int _posizione) { posizione = _posizione ; return 0 ; } ; } ;

// Esempio di lista invasiva doppiamente "linkata" // class Elemento_lista { private:

112CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

// dati privati // Contenitore *dati ; Elemento_lista *next; Elemento_lista *previous;

protected: public: // Costruttore // Elemento_lista(void) { // in line dati = new Contenitore() ; previous = NULL ; next = NULL ; }; Elemento_lista(long int _posizione, double _valore) { dati = new Contenitore() ; previous = NULL ; next = NULL ; Set_posizione(_posizione) ; Set_valore(_valore) ; } ;

// Distruttore // virtual ~Elemento_lista() { delete dati ; } ;

// Funzioni di interrogazione delloggetto // double Get_valore(void) { return dati->Get_valore() ; } ; long int Get_posizione(void) { return dati->Get_posizione() ; } ; Elemento_lista *Get_next(void) {

1.3. PROGRAMMAZIONE AD OGGETTI


return next ; } ; Elemento_lista *Get_previous(void) { return previous ; };

113

// Funzioni di setting delloggetto // int Set_valore(double _valore) { if(dati != NULL) { dati->Set_valore(_valore) ; return 0 ; } else { return 1 ; } } ; int Set_posizione(long int _posizione) { if(dati != NULL && _posizione >= 0) { dati->Set_posizione(_posizione) ; return 0 ; } else { return 1 ; } } ; int Set_next(Elemento_lista *_next) { next = _next ; if(next != NULL) { next->previous = this ; } } ;

int Set_previous(Elemento_lista *_previous) { previous = _previous ; if(previous != NULL) { previous->next = this ; } }; } ;

#endif

114CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

// ------------------ End esempio_lista_non_invasiva -----------------

vettore lista.hpp Nome le: vettore lista.hpp Contenuto: denizione della classe Vettore lista (derivata da Vettore)
// // Dichiarazione della classe Vettore_lista

#ifndef _VETTORE_LISTA_HPP #define _VETTORE_LISTA_HPP

#define #define #define #define

CURSORE_CENTRATO_SU_POSIZIONE CURSORE_A_SINISTRA_DI_POSIZIONE CURSORE_A_DESTRA_DI_POSIZIONE CURSORE_INVALIDO

0 -1 +1 -100

#include "vettore.hpp" // #include "elemento_lista_non_invasiva.hpp" #include "elemento_lista_invasiva.hpp" class Vettore_lista : public Vettore { private: // dati privati // Elemento_lista *elemento_lista_corrente ; int counter_elementi ;

// funzioni private // int Alloc_vettore_lista() ;

protected: public: // Costruttore //

1.3. PROGRAMMAZIONE AD OGGETTI


Vettore_lista(void) : Vettore() { Alloc_vettore_lista() ; }; // in line

115

Vettore_lista(long int _dim) : Vettore(_dim) { Alloc_vettore_lista() ; } ; Vettore_lista(long int _dim, double *_pointer_vettore) ; Vettore_lista(Vettore_lista &obj) ; // Distruttore // virtual ~Vettore_lista() ;

// Funzioni virtuali di input/output // virtual int Set_element(long int posizione, double valore) ; virtual double Get_element(long int posizione) ; // ridefinizione operatori // virtual double operator*(Vettore &obj) ;

// Funzioni specifiche di Vettore_lista // int Posiziona_cursore(long int posizione) ; Elemento_lista *Get_cursore(void) { return elemento_lista_corrente ; } ; int Set_cursore(Elemento_lista *_elemento_lista_corrente) ; void Set_cursore_ultimo_elemento_valido(void) ; void Set_cursore_primo_elemento_valido(void) ; int Inserisci_elemento(long int posizione) ; } ; #endif

116CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI vettore lista.cpp Nome le: vettore lista.cpp Contenuto: implementazione funzioni della classe Vettore lista
// // Implementazione metodi della classe Vettore_lista

#include <cstdlib> #include <iostream> #include "vettore_lista.hpp" extern int run ; using namespace std;

// ----------> Class: Vettore_lista // ----------> Function name: Vettore_lista // ----------> Description: Costruttore di Vettore_lista // Vettore_lista::Vettore_lista(long int _dim, double *_pointer_vettore) : Vettore(_dim) { Alloc_vettore_lista() ; for(int i=0; i< Get_dim(); i++) { Set_element(i, _pointer_vettore[i]) ; ; } } // ----------> Class: Vettore_lista // ----------> Function name: Vettore_lista // ----------> Description: Costruttore di copia per la // classe Vettore_lista // Vettore_lista::Vettore_lista(Vettore_lista &obj) : Vettore( (Vettore &) obj) { Alloc_vettore_lista() ; for(long int i=0; i< Get_dim(); i++) { Set_element(i, obj.Get_element(i)) ; } }

// ----------> Class: // ----------> Function name:

Vettore_lista ~Vettore_lista

1.3. PROGRAMMAZIONE AD OGGETTI


// ----------> Description: Distruttore di Vettore_lista // Vettore_lista::~Vettore_lista(void) { int status_cursore = 0 ; cout << "Distruttore di Vettore_lista \n" ; Elemento_lista *elemento_lista_next = NULL ; Set_cursore_primo_elemento_valido() ; status_cursore = 0 ; while(status_cursore == 0) { elemento_lista_next = Get_cursore()->Get_next() ; delete Get_cursore() ; counter_elementi-- ; status_cursore = Set_cursore(elemento_lista_next) ; } ; }

117

// ----------> Class: Vettore_lista // ----------> Function name: Set_element // ----------> Description: Set di un elemento del vettore_lista // int Vettore_lista::Set_element(long int posizione, double valore) { if(posizione >=0 && posizione < Get_dim()) { if(Posiziona_cursore(posizione) == CURSORE_CENTRATO_SU_POSIZIONE) { // esiste un elemento della lista nella posizione // indicata // Get_cursore()->Set_valore(valore) ; } else { // non esiste un elemento della lista nella posizione // indicata. Lo creo solo se il valore e non nullo! if(valore == 0) { } else { Inserisci_elemento(posizione) ; Set_element(posizione, valore) ; } } } else {

118CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

cout << "Error in Vettore_lista::Set_elemento, posizione = " << posizione << " e fu return 1 ; } }

// ----------> Class: Vettore_lista // ----------> Function name: Get_element // ----------> Description: Get di un elemento del vettore_lista // double Vettore_lista::Get_element(long int posizione) {

if(posizione >=0 && posizione <Get_dim()) { if(Posiziona_cursore(posizione) == CURSORE_CENTRATO_SU_POSIZIONE) { return Get_cursore()->Get_valore() ; } else { return 0.0 ; } } else { cout << "Error in Vettore_lista::Get_elemento, posizione = " << posizione << " e fu return 0.0 ; } }

// ----------> Class: Vettore_lista // ----------> Function name: Inserisci_elemento // ----------> Description: // int Vettore_lista::Inserisci_elemento(long int posizione) { Elemento_lista *nuovo_elemento_lista = NULL ; Elemento_lista *elemento_lista_next = NULL ; Elemento_lista *elemento_lista_previous = NULL ; int status_cursore = 0 ; status_cursore = Posiziona_cursore(posizione) ; if(status_cursore == CURSORE_CENTRATO_SU_POSIZIONE) { // elemento gia esistente nella posizione specificata // return -1 ; } if(status_cursore == CURSORE_INVALIDO) {

1.3. PROGRAMMAZIONE AD OGGETTI


// posizione specificata invalida // return -2 ; } elemento_lista_next = Get_cursore()->Get_next() ; elemento_lista_previous = Get_cursore()->Get_previous() ; // Creo nuovo elemento // nuovo_elemento_lista = new Elemento_lista(posizione, 0) ; if(status_cursore == CURSORE_A_SINISTRA_DI_POSIZIONE) { // Collego il nuovo elemento nella lista // nuovo_elemento_lista->Set_previous(Get_cursore()) ; nuovo_elemento_lista->Set_next(elemento_lista_next) ; } else if(status_cursore == CURSORE_A_DESTRA_DI_POSIZIONE) {

119

// Collego il nuovo elemento nella lista // nuovo_elemento_lista->Set_previous(elemento_lista_previous) ; nuovo_elemento_lista->Set_next(Get_cursore()) ; } // incremento il contatore di elementi della lista // counter_elementi ++ ; // Posiziono il cursore sul nuovo elemento // Set_cursore(nuovo_elemento_lista) ; return 0 ; }

// ----------> Class: Vettore_lista // ----------> Function name: Posiziona_cursore // ----------> Description: Posiziona il cursore // int Vettore_lista::Posiziona_cursore(long int posizione) { if(posizione >= 0 && posizione < Get_dim()) {

120CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

if( posizione == Get_cursore()->Get_posizione() ) { return CURSORE_CENTRATO_SU_POSIZIONE ; } else if(posizione > Get_cursore()->Get_posizione()) { while(Get_cursore()->Get_next() != NULL && posizione >= Get_cursore()->Get_next()->Get_posizione()) { // Movimento indietro // Set_cursore(Get_cursore()->Get_next()) ; } if(posizione == Get_cursore()->Get_posizione()) { return CURSORE_CENTRATO_SU_POSIZIONE ; } else { return CURSORE_A_SINISTRA_DI_POSIZIONE ; } } else if(posizione < Get_cursore()->Get_posizione()) { while(Get_cursore()->Get_previous() != NULL && posizione <= Get_cursore()->Get_previous()->Get_posizione()) { // Movimento indietro // Set_cursore(Get_cursore()->Get_previous()) ; } if(posizione == Get_cursore()->Get_posizione()) { return CURSORE_CENTRATO_SU_POSIZIONE ; } else { return CURSORE_A_DESTRA_DI_POSIZIONE ; } } else { cout << "Errore inatteso \n" ; return CURSORE_INVALIDO ; } } else { cout << "Index out of range \n" ; return CURSORE_INVALIDO ; } }

// ----------> Class: // ----------> Function name: // ----------> Description:

Vettore_lista Set_cursore_ultimo_elemento

1.3. PROGRAMMAZIONE AD OGGETTI


// void Vettore_lista::Set_cursore_ultimo_elemento_valido(void) { while(Get_cursore()->Get_next() != NULL) { Set_cursore(Get_cursore()->Get_next()) ; } } // ----------> Class: Vettore_lista // ----------> Function name: Set_cursore_primo_elemento // ----------> Description: // void Vettore_lista::Set_cursore_primo_elemento_valido(void) { while(Get_cursore()->Get_previous() != NULL) { Set_cursore(Get_cursore()->Get_previous()) ; } }

121

// ----------> Class: Vettore_lista // ----------> Function name: Alloca_vettore_lista // ----------> Description: // int Vettore_lista::Alloc_vettore_lista(void) {

Elemento_lista *nuovo_elemento_lista = NULL ; counter_elementi = 0 ; nuovo_elemento_lista = new Elemento_lista(0, 0.0) ; nuovo_elemento_lista->Set_previous(NULL) ; nuovo_elemento_lista->Set_next(NULL) ; counter_elementi ++ ; Set_cursore(nuovo_elemento_lista) ; return 0 ; }

// ----------> Class: // ----------> Function name: // ----------> Description: //

Vettore_lista Set_cursore

122CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


int Vettore_lista::Set_cursore(Elemento_lista *_elemento_lista_corrente) { if(_elemento_lista_corrente != NULL) { if(_elemento_lista_corrente->Get_posizione() >= 0 && _elemento_lista_corrente->Get_posizione() < Get_dim()) { elemento_lista_corrente = _elemento_lista_corrente ; return 0 ; } else { return 1 ; } } else { return 1 ; } } // ----------> Class: Vettore_lista // ----------> Function name: operator* // ----------> Description: Prodotto interno // double Vettore_lista::operator*(Vettore &obj) { double result = 0 ; long int posizione = 0 ; int status_cursore = 0 ; // cout << "prodotto ottimizzato (" << counter_elementi << ")\n " ; Set_cursore_primo_elemento_valido() ; status_cursore = 0 ; while(status_cursore == 0) { posizione = Get_cursore()->Get_posizione() ; result = result + Get_cursore()->Get_valore() * obj.Get_element(posizione) ; status_cursore = Set_cursore(Get_cursore()->Get_next()) ; } ; return result ; }

1.3.6.b

Commenti

Di seguito alcuni commenti: (1) Si noti come la funzione che eettua il prodotto interno tra i due

1.3. PROGRAMMAZIONE AD OGGETTI

123

vettori desempio, possa utilizzare indierentemente oggetti di tipo Vettore std o di tipo Vettore lista. In altri termini il codice presente nel main, per gestire il prodotto interno tra vettori, risulta totalmente astratto, non dipendente dallimplementazione degli oggetti. Questo perch nella scrittura del codice ci si riferiti allinterfaccia della classe e e astratta Vettore e non allimplementazione specica utilizzata nelle due classi concrete Vettore std e Vettore lista. Questo un tipico ese empio di uso avanzato del polimorsmo. Il polimorsmo consiste nel fatto che solo in fase di run-time verrano chiamate (ovvero risolte ed eseguite) le funzioni appropriate in base al tipo di oggetto reale coinvolto. In altre parole nel codice che eettua il prodotto scalare, vengono utilizzate delle funzioni membro di Vettore, in modo totalmente astratto e solo durante il run-time verranno risolte in maniera adeguata in base agli oggetti eettivamente passati alla funzione. Il polimorsmo costituisce il terzo pilastro della programmazione ad oggetti ed larchitrave fondamentale per garantire una piena ed efe cace riutilizzabilit del codice. (Nellesempio scritto sopra, il codice a per la gestione del prodotto interno nel main, non va modicato se ad esempio si dovesse decidere di inserire una terza classe derivata da Vettore, con unimplementazione dierente dalle prime due. In tal modo possibile estendere il codice, inserendo nuove implementazioni senza e dover modicare in alcun punto il codice gi scritto.) a (2) Si osservi luso delle funzioni virtual nel codice. Queste sono essenziali per garantire lutilizzo pieno del polimorsmo. (3) Entrando nel merito dellesempio, va osservato come lutilizzo di Vettore lista risulti nettamente preferibile a quello di Vettore std nel caso di vettori sparsi (vettori di grandi dimensioni in cui la maggior parte degli elementi sia nulla). Questo sia dal punto di vista della memoria allocata, sia in termini di performance della cpu. (4) Si noti la ridenizione delloperatore prodotto nella classe Vettore al ne di trattare il prodotto interno tra vettori. Loperatore prodotto e stato dichiarato virtual al ne di consentirne la ridenizione (nellottica del polimorsmo) nelle classi a valle. In eetti nella classe Vettore lista si ridenito loperatore prodotto e in modo da migliorarne le performance. Questo dunque un esempio e di come in alcuni casi sia utile ridenire un membro di una classe a valle, rispetto a quello omonimo denito nella classe padre, per ragioni riconducibili esclusivamente a questioni di performance di calcolo. Se ad es. si evita di ridenire il prodotto nella classe Vettore lista sar a ovviamente possibile calcolare il prodotto interno di due vettori di

124CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI tipo lista, ma in tal caso lalgoritmo utilizzato (quello contenuto nella generica classe Vettore) sar meno eciente. a

1.3. PROGRAMMAZIONE AD OGGETTI

125

1.3.7

Esempio di utilizzo avanzato del polimorsmo.

Il codice scritto sopra comprende come abbiamo visto consente di eseguire il prodotto interno di vettori. Questi possono essere di due tipi fondamentali: vettori standard (stile C ma incapsulati in una classe) e vettori di tipo lista (adatti a trattare vettori sparsi). Supponiamo che successivamente nasca la necessit di utilizzare un tipo a dierente di vettore, ad es. si voglia utilizzare la classe vector disponibile nella standard library del C++. In questo caso vi un problema fondamene tale allutilizzo un oggetto di tipo vector double allinterno della funzione prodotto interno, ovvero il fatto che vector double non glio della classe e astratta Vettore. In sostanza in tale contesto non possibile utilizzare il e polimorsmo in quanto la classe vector double non ha la stessa interfaccia di Vettore. Questo problema pu per essere superato attraverso una o o tecnica di programmazione ad oggetti nota come Adapter. Tale tecnica costituisce un esempio di design pattern ed illustrata nellesempio riportato e di seguito. 1.3.7.a Programma: classi per la gestione dei vettori (vedi codice libreria 03.05.02)

main.cpp Nome le: main.cpp Contenuto: main per la manipolazione di alcuni vettori
#include <cstdlib> #include <iostream> #include "vettore_std.hpp" #include "vettore_lista.hpp" #include "prodotto_interno.hpp"

using namespace std; int main(void) { int dim ; // Legge il valore e lo copia in n come scanf() // cout << "Inserire dim del vettore \n" ; cin >> dim;

126CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

// Creo dei vettori utilizzando i vari costruttori // Vettore_std v1(dim, 10.0) ; v1.Set_elemento(2, 5.0) ; Vettore_con_adapter v1(dim, 10.0) ; v1.Stampa() ; v2.Stampa() ; double result ; Prodotto_interno_tra_vettori(&result, &v2, &v4) ; cout << "prodotto interno = " << result << " \n" ;

vector con adapter.hpp Nome le: vector con adapter.hpp Contenuto: denizione della classe Vector con adapter
// // Dichiarazione di una classe

#ifndef _VECTOR_CON_ADAPTER_HPP #define _VECTOR_CON_ADAPTER_HPP #include "vettore.hpp"

class Vector_con_adapter : public Vector { private: // dati privati // vector <double> *vector_std_library ;

1.3. PROGRAMMAZIONE AD OGGETTI


protected: public: // Costruttore // Vector_con_adapter(void) : Vector() { // in line vector_std_library = new vector <double> ; }; Vector_con_adapter(int _dim) : Vector() { if(_dim > 0) { vector_std_library = new vector <double> (_dim) } else { vector_std_library = NULL ; } } ;

127

Vector_con_adapter(int _dim, double *_pointer_vettore) : Vector() vector_std_library = new vector <double> ; for( int i = 0; i < _dim; ++i ) { vector_std_library->push_back( _pointer_vettore[i] ); } } ;

Vector_con_adapter(const Vector_con_adapter &obj) : Vector( (Vector &) obj) { vector_std_library = new vector <double>(obj.vector_std_library->size()) ; for( int i = 0; i < obj.vector_std_library->size(); ++i ) { vector_std_library->push_back( obj.vector_std_library->at(i) ); } } ;

// Distruttore // virtual ~Vector_con_adapter() { delete vector_std_library ; } ;

// Funzioni di input/output // virtual int Set_elemento(int posizione, double valore) { if(posizione>=0 && posizione < vector_std_library->size()) { vector_std_library->at(posizione) = valore ;

128CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI


} } ; virtual double Get_elemento(int posizione) { if(posizione>=0 && posizione < vector_std_library->size()) { return vector_std_library->at(posizione) ; } } ;

} ; #endif

(1) Si noti come la nuova classe Vector con adapter non faccia altro che avvolgere un oggetto di tipo vector double , andando a rivestirne linterfaccia. La classe Vector con adapter essendo derivata da Vector ne eredit linterfaccia e daltra parte possedendo al proprio interno un a pointer a vector double consente di gestire un vettore utilizzando la standard library del C++. Il programmatore della classe dovr solo preoccuparsi di implementare a le funzioni di interfacci per connettere linterfaccia della classe con linterndo delloggetto costituita dal pointer di tipo vector double . Questa metodologia di programmazione nota come adapter in quane to quello realizzato un vero e proprio adattatore di classe, ovvero e consente di rivestire o riconvertire linterfaccia di una classe (nel nostro esempio quella di vector double ) in quella di unaltra (nel nostro esempio Vector). (2) Una volta adattata linterfaccia di vector double a quella di Vector, ecco che saremo in grado di utilizzare gli oggetti di tipo Vector con adapter nella funzione per il calcolo del prodotto interno. (3) Si osservi inne come laggiunta di una terza tipologia di vettori (derivati dalla classe astratta Vettore), sia avvenuta in maniera assolutamente modulare, senza richiedere la riscrittura del codice pre-esistente (nel nostro caso la funzione per il calolo del prodotto interno). In conclusione in questo capitolo abbiamo mostrato come il polimorsmo consenta di aggiungere in un secondo momento alla libreria una nuova sottotipologia di oggetti, senza per questo modicare il codice pre-esistente. Nel caso in cui la tipologia di oggetto da inserire stata sviluppata da una parte e terza e perci caratterizzata da un interfaccia non compatibile da quella oe richiesta, sempre possibile ricorrere ad un adattatore (adapter). e

1.3. PROGRAMMAZIONE AD OGGETTI

129

Ladapter mostrato un esempio di design pattern, di cui si parler pi e a u diusamente nel capitolo successivo.

130CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

1.3.8
1.3.8.a

Design patterns
Design patterns: il singleton

Un esempio molto famoso e molto semplice di design pattern il singleton. e 1.3.8.b Esempio di denizione di un singleton (vedi codice libreria 04.01)

main.cpp Nome le: main.cpp Contenuto: main per lutilizzo del singleton
// initialize pointer // Singleton_coda_messaggi *Singleton_coda_messaggi::pointer_istanza = NULL ; int main() { Singleton_coda_messaggi *coda_msg ; coda_msg = Singleton_coda_messaggi::Get_instance() ; coda_msg->Put_msg("messaggio 1") ; coda_msg->Put_msg("messaggio 2") ; coda_msg->Put_msg("messaggio 3") ; coda_msg->Print_all_msg() ; return 0; }

singleton.hpp Nome le: singleton.hpp Contenuto: denizione della classe Singleton


// // Dichiarazione di una classe

1.3. PROGRAMMAZIONE AD OGGETTI

131

#ifndef _SINGLETON_HPP #define _SINGLETON_HPP #include <iostream>

class Singleton_coda_messaggi { private: static singleton* pointer_istanza ; Singleton_coda_messaggi() { }; public: ~Singleton_coda_messaggi() { }; static Singleton_coda_messaggi* Get_instance() { if (pointer_istanza == NULL) { pointer_istanza = new Singleton_coda_messaggi() ; } return pointer_istanza; } ; int Put_msg(String *_msg) ; String Get_msg(int counter) ; };

#endif

1.3.8.c

Altri design patterns

Vi sono vari tipi di design patterns. Un valido libro dapprofondimento su questo tema dato da [3]. e Esempi di design pattern (relativamente semplici) sono il decorator e lobserver.

132CAPITOLO 1. ELEMENTI DI PROGRAMMAZIONE AD OGGETTI

Capitolo 2

Elementi di nanza

133

134

CAPITOLO 2. ELEMENTI DI FINANZA

2.1

Il contesto - Elementi di nanza

In questo primo capitolo deniremo alcuni elementi base della nanza (tasso di interesse, principio di non arbitraggio, attualizzazione dei ussi di cassa, denizione di bond, concetto di opzione, ecc.). Una pi esauriente e apu profondita presentazione di questi argomenti pu essere trovata in [7, 8]. o

2.1.1

Tasso di interesse

Allinterno delle economie di mercato il denaro, se investito, riceve una remunerazione in base al cosiddetto tasso di interesse. Se ad esempio il tasso di interesse ad un anno del 5%, ed investiamo una quantit di denaro pari e a a 100 EUR, fra un anno riceveremo: 100 (1 + 5/100) = 105 EUR. Questo signica che il denaro nel nostro sistema economico tende a generare altro denaro. Il tasso di interesse misura questa capacit daccrescimento. Ovvia amente perch si verichi questo fenomeno di moltiplicazione del capitale e necessario che il denaro venga investito (ovvero che diventi capitale). La e teoria nanziaria non si occupa in ogni caso di esaminare attraverso quali meccanismi il capitale possa generare se stesso, n di conseguenza in grado e e di derivare quale sia il valore corretto del tasso di interesse. Semplicemente in nanza si assume, come dato sperimentale, che un capitale investito generi un interesse con un certo tasso. Sar compito di una teoria economica staa bilirne lorigine. In generale quando si indica un tasso di interesse, va sempre specicato quale sia la frequenza di pagamento degli interessi. Si consideri ad esempio un capitale iniziale Ci su cui vengano pagati degli interessi rf1 con una frequenza pari a f1 volte lanno per un totale di T anni. Il valore alla ne del periodo T , ipotizzando di re-investire gli interessi allo stesso tasso, sar pari a a: rf1 f1 T . (2.1) Cf = Ci 1 + f1 Se ora consideriamo una dierente frequenza di pagamento, f2 , possiamo domandarci quale sia il tasso annuo rf2 in grado di produrre lo stesso capitale nale Cf , ovvero quale sia il tasso rf2 equivalente a rf1 . La risposta data e dalla seguente espressione: f1 rf1 f2 rf2 = f2 1 + 1 , (2.2) f1 Da questa discussione si evince quanto sia importante specicare sempre la frequenza di pagamento degli interessi. Dallequazione (2.1), nel limite f 1 (ovvero nel cosiddetto limite di

2.1. IL CONTESTO - ELEMENTI DI FINANZA capitalizzazione continua), si ottiene la formula: Cf = Ci erc T ,

135

(2.3)

Nel seguito supporremo sempre che il tasso di interesse faccia riferimento ad una capitalizzazione continua. Ovviamente nel mondo nanziario reale qualunque investimento in grado di generare un interesse caratterizzato da un certo rischio, pi o meno e u elevato. Ad esempio concedere prestiti per lacquisto di case (i cosiddetti mutui) ha un grado di rischio pi alto di quello che si ha investendo in titoli u di stato italiani (infatti pi facile che i mutuatari, per varie ragioni, non e u siano in grado di restituire il prestito ricevuto piuttosto che lo stato italiano fallisca). E daltra parte, linvestimento in obbligazioni emesse dallo stato italiano pi rischioso dellacquisto di titoli di stato americani. Generale u mente, come del resto ovvio, si osserva che tanto pi grande il rischio di u e un investimento tanto maggiore sar il tasso di interesse richiesto. Daltra a parte possiamo attenderci che in un economia sviluppata, dove sia valido il principio di non arbitraggio (vedi paragrafo successivo), investimenti caratterizzati dalla stessa durata e dallo stesso rischio fruttino interessi uguali. Relativamente al rischio di un investimento, questo pu essere denito come o la probabilit che a scadenza linvestimento (e gli interessi generati) non a vengano restituiti o vengano restituiti solo in parte. Se indichiamo con rT (p) il tasso di interesse su un periodo di tempo pari a T e con p la probabilit che tale investimento vada completamente perso, a allora si denisce tasso di interesse privo di rischio, il seguente limite:
p0

lim rT (p)

(2.4)

Il tasso privo di rischio (risk free rate), pur essendo unastrazione, un e concetto fondamentale della nanza ed presente in tutti i modelli di price ing di strumenti nanziari sosticati. In concreto possiamo immaginare che gli interessi corrisposti dai titoli di stato o pagati dalle banche sui depositi inter-bancari si avvicinino al tasso privo di rischio. Un secondo elemento da considerare nella denizione data sopra, lintere vallo di tempo T . Infatti in generale il tasso di interesse dipende dalla scadenza temporale considerata. E quindi pi corretto parlare di curva u dei tassi risk free. Ad es. un investimento privo di rischio a lunga durata potrebbe essere caratterizzato da un rendimento annuo pi basso o pi alto u u di un investimento a breve durata.

2.1.2

Il principio del non arbitraggio

In questo paragrafo enunceremo una degli assiomi fondamentali della nanza. Vedremo come molti dei risultati che deriveremo nei prossimi capitoli

136

CAPITOLO 2. ELEMENTI DI FINANZA

poggiano su questo assunto fondamentale. Il principio in questione si enuncia nei seguenti termini: Assioma del non arbitraggio: Nei mercati nanziari impossibile e realizzare un guadagno certo che abbia un rendimento superiore al tasso privo di rischio. In gergo nanziario, questo principio ecacemente sintetizzato aere mando che: Theres no such thing as a free lunch in the market. Si devono fare a questo proposito alcune considerazioni: questo principio vale in media, non si pu infatti escludere che per brevi o intervalli di tempo, possano comparire sul mercato delle opportunit a di arbitraggio, ovvero mis-pricing di titoli nanziari che consentano di realizzare un guadagno certo superiore a quello dato dal tasso risk free. Naturalmente se il mercato maturo ed eciente, tali oppore tunit scompariranno in un tempo brevissimo. Facciamo un esempio a concreto, considerando un titolo che venga quotato in due borse differenti, diciamo a Londra e a New York. Supponiamo che il cambio sterlina contro dollaro sia pari a 1,57 dollari per 1 sterlina e che le quotazione del titolo siano di una sterlina alla borsa di Londra e di 1.58 dollari a New York. In tale situazione si viene a realizzare unopportunit di arbitraggio. Infatti acquistando ad esempio 100 titoli alla a borsa di Londra al prezzo di 100 sterline e rivendendole immediatamente alla borsa di New York al prezzo di 158 dollari, ottengo un protto istantaneo pari a 1 dollaro1 . In tal caso avrei una violazione del principio di non arbitraggio, in quanto ho realizzato un guadagno certo in un tempo idealmente nullo (ottenendo quindi un rendimento innito). Il mercato per tende a far scomparire queste opportunit o a in tempi rapidissimi. Ad esempio, nel caso considerato sopra, si vericheranno, per il titolo in oggetto, una serie di richieste dacquisto alla borsa di Londra e contemporaneamente altrettante vendite a quella di New York. Per la legge della domanda e delloerta, questo si tradurr a in un aumento di prezzo del titolo sulla piazza di Londra e una diminuzione su quella di New York. In tal modo, in pochissimo tempo i due prezzi si riporteranno in equilibrio, impedendo ogni ulteriore protto. Nel mercato esistono alcune persone la cui professione consiste proprio nello sfruttare piccoli disallineamenti di prezzo al ne di realizzare un guadagno. Questi trader prendono il nome di arbitraggisti. Paradossalmente, proprio la loro esistenza che rende vero il principio di non e arbitraggio.
1 Supponiamo in questo caso che non vi siano costi di transazione. generalmente un ostacolo allo sfruttamento di mis-pricing nel mercato.

Questi sono

2.1. IL CONTESTO - ELEMENTI DI FINANZA

137

Esistono sul mercato diverse opportunit che consentono di realizzare a un guadagno superiore al tasso privo di rischio, tipicamente gli investimenti azionari. Questi per sono sempre caratterizzati da unincertezo za nei risultati. Come vedremo, il principio di non arbitraggio giocher un ruolo chia ave nellargomentazione di Black & Scholes per loption pricing e di fatto costituisce uno dei pilastri su cui si regge lintera nanza quantitativa.

2.1.3

Attualizzazione del denaro

Da quanto discusso nel paragrafo 2.1.1, chiaro che detenere 1000 EUR oggi e non la stessa cosa che avere 1000 EUR fra un anno. Un metodo molto e semplice per rendere quantitative queste considerazioni consiste nellintrodurre il concetto di attualizzazione del denaro. In particolare proviamo a rispondere alla domanda: qual il valore attuale (present value) ad oggi e di un usso di cassa futuro? Sia T lintervallo di tempo che ci separa da un pagamento futuro pari a PT , indichiamo con r il tasso di interesse privo di rischio, composto in maniera continua (cfr. eq. (2.3)), praticato dal mercato su un intervallo di tempo pari a T , allora il valore attuale di PT pari a: e P0 = PT erT . (2.5)

Dim. In base al principio del non arbitraggio se il diritto a ricevere PT fra un tem po T valesse pi di P0 , diciamo P , potrei vendere questo diritto ricevendo u e impegnandomi a rimborsare PT al tempo T , poi investirei il denaro oggi P P al tasso risk free. A scadenza, dopo T anni guadagnerei in maniera cer ta: P er T PT > 0, senza aver impiegato alcun capitale iniziale2 e questo sarebbe in contraddizione con il principio di non arbitraggio. Analogamente se il valore del diritto a ricevere PT fra un tempo T valesse meno di P0 , potrei prendere a prestito P0 al tasso di mercato r impegnan domi a rimborsare PT a scadenza. Una parte del denaro ricevuto oggi, P , lo utilizzo per acquistare il diritto a ricevere PT a scadenza, coprendo cos il mio debito al tempo T . In tal modo ottengo oggi una quantit certa di a denaro pari a: P0 P > 0 senza nessun ulteriore obbligo e senza aver investito alcun capitale. Anche in questo caso avrei una violazione del principio di non arbitraggio. Resta quindi dimostrata la formula (2.5). La formula (2.5) consente di poter dare un valore a ussi di denaro futuri. Nei fatti questo uno dei risultati pi fondamentali nel campo della e u nanza quantitativa, in quanto ogni strumento nanziario caratterizzato e sempre da ussi di cassa (pi o meno certi) che verranno pagati in momenti u
2

Il rendimento dellinvestimento sarebbe quindi innito.

138

CAPITOLO 2. ELEMENTI DI FINANZA

futuri. Generalmente gli strumenti nanziari si distinguono solo in base al meccanismo con cui vengono stabiliti i ussi futuri. Ad esempio in un titolo di stato (vedi paragrafo 2.1.4) che paga il 5% di interessi lanno, i ussi futuri sono appunto le cedole annuali pari al 5% dellinvestimento iniziale, pi la u restituzione del capitale a scadenza. Nel caso di unazione, il suo valore e determinato dai tutti i dividendi che essa potr corrispondere in futuro. E a quindi fondamentale poter disporre di una metodologia che ci consenta di dare un prezzo attuale a pagamenti che avverranno in futuro, fornendo in tal modo una misura omogenea. A questa richiesta risponde la formula (2.5).

2.1.4

Denizione di bond e sua valutazione

Utilizzando lequazione (2.5) relativamente semplice poter valutare gli strue menti a reddito sso presenti sul mercato. A titolo di esempio consideriamo le obbligazioni a tasso sso (bond). Questo un titolo che viene sottoscrite to dallinvestitore ad un certo prezzo iniziale Pi e che paga con una certa c frequenza f (tipicamente una o due volte lanno) delle cedole pari a: f N , dove N il nozionale acquistato e c il tasso di interesse pagato dal bond. e e A scadenza, dopo T anni, il titolo rimborsa al sottoscrittore il suo valore nominale N . In altri termini il titolo garantisce allacquirente il pagamento dei seguenti ussi monetari: c N per t = ti = i/f i = 1, ...., f T f N per t = T (data di scadenza del bond) , Ci = (2.6) (2.7)

dove T e ti sono tempi espressi dimensionalmente in anni. Se supponiamo di conoscere la curva dei tassi di interesse risk free, r(t), e che non vi sia alcun rischio di mancato rimborso legato al bond, allora e molto semplice, utilizzando la formula (2.5), calcolare il valore Pi del bond:
fT

Pi = N er(T ) T +
i=1

Ci er(ti ) ti .

(2.8)

Come si vede ogni usso di cassa futuro viene valorizzato ad oggi applicando il relativo fattore di sconto.

2.1.5

Curva dei tassi di interesse

Come si evidenziato nel paragrafo precedente, il calcolo del prezzo di un e titolo a tasso sso presuppone la conoscenza della curva dei tassi. Questa pu essere determinata sperimentalmente dai dati di mercato attraverso una o procedura nota come bootstrap. Questa metodologia prende come dati di partenza, una serie di prezzi di titoli obbligazionari quotati sul mercato (di

2.1. IL CONTESTO - ELEMENTI DI FINANZA

139

fatto quelli ritenuti pi rappresentativi) e ricava la curva dei tassi che in u e grado di produrre, tramite leq. (2.8), dei prezzi teorici, per ciascun titolo, identici ai rispettivi valori di mercato. Per ulteriori dettagli, rimandiamo al testo di Hull [7].

2.1.6
2.1.6.a

Titoli derivati e opzioni plain vanilla


Titoli derivati

Def. Un titolo derivato un contratto nanziario in cui loggetto della e contrattazione un altro strumento nanziario pi fondamentale. Ne cone u segue che il valore di un titolo derivato dipende dal valore degli strumenti sottostanti su cui viene scritto il contratto. Il sottostante di un contratto derivato generalmente costituito da una e variabile quotata sul mercato (ad es. pu essere unazione o un tasso di o interesse o anche una materia prima quale ad esempio il petrolio) ma anche una grandezza daltro tipo (purch ben denita) come ad es. la quantit di e a precipitazioni che si sono vericate in un certo periodo su una certa regione (i cosiddetti weather derivatives, che sono entrati recentemente anche sul mercato italiano). Non ce limite alla fantasia nello scrivere nuovi contratti derivati su sottostanti sempre pi esotici. u I titoli derivati hanno conosciuto unenorme crescita negli ultimi decenni e sono trattati sia nelle borse uciali, sia tra le grandi istituzioni nanziarie (i cosiddetti derivati over the counter, cio sopra il banco). Inoltre diversi e titoli obbligazionari, emessi da banche, contengono implicitamente contratti derivati. Esistono diversi tipi di derivati. I pi popolari sono i contratti futures, u forward, IRS (Interest Rate Swap), cap&oor e le opzioni. In queste lezioni rivolgeremo la nostra attenzione unicamente alle opzioni. 2.1.6.b Denizione di opzione

Le opzioni furono introdotte per la prima volta nel 1973 e da allora hanno conosciuto una crescita di volumi inarrestabile. Le pi semplici sono le cosiddette opzioni plain vanilla. A tal riguardo, diu amo la seguente denizione: Def. Unopzione d diritto al possessore di acquistare o vendere, ad una a data futura, un certo bene (il sottostante) ad un certo prezzo (detto prezzo di esercizio o strike price). La prima cosa da osservare il fatto che il proprietario di unopzione ha e acquistato un diritto e non un obbligo. Se ad esempio lopzione d diritto a ad acquistare un certo asset nanziario ad un prezzo maggiore del suo valore di mercato, ovvio che tale diritto non verr esercitato. Questa la e a e

140

CAPITOLO 2. ELEMENTI DI FINANZA

caratteristica principale che dierenzia unopzione da altri contratti derivati (ad es. forward o future). Le opzioni si dividono in tre grandi famiglie per quanto riguarda le condizioni temporali in cui il diritto insito nellopzione pu essere esercitato: o (i) Esercizio di tipo europeo per le opzioni di tipo europeo, il diritto pu essere fatto valere solo in o corrispondenza ad una pressata ed unica data futura, detta data di maturit (in inglese maturity date). a (ii) Esercizio di tipo americano in questo caso lopzione pu essere esercitata in qualunque momento o compreso tra oggi e la data di maturit dellopzione. E quindi chiaro a che unopzione americana, rispetto ad una europea con le stesse caratteristiche, ore un diritto maggiore e di conseguenza avr un prezzo a pi alto. u (iii) Esercizio di tipo bermudano 3 nelle opzioni bermudane, lopzione pu essere esercitata solo in certe o date prestabilite. Se indichiamo con {Ti }i=1,....,N il set di date in cui il diritto esercitabile, allora la data di maturit dellopzione denie a e ta come Tmat. = M ax{Ti }i=1,....,N . Unopzione di tipo europeo pu o quindi essere vista come una particolare opzione bermudana in cui il set di date di esercizio si riduce alla sola data di maturit. E ovvio che a a parit di caratteristiche unopzione con esercizio bermudano avr un a a valore superiore ad una di tipo europeo. Daltra parte, anche unopzione americana risulta un caso limite di una opzione bermudana, e precisamente quello in cui il set di date {Ti }i=1,....,N include tutti i giorni compresi tra oggi e la maturity date. In questo caso, sempre a parit di caratteristiche, unopzione bermua dana avr un valore inferiore ad una americana, in quanto si ha una a restrizione del diritto di esercizio da parte del proprietario. Il bene nanziario oggetto di un contratto di opzione, si dice sottostante. Sempre riguardo alla nomenclatura utilizzata in nanza, unopzione si dir a di tipo call se d diritto ad acquistare il sottostante, mentre sar di tipo put a a nel caso in cui dia diritto a venderlo. A titolo esemplicativo, consideriamo unopzione che d diritto ad acquistare a delle azioni ENEL fra 1 mese ad un prezzo di 4 EUR. Si tratta in questo caso di unopzione europea, di tipo call, con maturity ad 1 mese ed uno strike price di 4 EUR.
3 Per la precisione, le opzioni con esercizio bermudano non rientrano tra quelle plain vanilla, e andrebbero gi considerate opzioni esotiche (vedi capitolo 2.4). a

2.1. IL CONTESTO - ELEMENTI DI FINANZA

141

E ovvio che unopzione verr esercitata dal suo possessore solo se questo a porta ad un protto. Ci signica che nel caso di unopzione call il prezzo o a scadenza del sottostante dovr essere maggiore dello strike price, mentre a per una put dovr essere inferiore; diversamente il proprietario dellopzione a non eserciter il suo diritto. a Se indichiamo con S(0) il prezzo del sottostante al tempo t = 0, con T il tempo mancante alla scadenza dellopzione e con E lo strike price, allora il protto (detto pay-o) per unopzione europea alla data di maturit (cio a e al tempo T ) sar nel caso di una call: a Pay-ocall = M ax [S(T ) E, 0] , mentre per una put: Pay-oput = M ax [E S(T ), 0] . (2.10) (2.9)

Il graco dei due pay-o riportato in gura 2.1 In altri termini alla dae
Pay-off

Pay-off

S(T)

S(T)

Call

Put

Figura 2.1: Pay-o plain vanilla(call e put). ta di maturit, il valore dellopzione diventa certo (ovvero deterministico) a ed stabilito dallequazione riportata sopra. Viceversa per ogni istante di e tempo precedente, il valore di questo diritto va valutato usando modelli probabilistici, perch nessuno in grado di prevedere deterministicamente e e come evolver il prezzo del sottostante. Il grande merito di Black e Scholes a stato quello di creare un modello scientico razionale che consentisse di e valutare correttamente il prezzo di unopzione [19]. Da quanto detto chiaro e che il modello di Black & Scholes, cos come qualunque altro modello che voglia stabilire il prezzo di unopzione, si basa necessariamente su una teoria stocastica per descrivere il movimento dei prezzi del sottostante. E interessante osservare che il pay-o di unopzione call o put dipende solo dalla dierenza tra il valore del sottostante ed il prezzo di esercizio E. Il sottoscrittore dellopzione pu realizzare questo protto esercitando il proo prio diritto, ovvero, nel caso di una call, acquistando lazione al prezzo E e subito rivendendola al suo prezzo di mercato S(T ). Molto spesso lopzione

142

CAPITOLO 2. ELEMENTI DI FINANZA

viene regolata versando al suo proprietario direttamente il protto S(T ) E (nel caso di una call) evitando di consegnare sicamente il sottostante. Le opzioni in cui il pay-o viene regolato in contanti, prendono il nome di cash option, mentre quelle dove viene eettivamente consegnato il sottostante, prendono il nome di delivery option. E abbastanza chiaro che, dal punto di vista del calcolo del prezzo, una delivery option equivalente ad una e cash option. Nel seguito, per semplicit, supporremo sempre di considerare a opzioni che regolano il pay-o in modalit cash. a Inne dobbiamo osservare che unopzione un contratto e come tale e coinvolge sempre due parti: chi acquista lopzione e chi la vende (in gergo nanziario questultimo viene indicato come colui che scrive lopzione). Il possessore dellopzione acquisisce un diritto e di conseguenza dovr cora rispondere, al tempo iniziale, un premio a chi ha venduto lopzione. Alla data di maturit sar chi ha scritto lopzione a dover garantire il pagamento a a del pay-o in caso di esercizio da parte dellacquirente. In gergo nanziario si aerma che chi vende lopzione va corto e chi lacquista va lungo. Di conseguenza nel caso di unopzione di tipo call ci saranno due possibili posizioni: 1) call lunga (acquisto il diritto); 2) call corta (vendo il diritto, ovvero contraggo un obbligo, ricevendo in cambio un premio iniziale). Si noti che a tutti gli eetti, unopzione pu essere vista come una sorta di o assicurazione, in cui chi va lungo lassicurato e chi va corto lassicuratore. e e La principale dierenza sta nel fatto che le opzioni possono essere utilizzate anche a ni puramente speculativi. 2.1.6.c Eetto leva delle opzioni

Come dovrebbe essere emerso in maniera abbastanza chiara dalla discussione condotta no ad ora, le opzioni si caratterizzano per il loro elevato grado di incertezza. Il pay-o corrisposto da unopzione a scadenza dipende dallandamento del sottostante. Poich il sottostante segue unevoluzione e stocastica (come illustreremo in maniera pi precisa nel prossimo capitolo) u ovvio che anche il valore di unopzione sar caratterizzato da una forte e a componente probabilistica. Anzi per unopzione la cosa ancora pi vera e u che per il sottostante. Consideriamo il seguente esempio: supponiamo di acquistare, in data odierna, unazione al prezzo di 100 EUR. Supponiamo poi che a distanza di un anno lazione venga quotata 120 EUR. In altri termini lazione ha subito un incremento del 20%, ci signica che investendo o un capitale di 100 EUR abbiamo realizzato un guadagno di 20 EUR. Viceversa supponiamo di investire la medesima cifra di 100 EUR nellacquisto di unopzioni call su questa azione con strike price pari a 100 EUR e data di maturit fra un anno. Il prezzo della call sullazione di 10.002 EUR4 , quina e
4 Il prezzo ottenuto applicando la formula di Black & Scholes (vedi paragrafo 2.3.5), e considerando un tasso r = 3% e una volatilit = 21.5%. Abbiamo anche supposto che a

2.1. IL CONTESTO - ELEMENTI DI FINANZA

143

di con 100 EUR possiamo comprare il diritto ad acquistare fra un anno circa 10 azioni al prezzo di 100 EUR. Perci il guadagno netto che realizziamo o dopo un anno (nel caso di un fortunato aumento del 20% nel prezzo dellazione) : 10 (120 100) 100 = 100 EUR, ovvero un guadagno del 100%! e Questo comportamento noto come eetto leva. Ovviamente poich nel e e mercato, per il principio di non arbitraggio, non si hanno free lunch, ad una maggiore possibilit di guadagno corrisponde sempre un maggior rischio. In a eetti nel caso di un calo nel prezzo dellazione, la call option pu andare o 5 e linvestimento iniziale andare cos completamente perso. out of the money Nellesempio riportato sopra, se a distanza di un anno lazione subisse un calo del 5%, linvestitore che ha acquistato lazione perderebbe solo 5 EUR, mentre lacquirente delle opzioni call perderebbe lintero capitale. In denitiva il mercato delle opzioni notevolmente pi rischioso e come u quindi molto importante poter calcolare con plesso di quello azionario. E precisione il valore di unopzione. Mentre per nel caso di un bond la deo terminazione del prezzo si riduce a scontare ussi di cassa certi, nel caso di unopzione si tratter di scontare ussi di cassa incerti. E quindi necessario a ricorrere al calcolo stocastico al ne di determinare probabilisticamente il valore del pay-o a scadenza, per poterlo poi scontare ad oggi. Come vedremo nel capitolo 2.3, per le opzioni plain vanilla possibile ottenere delle e formule chiuse per il prezzo del contratto.

lazione non paghi dividendi durante lanno. 5 Un gergo nanziario per indicare che lopzione non viene esercitata ed perci priva e o di valore

144

CAPITOLO 2. ELEMENTI DI FINANZA

2.2

Processi stocastici per descrivere le azioni

Questo capitolo dedicato alla discussione dei processi stocastici, con partie colare riguardo a quelli markoviani e di Wiener; questi ultimi, come vedremo, svolgono un ruolo fondamentale in nanza. Oltre a denire le diverse tipologie di processi stocastici e discutere le motivazioni che portano a modellizzare i movimenti azionari tramite processi di Wiener, presenteremo anche il famoso lemma di Ito che avr un ruolo chiave a nellargomentazione di Black & Scholes per il pricing di unopzione.

2.2.1

Introduzione

Una delle cose pi sorprendenti che un sico pu incontrare leggendo un testo u o di nanza, scoprire che il modello pi largamente utilizzato per descrivere e u i movimenti casuali nei prezzi azionari il ben noto modello browniano. e Da un punto di vista storico, il random walk fu introdotto da Einstein per giusticare il moto browniano cui soggetto un granello di polline immerso e in un liquido. Gli urti a cui il granello soggetto da parte delle molecole e dacqua, porta ad un classico cammino casuale che ben descritto dal mode ello random walk (vedi paragrafo 2.2.2). Facendo un parallelo tra il moto browniano della sica e le oscillazioni nel valore di unazione, possiamo immaginare che le informazioni che arrivino alla borsa svolgano lo stesso eetto degli urti delle molecole dacqua, in altri termini ciascuna delle molte informazioni che pervadono il mercato nanziario ha leetto di portare ad una piccola variazione (al rialzo o al ribasso) nel prezzo dellazione. Lazione combinata di tutte le informazioni fa si che il prezzo dellazione si muova in accordo con un random walk. Naturalmente questa solo una giusticazione e qualitativa di carattere euristico, ed in eetti indagini pi quantitative hanu no messo in discussione questo modello (vedi paragrafo 2.2.6). In questo capitolo introdurremo dapprima il modello random walk, considerandone il limite continuo, per poi passare alla discussione dei processi di Wiener e di Ito, entrambi sottoclassi dei pi generali processi markoviani. u Successivamente vedremo come i processi stocastici di Wiener possano essere utilizzati nellambito della nanza e con quali limiti. Concluderemo quindi con lenunciazione e la dimostrazione del lemma di Ito.

2.2.2

Il modello random walk

Si consideri una variabile w che assume i valori: s s con probabilit pleft = p a con probabilit pright = 1 p a

(2.11)

Consideriamo ora una serie di salti, {wi }, di ampiezza S e durata t ed n esaminiamo il valore assunto dalla variabile x = i=1 wi . Da un punto

2.2. PROCESSI STOCASTICI PER DESCRIVERE LE AZIONI

145

di vista intuitivo la grandezza x(t = n t) pu essere riguardata come il o cammino percorso in un tempo t = n t, da un ubriaco che si sposti aleatoriamente in accordo alleq. (2.11). E chiaro che anche x una variabile aleatoria, e per il teorema del limite e
p 1-p

x-s

x PD(x,t)

x+s

Figura 2.2: Random walk. centrale sar caratterizzata, nel limite n , da una distribuzione gausa siana. Se introduciamo la densit di probabilit nel discreto PD (x, t), denita come a a la probabilit di trovare il walker nel punto x al tempo t, allora possiamo a scrivere per PD la seguente equazione fondamentale 6 : PD (x, t + t) = p PD (x s, t) + (1 p) PD (x + s, t) . con condizioni al contorno date da: PD (x, t = 0) = x,0 ; (2.13) (2.12)

ovvero al tempo iniziale (t = 0) abbiamo la certezza di trovare il walker nellorigine (x = 0). 1 Riscrivendo p come: p = 2 + k, lequazione sopra diventa: PD (x, t + t) PD (x, t) = PD (x + s, t) + PD (x s, t) 2PD (x, t) 2 (2.14)

k [PD (x + s, t) PD (x s, t)] .

Se ora consideriamo il limite del continuo, t 0 e s 0, utilizzando la seguente ricetta: n t = t valore nito , s2 lim = b2 valore nito , t0 t s lim 2 k = a valore nito , t0 t PD PD (x, t + t) PD (x, t) + t , t
6

(2.15)

Vedi gura 2.2.

146

CAPITOLO 2. ELEMENTI DI FINANZA PD (x s, t) PD (x, t) P (x, t) = PD (x, t) , s PD 1 2 PD s + s2 , x 2 x2

dove abbiamo indicato con P (x, t) la densit di probabilit nel continuo. In a a eetti lultima equazione si giustica osservando che: 1=
x

PD (x, t) =
x

PD (x, t) s = s

P (x, t) s =
x

P (x, t) dx ,

(2.16) garantendo quindi la consueta normalizzazione della densit di probabilit a a nel limite del continuo. Osserviamo inne che le condizioni (2.16) implicano: k = 1 ba S S 2 2 0; ovvero per avere un corretto limite nel continuo necessario che la dife ferenza tra la probabilit di salto a sinistra (pleft = p) e quella di salto a a destra (pright = 1 p), svanisca nel limite in cui il passo reticolare S vada a zero. Il modo in cui per pleft pright tende a zero determina un o diverso comportamente del modello nel continuo (ovvero diversi valori per i parametri a e b). Con le trasformazioni indicate sopra, la master equation per la distribuzione di probabilit del walker si traduce, nel continuo, in unequazione dierena ziale alle derivate parziali: P 1 2P P = a + b2 , t x 2 x2 con la condizione al contorno: P (x, t = 0) = (x) delta di Dirac. Se ora consideriamo il cambio di variabile: t =t x = b1 (x a t) lequazione (2.17) si pu riscrivere come: o P 1 2P = , t 2 x 2 ovvero la classica equazione del calore. La soluzione, con il vincolo (2.18), la solita gaussiana: e
x2 1 P (x , t ) = e 2t , 2t b

(2.17)

(2.18)

, ,

(2.19)

(2.20)

2.2. PROCESSI STOCASTICI PER DESCRIVERE LE AZIONI con media nulla e varianza t . In termini delle variabili iniziali x e t:
(xa t)2 1 P (x, t) = e 2 b 2 t . 2t b

147

(2.21)

E quindi immediato dimostrare che:


+

1 x (x x )2

=
+

P (x, t) dx = 1 , x P (x, t) dx = a t ,
+

= =

(2.22)

(x x )2 P (x, t) dx = b2 t , (2.23)

in altri termini la distribuzione di probabilit P (x, trasla con velocit a t) a uniforme a t ed ha una deviazione standard pari a: b t (ovvero il ben noto risultato, secondo cui in un random walk la deviazione standard del cammino percorso, x, scala come la radice quadrata del tempo). Se consideriamo un intervallo t molto breve, diciamo dt, possiamo scrivere: dx = a dt + bdz , (2.24)

dove dz una variabile stocastica con varianza pari a dt. e Le due equazioni: (2.17) e (2.24), sono due diverse descrizioni dello stesso fenomeno. La prima rappresenta lequazione dierenziale alle derivate parziali per la distribuzione di probabilit della variabile x(t), mentre la a seconda costituisce lequazione dierenziale stocastica che descrive direttamente levoluzione di x(t).

2.2.3

Processi di Wiener e di Ito

Il modello random walk visto nel paragrafo precedente, rappresenta la versione discretizzata di quello che comunemente viene chiamato processo di Wiener. A questo proposito diamo la seguente denizione: Def. Si dice che una variabile stocastica x segue un processo di Wiener generalizzato se la variazione dx da essa subita in un intervallo di tempo innitesimo dt, data dalla seguente formula: e dx = a dt + b dz . (2.25)

La costante a viene comunemente indicata come il drift del processo, mentre b prende il nome di volatilit. dz rappresenta la componente stocastica e a

148

CAPITOLO 2. ELEMENTI DI FINANZA

corrisponde ad un numero casuale estratto da una distribuzione normale con media nulla e varianza pari a dt. Possiamo dunque riscrivere dz come: dz = w dt, dove w una variabile aleatoria la cui densit di probabilit, e a a P (w), una distribuzione gaussiana con varianza unitaria e media nulla: e
w2 1 P (w) = e 2 dw . 2

(2.26)

Se F una funzione di w, deniremo il valore di aspettazione di F come: e

F =

F (w) P (w) dw .

(2.27)

Considerando il cambio di variabile dz = w dt, immediato vericare che e dz 2 = dt. Si osservi che nel caso un cui b = 0, lequazione (2.25) si riduce ad una semplice equazione dierenziale ordinaria, la cui soluzione banalmente: e x(t) = x0 + a t. Il fatto che sia presente anche il termine dz cambia completamente la natura del problema, in quanto levoluzione di x non risulta pi deterministica ma aleatoria, in altri termini, non si ha pi a che fare u u con unequazione dierenziale ordinaria ma con unequazione dierenziale stocastica.

2.2.4

Lemma di Ito

Una ulteriore generalizzazione dei processi di Wiener sono i cosiddetti processi stocastici di Ito. Diamo la seguente denizione: Def. Si dice che una variabile stocastica x segue un processo di Ito se la sua variazione dx in un intervallo di tempo innitesimo dt data dalla e formula: dx = a(x, t) dt + b(x, t) dz (2.28) In altri termini un processo generalizzato di Wiener un caso particolare di e un processo di Ito in cui le funzioni a(x, t) e b(x, t) sono costanti. Relativamente a questi processi, un importante risultato dato dal noto e lemma di Ito: Lemma di Ito Sia x una variabile stocastica che segua un processo di Ito con drift a(x, t) e volatilit b(x, t); sia F (x, t) una funzione di x e del a tempo t. Allora anche F segue un processo stocastico di Ito, con drift: a e volatilit: a b F 1 2F F + + b2 , x t 2 x2 F . x (2.29)

(2.30)

2.2. PROCESSI STOCASTICI PER DESCRIVERE LE AZIONI

149

In questo paragrafo esporremo unargomentazione euristica a sostegno del lemma di Ito. Dim. La funzione F dipende dalle due variabili: x e t. A sua volta x segue un processo di Ito che dipende dal tempo e dalla variabile stocastica dz. La variazione di F , a seguito di variazioni innitesime in x e t, : e dF = F F 1 2F 2 1 2F 2 2F dx + dx + dt + dt + dx dt , x t 2 x2 2 t xt (2.31)

dove abbiamo arrestato lo sviluppo di Taylor al secondo ordine. Si noti che dx dipende dal tempo dt sia direttamente, sia indirettamente tramite dz. Ricordiamo infatti che dz una variabile stocastica estratta e da una distribuzione normale con media nulla e varianza pari a dt (ovvero dz = w dt). Tronchiamo ora lo sviluppo (2.31), trattenendo soli i termini deterministici di ordine dt e quelli stocastici di ordine dt. In tal modo rimangono solo i fattori: dx, dt e dx2 . In eetti si potrebbe rimanere sorpresi dal fatto che dx2 rientri tra i termini da conservare. Basta per osservare che: dx2 = o 2 (dz)2 +o(dt) e che (dz)2 una variabile aleatoria che ha media: (dz)2 = dt b e e varianza: 2 (dz)2 (dz)2 dt2 , (2.32) pertanto la parte stocastica di dx2 , essendo di ordine dt, trascurabile rispete to a dz dt ma la sua parte deterministica (approssimabile con (dz)2 ), essendo di ordine dt, non pu essere scartata. o In denitiva: dF = a F F 1 2F + + b2 x t 2 x2 dt + b F dz . x (2.33)

c.v.d. Questo risultato particolarmente utile nel caso dello studio di opzioni, e in quanto come vedremo fra breve, le azioni sono modellate tramite un processi di Wiener generalizzato e poich le opzioni non sono altro che funzioni e del proprio sottostante chiaro che ad esse pu essere applicato il lemma di e o Ito. Come curiosit ci si potrebbe chiedere se sia possibile scrivere unopzione a che abbia come sottostante unaltra opzione. Questo non solo concettuale mente possibile ma viene anche realizzato nella pratica; sul mercato si trovano a volte opzioni che consentono alla data di maturit di acquistare a o vendere opzioni su un certo sottostante (si parla in tali casi di opzioni composte). Perci a partire da un sottostante reale (ad es. unazione) o e idealmente possibile costruire una intera gerarchia di opzioni che possiamo indicare con {O(i) }, dove lopzione i-esima ha come sottostante lopzione

150

CAPITOLO 2. ELEMENTI DI FINANZA

(i-1)-esima e O0 S rappresenta unazione. La cosa interessante che se e ci limitiamo a considerare opzioni in cui il valore del pay-o dipende solo dal valore del sottostante alla data di maturity7 , il prezzo dellopzione O1 sar funzione unicamente del prezzo del sottostante S e del tempo t. Perci a o in base al lemma di Ito anche il valore di O(1) seguir un processo di Ito, e a per induzione lo stesso sar vero per ogni O(i) , i > 1. Esistono per molte a o opzioni in cui il pay-o dipende dalla storia del sottostante8 e non solo dal suo valore nale (queste opzioni sono dette path dependent). In questi casi il prezzo dellopzione, istante per istante, non detto che segua un procese so di Ito e perci la gerarchia creata sopra potrebbe condurre a variabili o stocastiche non appartenenti alla famiglia dei processi di Ito.

2.2.5

Processi di Markov

I processi di Wiener generalizzati ed i processi di Ito, sono a loro volta casi particolari di una pi ampia classe di processi stocastici detti di Markov. u Un processo markoviano caratterizzato dal fatto che la variazione dx della e variabile stocastica x in un intervallo di tempo dt, dipende solamente dal valore assunto da x al tempo t e non dalla sua storia precedente. In altri termini il cammino seguito dalla variabile per giungere al suo valore attuale non inuenza la sua evoluzione futura. I processi stocastici che abbiamo esaminato nei paragra precedenti sono casi molto particolari di processi markoviani in cui la componente casuale segue una distribuzione gaussiana. Esempi di processi markoviani che non rientrano in quelli di Ito sono ad esempio i processi di Levy, che hanno assunto una certa importanza in nanza [10]. Come abbiamo visto nei paragra precedenti, i processi di Wiener generalizzati sono lequivalente continuo di un random walk e sono caratterizzati da un distribuzione probabilistica gaussiana che evolve nel tempo con una varianza proporzionale a t. Questi processi vengono anche detti diusivi in quanto la loro varianza evolve linearmente col tempo. Dal punto di vista discreto, un processo di Wiener e caratterizzato da una particella che compie salti casuali, ciascuno dei quali relativamente piccolo (nel modello del paragrafo 2.2.2, assumevamo che e ogni salto avesse ampiezza costante s). Di contro si potrebbe esaminare un processo discreto, in cui a salti di piccola entit si inframmezzano salti a maggiori (ights). In tale situazione, la particella esplorer una porzione di a spazio pi grande (il processo cos originato si dir di tipo super-diusivo), e u a il percorso risultante sar caratterizzato da linee raggomitolate, molto sima ili a quelle generate da un random walk, disconnesse le une dalle altre da salti bruschi. I processi di Levy non sono altro che lequivalente continuo di questi modelli discreti e sono caratterizzati da una varianza che tende a divergere.
7 8

Ovvero opzioni con esercizio europeo non path dependent Ad esempio nel caso di opzioni asiatiche (vedi paragrafo 2.4.1).

2.2. PROCESSI STOCASTICI PER DESCRIVERE LE AZIONI

151

2.2.6

Il processo log normale come modello per le azioni

Una delle assunzioni fondamentali che vengono fatte in nanza che levoluzione e nei prezzi di una azione, segua un processo di tipo markoviano. Ci signica o che ai ni del mercato, lunica cosa che conta per il futuro di un unazione e il suo prezzo corrente. In altri termini, tenendo presente che le variazioni nei prezzi azionari sono di tipo aleatorio, ipotizzare per tali movimenti un processo di Markov equivale ad assumere che la distribuzione probabilistica per il prezzo futuro di unazione dipenda unicamente dal suo prezzo corrente. Poich le variazioni nei prezzi delle azioni sono determinate dalla infore mazioni che arrivano alla borsa, lassunzione precedente in stretta relazione e con la cosiddetta ipotesi di ecienza debole del mercato. Questa aerma che tutte le informazioni disponibili sul mercato sono racchiuse completamente nel prezzo attuale delle azioni. Una conseguenza immediata di quanto aermato sopra, linfondatezza dele la cosiddetta analisi tecnica. Questa una pratica abbastanza diusa in e nanza, la quale pretende di fornire delle previsioni sugli andamenti azionari futuri, partendo dallanalisi dei graci delle serie storiche dei prezzi azionari. I sostenitori dellanalisi tecnica, asseriscono di poter realizzare guadagni maggiori, grazie alle informazioni ricavate da tale pratica. Comunque. ad avviso del sottoscritto un mercato eciente, ovvero un mercato in cui sono eliminate le opportunit di arbitraggio, non implica aua tomaticamente il fatto che tutti i titoli in esso trattati seguano necessariamente processi markoviani. Semplicemente i processi stocastici che caratterizzano i vari strumenti, sono tali da non consentire, tramite lanalisi delle serie storiche, la realizzazione di un guadagno certo maggiore del tasso risk free. Esistono ovviamente molti cammini stocastici non markoviani che godono di questa caratteristica. Vedremo in particolare nel paragrafo 5.1.3 come sia possibile denire strumenti di mercato che pur non violando lipotesi di assenza di arbitraggio, ugualmente non seguono un cammino markoviano (e dove quindi la storia dei prezzi importante per conoscere levoluzione e futura). In conclusione, la vera motivazione in base alla quale riutare la teoria dellanalisi tecnica, il fatto che questa violerebbe clamorosamente e lipotesi di non arbitraggio. Generalmente non solo si suppone che le variazioni percentuali nei prezzi delle azioni9 seguano un processo markoviano, ma addirittura che siano in accordo con un processo di Wiener generalizzato. Questa proposta fu formu lata da Bachelier nel suo lavoro di tesi di dottorato ([12]). E sorprendente il fatto che Bachelier abbia introdotto e studiato il moto browniano quasi cinque anni prima di Einstein. Ovviamente assumere per i ritorni nei rendimenti azionari una distribuzione
9

Ovvero:

S(t+t)S(t) S(t)

S S

152

CAPITOLO 2. ELEMENTI DI FINANZA

log-normale, unipotesi molto forte. Al di l delle giusticazioni di carate a tere euristico, date nel paragrafo 2.2.1, ovvio che tale assunzione vada e sottoposta ad una attenta indagine empirica. Relativamente allassunzione di markovianit nella serie storica dei prezzi a azionari, diverse sono gli studi che hanno esaminato lautocorrelazione nei ritorni dei prezzi. I risultati ottenuti [10], mostrano che lautocorrelazione nei ritorni azionari tende a sopravvivere solo per intervalli di tempo molto piccoli, generalmente dellordine di alcuni minuti. E quindi abbastanza giusticato descrivere le oscillazioni nei prezzi azionari, tramite processi markoviani. Riguardo allassunzione di log normalit nella distribuzione dei ritorni, la a prima analisi approfondita fu condotta da Mandelbrot in un famoso articolo del 1963 [13]. Mandelbrot consider la serie storica dei prezzi del cotone su o un intervallo di tempo molto lungo, riscontrando una deviazione dal previsto comportamento log-normale in corrispondenza delle code della distribuzione. Le code di una distribuzione dei ritorni dei prezzi rappresentano gli eventi in qualche modo estremi, ovvero i grandi crolli o i forti guadagni. In accordo alla teoria standard che descrive le variazioni percentuali nei prezzi delle azioni tramite un processo browniano, si sarebbe portati a concludere che i grandi shock azionari (positivi o negativi) avverrebbero con una probabilit a che tende a calare esponenzialmente. In eetti lindagine di Mandelbrot dimostr che le forti oscillazioni di borsa sono pi probabili di quanto non o u prescriva la teoria ordinaria. In particolare Mandelbrot propose di descrivere la distribuzione dei ritorni tramite un processo stabile di Levy. Questi processi stocastici sono caratterizzati da delle distribuzioni di probabilit a con code (eventi estremi) che presentano un andamento a legge di potenza (tipo 1/x ) e che sono quindi pi grasse delle corrispondenti code espou nenziali dei processi di Wiener [14]. Successive analisi empiriche sulle serie nanziarie, hanno confermato linadeguatezza del modello proposto da Bachelier. Attualmente la ricerca si concentra nello studio di dinamiche stocastiche alternative per descrivere la distribuzione dei ritorni azionari 10 . Resta comunque il fatto che, al momento, in nanza il modello correntemente utilizzato rimane quello log-normale. Questo ha due importanti conseguenze pratiche: 1) da un lato si tende a sottostimare i rischi di possibili perdite; 2) dallaltro si commetter un certo a errore nel pricing di strumenti derivati. In conclusione il modello standard utilizzato in nanza per descrivere i movimenti azionari pu essere enunciato come segue: o

Alcuni articoli interessanti che costituiscono un buon esempio del tipo di ricerca oggi condotta sul tema dellanalisi delle serie storiche nanziarie e delle leggi di scala che le governano, sono riportati nelle referenze [15, 16, 17, 18].

10

2.2. PROCESSI STOCASTICI PER DESCRIVERE LE AZIONI

153

Def. Sia S(t) il prezzo di unazione al tempo t. Le variazioni nel prezzo dellazione sono descritte dal seguente processo di Ito: dS = dS + dz S (2.34)

In altri termini le variazioni percentuali dei prezzi azionari sono caratterizzate da un termine deterministico, proporzionale a , e da un termine aleatorio gaussiano. La costante prende il nome di fattore di drift mentre la costante viene indicata in nanza con il termine volatilit (nel seguito utilizzeremo sempre a per la volatilit il simbolo ). a Dalla denizione data sopra, e ricordando il lemma di Ito, si deduce immediatamente che: 2 d log S = dt + dz , (2.35) 2 ovvero il logaritmo dei prezzi caratterizzato da un processo di Wiener e generalizzato; si dice anche che il prezzo dellazione segue un processo lognormale. Dallequazione (2.35) si pu ottenere immediatamente la soluzione in forma o chiusa per il processo stocastico (2.34):


S(T ) = S0 e

T + T w

(2.36)

dove S0 il prezzo dellazione al tempo zero e w una variabile stocastica e e estratta da una distribuzione gaussiana con media nulla e varianza unitaria. Si pu facilmente dimostrare che la media di S, S(T ) data da e T . o e Questo consente di interpretare il termine di drift, , come il rendimento medio atteso di S su un periodo T .

154

CAPITOLO 2. ELEMENTI DI FINANZA

2.3
2.3.1

Analisi di Black Scholes per il pricing delle opzioni


Introduzione

Questo capitolo dedicato alla formula di Black & Scholes (nel seguito ine dicata con lacronimo BS). Questa formula estremamente importante sia e per ragioni storiche, sia pratiche. Fu la prima derivazione quantitativa di una formula per valutare il prezzo di unopzione [19]. Da un punto di vista pratico la formula di BS ancora oggi largamente utilizzata in nanza. e Il presente capitolo inizia esponendo in dettaglio largomentazione di Black & Scholes per il pricing di opzioni europee. Discuteremo poi il signicato di valutazione neutrale verso il rischio, un concetto chiave nel pricing dei derivati. Ricondurremo quindi lequazione dierenziale di Black & Scholes allequazione del calore che si soliti incontrare in sica e presenteremo la sua soluzione, la e famosa formula di BS, nel caso di unopzione plain vanilla. Inne sottoporremo ad analisi critica, le principali assunzioni su cui si basa la derivazione di BS.

2.3.2

Largomento di Black & Scholes

Nel 1973 compare sulla rivista Journal of Political Economy un articolo rmato da F. Black e M. Scholes [19]. Questo paper, che porter i suoi a autori al nobel, segna una svolta nel campo delloption pricing e pi in u generale della nanza quantitativa. Con esso, per la prima volta, veniva derivata una formula analitica (la cosiddetta formula di Black & Scholes) per calcolare il valore di unopzione plain vanilla. Dopo quasi trenta anni dalla pubblicazione di quellarticolo, la formula di Black & Scholes viene ancora utilizzata attivamente dagli operatori nanziari, nonostante i suoi evidenti limiti (che discuteremo successivamente in questo capitolo). Largomentazione di Black & Scholes per il calcolo del prezzo di unopzione europea plain vanilla, si basa su una serie di presupposti. Enunceremo in modo esplicito tutte le assunzioni fatte da BS al ne di stabilire i limiti di validit dei loro risultati. a Le principali assunzioni su cui si basa largomentazione standard di BS sono: (A) il sottostante segue un processo di Wiener generalizzato; inoltre la volatilit un parametro costante; ae (B) la curva dei tassi costante e (C) non esistono costi di transazione per operare sul mercato; (D) si suppone che le azioni possano essere acquistate e vendute anche in valori frazionari;

2.3. ANALISI DI BLACK SCHOLES PER IL PRICING DELLE OPZIONI155 (E) lazione sottostante non paga dividendi durante la vita dellopzione; (F) il mercato segue perfettamente lipotesi di non arbitraggio. La derivazione dellequazione dierenziale di Black & Scholes parte considerando unazione, il cui prezzo sia S(t), e un derivato qualsiasi costruito su di essa, il cui valore indichiamo con F . Se ci limitiamo a considerare un derivato che non sia path dependent, allora certamente possiamo assumere che F = F (S, t). Se ora utilizziamo lassunzione (A) e ricordiamo il risultato fornito dal lemma di Ito, possiamo scrivere le equazioni stocastiche che descrivono le variazioni di S e F : dS = Sdt + Sdz dF = S
F S

, +
1 2
2 S 2 2 F S 2

F t

dt + S

F S

dz ,

dove il punto essenziale dato dal fatto che il processo stocastico dz lo e e stesso in entrambe le equazioni. Questo fatto ci permette di considerare una combinazione lineare di S e F in cui non si abbia dipendenza da dz, ovvero in cui levoluzione sia completamente deterministica. In particolare supponiamo di denire un portafoglio composto dal derivato meno un numero di azioni pari a (sfruttiamo a questo proposito lipotesi (D)): = F S (2.37)

La variazione nel prezzo di in un intervallo di tempo innitesimo : e F 1 2F F F + + 2 S 2 2 S dt + S S dz . S t 2 S S (2.38) La variazione nel prezzo del portafoglio pu essere resa puramente detero ministica scegliendo per il seguente valore: d = S = F S (2.39)

naturalmente il valore di Delta potr essere ritenuto costante, e pari al valore a indicato dalleq. (2.39), solo per un intervallo innitesimo dt, in quanto la derivata di F rispetto a S tende a cambiare con il tempo. Sar quindi a necessario ri-eseguire un continuo ribilanciamento al ne di mantenere il portafoglio privo della componente stocastica (si parla in questo caso di hedging della posizione)11 . Poich il portafoglio evolve in maniera deterministica, per il principio di non e
Da un punto di vista teorico il ribilanciamento va eettuato in maniera continua. Questo non comporta alcun problema nel ragionamento di BS, in quanto ipotizziamo (punto (C)) che non vi siano costi di transazione.
11

156

CAPITOLO 2. ELEMENTI DI FINANZA

arbitraggio (ipotesi (E)) la variazione d deve essere la stessa che si avrebbe nel caso di un investimento privo di rischio, ovvero: d = r dt. Otteniamo quindi lequazione dierenziale alle derivate parziali di Black & Scholes: F F 1 2F + rS + 2 S 2 2 = rF . (2.40) t S 2 S Si osservi che questa equazione valida per un generico derivato, il cui e prezzo dipenda unicamente da S e t12 . La dierenza tra unopzione e laltra rimandata alle condizioni al contorno che si impongono su F al ne di e risolvere lequazione (2.40). In particolare, come abbiamo visto nel capitolo precedente, quello che caratterizza principalmente unopzione la formula e che assegna il pay-o nale sulla base del prezzo raggiunto dal sottostante. Pertanto la condizione al contorno a cui deve soddisfare F data da: e F (S, t = T ) = Pay-o(S) (2.41)

Il sistema formato da (2.40), completata con la condizione (2.41), sono sufcienti a derivare ununica soluzione. Nel paragrafo 2.3.5 vedremo come sia possibile risolvere esattamente lequazione di Black & Scholes nel caso di unopzione europea plain vanilla (put o call). E interessante sottolineare lestrema semplicit dellargomentazione di Black a & Scholes, che pur consistendo di pochissimi passaggi ha portato ad un risultato notevole, premiato con il Nobel. Di pi, essa fornisce una ricetta precisa, u utilizzata in tutto il mondo nanziario, per annullare il rischio connesso con unopzione. Infatti abbiamo visto come sia possibile creare un portafoglio, basato su una combinazione del derivato e del suo sottostante, in cui la com ponente stocastica sia assente. E chiaro che questa propriet del portafoglio, a , viene mantenuta solo per un intervallo di tempo innitesimo, in quanto = F/S tende a cambiare col tempo. E perci necessario eettuare o un continuo ribilanciamento al ne di mantenere il portafoglio privo di rischio. Nella pratica, questa operazione non pu essere eettuata in maniera o continua, sia per motivi pratici sia perch esistono dei costi di transazione e (trascurati nellargomentazione di BS). Ci fa si, che i portafogli nella realt o a non siano mai completamente privi di rischio. Ci si potrebbe domandare quale sia il senso di avere un portafoglio non soggetto a componenti aleatorie. Il motivo riconducibile al fatto che le opzioni hanno un contenuto e di rischio elevatissimo (come abbiamo spiegato nel paragrafo 2.1.6.c), ci o signica che a parte gli speculatori, tutti gli altri operatori di borsa hanno necessit di ridurre il rischio a cui sono esposti13 ; questo viene fatto a
Perci in questa trattazione non sono inclusi i derivati path dependent, in cui il valore o del derivato dipende anche dalla storia del sottostante. 13 In particolare esistono normative molto severe che richiedono alle istituzioni nanziarie di accantonare dei capitali tanto pi grandi quanto maggiori sono i rischi di mercato a cui u si espongono. In generale qualunque sala operativa di una banca, ssa limiti precisi per lesposizione al rischio. Questultimo viene calcolato in maniera quantitativa tramite una metodologia nota come Var: valore a rischio.
12

2.3. ANALISI DI BLACK SCHOLES PER IL PRICING DELLE OPZIONI157 utilizzando la tecnica di hedging descritta sopra.

2.3.3

Il concetto di valutazione neutrale verso il rischio

Lequazione di BS (2.40), dipende da alcuni importanti parametri quali il tasso di interesse privo di rischio r e la volatilit . Avremo modo nei a prossimi paragra di discutere questi aspetti. La cosa per pi interessante o u non tanto da quali fattori dipende lequazione di BS ma da quali non e dipende. In particolare si pu rimanere sorpresi dal fatto che nella formuo la (2.40) non compaia il termine , ovvero il tasso di crescita atteso per lazione sottostante S! Ci signica che il prezzo del derivato (ad esempio o di unopzione call) non dipende dal tasso di crescita del bene sottostante! Questo fatto, apparentemente controintuitivo, porta a denire un concetto chiave nella valutazione dei derivati, ovvero quello di mondo neutrale al rischio. Esaminiamo prima di tutto il signica di avversione al rischio. Investire su una azione comporta lesposizione ad un certo rischio. Lazione infatti pu aumentare, cos come perdere considerevolmente di valore. In generale o il mercato richieder che lazione fornisca un rendimento mediamente pi a u alto del tasso risk free, come compenso al rischio a cui si esposti. Questo e giustica il fatto che nel modello di evoluzione dei prezzi azionari, presentato nel paragrafo 2.2.6, abbiamo considerato un fattore di crescita, , distinto dal tasso privo di rischio r. Limportante risultato, rappresentato dallequazione di Black & Scholes, ha come corollario il fatto che il prezzo, F , del derivato non dipende da . Perci o possibile eettuare il pricing di F ipotizzando che il mercato sia neutrale e al rischio (ovvero ponendo = r). Ci comporta unenorme semplicazione, o come cercheremo di spiegare meglio nel prossimo paragrafo.

2.3.4

Alberi binomiali ad uno stadio e valutazione neutrale verso il rischio

In questo paragrafo andremo ad esaminare una situazione semplicata rispetto a quella considerata nel paragrafo 2.3.2. Questo al ne di discutere in dettaglio le argomentazioni che ci permettono di assumere una condizione di neutralit al rischio, durante la valutazione del prezzo di un derivato. a Supponiamo che oggi il valore di unazione sia S0 e che fra un periodo di tempo T , lazione possa assumere unicamente due valori: Sup con probabilit pup e Sdown con probabilit pdown (vedi gura 2.3). Questo modello a a e ovviamente una semplicazione estrema rispetto alla situazione reale, per o ci consentir di esaminare con maggiore dettaglio quanto aermato nel paraa grafo precedente. Il valore medio atteso per lazione S al tempo T dato da: e S(T ) = pup Sup + pdown Sdown , (2.42)

158

CAPITOLO 2. ELEMENTI DI FINANZA

S
Sup pup S0 erT S0 pdown T

Sdown

time
Figura 2.3: Albero binomiale ad uno stadio.

mentre la volatilit14 , nel prezzo futuro dellazione, sar: a a = (S(T ) S(T ) )2 = (Sup Sdown ) pup (1 pup ) . (2.43)

Poich linvestimento in S caratterizzato da una certa incertezza (data da e e ), il mercato richieder un rendimento medio atteso pi alto di quello che a u si avrebbe in un caso privo di rischio: S(T ) = S0 e()T () > r (2.44) Si dice in questi casi che il mercato avverso al rischio e che di conseguenza e richieda un premio per assumerne uno. Possiamo aspettarci naturalmente che: lim0 () = r. Si noti che linterpretazione di come rendimento atteso della media della distribuzione, esattamente lanalogo di quanto e ottenuto nel paragrafo 2.2.6 . Ovviamente se il mercato fosse completamente neutrale al rischio, ovvero se non si richiedesse alcun premio per assumere posizioni rischiose, si avrebbe = r. Nella realt, il mercato avverso al rischio e quindi > r, ovvero a e Sdown < S0 er T < Sup (in gura 2.3, questa considerazione si traduce nel fatto che il segmento terminante nel punto S0 er T , debba necessariamente rimanere connato tra i due possibili scenari evolutivi Sdown e Sup ).
14

Ovvero la deviazione standard

2.3. ANALISI DI BLACK SCHOLES PER IL PRICING DELLE OPZIONI159 Consideriamo ora un derivato scritto sopra lazione S. Il suo generico pay-o sar denito come: a F (t = T ) = Fup se S(T ) = Sup F (t = T ) = Fdown se S(T ) = Sdown (2.45) Anche in questo caso possiamo costruire un portafoglio perfettamente privo di rischio, considerando una opportuna combinazione lineare del sottostante e del derivato: = F S (2.46) dove una costante scelta in modo da eliminare la componente stocastica e dal portafoglio . In altri termini: up = Fup Sup = down = Fdown Sdown , da cui: = Fup Fdown . Sup Sdown (2.47)

(2.48)

Lequazione (2.48) esattamente lanalogo della condizione (2.39), dove al e posto delle derivate parziali abbiamo delle dierenze nite. Se ora imponiamo che la variazione nel valore del portafoglio sia pari a quella di un investimento privo di rischio: (T ) (0) = (0)erT (0), otteniamo lanalogo dellequazione di Black & Scholes: Fup Sup = erT (F0 S0 ) , (2.49)

dove lunica incognita il valore del derivato F0 ad oggi. e Si noti come, anche in questo caso, nellequazione non compaiano le probabilit pup e pdown . Ci signica che il prezzo F0 del derivato, non dipende a o dal tasso di crescita del valore atteso dellazione, . Questo esattamente e lo stesso risultato che abbiamo incontrato nei paragra 2.3.2 e 2.3.3. Lequazione (2.49) unita alle condizioni al contorno (2.45) pu essere facilo mente risolta, ottenendo: F0 = erT [Fup p + Fdown (1 p)] , dove: p= S0 erT Sdown . Sup Sdown (2.50)

(2.51)

Si osservi che la valutazione di F0 risulta totalmente indipendente dalla probabilit di rialzo eettiva, pup . a Si pu dare una semplice interpretazione della variabile p, invertendo leo quazione (2.42), ovvero esprimendo la probabilit pup in termini di : a pup = S0 eT Sdown , Sup Sdown (2.52)

160

CAPITOLO 2. ELEMENTI DI FINANZA

come si pu vedere la variabile p coincide con la probabilit di rialzo delo a lazione S, nel caso in cui il mercato fosse neutrale al rischio. Se ora vogliamo trovare qual il rendimento atteso sul derivato F , baster e a osservare che: F0 eT = F (T ) = Fup pup + Fdown (1 pup ) , (2.53)

sostituendo nellequazione (2.53) la (2.50), otteniamo la relazione che lega a e r: Fup pup + Fdown (1 pup ) eT = erT , (2.54) Fup p + Fdown (1 p) Come si vede il rendimento medio atteso sul derivato , dipende dal tasso risk free r e da (tramite pup ). Osserviamo che nel caso in cui il mercato sia neutrale al rischio ( = r) allora = r. E anche interessante esaminare il valore di in due semplici situazioni: Call option Supponiamo di considerare una call option, in cui lo strike price E sia compreso tra Sdown e Sup . In tal caso: Fdown = 0 e Fup = Sup E. Dallequazione (2.54) segue che: ecall T = erT S0 eT Sdown . S0 erT Sdown (2.55)

Poich in un mondo avverso al rischio > r, segue che call > r. e Put option Supponiamo di considerare una put option, in cui lo strike price E sia compreso tra Sdown e Sup . In tal caso: Fup = 0 e Fdown = E Sdown . Dallequazione (2.54) segue che: eput T = erT Sup S0 eT . Sup S0 erT (2.56)

Poich in un mondo avverso al rischio > r, segue che put < r. e Il risultato ottenuto per nel caso di una put option pu sembrare curioso, o in quanto il rendimento per questo tipo di strumento, in un mondo avverso al rischio, inferiore al tasso risk free. In realt la cosa perfettamente e a e coerente, in quanto la put svolge allinterno del portafoglio , il ruolo di unassicurazione contro i crolli azionari. Infatti se richiediamo allazione S un rendimento mediamente pi alto di r, per essere ripagati dellincertezza a u cui ci esponiamo, abbastanza ovvio che unassicurazione (put) che ci tuteli e dai movimenti sfavorevoli, Sdown , deve fornire un rendimento inferiore a r. In ogni caso per, il prezzo del derivato non dipender da . Se pi alto o a e u (ovvero se pup maggiore) la put avr una minore probabilit di esercizio, e a a

2.3. ANALISI DI BLACK SCHOLES PER IL PRICING DELLE OPZIONI161 ovvero generer un pay-o atteso minore, ma questo verr attualizzato con a a un fattore di sconto pi basso, non alterando quindi la stima di F0 . u Riassumendo, assumere unavversione al rischio da parte degli investitori porta ad avere per lazione un rendimento medio pi alto del tasso risk free e u per il derivato un rendimento che pu essere pi alto o pi basso a seconda di o u u come esso sia denito. La cosa per fondamentale e veramente importante, o che la stima del valore del derivato oggi non dipende da questi parametri. e In altri termini ai ni del calcolo del prezzo del derivato, possiamo assumere che il mondo sia perfettamente neutrale al rischio (ovvero = r) e valutare quindi il pay-o atteso (tramite il calcolo del valore di aspettazione su tutti i possibili scenari, ciascuno pesato con una probabilit neutrale al rischio) a attualizzandone il valore ad oggi tramite il tasso risk free. Questa ricetta, che trova la sua giusticazione teorica nelle formule (2.40) e (2.49), consente da un lato di semplicare notevolmente il problema del pricing di unopzione e dallaltro permette di prescindere dalla valutazione di . Infatti mentre la stima del tasso risk free relativamente agevole, valutare il valore di e e tuttaltro che semplice.

2.3.5

Soluzione dellequazione di Black & Scholes

Ritorniamo allequazione di Black & Scholes (2.40). Come abbiamo avuto modo di spiegare nel paragrafo 2.3.2, questa equazione valida per un genere ico derivato scritto sopra lazione S. Il punto in cui entrano le caratteristiche dei diversi derivati, sono le condizioni al contorno (vedi eq. (2.41)). Lequazione dierenziale alle derivate parziali (2.40), completata con la condizione (2.41), pu essere utilmente riscritta introducendo i seguenti cambi o di variabile: t=T , 1/2 2 F (S, t) = C v(x, ) , dove per ora C una costante generica. e Otteniamo cos la seguente equazione dierenziale: v 2v v = + (k 1) kv . 2 x x con la condizione al contorno v(x, 0) = P(x) . (2.61) (2.60) S = C ex , (2.57) (2.58) (2.59)

1 La costante k un parametro adimensionale dato da: k = r/ 2 2 . e Lequazione (2.60) molto simile allequazione del calore della sica, a parte e

162

CAPITOLO 2. ELEMENTI DI FINANZA

la presenza di termini in v/x e in v. Questi possono essere facilmente eliminati introducendo una funzione u(x, ) denita come: u(x, ) = ex v(x, ) . ottenendo: u 2 u u + = [(k 1) + 2] + u (k 1) + 2 k . x2 x Baster ora porre: a = k1 , 2 (k + 1)2 , 4 (2.63) (2.62)

= (k 1) + 2 k = per ottenere lusuale equazione del calore: u 2u = . x2

(2.64)

Lequazione dierenziale alle derivate parziali che denisce il pricing di un generico derivato di stile europeo quindi la ben nota equazione del e calore! Un risultato che mostra, ancora una volta, le similitudini che legano i modelli utilizzati in nanza con quelli della sica. E interessante ora considera un semplice caso, quello delle opzioni call eu ropee plain vanilla. In questo caso la condizione al contorno data da: Fcall option (S, t = T ) = M ax [S(T ) E, 0] . Se nel cambio di variabile (2.59) poniamo: C=E, la condizione (2.65) diventa: u(x, 0) = u0 (x) = M ax e
def.
k+1 x 2

(2.65)

(2.66)

k1 x 2

,0 =

e 0

k+1 x 2

k1 x 2

se x > 0 se x 0

La soluzione dellequazione (2.64), con le condizioni al contorno date sopra, : e (xs)2 1 u(x, ) = (2.67) u0 (s)e 4 ds . 2 Infatti nel limite 0 si ha:
0

lim u(x, ) =

u0 (s)(x s)ds = u0 (x) ,

(2.68)

2.3. ANALISI DI BLACK SCHOLES PER IL PRICING DELLE OPZIONI163 La formula (2.67) pu essere riscritta nella seguente maniera: o u(x, ) = I(x, , k + 1) I(x, , k 1) . dove: 1 I(x, , k 1) = 2

k1 s 2

(2.69)

e
0

(xs)2 4

ds .

(2.70)

Lintegrale I, pu essere riscritto considerando un cambio di variabile: o s = ay + b . dove a e b vanno determinare richiedendo che: k+1 (x s)2 1 s = y 2 + f (x, ) . 2 4 2 da questa condizione deriva immediatamente che: a = 2 , x k+1 + , b = 2 2 2 1 1 f (x, ) = (k + 1)2 + x(k + 1) , 4 2 e quindi: dove: I(x, , k + 1)) = e 4 (k+1) 1 N (d1 ) = 2 d1 =
1 2 + 1 x(k+1) 2

(2.71)

(2.72)

(2.73)

N (d1 ) ,

(2.74) (2.75)

+ d1

y2 2

dy ,

b 1 x = 2 (k + 1) + a 2 2

(2.76)

Se ora ri-sostituiamo a x, e u, le originarie variabili S, t e Fcall , otteniamo: Fcall option = erT SN (d1 )erT EN (d2 ) . con:
S log E + r + d1 = T S log E + r d2 = T 2 2

(2.77)

T T

, = d1 T .

(2.78) (2.79)

2 2

La formula (2.77) pu essere interpretata nel seguente modo: N (d2 ) la o e probabilit in un mondo neutrale verso il rischio, che lopzione venga esercia tata, cosicch E N (d2 ) rappresenta il valore atteso per il prezzo di esercizio. e

164

CAPITOLO 2. ELEMENTI DI FINANZA

Viceversa, SN (d1 )erT il valore atteso per una variabile che risulti uguale e a S(T ) se S(T ) > E ed invece nulla in caso contrario. e Analogamente si pu dimostrare che per unopzione put il valore dato o e dalla seguente formula: Fput option = erT EN (d2 ) SN (d1 )erT . (2.80)

Il termine N (d) che compare nelle formule di valutazione di Black & Scholes, la ben nota funzione di distribuzione normale cumulata. Questa e pu essere valutata tramite funzioni di libreria oppure ricorrendo a formule o approssimate. Riportiamo di seguito un schema per la sua valutazione, esatta no alla sesta cifra decimale: N (d) = dove: N (d) = 1 2 ed /2 , 2 1 k = , 1+d = 0.2316419 , 1 N (d) (a1 k + a2 k 2 + a3 k 3 + a4 k 4 + a5 k 5 ) quando d 0 1 N (d) quando d < 0,

a1 = 0.319381530 , a2 = 0.356563782 , a3 = 1.781477937 , a4 = 1.821255978 , a5 = 1.330274429 .

2.3.6

Critica allapproccio di Black & Scholes

Volendo sottoporre ad analisi critica, il modello proposto da BS per il pricing di unopzione, dobbiamo ritornare alle cinque assunzioni che ne stanno alla base (vedi paragrafo 2.3.2). Di queste, alcune possono essere rese meno stringenti, in particolare pose sibile derivare ugualmente delle formule di pricing esatte, nel caso in cui si abbia un tasso risk free che dipenda dal tempo in maniera deterministica. Ugualmente nel caso in cui = (t)15 . Anche le assunzioni C, D e E non pongono problemi seri. Inne lipotesi F un principio che dicilmente pu e o essere messo in discussione. Lunica vera ipotesi che risulta determinante lassunzione di log-normalit per le oscillazioni del sottostante. A questo e a
Anche in questo caso si deve per supporre che la dipendenza della volatilit dal tempo o a sia di natura deterministica. Se viceversa si introduce una volatilit stocastica, si perde a la trattabilit analitica. a
15

2.3. ANALISI DI BLACK SCHOLES PER IL PRICING DELLE OPZIONI165 riguardo, abbiamo gi evidenziato come le analisi empiriche mettano in disa cussione questo modello stocastico per le azioni. Non stupisce quindi che le formule di BS non siano perfettamente in linea con il mercato reale. La cosa particolarmente evidente nel calcolo della e volatilit implicita, come ora spiegheremo. a Uno dei pregi maggiori del modello di BS il fatto che questo dipenda da un e unico parametro non direttamente osservabile: la volatilit. Questultima a pu certamente essere calcolata utilizzando i dati storici dei prezzi del soto tostante, ma rimane comunque una grandezza non direttamente quotata dal mercato (a dierenza del tasso di interesse). Di fatto la formula di BS viene utilizzata dal mercato per ricavare, partendo dalle quotazioni delle opzioni trattate regolarmente, il valore di volatilit che dovrebbe avere il sottostante a per produrre il prezzo osservato. In altri termini si inverte lequazione di BS per ricavare . Questa stima prende il nome di volatilit implicita. a Se il modello di BS fosse corretto, ci si dovrebbe aspettare un valore di sigma implicito indipendente ad esempio dallo strike price delle opzioni considerate16 , questo perch la volatilit una propriet statistica del sottostante e a e a e non dellopzione. In realt, la volatilit implicita dipende da E, con un a a caratteristico andamento a smile. In pratica la volatilit sembra pi alta se a u si considerano opzioni molto in the money17 o out of the money18 e minore per le opzioni at the money. Per giusticare questo eetto di smile, necessario considerare dinamiche e alternative per il sottostante. A questo riguardo diverse sono le proposte avanzate [20].

16 Ovviamente prenderemo in considerazione diverse opzioni con uguale maturity, scritte sul medesimo sottostante e che per abbiano dierente strike price o 17 Nel caso di unopzione di tipo call, si usa lespressione in the money quando il prezzo ad oggi del sottostante maggiore dello strike price. Lopposto nel caso di una put. e 18 Nel caso di unopzione di tipo call, si dice che lopzione e out of the money quando il valore attuale del sottostante minore dello strike price. Viceversa nel caso di una put. e

166

CAPITOLO 2. ELEMENTI DI FINANZA

2.4

Opzioni esotiche

Fino ad ora abbiamo considerato le cosiddette opzioni plain vanilla, ovvero opzioni standard. In generale il mercato nel corso degli anni ha sviluppato opzioni con caratteristiche pi complesse rispetto alle semplici plain vanilla u esaminate nel paragrafo 2.1.6. Queste opzioni pi sosticate prendono il u nome di opzioni esotiche. Esistono una miriade di opzioni esotiche e, di fatto, una classicazione esaustiva dicilmente realizzabile, in quanto ogni e giorno ne vengono inventate di nuove. E comunque possibile illustrare le principali caratteristiche di quelle pi diuse. u

2.4.1

Opzioni asiatiche

In queste opzioni, che hanno sempre esercizio di tipo europeo, il pay-o denito confrontando lo strike price, non con il prezzo del sottostante e a scadenza, ma con la media dei prezzi durante la vita dellopzione. Le date di rilevazione da considerare al ne del calcolo della media possono corrispondere, per esempio, ad una frequenza mensile, piuttosto che ad un insieme di date non uniformemente distanziate. Le opzioni asiatiche sono il tipico esempio di opzioni path dependent, in cui cio il pay-o nale dipende non solo dal valore nale del sottostante ma e anche dalla sua storia.

2.4.2

Opzioni digitali

Nelle opzioni di tipo digital il pay-o pu assumere solo valori discreti. Un o tipico esempio lopzione call (put) cash or nothing in cui il pay-o pari a e e una quantit pressata K se alla data di maturity il valore del sottostante a maggiore (minore) dello strike price, E, oppure a zero diversamente (vedi e g. 2.4). Un altro esempio lopzione call (put) asset or nothing, in cui il pay-o e e pari al valore del sottostante se alla data di maturity questultimo maggiore e (minore) dello strike price, E, oppure a zero diversamente. E chiaro che una call (put) plain vanilla con strike, E, la somma di una e call (put) asset or nothing meno una call (put) cash or nothing con K uguale allo strike price E. Ovviamente gli esempi dati sopra sono molto semplici e per questi sono disponibili delle formule chiuse. In generale comunque possibile trovare e sul mercato opzioni digitali pi complesse. u

2.4.3

Opzioni con barriera

Queste opzioni sono un altro esempio di opzioni path dependent. Nelle opzioni con barriera il pay-o nale condizionato dal fatto che il prezzo e dellattivit sottostante abbia raggiunto o meno un certo livello (barriera). a

2.4. OPZIONI ESOTICHE


Pay-off

167

S(T)

Figura 2.4: Pay-o di unopzione digitale.

Anche per le opzioni con barriera esiste una esoticit notevole. Quelle pi a u comuni si dividono in due famiglie: le Knock in e le Knock out. Nelle opzioni Knock in il pay-o nale viene corrisposto solo se il sottostante ha raggiunto un certo livello durante la vita dellopzione; in altri termini sono opzioni che iniziano ad esistere solo se il sottostante colpisce una certa barriera. Per contro le opzioni Knock out pagano un pay-o nale solo se il sottostante non ha mai toccato la barriera. In altri termini possiamo dire che le Knock out sono opzioni che cessano di esistere nel momento in cui il sottostante tocca la barriera. Le opzioni con barriera sono sempre opzioni over the counter, ovvero opzioni che le societ nanziarie creano per soddisfare le esigenze della propria cliena tela. Sono richieste in quanto hanno un prezzo pi contenuto (avendo una u clausola per la validazione o lestinzione) rispetto alle corrispondenti opzioni plain vanilla. Come esempi di opzioni Knock in, citiamo le: opzioni down & in call (put): che danno il pay-o di una plain vanilla call (put) se il sottostante scende almeno una volta sotto la barriera, altrimenti non pagano nulla; opzioni up & in call (put): che corrispondono il pay-o di unopzione plain vanilla call (put) solo se il sottostante supera almeno una volta la barriera, diversamente non pagano nulla. come esempi di opzioni Knock out, citiamo le: opzioni down & out call (put): che danno il pay-o di una plain vanilla call (put) solo se il sottostante non scende mai sotto la barriera, altrimenti non pagano nulla;

168

CAPITOLO 2. ELEMENTI DI FINANZA

opzioni up & out call (put): che corrispondono il pay-o di unopzione plain vanilla call (put) solo se il sottostante non supera mai la barriera, diversamente non pagano nulla. Esistono poi opzioni con doppia barriera di tipo Knock out, in cui viene corrisposto un pay-o solo se il sottostante rimane connato tra le due barriere, oppure con doppia barriera di tipo Knock in, in cui il pay-o viene pagato solo se il sottostante, durante la vita dellopzione, supera la barriera superiore oppure scende sotto quella inferiore. Una ulteriore esoticit viene a ottenuta con le opzioni a cipolla (onion option). In questultime opzioni si deniscono una successione di barriere inferiori I1 > I2 > I3 ..... > In e superiori S1 < S2 < S3 ..... < Sn . Se durante la vita dellopzione il sottostante rimane connato nel corridoio pi interno (ovvero se I1 < S(t) < S1 t u (0, T )) allora viene pagato a scadenza un premio P1 ; se il sottostante supera una delle due barriere (L1 o S1 ) ma rimane connato nel corridoio successivo (I2 < S(t) < S2 t (0, T )) allora viene corrisposto un premio P2 < P 1; e cos via. Se il sottostante non rimane connato nemmeno nel corridoio pi u eterno (Ln , Sn ) allora non viene corrisposto alcun pay-o. Questo tipo di opzioni a cipolla, pu essere facilmente scomposto in una somma di opzioni o con doppia barriera di tipo Knock out. In particolare facile dimostrare che e il pay-o denito sopra pu essere riprodotto nella seguente maniera: o
N

Pay-o onion =
i=1

Pay-o double barrier(Ii , Si , Pi Pi1 ) .

(2.81)

dove P0 = 0 e Pay-o double barrier(Ii , Si , P ) il pay-o di unopzione e Knock out avente barriera inferiore Ii , barriera superiore Si e un premio a scadenza pari a P . Un elemento importante che viene sempre specicato nei contratti, oge ni quanto vericare leventuale raggiungimento della barriera. Usualmente nella maggior parte dei casi, si considera il valore di chiusura del sottostante in ogni giorno della vita dellopzione. Come ultima considerazione, interessante osservare che nelle opzioni con e barriera lassunzione di log-normalit per il processo che descrive il sota tostante ha conseguenze ancora pi importanti di quanto non avvenga per u le plain vanilla. Infatti le opzioni con barriera entrano in funzione (o scompaiono) in seguito ad eventi estremi come il tocco della barriera. Se la distribuzione dei ritorni del sottostante caratterizzata da code grasse, il e tocco di una eventuale barriera pi probabile. Possiamo quindi aspettarci, e u ad esempio, che unopzione down & out o up & out abbia un prezzo reale pi basso di quanto non prescriverebbe il modello di BS (in cui il tocco di u una barriera lontana dal valore attuale un evento sottostimato); lopposto e per unopzione down & in o up & in.

2.4. OPZIONI ESOTICHE

169

2.4.4

Opzioni cliquet e reverse cliquet

Unaltra tipologia di opzioni presente sul mercato, soprattutto quello francese, dato dalle cliquet option. In queste opzioni il pay-o denito nel seguente e e modo:
N 1

Pay-o call cliquet =


i=0 N 1

M ax [S(ti+1 ) S(ti ), 0] M ax [S(ti ) S(ti+1 ), 0]


i=0

(2.82) (2.83)

Pay-o put cliquet =

dove S(t) il sottostante, t0 la data attuale e {ti }i=1,...N un insieme di e e e date future. Il risultato ottenuto da queste opzioni quello di bloccare il guadagno che si e realizza con il passare del tempo. Consideriamo ad esempio una call cliquet su un indice S che al tempo iniziale valga 100, supponiamo di considerare tre date di rilevazione a 1, 2 e 3 anni. Se dopo il primo anno lazione vale 110 lopzione avr maturato un guadagno di 10 (che pagher a scadenza). a a A questo punto come se lo strike della nostra call option venisse ri-ssato e a 110. Alla ne del secondo anno se il sottostante chiude a 105 non verr a maturato alcun guadagno ma lo strike verr riportato a 105. Inne se al a compimento del terzo anno lazione arriva a 120, si avr un guadagno di 15. a In totale il pay-o corrisposto alla scadenza dellopzione sar: 10 + 0 + 15 = a 25. In altri termini possiamo dire che unopzione cliquet pu essere vista o come la somma di una serie di opzioni plain vanilla, una per ogni intervallo (ti , ti+1 ), con uno strike price che di volta in volta assume un valore pari a: S(ti ), i = 0, ...., N 1. Come si vede il vantaggio fondamentale oerto da questa tipologia di opzioni quello di garantire allacquirente un blocco nei guadagni via via realizzati. e E chiaro che questo vantaggio supplementare, come tutti i diritti, verr a pagato corrispondendo un premio pi alto al momento della sottoscrizione u dellopzione. Basta infatti osservare che: M ax [S(ti+1 ) S(ti ), 0] S(ti+1 ) S(ti ) , (2.84)

da cui: Pay-o call cliquet Pay-o call plain vanilla con strike S(t0 ). (Relazione analoga vale nel caso delle put.) Ci conferma che il prezzo di una o cliquet option sempre pi grande della corrispondente at the money plain e u vanilla option19 Una variante pi complicata delle cliquet sono le opzioni reverse cliquet. u
19 Per at the money plain vanilla option intendiamo una opzione standard in cui lo strike price sia pari al valore dellazione ad oggi.

170

CAPITOLO 2. ELEMENTI DI FINANZA

In esse il pay-o denito dalle seguenti formule: e


N 1

Pay-o reverse call cliquet = M ax 0, C


i=0 N 1

M ax [S(ti+1 ) S(ti ), 0] M ax [S(ti ) S(ti+1 ), 0]


i=0

Pay-o reverse put cliquet = M ax 0, C

(2.85) dove C una costante predenita. e In questo caso il gioco consiste nel partire da un pay-o potenziale molto alto (C), a cui via via si scalano le performance del sottostante (positive nel primo caso e negative nel secondo) maturate nei vari periodi. Le opzioni cliquet, avendo un pay-o dipendente dalla storia del sottostante, sono un altro esempio di path dependent option.

2.4.5

Opzioni lookback

Le opzione lookback possono essere di tipo call o put. Il pay-o, per queste opzioni, viene denito in accordo alle seguenti formule: Pay-o call lookback = M ax S(T ) M in [S(t)]t(0,T ) , 0 Pay-o put lookback = M ax M ax [S(t)]t(0,T ) S(T ), 0 (2.86) In altri termini la call (put) lookback option simile ad una call (put) e plain vanilla in cui per lo strike price non ssato allistante iniziale ma o e dato dal valore minimo (massimo) raggiunto dal sottostante durante la e vita dellopzione. Un elemento importante in questo tipo di opzioni perci e o la frequenza di osservazione del prezzo del sottostante. E infatti ovvio che rilevare il valore dellazione giornalmente piuttosto che settimanalmente pu o portare ad un cambiamento nella determinazione del minimo. Nel caso in cui si supponga di adottare unosservare continua, possibile derivare delle e formule di pricing esatte per questo tipo di opzioni. Anche le lookback option forniscono un ulteriore esempio di opzioni path dependent, in quanto il pay-o non dipende sola dal valore nale raggiunto dal sottostante, ma anche dalla sua storia precedente.

2.4.6

Opzioni su basket

Per concludere la nostra breve panoramica sulle opzioni esotiche pi diuse, u non possiamo non citare le opzioni scritte su basket di azioni. In questo caso la principale novit rispetto a tutte le tipologie viste no ad ora, consiste a nella presenza di pi sottostanti. Illustrare una casistica completa delle u

2.4. OPZIONI ESOTICHE

171

opzioni su basket trattate sul mercato impossibile, ci limiteremo quindi a e fornire alcuni esempi. 2.4.6.a Opzioni best asset

Nelle opzioni best asset il pay-o nale dato dal migliore (o peggiore) paye o scritto su ciascuna azione. Indichiamo con {Si }i=1,...,N un set di azioni e per ciascuna di queste deniamo un pay-oi (usualmente la denizione e la medesima per ogni asset Si ). Il pay-o dellopzione best asset denito e come: Pay-o = M ax [Pay-oi ] , (2.87) mentre per lopzione worst asset : e Pay-o = M in [Pay-oi ] , (2.88)

A titolo di esempio illustriamo due tipici casi. Consideriamo due sottostanti, S1 e S2 ; un esempio di opzione best asset sui due sottostanti data da: e S1 (T ) S2 (T ) Pay-o = M ax M ax 1, 0 , M ax 1, 0 , (2.89) S1 (t0 ) S2 (t0 ) dove t0 listante iniziale e T la maturity dellopzione. e e In questo caso abbiamo scelto come formula di pay-o sul singolo sottostante, quella di unopzione call plain vanilla. Si noti anche che lopzione best asset su S1 e S2 varr pi della migliore tra le opzioni plain vanilla scritte a u rispettivamente su S1 e S2 . Un altro esempio, che si incontra abbastanza spesso sul mercato, quello e di unopzione che paga un pay-o pari a K se durante la vita dellopzione nessuna delle azioni del basket ha una performance che scenda al di sotto di una certa percentuale p. In questo caso si tratta di unopzione worst asset, con un pay-o sulla singola azione di tipo knock out: Pay-oi = 2.4.6.b Opzioni su indici
S (t) K se Sii(0) > p t (0, T ) 0 diversamente

Molte volte si incontrano delle opzioni denite su basket di azioni in cui il pay-o viene specicato utilizzando unicamente un indice costruito sul basket. Generalmente un indice su un basket di N azioni denito assegnando: e 1) a ciascuna azione il peso pi (0 pi 1) che questa ha sullindice stesso ad un certo istante iniziale t0 ; 2) il valore dellindice al tempo t0 : I(t0 ) = I0 . Se consideriamo dunque lindice composto da n1 azioni S1 , n2 azioni S2 ecc. Avremo:
N

I(t) =
i=1

ni Si (t) ,

(2.90)

172

CAPITOLO 2. ELEMENTI DI FINANZA

imponendo la condizione sui pesi: ni Si (t0 ) = pi , I(t0 ) ne segue che:


N

(2.91)

I(t) = I(t0 )
i=1

pi

Si (t) . Si (t0 )

(2.92)

Poich, come abbiamo visto nel paragrafo 2.2.6, si assume generalmente che e la dinamica stocastica seguita dalle azioni sia un processo di Wiener generalizzato, facile mostrare che anche la combinazione lineare che denisce e I(t), segue la stessa dinamica. Se ne conclude che il pricing dellopzione sul basket ricondotto al caso di unopzione su un singolo sottostante. e

2.4.7

Denizione generale di opzione

Come si vede, sul mercato esistono una miriade di opzioni esotiche diverse e lesposizione fornita sopra rappresenta solo la descrizione di quelle pi u comuni. In generale possiamo dare la seguente denizione di opzione: Def. Siano dati N sottostanti i = 1, 2, 3.....N . Sia Si (t) la funzione che assegna a ciascun sottostante i il suo valore al tempo t (0 t T ). Unopzione (di tipo cash) su questi sottostanti un contratto nanziario tra due parti, e una che vende lopzione e laltra che lacquista: chi vende lopzione riceve oggi una quantit di denaro prestabilita, a detta premio; chi compra lopzione acquisisce, in cambio del premio, un diritto, esercitabile unicamente in corrispondenza a certe date future: t {ti }i=1,2,....K . Questo diritto consiste nella possibilit di ricevere una a quantit di denaro (al momento non denita e che potr eventualmente a a essere nulla) pari a: P = P(S1 , S2 , ....SN ). Dove P un funzionale: e P : S N [0, R] , S = {S : [0, ti ] [0, R]} . (2.93) Se lopzione di tipo europeo allora {ti }i=1,2,....K = {T }, dove T la matue e rity date. Se lopzione di tipo americano allora {ti }i=1,2,....K = [0, T ]. e Allinterno della denizione data sopra, ricadono come casi particolari le opzioni plain vanilla esaminate nel paragrafo 2.1.6. Ad esempio unopzione

2.4. OPZIONI ESOTICHE

173

call europea sar caratterizzata dal seguente funzionale che ne denisce il a pay-o: P(S) = M ax[S(T )E, 0], dove E lo strike price. In questo caso il e funzionale P si riduce ad una semplice funzione, in quanto il pay-o dipende unicamente dal prezzo del sottostante a scadenza. La denizione data sopra abbastanza generale da includere tutte le opzioni e esotiche generalmente trattate dal mercato. In particolare facile vericare e che tutti gli esempi considerati nei precedenti paragra rientrano un questo schema. Mentre nel caso delle opzioni plain vanilla sono disponibili formule esatte per il pricing, in generale per le opzioni esotiche non possibile trovare e formule analitiche chiuse e si dovr perci ricorre a tecniche numeriche. A a o questo riguardo, uno degli strumenti pi diusi e potenti il metodo Monte u e Carlo, che sar largomento del prossimo capitolo. a

2.4.8

Esercizi

Si consideri unopzione digital cash or nothing di tipo call (vedi paragrafo 2.4.2) e si derivi una formula esatta per il prezzo.

174 di opzioni asiatiche

CAPITOLO 2. ELEMENTI DI FINANZA

2.5

Una formula approssimata per la valutazione di opzioni asiatiche

In questa sezione deriveremo una formula chiusa approssimata per determinare il prezzo di unopzione asiatica. Il metodo esposto consiste nellapprossimare la media dei prezzi di unazione in corrispondenza delle diverse date di xing, tramite una distribuzione log-normale. Tale approccio stae to sviluppato in letteratura da Turnbull e altri [21, 22]. Nel seguito verr a esposta una derivazione pi vicina alle esigenze del mercato in cui si conu siderano un set di date discrete di xing non necessariamente equispaziate, una curva dei tassi a priori non piatta e una volatilit non costante. a Consideriamo quindi unopzione call con strike price E, di tipo asiatico, scritta su unazione con valore iniziale S(t0 ). Non facciamo alcuna ipotesi sulla curva dei tassi (che potr avere una sua struttura a termine) o sulla a volatilit (che potr anche essere variabile). a a Il pay-o dellopzione denito come: e Pay-oAsian = Max 1 m+1
m

S(ti ) E, 0
i=0

(2.94)

dove S(ti ) il prezzo dellazione sottostante in corrispondenza ai tempi ti , e {ti }i=0,1,.....m il set delle date di osservazione (includendo la data spot t0 ), e T = tm t0 il tempo a maturit e m + 1 il numero di date di xing. e a e Ora il prezzo dellazione al tempo tj (j = 1, . . . m), pu essere scritto come: o
Pj

S(tj ) = S(t0 ) e

i=1

   2 i ri 2 ti +i ti ei

(2.95)

dove: ei sono variabili stocastiche normali N (0, 1) (ovvero con media nulla e varianza unitaria); ti = ti ti1 lintervallo di tempo i-esimo; ri = rti1 ti e e i = ti1 ti sono rispettivamente il tasso di interesse e la volatilit del a sottostante nellintevallo (ti1 , ti ). Introduciamo ora le variabili stocastiche ausiliarie, {ai }, denite ricorsivamente come segue: a0 = log ai = 1 + m ea 1 , m+1 2 ri i ti + i 2
2 m 2

ti ei + log

1 + (m i) eai+1 m+1i

, (2.96)

con la condizione iniziale: am = rm tm + m tm em . (2.97)

2.5. UNA FORMULA APPROSSIMATA PER LA VALUTAZIONE DI OPZIONI ASIATICHE175 E conveniente riscrivere ai s come: ai = i + vi ei , (2.98)

2 dove i e vi sono la media e la varianza delle ai e {i } sono delle nuove e variabili stocastiche con media zero e varianza unitaria. Queste ultime, al contrario delle ei s, sono strettamente correlate luna allaltra e cosa pi u importante, le loro PDF (probability distribution function), indicate nel seguito come Pei , sono non normali.

Utilizzando le denizioni (2.96) riportate sopra, le equazioni che governano levoluzione della media dei prezzi del sottostante, diventano: 1 m+1k
m

S(ti ) =
i=k

S(tk1 ) ek +vk ek 0 +v0 e0 S(t0 ) e

if k 1 if k = 0

(2.99)

che sono lanalogo delle leggi di evoluzione standard per il prezzo di unazione, dove al posto di una variabile normale standard gura unopportuna variabile stocastica ei . E immediato a questo punto scrivere il prezzo dellopzione, casian , come: casian = ert0 tm T
+

Max S(t0 ) e0 +v0 x E, 0 Pe0 (x) dx .

(2.100)

Perci il prezzo di unopzione asiatica, con date di xing discrete, ricondoto e to al calcolo di un integrale unidimensionale, lesatto analogo di una semplice opzione call plain vanilla in cui al posto della classica funzione di probabilit a gaussiana compare una PDF data da Pe0 . 0 e v0 devono essere calcolate in accordo allo schema riportato sopra. Cerchiamo ora di risolvere la relazione ricorsiva (2.96) considerando unicamente i primi due momenti (media e varianza), in altre parole le variabili stocastiche ei s vengono trattate come delle pure variabili gaussiane. E conveniente prendere lesponenziale di entrambi i lati dellequazione (2.96): (m + 1) ea0 = 1 + m ea1 , (m + 1 i) eai = e
2 i (ri 2 ) ti + ti ei

if i = 0 [1 + (m i) eai+1 ] ,

if i > 0 (2.101) a questo punto imponiamo che entrambi i lati dellequazione riportata sopra abbiano la stessa media e varianza. Tenendo conto che20 : < f (ei ) f (ai+1 ) >=< f (ei ) >< f (ai+1 ) > , (2.102)

prendendo il logaritmo di entrambi i lati dellequazione e considerando le seguenti due approssimazioni:


20 Infatti va ricordato che le variabili stocastiche ei e ai+1 sono tra loro indipendenti e quindi il valore di aspettazione < f (ei ) f (ai+1 ) > pu essere fattorizzato o

176

CAPITOLO 2. ELEMENTI DI FINANZA

assumiano che la distribuzione per la media dei prezzi sia log-normale


(ovvero che le ei siano normali), allora eai = ei +vi ei ei +
2 vi 2

2 linearizziamo le equazioni ricorsive al primo ordine in i and vi ;

otteniamo due insiemi di relazioni ricorsive (una per la media e laltra per la varianza): 2 2 v1 0 + v0 = m , if i = 0 2 m+1 1 + 2 (2.103) 2 2 vi+1 i + vi = ri ti + mi , if i > 0 2 mi+1 i+1 + 2 2 2 v2 = m v1 , if i = 0 0 m+1 (2.104) 2 v 2 = 2 t + mi 2 vi+1 , if i > 0 i i i mi+1 le quali devono soddisfare le seguenti condizioni iniziali: m = (rm
2 vm 2 m ) tm , 2 2 = m tm .

Il sistema (2.103-2.104) pu essere risolto analiticamente tramite una ricoro sione allindietro, andando da i = m a i = 0. Il risultato nale : e 0 +
2 v0 = i=1 2 v0 = 2 m 2 i m

ri
i=1

i m+1
2

ti ,

(2.105) (2.106)

i m+1

ti ,

Perci il valore dellopzione dato dallequazione (2.100) si riduce alla classifa o formula di Black & Scholes con una volatilit e un dividend yield aggiustati a nel seguente modo: dadj =
2 adj =

1 T 1 T

ri
i=1 m i=1

i ti , m+1 1 i m+1
2

(2.107) ti . (2.108)

2 i

Dal risultato ottenuto sopra possibile derivare delle formule pi semplici e u valide nel caso di: intervalli equispaziati per le date di xing (ti = ti ti1 = T /m), curva dei tassi piatta (ri = r),

2.5. UNA FORMULA APPROSSIMATA PER LA VALUTAZIONE DI OPZIONI ASIATICHE177 volatilit costante (i = ), a ovvero: dadj =
2 adj

r , 2 1 2m + 1 2 = . 3 2m + 2

(2.109) (2.110)

Inne, le equazioni (2.107) e (2.108) diventano nel limite di rilevazioni continue (cio m ): e dadj =
2 adj =

1 T 1 T

T t=0 T t=0

r(t0 + t)

t dt , T 1 t T
2

(2.111) dt . (2.112)

(t0 + t)2

Le relazioni (2.107) e (2.108) riportate sopra, hanno una semplice interpretazione intuitiva dal punto di vista nanziario: lequazione (2.107) indica che il calcolo della media ha leetto di ridurre il fattore di drift standard (ad esempio nel caso di curva dei tassi piatta e date di monitoraggio equispaziate, il dividend yield aggiustato legato al tempo medio a scadenza, ovvero e T /2). Lequazione successiva, relativa a adj , rappresenta la riduzione nella volatilit eettiva dovuta al meccanismo della media nel prezzo del sota tostante (in eetti ben noto che le opzioni asiatiche sono caratterizzate e da una volatilit pi bassa, e quindi da un prezzo inferiore, rispetto alle a u corrispondenti opzioni plain vanilla). E inne interessante osservare che i valori di volatilit che caratterizzano il sottostante nei primi intervalli di a rilevazione, giocano un ruolo pi importante nella denizione della volatilit u a aggiustata adj . Formule simili a quelle riportate sopra sono state ottenute in letteratura [21, 22], nel caso di opzioni asiatiche campionate in maniera continua (ovvero m ) con curva dei tassi piatta e volatilit costante, imponendo a che la distribuzione della media dei prezzi del sottostante sia approssimabile tramite una lognormale. Altri risultati (vedi ad es. [23]) sono stati proposti per opzioni con date di xing discrete, assumendo sempre una curva dei tassi ed una volatilit costanti, senza per derivare esplicitamente una fora o perci interessante sottolineare che il risultato approssimato mula chiusa. E o riportato nelle equazioni (2.107) e (2.108), rappresenta una formula chiusa valida in presenza di xing discreti21 , non necessariamente equispaziati e con condizioni di mercato realistiche (ovvero tassi di interesse con una vera struttura a termine e volatilit non costante). a
In eetti, in questo caso, la volatilit aggiustata, adj , pu essede dierente dal noto a o limite continuo, 1/ 3 , specialmente quando si considerino poche date di rilevazione (vedi eq. (2.110)) oppure quando queste ultime non siano distribuite in modo uniforme.
21

178

CAPITOLO 2. ELEMENTI DI FINANZA

Opzioni asiatiche: option pricing con dierenti tecniche


=5 % = 10 % = 30 % = 50 %

4.274 (log-normal approx.)

4.871

8.742

12.913

ME (l = 4)

4.30799

4.90899

8.79859

12.96664

ME (l = 6)

4.30798

4.90899

8.80149

12.97995

ME (l = 8)

4.30798

4.90899

8.80142

12.98102

ME (l = 10)

4.30798

4.90899

8.80153

12.98124

ME (l = 20)

4.30798

4.90899

8.80151

12.98097

MC

4.30795 +/- 0.00003

4.9089 +/- 0.00014

8.80095 +/- 0.00062

12.980 +/- 0.0012

RNI

4.308

4.909

8.801

12.980

MDA

4.309

4.911

8.811

12.979

Tabella 2.1: Prezzo di un opzione call asiatica per i seguenti parametri: S(t0 ) = 100,
r = 9 %, T = 1 year, E = 100, m = 52 (numero di intervalli) e ti = T /m. La tabella mostra un confronto tra dierenti tecniche: approssimazione log-normale - soluzione analitica basata sulle eq. (2.107) e (2.108), ME - Espansione nei Momenti, l il numero e di momenti considerato (Airoldi [24]), MC - Monte Carlo (108 scenari con luso della variabile antitetica), RNI - Recursive Numerical Integration (Lim [25]) e MDA - Mixed Density Approximation (Lim [25]).

Nella tabella 2.1 viene riportato un confrontro tra il prezzo di unopzione asiatica call ottenuto tramite lapprossimazione analitica riportata sopra e altre popolari tecniche numeriche. Come si pu notare lerrore rispetto al o risultato esatto ragionevolmente piccolo (sempre inferiore a 1 %). e

Capitolo 3

Metodi numerici per il pricing di opzioni

179

180CAPITOLO 3. METODI NUMERICI PER IL PRICING DI OPZIONI

3.1
3.1.1

Metodo Monte Carlo


Introduzione

In questa sezione illustreremo una delle principali tecniche utilizzate in nanza per loption pricing: il metodo Monte Carlo. Esamineremo inizialmente questa metodologia da un punto di vista generale, partendo da un caso molto semplice [26]. Successivamente vedremo come le simulazioni Monte Carlo possano essere applicate alla nanza. Vedremo anche quali sono i punti di forza di questo metodo e in quali situazioni sia applicabile. Alla ne del capitolo si discuter di alcune tecniche per migliorare lecienza delle ordinarie a simulazioni Monte Carlo.

3.1.2

Il metodo Monte Carlo e

Il metodo Monte Carlo giustamente considerato uno dei pi potenti mezzi e u disponibili nellambito del calcolo numerico. A dispetto della sua fama, si basa su unidea estremamente semplice. Per esporla utile risalire allorige ine del suo nome. Questo deriva da un gioco molto popolare tra i bambini del principato di Monaco (da cui appunto il nome di metodo Monte Carlo). In questo gioco i partecipanti tracciano sul terreno un cerchio iscritto in un quadrato, una volta bendatisi gli occhi, cominciano a lanciare a caso delle pietre. Al termine si contano quante pietre sono cadute nel cerchio e quante nel quadrato. Si noti che il rapporto tra questi due numeri fornisce chiaramente una stima della supercie del cerchio (o pi precisamente di /4). u Questo semplice gioco, come ora spiegheremo, lessenza del metodo Monte e Carlo. Lanciare una serie di pietre allinterno del quadrato corrisponde, da un punto di vista astratto, a generare una coppia di numeri casuali (r1 e r2 ), ciascuno dei quali sia compreso tra 1 e 1 (sar quindi suciente disporre di una a routine numerica che generi numeri casuali tra loro scorrelati nellintervallo (1, 1), richiamandola due volte1 ). Questa coppia cadr allinterno del cera
Questo punto in eetti estremamente delicato. La routine numeriche dei calcolatori e sono in grado di generare delle sequenze che, per correttezza, sarebbe bene denire pseudo casuali. Infatti la sequenza di numeri casuali (ovvero scorrelati) che un computer in e grado di generare, viene ottenuta tramite un programma che, per denizione produce un output deterministico. In eetti ogni routine di numeri random, viene inizializzata con un seme iniziale. Partendo dallo stesso seme si ottiene la medesima successione di numeri pseudo casuali. Generalmente tutti i generatori di numeri pseudo casuali utilizzano una relazione ricorsiva xn+1 = f (xn ) al ne di generare una sequenza random {xn }. Poich la memoria del computer limitata, abbastanza intuibile che dopo un certo e e e periodo, la sequenza tender a ripetersi. Questo introduce un elemento di correlazione a nella successione, in grado di alterare potenzialmente la validit delle nostre simulazioni. a E quindi sempre buona norma accertarsi che una simulazione utilizzi solo una porzione molto ridotta del periodo con cui la sequenza di numeri pseudo casuali si ripresenta. Inoltre se vogliamo ripetere la simulazione sar bene utilizzare sempre un seme diverso, a onde evitare di riottenere esattamente gli stessi risultati.
1

3.1. METODO MONTE CARLO

181

2 2 chio se r1 + r2 1, o n rimarr al di fuori in caso contrario. Supponiamo e a di ripetere molte volte questo esperimento, andando ogni volta a stabilire se il punto cade o meno allinterno del cerchio. Indichiamo con AN i punti allinterno del cerchio, dove N il numero totale di campioni considerati e (in gura 3.1, AN rappresentato dai punti rossi pieni, N invece dato e e dalla somma dei punti rossi pieni e dei bianchi). Nel limite di grande N , il

-1

-1
Figura 3.1: Monte Carlo per la stima di . rapporto AN /N tende allintegrale:
N

lim AN /N =

f (x, y) p(x, y)dx dy .


(x,y)R2

(3.1)

dove: f (x, y) = e p(x, y) =

1 se (x2 + y 2 ) 1 0 altrimenti

1/4 se x (1, 1) e y (1, 1) 0 altrimenti

p(x, y) rappresenta la densit di probabilit dei lanci (in questo caso, un a a valore uniforme allinterno del quadrato). Come risulta chiaro dallequazione (3.1), nel limite di grande N il rapporto AN /N tende a /4, fornendo cos una stima di . Essendo quello descritto un metodo statistico, il risultato sar aetto da unincertezza dellordine di a 1/ N , dove con N indichiamo il numero di campioni indipendenti. Questa

182CAPITOLO 3. METODI NUMERICI PER IL PRICING DI OPZIONI aermazione pu essere facilmente provata ricorrendo al teorema del limite o centrale. Questo aerma che: Teorema Siano {wi } un set di variabili stocastiche indipendenti e identicamente distribuite. Supponiamo altres che la distribuzione di probabilit, a 2 , ben denite. Se p(w), che le caratterizza, abbia media e varianza, N 1 consideriamo la media W = N e i=1 wi , questa a sua volta una variabile stocastica che, nel limite N , descritta da una distribuzione gaussiana e con media: e deviazione standard / N . Nel nostro caso ogni estrazione di coppie (x, y) ha una probabilit pari a a /4 di cadere allinterno del cerchio. Pertanto f (x, y) una variabile e stocastica che assume unicamente due valori: 1 con probabilit p = /4 e a 0 diversamente. In base al teorema del limite centrale, il valor medio di f sar una variabile distribuita gaussianamente con media pari a: /4 e a deviazione standard p (1 p)/N . Nel caso in questione, questo risultato pu essere ottenuto direttamente osservando che se ciascuna estrazione ha o una probabilit di cadere allinterno del cerchio pari a p = /4, dopo N lanci a la probabilit di osservare n punti allinterno del cerchio sar data da una a a distribuzione binomiale, la cui media N p e la cui varianza : N p (1 p). e e Riotteniamo perci che il valore medio per la nostra stima /4 con un o e errore (standard deviation) pari a p (1 p) . (3.2) N Come si vede lerrore commesso dipende da 1/ N tramite una costante di proporzionalit che nel caso specico data da: a e err. = p (1 p) = /4 (1 /4) 0.41 . (3.3) Una dipendenza da 1/ N nella velocit di convergenza non delle pi a e u 2 , esistono algoritmi pi ecienti per calcolare un rapide e certamente in R u integrale; ricordiamo a questo proposito il noto metodo del reticolo. Questo consiste nel decomporre il dominio di integrazione in piccoli quadrati di lato 2 e nellapprossimare lintegrale tramite la somma: e xi f (xi ) , dove xi il generico punto al centro di ogni quadratino. Ovviamente il valore esatto si ottiene unicamente nel limite 0. Come vedremo fra poco, questo approccio risulta pi eciente del metodo Monte Carlo, almeno in R2 . Le u cose per cambiano nel momento in cui si considerino spazi a pi alte dio u mensioni. In generale in uno spazio a D dimensioni, gli usuali algoritmi per il calcolo di un integrale, tendono a diventare inecienti in quanto il tempo di calcolo cresce esponenzialmente al crescere di D e anche la complessit a del problema tende ad aumentare. Viceversa il metodo Monte Carlo risulta facilmente estendibile ed inoltre la velocit di convergenza non dipende da a

3.1. METODO MONTE CARLO

183

D. Supponiamo ad esempio di voler calcolare numericamente liper-volume di una sfera in D dimensioni. E chiaro che il metodo dei rettangolini diventa altamente ineciente, mentre il metodo Monte Carlo risulta la scelta migliore. In tal caso per calcolare lintegrale in D dimensioni: f (x) p(x)dx .
xRD

(3.4)

dove: f (x) = e p(x) =

1 se x 1 0 altrimenti

1/2D se xj (1, 1) j = 1, ...., D , 0 altrimenti,

baster generare N D numeri casuali, raggruppandolo in N vettori, ciascuno a (i) (i) (i) di lunghezza D: x(i) = (x1 , x2 , ...., xD ) i = 1, ..., N . A questo punto si utilizza la solita procedura algoritmica, in base alla quale si incrementa il contatore AN di ununit se e solo se x(i) 1, dove lindice i viaggia tra 1 a e N . La grandezza AN /N fornisce una stima del rapporto tra liper-volume della sfera e quello dellipercubo di lato 2, in D dimensioni. Ripetendo esattamente largomento visto prima, si dimostra che lerrore commesso scala come K/ N , dove il coeciente moltiplicativo K dipende solamente dal rapporto tra liper-volume della sfera di raggio 1 e liper-cubo di lato 2 che la contiene. Per contro, utilizzando il metodo del reticolo, possiamo immaginiamo di suddividere il dominio di integrazione in iper-cubi di lato ; indicando con x(i) il generico punto allinterno di ciascun iper-cubo, lintegrale D-dimensionale pu essere riscritto come: o f (x)dx =
D x(i) D D x(i) + 2 x(i) 2 D

f (x(i) ) +
j=1

f (i) (i) (x ) xj xj + xj
(i)

1 2

j=1 k=1

2f (i) (x(i) ) xj xj xj xk 1 D+2 24


D x(i) j=1

xk xk

+ .... dx =

D
x(i)

f (x(i) ) +

2 f (i) (x ) . x2 j

(3.5)

Ne consegue che lerrore relativo commesso trascurando il termine al secon2 do ordine, proporzionale a 2 N d ; in questo contesto, N rappresenta il e numero di punti su cui valutare la funzione f (ovvero il numero di punti che formano il reticolo). Ne segue che il metodo del reticolo vantaggioso rispete to al Monte Carlo solo per d < 4, mentre diventa via via pi ineciente in u dimensioni maggiori. Si noti anche che lestensione del metodo Monte Carlo

184CAPITOLO 3. METODI NUMERICI PER IL PRICING DI OPZIONI dal caso bidimensionale, D = 2, a quello generico in D dimensioni, assolue tamente banale. Riassumendo, la facilit di implementazione e di estensione a del metodo Monte Carlo, unito al fatto che la velocit di convergenza risulta a indipendente dalla dimensione dello spazio da campionare, fanno di questo algoritmo lo strumento ideale per arontare il calcolo di integrali in spazi ad alte dimensioni. Lesempio illustrato in questo paragrafo, per quanto semplicissimo, contiene gi tutti gli elementi essenziali del metodo Monte Carlo. Astraendo dal prea sente caso, possiamo supporre di considerare un generico spazio H da cui sia possibile estrarre dei campioni x con densit di probabilit p(x). Sia f a a una funzione denita su questo spazio a valori in R. Allora: 1 lim N N
N

f (xi ) =
i=1

f (x) p(x)dx .
xH

(3.6)

Lerrore che commettiamo nel valutare il limite considerando solo un numero nito di campioni, proporzionale a 1/ N . e

3.1.3

Miglioramenti al metodo Monte Carlo

Come abbiamo visto nel paragrafo precedente, una simulazione Monte Carlo intrinsecamente un metodo statistico che non fornisce mai due volte lo stese so valore (almeno se il generatore di numeri casuali inizializzato ogni volta e con un seme diverso). In altri termini il metodo Monte Carlo fornisce una stima con un certo errore, che tende a scalare come 1/ N . Ovviamente tanto pi alta la precisione che si desidera raggiungere tanto pi dispendiosa u e u sar la simulazione (se ad esempio vogliamo raddoppiare la precisione nella a stima di una grandezza, dobbiamo necessariamente quadruplicare il numero di campioni). Poich in generale le simulazioni Monte Carlo sono piuttosto e pesanti, sono state proposte una serie di miglioramenti al ne di ottenere stime pi corrette senza aumentare eccessivamente i tempi di calcolo. In u particolare esamineremo in dettaglio la tecnica della variabile di controllo. 3.1.3.a Tecnica della variabile di controllo

Una strada per migliorare la convergenza, consiste nel ridurre la varianza (e quindi lerrore) della stima fornita dalla simulazione Monte Carlo. Una metodologia, a questo riguardo molto utile e di facile implementazione, e la cosiddetta tecnica della variabile di controllo. Ne illustriamo i contenuti riprendendo lesempio precedente sulla stima di . Lidea alla base di questa metodologia quella di eseguire una simulazione e Monte Carlo con lobiettivo di stimare due grandezze: una sar quella di a nostro interesse mentre la seconda (detta variabile di controllo) relativa ad e un problema di cui sia nota la soluzione esatta. La valutazione Monte Carlo

3.1. METODO MONTE CARLO

185

per il problema di interesse verr quindi corretta tramite la dierenza tra la a stima Monte Carlo della variabile di controllo ed il suo valore esatto (noto a priori). Vediamo nel concreto come questa tecnica possa essere utilizzata per migliorare la stima di vista nel paragrafo precedente. Supponiamo di considerare un poligono di n lati inscritto nel cerchio di raggio unitario. Per ogni campione estratto (x, y), controlliamo non solo che questo cada o meno allinterno del cerchio ma anche allinterno del poligono (in particolare in gura 3.2, abbiamo considerato come poligono inscritto un quadrato. I punti che cadono dentro il cerchio ma fuori dal quadrato inscritto sono marcati in rosso pieno). In tal modo la nostra simulazione ci consentir di stimare due a

-1

-1
Figura 3.2: Monte Carlo per la stima di con lutilizzo di una variabile di controllo.

grandezze: Area cerchio di lato 1 # punti nel cerchio = = lim Area quadrato di lato 2 4 N N esatto Pn # punti nel poligono = lim Area quadrato di lato 2 N N (3.7) (3.8)

nel primo caso supponiamo incognito mentre nel secondo assumiamo come nota la formula chiusa per valutare larea del poligono di n lati iscritto nel cerchio unitario: esatto = n sin 1 sin2 . Pn (3.9) n n

186CAPITOLO 3. METODI NUMERICI PER IL PRICING DI OPZIONI Potremo quindi sostituire la nostra stima iniziale (3.7) con: esatto # punti nel poligono # punti nel cerchio Pn + . (3.10) 4 N 4 N Si noti che il valore daspettazione al secondo membro non cambiato, e e quindi nel limite di grande N converger ancora al valore /4, ma la varia anza della distribuzione si ridotta. Questo perch abbiamo sottratto alla e e variabile, # punti nel cerchio/N , una variabile ad essa anticorrelata. Infatti se per una uttuazione statistica si verica una maggiore concentrazione di punti campionati allinterno del cerchio (rispetto alla sua supercie) allora e altamente probabile che la stessa cosa accada anche per il poligono. In tale situazione larea del cerchio risulta sovrastimata ma questo eccesso viene controbilanciato dalla dierenza tra larea esatta del poligono meno la sua stima Monte Carlo. Ci consente di ridurre gli errori statistici, pervenendo o ad una migliore stima. La cosa pu essere resa pi rigorosa osservando che o u il secondo membro della (3.10) si pu riscrivere come: o esatto # punti nel cerchio - # punti nel poligono Pn + , (3.11) 4 N 4 dove lunica variabile incerta data appunto dal numero di punti che cadono e allinterno dellarea compresa tra il cerchio e il poligono. Questa variabile caratterizzata nel limite N , da una distribuzione gaussiana con e deviazione standard data dallequazione (3.2), in cui questa volta p assume il valore: esatto Pn < (3.12) p= 4 4 In altri termini lerrore viene ancora a dipendere da 1/ N ma con una costante di proporzionalit pi piccola. In eetti questo risultato non deve a u stupire, in quanto nella stima Monte Carlo corretta tramite luso della variabile di controllo, si introdotto un dato ulteriore: la conoscenza della e supercie del poligono. Questa informazione supplementare ci consente di focalizzare la simulazione Monte Carlo unicamente sulla stima della parte di area rimanente. Ne consegue che lerrore statistico implicito nella stima (3.10) tanto minore quanto pi larea del poligono (la variabile di e u controllo) tende a sovrapporsi (correlarsi) a quella del cerchio (in particolare tende a zero nel limite n ). Come conclusione possiamo dunque aermare che sempre desiderabile che la variabile di controllo tenda ad e avvicinarsi (ovvero a correlarsi) il pi possibile alla variabile da stimare. u

3.1.4

Il metodo Monte Carlo nel calcolo del prezzo di unopzione europea

In questo capitolo vedremo come viene applicato il metodo Monte Carlo nellambito della nanza [27, 28]. In particolare focalizzeremo la nostra attenzione sul problema del calcolo del prezzo di una opzione europea.

3.1. METODO MONTE CARLO 3.1.4.a

187

Formulazione del prezzo di unopzione europea tramite path integral

Ricordiamo che il pricing di unopzione consiste nellandare a determinare quantitativamente il valore (cio il prezzo) di un diritto, quello acquistato e dal sottoscrittore dellopzione. Il problema del prezzo di unopzione pu essere riformulato, nel caso di o unopzione di tipo europeo, in termini di un path integral, come ora vedremo. Consideriamo unopzione di tipo europeo. Sia C0,T un generico cammino stocastico, in un mondo neutrale al rischio 2 , che rappresenta una possibile evoluzione del sottostante a partire dal tempo iniziale t = 0 (in cui assume il valore iniziale S0 ) no al tempo T (data di scadenza dellopzione). Sia p(C0,T ) la densit di probabilit di questo cammino. Indichiamo inne con a a P(C0,T ), il pay-o calcolato sul cammino. Allora il prezzo dellopzione sar a dato da:
C0,T

p(C0,T ) P(C0,T ) erT .

(3.13)

Il problema del pricing di unopzione europea si riduce quindi al calcolo di un path integral su tutti i possibili cammini stocastici che abbiano inizio in S0 al tempo t = 0. 3.1.4.b Il Monte Carlo nel pricing di unopzione

Laver ridotto il pricing di unopzione europea ad un integrale, consente di applicare il metodo Monte Carlo alla stima del suo valore. Si noti infatti la similitudine tra lintegrale delleq. (3.13) e quello delleq. (3.6). Volendo fare un parallelo con il problema del calcolo dellarea del cerchio: Confronto MC nel calcolo di e nelloption pricing MC calcolo di MC Option pricing calcolo area del cerchio calcolo path integral per il pricing dellopzione densit di probabilit a a densit di probabilit p(C) a a uniforme p(x, y) coppia ordinata (x, y) con il cammino stocastico C = {S(t)}t[0,T ] vincolo 1 x 1 e 1 y 1 con il vincolo S(t = 0) = S0 funzione f (x, y) uguale a 1 funzione per il pay-o allinterno del cerchio e 0 altrove dellopzione f (C) Tabella 3.1: Confronto tra la metodologia Monte Carlo per il calcolo di e quella utilizzata nelloption pricing
2 Porremo quindi = r. Questa assunzione, che giusticabile in base al principio di e valutazione neutrale al rischio, semplica enormemente il problema

188CAPITOLO 3. METODI NUMERICI PER IL PRICING DI OPZIONI Come si vede cambiano la complessit del problema e le dimensioni dello a spazio che dobbiamo campionare ma non la ricetta da seguire. Il metodo Monte Carlo applicato alloption pricing consister quindi nei seguenti passi: a Campionare in maniera diretta lo spazio dei cammini stocastici S(t) con il vincolo S(t = 0) = S0 . Per far questo si dovranno seguire i seguenti punti: (A) Si divider lintervallo (0, T ) in L intervallini discreti ciascuno di a lunghezza t = T /L. Idealmente t dovrebbe essere reso molto piccolo. (B) Si costruir quindi un cammino stocastico procedendo nella seguente a maniera: si estrae un campione casuale w da una distribuzione gaussiana con media nulla e varianza unitaria; si denisce quindi il nuovo valore di S al tempo t1 = 0 + t come: S(t1 ) = S0 + S0 r t + S0 t w . (3.14) dove w un numero pseudo casuale, estratto da una distribuzione e normale, (0, 1) con media nulla e varianza unitaria. A questo punto si ripetono iterativamente i passi riportati sopra, estraendo un nuovo campione dalla distribuzione (0, 1) e costruendo il nuovo valore di S al tempo t2 . Questa procedura ricorsiva, avr termine dopo L passi. a In tal modo abbiamo campionato un cammino stocastico con drift pari a r e volatilit , che soddisfa il vincolo S(t = 0) = S0 . a (C) Il punto (B) viene ripetuto N volte. In tal modo si ottengono N cammini {Ci }i=1,...,N che avranno automaticamente la corretta densit di probabilit p(C). a a Si valutare il funzionale P su ciascun cammino Ci ;
N 1 Inne si calcola la media: N i=1 Pay-o(Ci ), e la si sconta ad oggi utilizzando il tasso privo di rischio. Questultimo valore fornisce una stima del prezzo dellopzione.

3.1.4.c

Generazione di numeri pseudo casuali distribuiti normalmente

Un punto fondamentale nella sequenza di passi illustrata sopra, la gene erazione di numeri casuali, w, estratti da una distribuzione gaussiana con media nulla e varianza unitaria (punto (B)). In generale molte librerie numeriche mettono gi a disposizione dei generatori che consentono di cama pionare direttamente questo tipo di distribuzione. Pu per accadere che o o

3.1. METODO MONTE CARLO

189

si abbia a disposizione unicamente un generatore di numeri pseudo casuali, con distribuzione uniforme nellintervallo (0, 1). In questi casi possibile fare e ricorso a delle semplici trasformazioni che consentono di ottenere numeri casuali soggetti ad una distribuzione di probabilit gaussiana. Supponiamo a dunque che p e q siano due variabili stocastiche scorrelate, distribuite uni formemente nellintervallo (0, 1). E possibile dimostrare che le due variabili derivate: x = y = 2 log p sin(2q) , 2 log p cos(2q) , (3.15)

sono fra loro scorrelate e distribuite normalmente con media nulla e varianza unitaria. Il principale inconveniente di questa trasformazione sta nel fatto che, da un punto di vista computazionale, il calcolo di funzioni trigonometriche risulta sempre oneroso. Pi vantaggioso, a tal riguardo, risulta la u seguente trasformazione: w = s z = t log u , u log u 2 , u 2

(3.16)

dove questa volta s e t sono due variabili distribuite uniformemente nellintervallo (1, 1) e u = s2 + t2 , deve soddisfare il vincolo: u 1 (ovvero (s, t) devono rappresentare le coordinate di un punto racchiuso allinterno del cerchio di raggio unitario). Anche in questo caso si pu dimostrare che o w e z sono due variabili gaussiane scorrelate. Poich da un punto di vista e numerico il calcolo di radici quadrate e logaritmi meno dispendioso rispete to al caso di funzioni trigonometriche, la trasformazione (3.16) preferibile e alla (3.15). Linconveniente principale presente in (3.16), risiede nel fatto che per ogni coppia di numeri casuali scorrelati, (s, t) [1, 1]x[1, 1], dobbiamo preventivamente accertarci che valga la condizione s2 + t2 1, viceversa si deve scartare la coppia. Poich la probabilit che la generica e a coppia (s, t) cada allinterno del cerchio unitario pari a /4, lecienza di e questo processo sar del 78.5%. a Le due trasformazioni riportate sopra costituiscono il cosiddetto metodo di BoxMuller. 3.1.4.d Simulazione Monte Carlo in presenza di pi sottostanti u

Nel paragrafo 3.1.4.b, abbiamo esaminato la situazione in cui vi sia solamente un sottostante che segua un processo log-normale (il cosiddetto modello browniano univariato). In generale per pu essere necessario considero o are pi sottostanti (ad esempio nel caso di opzioni su basket di azioni), in tal u

190CAPITOLO 3. METODI NUMERICI PER IL PRICING DI OPZIONI caso si fa riferimento ad un modello browniano multivariato. In questo modello oltre a denire quale sia la volatilit i (ovvero la deviazione standard) a dei ritorni di ogni singola azione Si , necessario denire anche linsieme delle e correlazioni 3 , i,j , tra i ritorni di ogni coppia di azioni Si , Sj . Si denisce in questo modo, quella che prende il nome di matrice di varianza covarianza, in cui nella diagonale principale gurano le volatilit mentre gli elementi fuori a diagonale rappresentano le correlazioni: 1 1,2 . . . C = 2,1 2 . . . . . .. . . . . . La matrice C ovviamente una matrice simmetrica in cui Ci,i 0 e 1 e Ci,j 1 i = j. Per simulare i cammini Monte Carlo seguiti dalle azioni {Si } dobbiamo tener conto anche delle loro correlazioni. Consideriamo il caso molto semplice in cui vi siano solamente due azioni (N = 2). Per generare una successione di variabili r1 e r2 che abbiano tra loro correlazione 1,2 e volatilit 1 e a 2 rispettivamente, consideriamo due variabili stocastiche scorrelate x1 e x2 , estratte da una distribuzione normale a media nulla e varianza unitaria, (0, 1). Consideriamo quindi la seguente combinazione lineare di x1 e x2 : r1 = 1 x1 r2 = 2 x1 + E facile dimostrare che: r1 = r2 = 0 ,
2 r1 = 1 , 2 r2 = 2 ,

1 2 x2

(3.17)

corr(r1 , r2 ) = . Di conseguenza partendo da due variabili stocastiche scorrelate a varianza unitaria, pressoch immediato ottenere le variabili stocastiche r1 e r2 con le e e varianze e la correlazione desiderate. Questo un risultato molto importante e in quanto generalmente le routine di calcolo sono in grado di produrre, in
3

Ricordiamo che la correlazione tra due serie {xi } e {yi } denita come: e
n X

(xi x)(yi y)
2 n X i=1

corr(x, y) = "

i=1

n X i=1

#1/2
2

(xi x)

(yi y)

3.1. METODO MONTE CARLO

191

maniera molto semplice, dei campioni casuali estratti da una distribuzione normale (0, 1). Utilizzando questi campioni (che sono tra loro scorrelati) e possibile, tramite la procedura sopra descritta, generare coppie di sequenze stocastiche tra loro correlate. La metodologia illustrata sopra pu essere poi estesa al caso generico di n o variabili. 3.1.4.e Miglioramenti al metodo Monte Carlo nelloption pricing

In questo paragrafo esamineremo alcune semplici tecniche che consentono di ridurre notevolmente lerrore statistico insito nelle valutazioni Monte Carlo, senza incrementare il numero di cammini utilizzati. Miglioramenti nella discretizzazione del processo stocastico Un primo importante miglioramento che si pu apportare allo schema del parao grafo (3.1.4.b), riguarda la discretizzazione del processo stocastico. I passi A e B delle procedura per implementare il Monte Carlo, sono validi in generale per qualunque processo stocastico si consideri al ne di modellizzare levoluzione del sottostante. La discretizzazione dellintervallo di tempo (0, T ), in tanti intervallini di lunghezza T = T /L e la successiva rappresentazione del cammino C tramite una curva spezzata a tratti (3.14), risulter tanto pi precisa quanto maggiore il numero di intervalli cona u e siderati. Idealmente si dovrebbe far tendere L a innito. Ovviamente nella pratica si dovr sempre fare riferimento ad un numero nito di passi e questo a introduce un errore sistematico nel calcolo. La cosa risulta particolarmente evidente osservando che il valore di Si alli-esimo step potrebbe in linea di principio diventare anche negativo, in contraddizione con il fatto che: 1) da un punto di vista nanziario non ha senso parlare di prezzi negativi per unazione e 2) dallequazione (2.36) risulta che i valori possibili per la variabile S su qualunque orizzonte temporale, sono sempre positivi. A questo problema, sollevato dalla procedura di discretizzazione utilizzata, si pu rimediare osservando che nel caso di un processo log-normale, si ha o una formula analitica esatta per descrivere la distribuzione di probabilit che a caratterizza il prezzo del sottostante. Infatti utilizzando la (2.36) possiamo sostituire lequazione (3.14) con:


S(ti ) = S(ti1 ) e

r 2

t+

t w

(3.18)

Questo consente di eliminare lerrore sistematico che deriva dalla discretizzazione. Ovviamente ci risulta possibile unicamente quando il processo o stocastico che descrive il sottostante pu essere risolto esattamente. In mano canza di questo si dovr necessariamente ricorrere alla formula (3.14). a Si noti che nellequazione (3.18), come del resto nella (3.14), abbiamo sostituito a il tasso risk free r. Questo perch la valutazione del prezzo e dellopzione va sempre condotta in un mondo neutrale al rischio.

192CAPITOLO 3. METODI NUMERICI PER IL PRICING DI OPZIONI Metodo della variabile antitetica nelloption pricing Questa metodologia particolarmente utilizzata nellambito delloption pricing in quanto e consente di ridurre gli errori statistici delle simulazioni Monte Carlo, apportando una variazione minima allo schema descritto nel paragrafo (3.1.4.b). Come abbiamo visto, per generare un cammino stocastico C, dobbiamo estrarre L numeri casuali da una distribuzione gaussiana univariata (L rappresenta il numero di intervalli in cui si divisa la durata temporale dele lopzione). Sia {wi }, linsieme di questi numeri pseudo casuali e sia C{wi } il cammino stocastico che ne risulta. Senza rigenerare una nuova sequenza, possiamo considerare il cammino stocastico speculare a C che si ottiene considerando il set: {wi }. Questo corrisponde ad un secondo cammino C che risulta fortemente anticorrelato rispetto al primo (infatti le oscillazioni stocastiche di C sono opposte a quelle di C). Se ora generiamo N coppie di questi cammini gemelli e calcoliamo il prezzo dellopzione, otterremo una stima con un errore statistico pi basso. La ragione risiede nel fatto che u siamo riusciti a campionare pi ecacemente lo spazio del nostro problema, u avendo considerato cammini maggiormente scorrelati tra di loro. La cosa risulta ovvia osservando che: indicato con PC il pay-o dellopzione sul cammino C; indicato con PC il pay-o dellopzione sul cammino C; indicato con PC+C = indicato con PC ;
PC +PC 2

la media tra i due pay-o;

lerrore statistico su PC e con la correlazione tra PC e

allora lerrore statistico su P , dopo aver generato N coppie di cammini, : e N


(1+) 2

err. P =

< . N

(3.19)

si ottiene cos una riduzione dellerrore statistico, diminuzione che tanto e maggiore quanto pi i due cammini gemelli sono anticorrelati. Non cambia u invece la dipendenza dallinverso della radice quadrata del numero di cammini. Si noti inne che dal punto di vista computazionale, generare il secondo cammino a partire dal primo ha un costo pressoch nullo. Si ha cos un e doppio benecio. Metodo della variabile di controllo nelloption pricing E utile rivedere il metodo della variabile di controllo, nel caso del pricing di unopzione tramite metodo Monte Carlo. Come abbiamo visto nel paragrafo 3.1.3.a, il metodo della variabile di controllo consiste nelleseguire una simulazione

3.1. METODO MONTE CARLO

193

Monte Carlo su due variabili: una ha un valore ignoto di cui vogliamo fornire una stima, mentre per laltra disponibile una formula chiusa per la sua vae lutazione. La seconda prende il nome di variabile di controllo. Il metodo consiste nel correggere la stima Monte Carlo per la variabile ignota tramite la dierenza (o il rapporto) tra il valore esatto della variabile di controllo e la sua stima Monte Carlo. Se indichiamo il prezzo Monte Carlo di unopzione M esotica A con PA C e consideriamo unopzione di controllo B, il cui prezM zo fornito dallo stesso Monte Carlo sia PB C , mentre il suo valore esatto V sia PB ERO , allora possiamo ottenere una migliore stima di PA tramite la formula: M M V M PA IGLIORAT O = PA C + PB ERO PB C . (3.20) Questo metodo sar tanto pi ecace quanto pi la variabile di controla u u lo tende ad essere simile alla variabile incognita (si rammenti il caso del poligono iscritto nel cerchio). Nel caso delloption pricing, perci utile e o scegliere unopzione (di cui sia nota una formula chiusa per il prezzo) con un pay-o molto simile a quello dellopzione sotto indagine. Ad esempio se vogliamo calcolare tramite un Monte Carlo il prezzo di unopzione call down & out con barriera, la scelta migliore sar quella di utilizzare come variabile a di controllo unopzione call con uguali caratteristiche (ovvero, stesso strike price, stessa maturity ecc.). Come nel caso dei poligoni e del cerchio (vedi lesempio del paragrafo 3.1.3.a), anche in questo caso questo approccio non riduce la dipendenza dellerrore dal numero di campioni (ovvero lerrore commesso sar ancora del tipo: a K/ N ) ma permette di ridurre il coeciente moltiplicativo K.

194CAPITOLO 3. METODI NUMERICI PER IL PRICING DI OPZIONI

3.2

Alberi Binomiali

In questo capitolo esporremo, in sintesi, la metodologia numerica basata sugli alberi binomiali. In particolare introdurremo inizialmente tale tecnica in un contesto non nanziario (paragrafo 3.2.1) per poi passare al mondo della nanza in senso stretto (paragrafo 3.2.2). Nei paragra 3.2.3 e 3.2.4, presenteremo le due possibili versioni con cui gli alberi binomiali possono venire generati. Nel paragrafo 3.2.6 verr descritto come eettuare la vaa lutazione di un derivato ricorrendo alla generazione di alberi binomiali. Il capitolo si conclude con una valutazione dei vantaggi e degli svantaggi di questa metodologia rispetto ad altre note tecniche numeriche, quali ad esempio il metodo Monte Carlo ed il metodo alle dierenze nite (che verr a introdotto nel capitolo 3.3).

3.2.1

Gli alberi binomiali nel gioco dazzardo - esercitazione

Si consideri il seguente problema: un giocatore dazzardo vuole mettersi al riparo da eventuali perdite al casin e stipula per questo unassicurazione. o Tale contratto prevede che il giocatore parta con un patrimonio iniziale C e possa eettuare un numero di puntate alla roulette pari a n giocate, puntanto di volta in volta sul rosso o sul nero una percentuale pressata p del patrimonio a sua disposizione in quel dato momento. Al termine delle n puntate, se il capitale disponibile sar inferiore al patrimonio iniziale C, il a giocatore ricever un indennizzo pari alla dierenza tra C ed il valore attuale a (ovvero verr risarcito delleventuale perdita subita). a Si domanda qual il giusto prezzo che il cliente dovr versare per questa e a polizza assicurativa. Si eettui il calcolo trascurando la presenza del numero zero alla roulette (in altri termini la probabilit di ottenre rosso o nero pari, in entrambi, i a e casi al 50 %).

3.2.2

Introduzione agli alberi binomiali in nanza

La tecnica degli alberi binomiali per il pricing estemamente utile da un e punto di vista didatto anche se, come metodo numerico, si rivela poco robusto, soprattutto se paragonata al metodo delle dierenze nite (che, come vedremo, strettamente imparentato con il metodo degli alberi trinomiali). e Il metodo degli alberi binomiali consiste nellapprossimare il processo stocastico lognormale per le azioni (tipicamente continuo) tramite un processo discreto su reticolo. Questultimo dovr essere in grado di riprodurre il cora retto limite continuo nel momento in cui il passo reticolare 4 venga fatto tendere a zero.
4 Ovvero lintervallo di tempo t in cui si suddivide lintervallo di tempo (0, T ), dove T la maturity dellopzione e

3.2. ALBERI BINOMIALI

195

In particolare, dividiamo il generico intervallo di tempo (0, T ) in n intervalli di ampiezza t = T /n, e supponiamo di approssimare levoluzione stocastica dellazione (che al tempo t = 0 assume il valore S0 ) tramite una semplice evoluzione a due soli valori (al posto degli inniti che lazione pu assumere o in base al modello log-normale): S0 u movimento verso lalto di S con probabilit p a S0 d movimento verso il basso di S con probabilit 1 p a (3.21) dove u e d rappresentano i fattori di rialzo e ribasso, rispettivamente con probabilit p e 1 p. a Lalbero binomiale viene quindi ottenuto re-iterarando la regola rappresentata dallequazione (3.21) su pi stadi, no ad arrivare al tempo t = n t = T . u I fattori p, u e d devono essere scelti in modo da garantire che nel limite del continuo (ovvero quando n e quindi t 0) il modello discreto con verga al modello log-normale standard. E facile dimostrare che condizione necessaria e suciente perch questo avvenga che la media e la varianza e e di S(t), relativamente al processo discreto binomiale, coincidano con quelle del processo continuo, ovvero valgano le seguenti due condizioni: S(t) = in un mondo neutrale al rischio (e tale il framework in cui dobbiamo e operare per ottenere il prezzo corretto di unopzione) il valore atteso che lazione assume nellintervallo temporale (0, t), deve essere pari allincremento determinato dal tasso privo di rischio: S(t) = puS0 + (1 p)dS0 = S0 ert , da cui p= ert d , ud (3.23) (3.22)

la varianza di S sullintervallo t sia:


2 2 S(t)2 = S0 p u2 + (1 p) d2 = S0 e(2 r+
2 ) t

(3.24)

Le due condizioni riportate sopra (condizioni rispettivamente sulla media e sulla varianza della variabile stocastica S(t), non sono per sucienti a o determinare in maniera univoca le tre variabili p, u e d, questo implica che la costruzione di un albero binomiale in grado di riprodurre per t 0 il corretto limite continuo (rappresentato dal modello log-normale) non e univoca. In eetti in letteratura sono state proposte due soluzioni (tra le innite possibili); queste saranno loggetto dei prossimi due paragra.

196CAPITOLO 3. METODI NUMERICI PER IL PRICING DI OPZIONI

3.2.3

Alberi Binomiali per un sottostante - metodo di Cox, Ross e Rubinstein (CRR)

Cox, Ross e Rubinstein, al ne di trovare una soluzione univoca, impongono unulteriore condizione che si aanca alle equazioni (3.23) e (3.24), ovvero: ud = 1 , (3.25)

In tal modo lalbero che viene generato ha la propriet di avere una serie di a nodi esattamente pari a S0 , ovvero lalbero risulta simmetrico rispetto alla retta che passa per S = S0 (vedi gura 3.3). La condizione (3.25), insieme
S0u
6

S0du S0u S0
p 1-p

S0d u

2 4

S0d u = S0 S0d u S0d u S0d


6 5 4 2

3 3

S0d

Figura 3.3: Albero binomiale CRR. alle due equazioni (3.23) e (3.24), porta a determinare la seguente soluzione per u e d: u = e d = e
t , t

(3.26) . (3.27)

3.2.4

Alberi Binomiali per un sottostante - metodo di Rubinstein

La seconda soluzione, dovuta a Rubinstein, pu essere pi utilmente illuso u trata richiamando direttamente lequazione stocastica che esprime il valore aleatorio di S(t): S(t) = S(0) e
  2 rq t+ t z 2

(3.28)

3.2. ALBERI BINOMIALI

197

q rappresenta il dividend yield dellazione. Lidea per derivare un modello discreto in grado di riprodurre nel limite del continuo la fomula riportata sopra, consiste essenzialmente nel sostituire la variabile aleatoria normale z con una variabile stocastica bimodale, z (d) che assuma con uguale probabilit i seguenti due valori: a z (d) = +1 1 con probabilit 0.5 a con probabilit 0.5 a (3.29)

In tal modo si ottiene un albero binomiale, in cui la varianza e la media della variabile bimodale z (d) rimane identica a quella della variabile continua z (ovvero media nulla e varianza unitaria). Considerando un albero a pi u stadi molto tto (ovvero in cui n ), il prezzo generico del sottostante S(T ) = S(tn)) sar dato da: a S(T ) = S(0) e
  2 rq T + T 2
1 n

Pn

(d) i=1 zi

(3.30)

1 e in base al teorema del limite centrale: n n zi converge ad una disi=1 tribuzione gaussiana con media nulla e varianza unitaria, ovvero si recupera la variabile stocastica z e quindi la classica equazione nel continuo (3.28). A questo punto, partendo dallequazione (3.29), levoluzione dellazione dopo un singolo step, pu assumere unicamente due valori: o

(d)

S(t) = dove

S0 u movimento verso lalto di S con probabilit 1/2 a S0 d movimento verso il basso di S con probabilit 1/2 a (3.31)


u = e


rq 2

 t+ t

(ottenuto imponendo z (d) = 1) , (3.32) (ottenuto imponendo z (d) = 1) ,

d = e

2 rq 2

 t t

Lequazione riportata sopra consente di costruire algoritmicamente lintero albero, reiterando pi volte il processo sopra denito. u Rispetto al metodo CRR, la probabilit associata ai vari rami sempre a e tenuta ssa al 50%, il prezzo da pagare per tale semplicit sta nel fatto che a lalbero generato non risulta pi simmetrico rispetto allasse S = S0 (vedi u gura 3.4).

3.2.5

Estensione al caso di due sottostanti correlati

Rubinstein ha proposto un metodo abbastanza semplice per costruire un albero nel caso di due sottostanti correlati. Si tratter quindi di un albero a in tre dimensioni (una dimensione per ciascuno dei due sottostanti e la terza

198CAPITOLO 3. METODI NUMERICI PER IL PRICING DI OPZIONI


S0u
6 5

S0du

S0d u S0u S0
1/2 1/2

2 4 3 3

S0d u S0d u
5

4 2

S0d

S0d u S0d
6

Figura 3.4: Albero binomiale di Rubinstein.

dimensione dedicata come al solito al tempo). Si consideri quindi il generico nodo dellalbero (S1 , S2 ), partendo da questultimo avremo solo quattro possibilit, ciascuna con probabilit 0.25: a a (S1 u1 , S2 u2 ) (S1 u1 , S2 d2 ) (S1 d1 , S2 u2 ) (S1 d1 , S2 d2 ) S1 e S2 tendono a salire , S1 sale mentre S2 tenderebbe a decrescere , S1 decresce e S2 tenderebbe a salire , S1 e S2 decrescono . (3.33) Per ricavare i valori di u1 , d1 , u2 , d2 , u2 , e d2 , adottiamo il medesimo principio seguito nel caso di un albero bidimensinale, andiamo cio a scrivere e lequazione stocastica per i due sottostanti S1 e S2 al tempo t partento dai valori iniziali S1 (0) e S2 (0): S1 (t) = S1 (0) e
  2 1 r 2 t+1 t w1

(3.34) (3.35)

S2 (t) = S2 (0) e

  2 2 r 2 t+2 t w2

(3.36)

dove w1 e w2 sono due variabili stocastiche correlate con correlazione pari a . Possiamo quindi esprimere le due variabili w1 e w2 in termini di due variabili normali scorrelate z1 e z2 nel seguente modo (vedi paragrafo 3.1.4.d): w1 = z1 w2 = z1 + 1 2 z2 . (3.37)

3.2. ALBERI BINOMIALI

199

2 2 infatti facile dimostrare che: w1 = w2 = 1 e w1 w2 = . e Ora utilizzando lo stesso argomento che abbiamo visto nel caso di un albero su di un singolo sottostante, sostituiamo z1 e z2 (variabili stocastiche normali) con altrettante variabili stocastiche bimodali che possono assumere solo i valori 1, con uguale probabilit (ovvero 50% in entrambi i casi). In a tal modo la varianza e la media delle variabili z1 e z2 non cambiano e nel limite in cui si consideri un albero a pi stadi molto tto, si recuperera il u limite continuo dato dalle equazioni (3.35)5 . In tal modo possiamo ricavare la seguente valorizzazione per i parametri del nostro albero tridimensionale:
  2 1 r 2 t+1 t

u1 = e

(z1 = 1) , (3.38) (z1 = 1) ,

d1 = e e u2 = e d2 = e

  2 1 r 2 t1 t

  2 2 r 2 t+2 (+ 12 ) t   2 2 r 2 t+2 ( 12 ) t

(z1 = 1 e z2 = 1) , (z1 = 1 e z2 = 1) , (3.39) (z1 = 1 e z2 = 1) , (z1 = 1 e z2 = 1) ,

u2 = e d2 = e

  2 2 r 2 t2 ( 12 ) t   2 2 r 2 t2 (+ 12 ) t

Lestensione del metodo denito sopra al caso di n sottostanti risulta relativamente immediato una volta che si consideri la decomposizione di Cholesky (la quale permette di esprimere, tramite una matrice triangolare, n variabili normali correlate in termini di n variabili normali scorrelate, ovvero lesatto analogo del sistema di equazioni (3.37)). In generale per un albero in alte dimensioni diventa computazionalmente o ineciente rispetto ad altri metodi numerici (come ad es. il Monte Carlo). La costruzione di alberi in alte dimensioni quindi una divagazione di scarsa e rilevanza pratica.

3.2.6

Alberi Binomiali a pi stadi u

Vediamo ora come sia possibile eettuare il pricing di un generico derivato tramite gli alberi binomiali. Lalgoritmo il seguente: e
5 Infatti per il teorema del limite centrale la somma di varibili identicamente distribuite converge ad una gaussiana

200CAPITOLO 3. METODI NUMERICI PER IL PRICING DI OPZIONI Una volta stabilite le regole per la costruzione di un albero binomiale ad uno stadio (ovvero con un solo step di ampiezza t), iterando nuovamente il procedimento possibile costruire lintero albero, con t e che va da zero al tempo nale T = n t. In tale costruzione ad ogni nodo viene assegnato un valore del sottostante e ad ogni ramo dellalbero (ovvero ogni segmento che connette due nodi) viene associata una probabilit. a Dopo aver costruito lalbero si procedere con la seconda parte del lavoro che consiste nel costruire a ritroso il prezzo dellopzione che si intende valutare, partendo dal pay-o nale (t = T ). In pratica si procede algoritmicamente nel seguente modo: Indicato con t = T it il tempo, si consideri inizialmente i = 0. Si riportano quindi sui nodi dellalbero corrispondenti al tempo a scadenza dellopzione t = T , i valori del pay-o. Questo pu o essere fatto in quanto il valore dellopzione a scadenza noto per e denizione. Si esegue un ciclo iterativo a ritroso, determinando il valore dellopzione, F , sui nodi al tempo t = T (i + 1)t, conoscendo i valori al tempo t = T it, tramite un semplice valore daspettazione: F (i, j) = ert [p F (i + 1, j + 1) + (1 p) F (i + 1, j 1)] , (3.40) Arrivati al tempo t = 0 (ovvero i = n), possibile ottenere la e stima del prezzo dellopzione data da F (n, 0).

3.2.7

Alberi Binomiali: vantaggi e svantaggi

In generale la tecnica dellalbero binomiale ha i seguenti vantaggi: rispetto al metodo Monte Carlo, consente il pricing di opzioni con esercizio americano o bermudano; estremamente semplice da implementare. e Ha per una serie di svantaggi: o meno robusto rispetto ad altri metodi simili, come il metodo alle e dierenze nite che presenteremo nel capitolo 3.3. Ha seri problemi allaumentare della dimensionalit del problema, dove a diventa rapidamente ineciente rispetta ad esempio al metodo Monte Carlo.

3.2. ALBERI BINOMIALI

201

Pi grave da un punto di vista strettamente operativo, lalbero binou miale risulta dicilemente estensibile ad opzioni con pay-o dierenti, richiedendo di volta in volta, unimplementazione ad hoc. A parte le opzioni con barriera, dove lestensione immediata, non banale e e vedere come applicare la tecnica dellalbero binomiale ad es. al pricing di opzioni asiatiche. Al contrario, sotto questo punto di vista, il metodo Monte Carlo risulta ottimale, in quanto la generazione dei cammini prescinde dal tipo di contratto, permettendo quindi di arrivare ad una gestione industriale del problema (ovvero ogni nuovo contratto richiede limplementazione solo della nuova funzione di pay-o, mentre il motore di calcolo rimane sempre lo stesso). Questo aspetto viene generalmente trascurato dagli accademici ma un punto essenziale che ha decretato forse pi di ogni e u altro, lenorme successo del Monte Carlo in nanza. Da quanto detto sopra, emerge in maniera evidente un buco allinterno delle metodologie numeriche, precisamente quando il tipo di contratto che si vuole valutare presenta un esercizio di tipo bermudano o americano ed allo stesso tempo risulta scritto su pi contratti o preveda diverse date di u xing (la qual cosa implica unalta dimensionalit del problema). In tali a casi infatti, il metodo Monte Carlo non applicabile 6 e daltra parte neme meno la tecnica dellalbero binomiale o alle dierenze nite, risultano fornire unalternativa valida a causa dellalta dimensionalit del problema. Non a e quindi un caso che sul mercato strumenti di questo tipo (alta dimensionalit a abbinato ad un esercizio di tipo non europeo) siano molto rari.

6 In realt in anni recenti sono state proposte delle estensioni che consentono di trattare a in una certa misura lesercizio anticipato anche allinterno del metodo Monte Carlo

202CAPITOLO 3. METODI NUMERICI PER IL PRICING DI OPZIONI

3.3

Dierenze Finite

In questo capitolo illustreremo il metodo esplitito alle dierenze nite.

3.3.1

Introduzione e schemi di discretizzazione

Il metodo delle dierenze nite, consiste nel andare a risolvere numericamente lequazione di Black & Scholes (2.40) tramite una procedura di discretizzazione, ovvero trasformando le variabili continue del problema in variabili discrete e approssimando le derivate (tipicamente derivate parziali) in quozienti di dierenze nite. Vedremo nei prossimi paragra, punto per punto, come implementare questo schema di discretizzazione per il problema formulato nel continuo. In generale utile osservare che nella matematica nanziara, come nella e sica, un utile modo di procedere, per risolvere un problema analiticamente (ovvero in forma chiusa), consiste nel formularlo inizialmente tramite un modello discreto per poi passare successivamente alla corrispondente versione continua. Infatti, usualmente, le equazioni nel continuo sono pi facili u da risolvere delle corrispondenti equazioni nel discreto. Ad es. Black & Scoles riuscirono a derivare una semplice formula chiusa in quanto il problema fu da loro formulato nel continuo (infatti assunsero che il prezzo di unazione potesse variare con continuit mentre nella realt i prezzi azionari a a per curioso osservare che nel momensono soggetti a variazioni discrete). E o to in cui si cerca di risolvere lo stesso problema numericamente, la situazione tenda a rovesciarsi: la formulazione del problema nel discreto risulta generalmente pi abordabile di quella nel continuo. La cosa in eetti non deve u sorprendere eccessivamente in quanto i calcolatori operano sempre in termini di grandezze discrete e nite.

3.3.2

Schemi di discretizzazione

Vediamo quindi come sia possibile riformulare lequazione di Black & Scholes nel discreto. 3.3.2.a Schema di discretizzazione per le variabili fondamentali

Lequazione che dobbiamo andare a risolvere numericamente lequazione e di Black & Scholes (2.40), ovvero unequazione alle derivate parziali in due variabili: S (prezzo dellazione) e t (il tempo). Dovremo quindi adottare per tali variabili il seguente schema di discretizzazione: S = j S t = i t con: 0 j J , con: 0 i I e t = T /I. (3.41) (3.42)

3.3. DIFFERENZE FINITE

203

Per quanto riguarda la prima equazione, il valore J S rappresenta il valore massimo cha andremo a simulare allinterno del nostro schema numerico per il valore del sottostante. In teoria dovremmo quindi considerare valori di J molto alti, in pratica sar suciente andare ad esplorare valori di a Smax = J S pari a tre o quattro volte il prezzo di esercizio di un opzione. Addiritttura nei casi un cui lopzione abbia una barriera superiore B oltre il quale il pay o si annulla (ad es. in unopzione up & out), si potr prendere a J tale che Smax = B. 3.3.2.b Schema di discretizzazione delle funzioni

In generale una funzione F (t, S) potr essere rappresentata in maniera disca reta dividendo lo spazio (t,S) in una griglia di punti secondo lo schema di discretizzazione specicato nelle equazioni (3.41) e (3.42), e rappresentando i valori della funzione sulla griglia come: Fi,j = F (it, jS) = F (t, S) , ovvero tramite una matrice bidimensionale di dimensioni IxJ. 3.3.2.c Schema di discretizzazione per le derivate (3.43)

Un punto fondamentale nel metodo delle dierenze nite consiste nellapprossimare delle derivate (tipicamente derivate parziali) tramite dei quozienti di dierenze nite. Il primo passo quindi quello di trovare delle formule e discrete che appossimino il meglio possibile delle derivate prime o seconde. A tal ne, consideriamo lespansione in serie di Taylor per una generica funzione g(x), arrestata al secondo ordine: g(x + h) = g(x) + g (x) h + 1 g (x) h2 + O(h3 ) , 2 (3.44)

e consideriamo anche lequazione gemella ottenuta scambiando h con h: g(x h) = g(x) g (x) h + 1 g (x) h2 + O(h3 ) , 2 (3.45)

immediato ottenere (sommando in un caso e sottraendo nel secondo, ambo e i membri delle equazioni (3.44) e (3.45)), le seguenti approssimazioni per la derivata prima, g (x) e g (x): g(x + h) g(x h) + O(h2 ) , 2h g(x + h) 2g(x) + g(x h) g (x) = + O(h2 ) . h2 g (x) = (3.46) (3.47)

204CAPITOLO 3. METODI NUMERICI PER IL PRICING DI OPZIONI

3.3.3

Discretizzazione dellequazione di BS - metodo esplicito

Se riconsideriamo leq. di Black & Scholes (2.40) ed introduciamo le seguenti greche: = F , t F = , S 2F = , S 2 (3.48) (3.49) (3.50)

possiamo riscrivere leq. (2.40) come: 1 (S, t) + rS(S, t) + 2 S 2 rF = 0 . 2 (3.51)

Se ora utilizziamo gli schemi di discretizzazione visti nel paragrafo precedente, ed approssimiamo le derivate e al tempo t con le corrispondenti derivate al tempo t + t, possiamo scrivere: = Fi+1,j Fi,j + O(t) , t Fi+1,j+1 Fi+1,j1 = + O(S 2 ) + O(t) , 2S Fi+1,j+1 2Fi+1,j + Fi+1,j1 = + O(S 2 ) + O(t) , S 2 (3.52) (3.53) (3.54)

e quindi lequazione di BS in formato discreto diventa: Fi+1,j Fi,j Fi+1,j+1 Fi+1,j1 + rS + t 2S Fi+1,j+1 2Fi+1,j + Fi+1,j1 1 + 2S 2 2 S 2 rFi,j = O(t) + O(S 2 ) . Riordinando i termini dellequazione (3.56), otteniamo: Fi,j = Ai Fi+1,j1 + Bi Fi+1,j + Ci Fi+1,j+1 + O(t2 ) + O(t S 2 ) , (3.56) dove: Aj Bj Cj = = = 1 , 1 + rt 0 , 1 + rt +1 . 1 + rt

(3.55)

(3.57)

3.3. DIFFERENZE FINITE dove:

205

1 2 j 2 rj t , 2 0 = 1 2 j 2 t , (3.58) 1 +1 = 2 j 2 + rj t . 2 Una rappresentazione graca della relazione (3.56) data in gura 3.5. e 1 =
S

Fi+1,j+1 Fi,j Ci Bi Ai Fi+1,j

S
Fi+1,j-1

i+1

Figura 3.5:

Metodo alle dierenze nite: la gura mette in evidenza la relazione che

lega F al tempo t = i t com i valori di F al tempo t = (i + 1) t.

3.3.3.a

Condizioni ai bordi

Il set di equazioni (3.56) vale unicamente per i punti interni alla griglia (ovvero 1 <= j <= J 1) e quindi, ssato i, si hanno solamente J 1 equazioni in J + 1 incognite (in quanto 0 <= j <= J). Per risolvere il problema necessario quindi trovare altre due equazioni, queste verrane no ottenute ssando delle opportune condizioni al contorno sui bordi della griglia, ovvero per j = 0 e j = I. Consideriamo il caso S = 0 (ovvero j=0), dallequazione di Balck & Scholes (2.40) otteniamo per S = 0 la seguente equazione nel continuo: F (0, t) rF (0, t) = 0 . (3.59) t quindi utilizzando lo schema di discretizzazione, otteniamo nel discreto lequazione corrispondente: Fi,0 = B0 Fi+1,0 , (3.60)

206CAPITOLO 3. METODI NUMERICI PER IL PRICING DI OPZIONI la quale consente di trattare il problema sul bordo inferiore j = 0. In tal modo una volta noto il valore della funzione F sul bordo inferiore (j = 0) per il tempo i + 1 possiamo estrapolare il valore, sempre sul bordo, al tempo i, applicando lequazione riportata sopra. Per S = (e quindi per j = J con J molto grande), se ipotizziamo 2 F (S,t) che il payo dellopzione sia lineare in S 7 , abbiamo che: S 2 0 ovvero applicando la solita discretizzazione: Fi,J = 2Fi,J1 Fi,J2 . (3.61)

In tal modo una volta risolto il problema allinterno della griglia per un certo i, possiamo estrapolare il valore sul bordo (j = J) applicando lequazione riportata sopra. 3.3.3.b Risoluzione dellequazione discreta tramite un processo iterativo

Fissate quindi le condizioni ai bordi possibile risolvere tramite una ricore sione di tipo backward (ovvero a ritroso) il set di equazioni (3.56), (3.60) e (3.61), ricavando {Fi,j } partendo da {Fi+1,j }. Come in tutti i processi ricorsivi, si dovr partire da un punto iniziale predea terminato, nel nostro caso: Fi=I,j , il quale dipender strettamente dal tipo a di contratto considerato, ovvero Fi=I,j = Payo(jS) 8 . La cosa rappresenta esattamente lanalogo di quanto abbiamo visto nel caso della risoluzione dellequazione di Black & Scholes (vedi capitolo 2.3), in cui a fronte dellequazione alle derivate parziali (2.40), il problema poteva poi essere risolto solo ssando opportune condizioni al contorno al tempo t = T (dipendenti dal tipo di contratto considerato). Il processo ricorsivo denito dal set di equazioni (3.56), (3.60) e (3.61), permette di calcolare, partendo dal dato noto FI,j , il valore della funzione Fi,j per ogni i, no ad arrivare a i = 0 (ovvero t = 0). In tal modo otterremo il valore del derivato al tempo iniziale (cio oggi) per ogni valore e di j (ovvero per ogni possibile valore del sottostante al tempo iniziale): F0,j = F (t = 0, S = j S). A questo punto risulta immediato ottenere il prezzo del derivato con le varie greche. Si osservi che dovendo iterare il set di di equazioni (3.56), un numero di volte pari a I = T /t, la stima del prezzo dellopzione avr una precisione a dellordine di O(s2 ) lungo la direzione spaziale e solo dellordine di O(t)
7 La qual cosa dipende dal tipo specico di contratto considerato. Ad esempio nel caso di una call o di una put questa ipotesi pienamente vericata. Diversamente sar e a necessario ricercare lopportuna condizione al contorno, analizzando il comportamento asintotico del prezzo dellopzione quando il valore del sottostante divenga innito. 8 Ad esempio nel caso di un cotratto di tipo call avremo: Fi=I,j = Payo(jS) = Max (jS E, 0)

3.3. DIFFERENZE FINITE

207

lungo quella temporale. Il metodo descritto sopra prende il nome di metodo alle dierenze nite esplicito. Si usa lespressione dierenze nitea causa della discretizzazione operata. Laggettivo esplicito si riferisce invece al fatto che il valore di Fi,j ad ogni passo, si ottiene esplicitamente dai valori assunti da Fi+1,j allo step immediatamente precedente.

3.3.4

Convergenza del metodo

Come tutti i metodi numerici, un fattore chiave anche nel caso del metodo alle dierenze nite la sua convergenza al valore esatto. In eetti non e sempre tale metodo converge, a meno di non ssare opportune condizioni sulla scelta dei parametri t e S (che nellesposizione riportata sopra sono stati sempre lasciati liberi). E possibile dimostrare che una condizione necessaria e suciente per la convergenza dei risultati prodotti dal metodo alle dierenze nite, consista nel scegliere t e S in modo tale da soddisfare le seguenti due relazioni:

t S

S 2 2S 2 2S r

S , S .

(3.62) (3.63)

Senza entrare nel merito della dimostrazione di quanto asserito sopra, e interessante vedere come sia possibile derivare tali espressioni, esaminando la questione da un punto di vista nanziario. Il metodo alle dierenze nite esplicito pu essere visto come un albero trinomiale in quanto il valore del o derivato, Fi,j , al tempo i t, si ottiene come opportuna combinazione lineare del derivato al tempo, (i + 1) t, nei punti j + 1, j e j 1. In tal caso i coecienti 1 , 0 e +1 vanno interpretate come le probabilit risk a neutral dellalbero. E in eetti immediato vericare che: 1 +0 ++1 = e 1, inoltre E(S(t + t) = S 1 + 0 0 + S +1 = r j S t = r S t a conferma che lincremento del valore dellazione nellintevallo di tempo t avviene con il tasso privo di rischio. Anche le probabilit 1 , 0 e +1 a possano per essere interpretate come delle vere probabilit di un albero o a trinomiale, necessario imporre la condizione di positivit, ovvero: e a 2 j r > = 0 (1 0) , 1 j t > = 0 (0 0) , da cui si derivano le condizioni (3.62) e (3.63).
2 2

(3.64) (3.65)

208CAPITOLO 3. METODI NUMERICI PER IL PRICING DI OPZIONI

3.3.5
3.3.5.a

Esempi di applicazione del metodo delle dierenze nite


Call option con esercizio di tipo europeo

A titolo di esempio, riportiamo uno schema sintetico dellalgortimo da seguire per il calcolo del prezzo di unopzione di tipo call europea, tramite il metodo esplicito alle dierenze nite illustrato nei paragra precedenti. Si ssi il numero di step della griglia, Num S step, relativamente al prezzo dellasset sottostante lopzione e si determini quindi il passo della griglia associato alla variabile prezzo: S = Num2E step . E lo strike price dellopzione. e S Si ssi il numero di step della griglia, relativamente alla dimensione temporale, Num t step e si determini il passo della griglia relativamente a tale direzione: t = T /Num t step, dove T la maturit dele a lopzione. Al ne di garantire la convergenza, possiamo scegliere in pri2 ma battuta: t = 2 S , calcoliamo poi Num t step = Int(T /t) + 1 E ed inne rideniamo: t = T /Num t step. Condizione nale: si ssi la condizione nale, ad es. nel caso di una call: F (i, 0) = Max(S E, 0), mentre per una put: F (i, 0) = Max(E S, 0) Loop ricorsivo backward (il cuore della routine): si esegue un ciclo di tipo for sul numero di step temporali, partendo dal punto nale (i = N um t step 1) no ad arrivare a i = 0. Per ogni i: si esegue un ciclo per j = 1 no a j = N um S step 1, andando prima a calcolare Aj , Bj e Cj e poi F (i, j) in base alla relazione ricorsiva (3.56). Si trova il valore del derivato ai bordi: F (i, j = 0) e F (i, j = Num S step), imponendo le condizioni (3.60) e (3.61) rispettivamente. Una volta ottenuto il vettore F (i = 0, j), si stima il prezzo dellopzione tramite uninterpolazione lineare tra i valori della griglia pi vicini al u valore del prezzo spot9 del sottostante, S0 , : jprox = Int(S0 /S)
Prezzo Opt = F (0, jprox ) + F (0, jprox + 1) F (0, jprox ) (S0 jprox S) , S (3.66)

Ovvero t = 0.

3.3. DIFFERENZE FINITE 3.3.5.b Call option con esercizio di tipo americano

209

Inserire nello schema del paragrafo precedente il caso di esercizio di tipo americano estremamente semplice, infatti suciente confrontare ad ogni e e passo il valore del derivato ottenuto tramite la relazione (3.56) con il valore che si otterrebbe dallesercizio anticipato. Il valore eettivo F (i, j) dato e dal massimo tra queste due grandezze. La modica al codice quindi minie male. Al ne di rendere pi chiaro il modo in cui si trattano le opzioni americane u tramite il metodo delle dierenze nite, consideriamo un problema proveniente da un altro ambito. Questo sar utile per evidenziare come da un lato a certe metodologie non sono ristrette alla nanza, dallaltro come in realt ci a siano delle similitudini notevoli tra ambiti apparentemente diversi. Esercitazione Si consideri il seguente gioco dazzardo: un giocatore ha a disposizione n lanci di un dado. Ad ogni lancio pu decidere di farsi pagare o un quantitativo di denaro pari al numero del dado uscito nellultimo lancio moltiplicato per una posta ssa di 100 euro, oppure proseguire ritentando la sorte no a quando non arriver al numero massimo di lanci consentiti, a pari a n. Si chiede qual il giusto prezzo da pagare allinizio del gioco, per e poter partecipare. 3.3.5.c Risultati numerici e metodi di accelerazione

In questo paragrafo riportiamo brevemente alcuni risultati numerici relativi al calcolo del prezzo di una call/put plain vanilla con esercizio di tipo europeo, confrontati con il valore esatto derivante dalla formula di Black & Scholes. Successivamente faremo vedere come luso di appropriate tecniche di accelerazione, consentano di migliorare considerevolmente le stime ottenute con il metodo alle dierenze nite. In gura 3.6 riportato landamento dellerrore relativo tra la valutazione e numerica ottenuta con le dierenze nite ed il risultato esatto, nel caso di unopzione call europea. Come si pu vedere allaumentare del numero di o step lungo S (ovvero diminuendo S), lerrore commesso tende a calare pro gressivamente. E anche interessante notare lalternanza dellerrore rispetto alla parit o meno del numero di step Ns (nellesempio in questione si ha a una sottostima nel prezzo della call per valori di Ns pari e una sovrastima per valori dispari). Tenendo presente il grado di approssimazione con cui abbiamo ricavato le equazioni ricorsive (3.56) e (3.56), intuibile che lerrore di valutazione e commesso applicando il metodo alle dierenze nite sar dellordine di 1S 2 a 2 , ovvero: Ns K(Ns ) (3.67) a (Ns ) Pdf (Ns ) Pesatto 2 Ns

210CAPITOLO 3. METODI NUMERICI PER IL PRICING DI OPZIONI

13.8 13.6

differenze finite Black Scholes

Relative error

13.4 13.2 13 12.8 12.6 12.4 0 20 40 60 80 100 120

Ns

Figura 3.6:

Stima del prezzo, con il metodo alle dierenze nite, di unopzione call

europea con con i seguenti parametri: = 20 %, S0 = 100, r = 2 %, E = 100 e T = 2 anni. La retta orizzontale rappresenta il valore esatto ottenuto con la formula di Black & Scholes.

dove: K(Ns ) = KP , se Ns pari e KD , se Ns dispari e (3.68)

la dipendenza dalla parit di Ns , nel termine K(Ns ), stata inserita al ne a e di tener conto dellandamento alternato osservato nel graco 3.6. La verica della relazione (3.67), immediata una volta che si costruisca un e graco, in coordinate log-log, dellerrore relativo r = Pdf (Ns )/Pesatto 1 al variare di Ns (vedi gura 3.7). Come si pu constatare il t con una retta con coeciente angolare molto o vicino a 2 risulta ottimo, confermando cos quanto prescritto dalla re lazione (3.67). E interessante osservare come la costante di proporzionalit a K dipenda in generale dalla parit di Ns (ovvero sia diversa a seconda che si a considerino valori interi pari o dispari per Ns ). In particolare in questo caso, il valore assoluto di KP pi piccolo di KD , e ci signica che le simulazioni e u o con Ns pari consentono di raggiungere una maggiore precisione di quelle con Ns dispari (in altri termini la convergenza risulta pi eciente sul ramo dei u valori pari). La conoscenza dellandamento dellerrore commesso tramite lapplicazione cruda del metodo alle dierenze nite, pu essere sfruttata al ne di o denire delle procedure di accelerazione, le quali consentano di ottenere stime con una maggiore precisione a parit di sforzo numerico/computazionale. a A tal ne, supponiamo di considerare due dierenti valori di Ns : Ns1 e Ns2 ,

3.3. DIFFERENZE FINITE


-3

211

-4

differenze finite interp. lineare (dispari) interp. lineare (pari)

log(|relative error|)

-5

-6

-7

-8

-9 2 2.5 3 3.5 4 4.5 5

log(Ns)

Figura 3.7: Errore relativo commesso con il metodo alle dierenze nite per unopzione
call europea con con i seguenti parametri: = 20 %, S0 = 100, r = 2 %, E = 100 e T = 2 anni. Il graco in formato log-log: in ascissa gura il logaritmo del nue mero di step spaziali, log(Ns ), mentre in ordinata compare il logaritmo dellerrore relativo log(| r |). Le rette interpolanti, applicando il metodo dei minimi quadrati, sono: 1.48232 2.01383 log(Ns ) per valori di Ns pari e 1.80828 1.99602 log(Ns ) per valori di Ns dispari. Da cui si ottengono le seguenti stime: KP = 57.662 e KD = 79.883.

entrambi pari o dispari, possiamo allora scrivere le due equazioni: K = Pdf (Ns1 ) Pesatto 2 Ns1 K a (Ns2 ) = Pdf (Ns2 ) Pesatto 2 , Ns2
a (Ns1 )

da cui si ricava facilmente che: P (Ns1 ) Pdf (Ns2 ) Pesatto Pdf (Ns1 ) df . 2 1 Ns1 Ns2 E immediato ottenere anche una stima di K: K Pdf (Ns1 ) Pdf (Ns2 ) . 1 N12 N2
s1 s2

(3.69)

(3.70)

A titolo esemplicativo, abbiamo eettuato la stima del prezzo della call, applicando il metodo daccelerazione descritto nellequazione (3.69), con i dati riportati in tabella 3.2. La valutazione nale (riportata sempre in tabella 3.2) presenta un errore relativo dello 0.0045 %, di gran lunga inferiore alla semplice stima ottenuta

212CAPITOLO 3. METODI NUMERICI PER IL PRICING DI OPZIONI

Metodo daccelerazione per lalgoritmo alle dierenze nite


Stima prezzo di una call (dierenze nite) Ns
r

Pdf (20) = 12.9578 Pdf (40) = 13.0616 Pdf () 13.0962

20

-1.0529 %

40

-0.2598 %

0.0045 %

Tabella 3.2: Opzione call con i seguenti parametri: S(t0 ) = 100, r = 2 %, T = 2 anni
e E = 100. Lultima riga riporta la stima ottenuta applicando il metodo daccelerazione allalgoritmo alle dierenze nite. Il valore di K stimato in base ai parametri riportati in tabella risulta pari a 55.3885, il segno meno indica che considerando valori di Ns pari, il prezzo della call risulta sottostimato rispetto al valore esatto.

con il metodo alle dierenze nite ad es. nel caso in cui Ns = 128 (dove lerrore relativo pari a 0.0253 %). e E anche interessante valutare quale sarebbe stato lo sforzo computazionale necessario per raggiungere lo stesso livello di precisione ricorrendo allalgoritmo base. A tal riguardo ricordiamo che, nellalgoritmo alle dierenze nite, il tempo di CPU scala proporzionalmente al numero di punti nella 2 griglia, ovvero Ns Nt e daltra parte Nt 1/t 1/S 2 Ns ; quindi 3 . Nel caso dellesempio il tempo di calcolo scala complessivamente come Ns ripotato sopra, abbiamo perci che il tempo di calcolo necessario ad ottenere o la stima migliorata (dato dalla somma dei tempi per le due simulazioni con Ns = 20 e Ns = 40) pari a 9 CPU time(Ns = 20) 10 . A questo punto e ricorrendo sempre alla formula (3.67), si pu stimare che per avere un errore o relativo pari a 0.0045 %, siano necessari circa 306 step spaziali 11 , con un CPU time totale pari a 3585 CPU time(Ns = 20), ovvero 398 volte il tempo di calcolo della stima migliorata. In altri termini a parit di precisione nella a stima del prezzo, il metodo alle dierenze nite abbinato con un sistema di accelerazione della convergenza, risulta quasi 400 volte superiore allalgorit10 Prendendo come riferimento il tempo di calcolo per Ns = 20, abbiamo che: CPU time(Ns = 40) 8 CPU time(Ns = 20), da cui il risultato. 11 Tale valore si ottiene applicando la formula:

"s

Ns = Int{pari}

KP Pesatto
r

(3.71)

facilmente derivabile dalla (3.67), dove abbiamo supposto di considerare un numero di step spaziali pari ed abbiamo utilizzato per KP la stima ottenuta in tabella 3.2. Se avessimo considerato valori di Ns dispari, il numero di step necessario a raggiungere la precisione desiderata sarebbe stato uguale a circa 369.

3.3. DIFFERENZE FINITE

213

mo base! Un risultato sorprendente. Analogamente a quanto abbiamo visto nel caso del Monte Carlo, dove tipicamente si utilizzano metodi di riduzione della varianza al ne di migliorare la qualit della stima a parit di tempo macchina, anche nel caso delle difa a ferenze nite quindi importante cercare di migliorare lalgoritmo base con e opportune tecniche di accelerazione.

3.3.6

Vantaggi e punti deboli del metodo alle dierenze nite

Rispetto allalbero binomiale (di cui stretto parente in base a quanto abe biamo visto) il metodo alle dierenze nite risulta molto pi robusto e soliu quindi da preferirsi sempre allalbero binomiale. Sore per degli do. E o stessi limiti che abbiamo gi visto a proposito dellalbero binomiale nel a paragrafo 3.2.7, rispetto alla questione della dimensionalit e della scarsa a estendibilit a payo generici. a

214CAPITOLO 3. METODI NUMERICI PER IL PRICING DI OPZIONI

Capitolo 4

Progetto di una libreria in C++ per il pricing

215

216CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING

4.1
4.1.1

Progetto per una libreria nanziaria in C++


Introduzione

In questa sezione deniremo sinteticamente le linee guida per costruire una semplice libreria nanziaria. La libreria verr scritta in C++, quindi ogni a oggetto nanziario (ad es. curva dei tassi, bond, opzioni ecc.) verr rapprea sentato tramite unopportuna classe.

4.1.2

Obiettivi della libreria

Lobiettivo che ci poniamo quello di creare una libreria nanziaria che ci e consenta di: 1) gestire le curve dei tassi; 2) eettuare il pricing dei bond; 3) descrivere le opzioni su equity; 4) eettuare il pricing delle opzioni su equity tramite formule chiuse (esatte o approssimate) e metodi numerici (Monte Carlo, alberi binomiali e metodi alle dierenze nite). Il primo passo, per denire una libreria di classi, consiste nellanalizzare il problema, isolando i principali oggetti coinvolti. Nel presente caso, possiamo individuare le seguenti macro aree: (A) Curva dei tassi (paragrafo 4.1.4). (B) Bond (paragrafo 4.1.5). (C) Pricing bond (paragrafo 4.1.6). (D) Azioni (paragrafo 4.1.7). (E) Processi stocastici (paragrafo 4.1.8). (F) Opzioni (paragrafo 4.1.9). (G) Pricing di opzioni su equity (Monte Carlo, Albero Binomiale, Dierenze Finite e Formule chiuse) (paragrafo 4.1.10). Naturalmente, sar necessario disporre di una libreria con funzionalit a a matematiche gi sviluppate, da utilizzarsi nella costruzione della nostra lia breria nanziaria. A tal riguardo, unottima scelta la libreria freeware e GNU Scientic Library sviluppata dalla GNU foundation.1 , in alternativa si pu far riferimento agli algoritmi di Numerical Recipes [29]. o
Il codice sorgente della libreria GNU Scientic Library disponie bile al sito: http://www.gnu.org/software/gsl. Inoltre esistono versioni gi compilate per lambiente windows, in particolare presso il sito: a http://sourceforge.net/project/showles.php?group id=23617 alla voce gsl, dove sono reperibili anche i sorgenti e la documentazione sullutilizzo delle routine della libreria.
1

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++

217

4.1.3

Avvertenze ed utilizzo delle presenti note

Le note di seguito allegate, costituiscono semplicemente una traccia per lo sviluppo della libreria. Il loro obiettivo quello di denire con chiarezza: a) e la struttura, ovvero lo scheletro della libreria e b) le principali funzioni con cui i vari oggetti interagiscono tra di loro; non quello di denire nei dettagli e ogni singolo oggetto o di elencare in maniera esaustiva tutte le funzioni membro delle varie classi. Sar compito degli studenti completare ciascun a oggetto (ovvero rinire nei dettagli la struttura delle classi) ed implementare le funzioni proprie di ciascuna classe. La notazione utilizzata per la descrizione graca delle classi e delle loro relazioni segue lo standard UML. Richiamiamo brevemente di seguito il signicato delle notazioni pi importanti di questo standard. u Una classe viene rappresentata tramite un rettangolo diviso in tre sezioni. Nella prima (quella che si trova nella parte alta), gura il nome della classe; nella seconda sezione vengono riportati gli attributi ed inne nellultima parte compaiono i metodi. Ad esempio in guPersona
Nome Cognome Data_di_nascita Get_age

Figura 4.1: Esempio notazione UML. ra 4.1 viene riportata una classe per raccogliere i dati anagraci di una persona. Il nome della classe Persona, gli attributi sono: il nome, e il cognome e la data di nascit. Inne gura un metodo, Get age, il a quale consente di calcolare let della persona partendo dalla sua data a di nascita e dalla data attuale. La relazione tra due classi (detta associazione), viene descritta tramite una linea che le unisce. In generale esiste unassociazione tra due
Cliente
Nome Cognome Data_di_nascita Get_age 1

Ordine
0..* Numero ordine Articolo

Figura 4.2: Esempio notazione UML. istanze di due classi se listanza di una classe deve conoscere laltra

218CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING al ne di eettuare correttamente il proprio lavoro. Nellesempio di g. 4.2, stata rappresentata la relazione tra la classe Cliente e la classe e Ordine. I numeri ai lati della linea che rappresenta lassociazione, indicano la molteplicit, ovvero il numero di possibili istanze della a classe, associate con una singola instanza dellaltra. Nel nostro esempio per ogni cliente ci possono essere pi ordini, mentre per un dato ordine u ci pu essere un solo cliente. Cos la molteplicit della classe Cliente o a 1, mentro la molteplicit della classe Ordine 0..* intendendo con e a e questo che pu essere un numero qualunque a partire da zero. o La relazione tra due classi pu comprendere delle frecce di navigabilit o a indicanti la direzionalit dellassociazione. Ad esempio in g. 4.3 la a
Persona
Nome Cognome Data_di_nascita Get_age 0..1 1

Indirizzo
Numero Via Citt

Figura 4.3: Esempio notazione UML. freccia sta ad indicare che una istanza della classe Persona possiede un indirizzo (o pi propriamente unistanza della classe Indirizzo) e u non viceversa. E importante notare che gracamente la freccia non piena (la freccia piena verr utilizzata per indicare la relazione di e a ereditariet). a Nel caso in cui una classe sia derivata da unaltra (tramite ereditariet), si utilizzera una freccia piena per indicare la relazione che le a lega. La freccia piena punter verso la classe padre partendo dalla a
Persona
Nome Cognome Data_di_nascita Get_age

Cliente
Codice cliente

Impiegato
Numero matricola

Figura 4.4: Esempio notazione UML. classe glio. Un esempio riportato in gura 4.4, dove viene mostrato e

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++

219

il rapporto gerarchico che lega le classi Cliente e Impiegato alla classe padre Persona. Ovviamente un cliente ed un impiegato sono casi particolari di una categoria pi ampia, quella delle persone. u Nei paragra successivi vengono denite le varie classi, raggruppate in base alle macroaree denite nel capitolo 4.1.2.

220CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING

4.1.4

Curva dei tassi

Descrizione: questa sezione dedicata alla gestione delle curve sui tassi e di interesse. Il diagramma di questo settore della libreria e riportato nella gura sottostante. Le frecce indicano la derivazione della classe sottostante partendo da quella sovrastante (ovvero le due classi Yield curve at e Yield curve term structure sono entrambe derivate dalla classe astratta padre, Yield curve).

Yield_curve
Currency Yield_curve ~Yield_curve Get_spot_rate Get_forward_rate Get_discount_factor Get_discount_factorYield_curve

Yield_curve_flat
rate

Yield_curve_flat ~Yield_curve_flat Get_spot_rate Get_forward_rate

Yield_curve_term_structure
rates times dim Yield_curve_term_structure ~Yield_curve_term_structure Get_spot_rate Get_forward_rate

Figura 4.5: Schema curve tassi. Gli scheletri per le classi sopra riportate sono schematizzate nelle pagine seguenti.

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ 4.1.4.a Classe: Yield curve

221

Nome classe: Yield curve Signicato: Classe astratta per gestire la curva dei tassi. Scheletro della classe (le .hpp)
// -------------------- Begin yield_curve.hpp ---------------------class Yield_curve { private: char *currency ; public: // Constructors // Yield_curve(void) ; Yield_curve(char *currency_init) ; // Destructor // virtual ~Yield_curve(void) ; // Functions // virtual double Get_spot_rate(double t) = 0 ; virtual double Get_forward_rate(double t_start, double t_end) = 0 ; double Get_discount_factor(double t) ; double Get_discount_factor(double t_start, double t_end) ; } ; // -------------------- End yield_curve.hpp ------------------------

Signicato dei membri della classe (1) currency: la valuta di riferimento per la curva dei tassi in oggetto. e

222CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING (2) Get spot rate(double t): restituisce lo spot rate al tempo t, ovvero il tasso di interesse tra oggi e la data t (rappresentata come year fraction). Il tasso espresso in capitalizzazione continua. e La funzione dichiarata come virtuale pura. e (3) Get forward rate(double t start, double t end): restituisce il tasso forward calcolato sulla curva tra il tempo t start e t end. I tempi sono espressi come year fraction. Il tasso rappresentato in capitalizzazione e continua. La funzione dichiarata come virtuale pura. e (4) Get discount factor(double t): restituisce il fattore di sconto calcolato tra oggi e la data t (epressa come year fraction). (5) Get discount factor(double t start, double t end): restituisce il fattore di sconto calcolato tra t start e la data t end (epresse entrambe come year fraction). Esercizio Si completi eventualmente la classe Yield curve riportata sopra e si implementino le funzioni membro di tale classe in un opportuno le yield curve.cpp.

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ 4.1.4.b Classe: Yield curve at

223

Nome classe: Yield curve at Signicato: Classe derivata da Yield curve per gestire una curva dei tassi piatta, ovvero senza alcuna term structure. Questa il tipo pi e u semplice di curva che si possa ipotizzare. Scheletro della classe (le .hpp)
// -------------------- Begin yield_curve_flat.hpp ----------------class Yield_curve_flat { private: double rate ; public: // Constructors // Yield_curve_flat(void) ; Yield_curve_flat(char *currency_init, double rate_init) ;

// Functions // virtual double Get_spot_rate(double t) ; virtual double Get_forward_rate(double t_start, double t_end) ; } ; // -------------------- End yield_curve_flat.hpp -------------------

Signicato dei membri della classe

(1) rate: tasso di interesse in capitalizzazione continua. (2) Yield curve at(char *currency init, double rate init): costruttore della classe Yield curve at. Riceve in input il nome della currency a cui la curva dei tassi si riferisce ed il tasso at espresso in capitalizzazione continua.

224CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING Esercizio Si implementino in un le yield curve at.cpp tutte le funzioni membro della classe : Yield curve at.

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ 4.1.4.c Classe: Yield curve term structure

225

Nome classe: Yield curve term structure Signicato: Classe derivata da Yield curve per gestire una curva dei tassi con term structure denita. Scheletro della classe (le .hpp)
// ------------- Begin yield_curve_term_structure.hpp -------------class Yield_curve_term_structure { private: double *rates ; double *times ; int dim ; . . public: // Constructors // Yield_curve_term_structure(void) ; Yield_curve_term_structure(char *currency_init, double *rate_deposit, double *t_deposit, int num_depositi, double *rate_swap, double *t_swap, int num_swap) ; Yield_curve_term_structure(char *currency_init, double *rates_init, double *times_init, int dim_init) ; // Destructor // virtual ~Yield_curve_term_structure(void) ; // Functions // virtual double Get_spot_rate(double t) ; virtual double Get_forward_rate(double t_start, double t_end) ; } ; // ------------- End yield_curve_term_structure.hpp ----------------

226CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING Signicato dei membri della classe (1) rates un vettore di tassi e times un vettore di tempi (espressi e e in termini di year fraction) avente uguale dimensione dim. rates[i] rappresenta il tasso risk free in capitalizzazione continua al tempo times[i]. (2) Yield curve term structure(double *rete deposit, .....): costruttore della classe Yield curve term structure. Riceve in input un vettore di tassi deposito, relativi alle scadenze specicate dal vettore t depositi, di lunghezza num depositi, e un vettore di tassi swap, relativi alle scadenze specicate dal vettore t swap, di lunghezza num swap. Tramite un algoritmo di bootstrapping viene costruita la struttura a termine della curva dei tassi, associata ai tessi deposito e swap passati al costruttore. (3) Yield curve term structure(double *rates init, ....): costruttore della classe Yield curve term structure. Riceve in input un vettore di tassi rates init e corrispondentemente un vettore di tempi (espressi in year fraction) avente uguale dimensione dim init. rates init[i] rappresenta il tasso risk free in capitalizzazione continua al tempo times init[i].

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++

227

4.1.5

Anagraca bond

Descrizione: questa sezione dedicata alla denizione di una classe e per gestire lanagraca delle obbligazioni (bond), sia a tasso sso che a tasso variabile. Il diagramma di questo settore della libreria e riportato nella gura sottostante.

Bond
isin_code ; name ; yc ; currency ; number_of_coupon_per_year Bond ; ~Bond ; Get_yc ;

0..*

Yield_curve

Bond_fixed_rate
fixed_rate

Bond_fixed_rate ~Bond_fixed_rate

Bond_floating_rate
floating_rate

0..*

Floating_rate_index

Bond_float ~Bond_float

Figura 4.6: Schema anagraca bond.

228CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING 4.1.5.a Classe: Bond

Nome classe: Bond Signicato: Classe per gestire lanagraca di un bond. Scheletro della classe (le .hpp)
// -------------------- Begin bond.hpp ----------------------------class Bond { private: char *isin_code ; char *name ; Yield_curve *yc ; char *currency ; int number_of_coupon_per_year ; . . . public: // Default constructor // Bond(void) ; // Destructor // virtual ~Bond(void) ; Yield_curve *Get_yc(void) { return yc ; } ; . . . } ; // -------------------- End bond.hpp -------------------------------

Signicato dei membri della classe (1) isin code: stringa contenente lisin code del titolo.

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ (2) name: nome per esteso del bond.

229

(3) yc: puntatore ad un oggetto di tipo Yield curve che rappresenta la curva dei tassi con cui scontare i ussi di cassa del titolo. (4) currency: stringa contenente la valuta dei ussi di pagamento del titolo. (5) number of coupon per year: numero di coupon staccati per anno. (6) Get yc: restituisce il puntatore alloggetto yc. Esercizio Si completi la classe denita sopra con tutti gli altri campi anagraci essenziali per una descrizione esaustiva di un titolo obbligazionario.

230CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING 4.1.5.b Classe: Bond xed rate

Nome classe: Bond Signicato: Classe per gestire lanagraca di un bond. Scheletro della classe (le .hpp)
// -------------------- Begin bond_fixed_rate.hpp -----------------class Bond_fixed_rate : public Bond { private: double fixed_rate ; public: // Default constructor // Bond_fixed_rate(void) { }; // Destructor // virtual ~Bond_fixed_rate(void) ; } ; // -------------------- End bond_fixed_rate.hpp --------------------

Signicato dei membri della classe (1) xed rate: tasso di interesse su base annua.

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ 4.1.5.c Classe: Bond oat

231

Nome classe: Bond oat Signicato: Classe per gestire lanagraca di un bond indicizzato ad un tasso variabile. Scheletro della classe (le .hpp)
// -------------------- Begin bond_floating_rate.hpp --------------class Bond_floating_rate : public Bond { private: Floating_rate_index *floating_rate ; // TO BE COMPLITED public: // Default constructor // Bond_float(void) ; // Destructor // virtual ~Bond_float(void) ; // TO BE COMPLITED } ; // -------------------- End bond_floating_rate.hpp -----------------

Signicato dei membri della classe (1) oating rate: indice di tipo Floating rate index a cui il bond indie cizzato. Esercizio Si completi la denizione della classe riportata sopra per la gestione dei un bond indicizzato ad un tasso variabile e si proceda allimplementazione delle relative funzioni. A tal ne sar necessario strutturare nei dettagli la a classe Floating rate index (il cui ne quello di caratterizzare e descrivere e un indice oating).

232CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING

4.1.6

Metodi per il pricing dei bond

Descrizione: questa sezione dedicata alla denizione di una classe e per gestire il pricing delle obbligazioni (bond). Il diagramma di questo settore della libreria e riportato nella gura sottostante.

Bond_pricer
bond

0..*

Bond

Bond_pricer ; ~Bond_pricer ; Get_bond_price ;

Bond_pricer_closed_formula
fixed_rate

Bond_pricer_closed_formula ~Bond_pricer_closed_formula Get_bond_price

Figura 4.7: Schema bond pricer.

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ 4.1.6.a Classe: Bond pricer

233

Nome classe: Bond pricer Signicato: Classe astratta da cui verranno derivate le altre classi. Scheletro della classe (le .hpp)
// -------------------- Begin bond_pricer.hpp ---------------------class Bond_pricer { private: Bond *bond ; // TO BE COMPLITED public: // Constructors & destructors // Default constructor Bond_pricer(void) ; // Constructor Bond_pricer(Bond *bond_init) { bond = bond_init ; }; // Destructor virtual ~Bond_pricer(void) ;

virtual double Get_bond_price(void) = 0 ;

} ; // -------------------- End bond_pricer.hpp ------------------------

Signicato dei membri della classe (1) bond: puntatore ad un oggetto di tipo Bond. bond rappresenta lobbligazione di cui si vule determinare il prezzo tramite il metodo in oggetto. (2) Bond pricer(Bond *bond init): il costruttore per la classe Bond pricer. e

234CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING (3) Get bond price(void): funzione virtuale pura che restituisce il valore (prezzo) del titolo. Tale funzione andr opportunamente implementata a nelle classi derivate da Bond pricer.

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ 4.1.6.b Classe: Bond pricer exact closed formula

235

Nome classe: Bond pricer exact closed formula Signicato: Classe per gestire il pricing tramite formula chiusa. Scheletro della classe (le .hpp)
// --------------- Begin bond_pricer_closed_formula.hpp -----------class Bond_pricer_closed_formula private: // TO BE COMPLITED public: // Constructors & destructors // Default constructor Bond_pricer_closed_formula(void): }; : public Pricer_bond {

Bond_pricer() {

virtual double Get_bond_price(void) ; // TO BE COMPLITED } ; // ----------------End bond_pricer_closed_formula.hpp --------------

Signicato dei membri della classe (1) Get bond price(void): in questa classe la funzione per il pricing del bond andr implementata utilizzando il noto algoritmo basato sul a discounting dei ussi di cassa futuri. Esercizio Si implementino le funzioni membro della classe Bond pricer exact closed formula, con particolare riguardo per la funzione Get bond price.

236CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING

4.1.7

Anagraca e prezzi di azioni

Descrizione: Linsieme delle classi di questa sezione ha come nalit a nel suo complesso, quella di permettere la descrizione e la gestione delle azioni (a livello anagraco) e dei relativi prezzi (quotazioni). Tra le classi presenti in questa sezione, gura anche la Volatility surface il cui ne quello di descrivere la supercie di volatilit associata e a ad unazione. Nella classe deputata a rappresentare lanagraca di unazione, gurerppunto un pointer ad un oggetto di tipo Volatilia ty surface. Questa sezione sar molto importante per quanto riguarda la costruzione a di una libreria di pricing, in quanto le azioni sono i tipici sottostanti dei contratti opzionali. Il diagramma di questo settore della libreria e riportato nella gura sottostante.

Equity_prices
time prices equity_description dim

0..*

Equity_description
isin_code ; name ; currency ; dividend_yield ; yield_curve ; volatility_surface Equity_description ~Equity_description Get_isin_code Get_name Get_currency Get_dividend_yield Get_yc Get_vol_surface Set_isin_code Set_name Set_currency Set_dividend_yield Set_yc Set_vol_surface

0..* 1

Yield_curve

0..1 1

Volatility_surface
vol

Equity_price Equity_price Get_price Set_price Get_time Set_time

Volatility_surface ~Volatility_surface Get_volatility

Figura 4.8: Schema anagraca e prezzi azioni

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ 4.1.7.a Classe: Volatility surfaces

237

Nome classe: Volatility surfaces Signicato: Classe per gestire le volatilit di un sottostante azionario. a Si parla di supercie di volatilit in quanto si pu avere, in generale, a o una dipendenza di questa grandezza da due fattori: (i) da un lato vi pu essere una vera e propria struttura a termine per la volatilita, o relativamente allasse temporale (analogamente a quanto accade per la curva dei tassi). Ovvero la volatilit dellazione tra listante attuale a ed il tempo t potr dipendere da t; (ii) vi anche una dipendenza della a e volatilit dal valore dellazione (a causa degli eetti di smile, si veda a a tal proposito il paragrafo 2.3.6). Nella classe riportata sotto abbiamo considerato solo il caso estremamente banale in cui non vi sia dipendenza temporale o dipendenza dal valore del sottostante; facile per creare unopportuna gerarchia di e o classi di superci di volatilit al ne di gestire situazioni pi complesse a u (sulla falsa riga di quanto fatto precedentemente per le curve dei tassi). Scheletro della classe (le .hpp)
// ------------------ Begin volatility_surface.hpp ----------------class Volatility_surface { private: double vol ; public: // Default constructor // Volatility_surface(void) ; double Get_volatility(double t_start, double t_end) { return vol ; } ; } ; // ------------------ End volatility_surface.hpp -------------------

Signicato dei membri della classe (1) vol: la volatilit dellazione. e a

238CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING (2) Get volatility: restituisce la volatilit dellazione nellintervallo di tema po compreso tra t start e t end. Se t start non corrisponde allistante attuale ma una data nel futuro, la funzione restituisce una volatilit e a forward. Nel caso in questione, poich la supercie di volatilit si e a riduce ad un punto, la funzione Get volatility si limita a restituire sempre la costante vol.

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ 4.1.7.b Classe: Equity description

239

Nome classe: Equity description Signicato: Classe per gestire lanagraca di una singola azione. Ogni azione caratterizzata da una serie di campi (detti campi anae graci) che la descrivono completamente. Ad esempio il nome dellazione, il suo codice isin 2 , la valuta in cui sono espresse le quotazioni, il mercato principale su cui il titolo viene trattato, i dividendi pagati con le relative date ecc. ecc. La classe riportata di seguito ha lo scopo di raccogliere tutti questi campi in un unico costrutto che costituir a appunto lanagraca dellazione. Scheletro della classe (le .hpp)
// ------------------ Begin equity_description.hpp ----------------class Equity_description { private: char *isin_code ; char *name ; char *currency ; double dividend_yield ; Yield_curve *yield_curve ; Volatility_surface *volatility_surface ; public: // Default constructor // Equity_description(void) ; // Destructor // virtual ~Equity_description(void) ; Volatility_surface *Get_vol_surface(void) { return volatility ; } ; Yield_curve *Get_yc(void) { return yc ; } ;
2 Il codice isin una stringa alfanumerica che identica in maniera univoca unazione e o un titolo obbligazionario.

240CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING

double Get_dividend_yield(void) { return dividend_yield ; } ; // TO BE COMPLITED } ; // ------------------ End equity_description.hpp -------------------

Signicato dei membri della classe (1) isin code: isin code dellazione (2) name: nome per esteso dellazione (3) currency: valuta con cui si esprime il prezzo dellazione in oggetto. (4) yc: puntatore ad un oggetto di tipo Yield curve, rappresentante la curva dei tassi associata alla currency dellazione. (5) dividend yield: dividend yield su base annua che caratterizza il titolo azionario. a (5) volatility surface: curva di volatilit dellazione (si veda per maggiori dettagli la descrizione della classe Volatility curve). Esercizio Si completi la denizione della classe con gli eventuali campi anagraci mancanti. Si arricchisca la classe con tutte le funzioni di interfaccia necessarie e con le relative implementazioni.

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ 4.1.7.c Classe: Equity prices

241

Nome classe: Equity prices Signicato: Classe per gestire i prezzi del/dei sottostanti. Questa classe denisce linvolucro dove immagazzinare i prezzi di una o pi u azioni. In generale un modo molto semplice di denire questa classe quella di inserire nella sua struttura: un membro double per rape presentare listante temporale a cui il prezzo o i prezzi si riferiscono ed un secondo membro di tipo double *, dove archiviare i prezzi delle azioni. Questa semplice scelta non consente di apprezzare a fondo il vantaggio di denire una classe dedicata per rappresentare i prezzi azionari, va infatti osservato che ad un dato istante temporale, per una singola azione, sono presenti sul mercato pirezzi, ad esempio il p prezzo bid, lask 3 e il mid (media tra i primi due). Vi sono poi a livello giornaliero i prezzi di apertura, quelli di chiusura ecc. E quindi utile pensare di denire una classe che consenta di trattare tutti questi tipi di prezzo tramite ununica struttura. Nellimplementazione riporata sotto ci limiteremo comunque a considerare il semplice caso in cui vi sia ununica tipologia di prezzi (possiamo pensare a questi valori come ai prezzi mid di un insieme di azioni). Scheletro della classe (le .hpp)
// ------------------ Begin equity_prices.hpp ---------------------class Equity_prices { private: double time ; double *prices ; Equity_description **equity_description ; int dim ; public: // Default constructor // Equity_prices(void) ; Equity_prices(double time_init, double *prices_init,
Si parla di prezzo bid (detto anche prezzo denaro) relativamente allacquisto da parte di un market maker che quota un certo titolo e di un prezzo ask (detto anche prezzo lettera) per la vendita. E quindi intuibile che il prezzo bid sar sempre pi basso di quello a u ask.
3

242CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING


Equity_description **equity_description_init, int dim) ; double Get_time(void) { return time ; } ; double Set_time(double time_init) { time = time_init ; } ; double Get_price(int i) { if(i>=0 && i<dim) { return prices[i] ; } else { // Error exit(1) ; } } ; int Set_price(int i, double price_init) { if(i>=0 && i<dim) { prices[i] = price_init ; } else { // Error exit(1) ; } } ; } ;

// ------------------ End equity_prices.hpp ------------------------

Signicato dei membri della classe (1) dim: numero di azioni di cui la classe denisce i prezzi. (2) prices: un vettore (di lunghezza dim) contenente i prezzi (mid) delle e dim azioni in oggetto, al tempo specicato da time. (3) time: tempo espresso in year fraction a cui il vettore di prezzi prices si riferisce. (4) equity description: pointer a pointer di tipo Equity description. E in pratica un vettore di lunghezza dim in cui il generico elemento i-esimo

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++

243

equity description[i] rappresenta un pointer ad un oggetto di tipo Equity description che contiene lanagraca dellazione il cui prezzo al tempo time dato da prices[i]. e (5) Equity prices(double time init, .....): costruttore della classe. Consente di inizializzare i membri di tipo dato che caratterizzano la classe. (6) Get price(int i): restituisce il prezzo dellazione i-esima. (7) Set price(int i, double price init): imposta il prezzo dellazione i-esima al valore specicato da price init. Si osservi che se si volesse estendere la classe riportata sopra al ne di trattare oltre al prezzo mid (rappresentato dal vettore double *prices) anche i prezzi bid e ask, sarebbe suciente introdurre nella classe dei vettori ulteriori: double *price_bid ; double *price_ask ; imponendo ad es. che: prices[i] = 0.5 * ( price_bid[i] + price_ask[i] ) ; in alternativa (con notevoli vantaggi per la coerenza dei dati) si pu o addirittura sopprimere in questo caso il vettore double *prices, lasciando solo i due vettori price bid e price ask e modicando la funzione Get price(int i) in modo che fornisca on demand il prezzo dellazione i-esima come media di price bid[i] e price ask[i]. Esercizio Si completi la classe con tutte le funzioni di interfaccia necessarie.

244CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING

4.1.8

Processi stocastici e generazione di cammini

Descrizione: questa sezione dedicata ai processi stocastici, con pare ticolare riguardo a quelli utilizzati in nanza per modellare le azioni. Come gi emerso nella descrizione dei processi stocastici fatta nel capia tolo 2.2, una dei tratti fondamentali che li caratterizza la presenza di e un fattore daleatoriet, per cui partendo da un dato prezzo azionario a al tempo t, il valore futuro dellazione al tempo t + t non stabilito e in maniera deterministica ma pu tipicamente assumere inniti valori, o ciascuno con una propria densit di probabilit. In defnitiva, dato un a a generico processo stocastico, sar necessario estrarre una o pi varia u abili da un generatore di numeri casuali (con distribuzione opportuna) al ne di calcolare il punto nale darrivo (ad es. il prezzo dellazione al tempo t + t). Per questa ragione sar quindi opportuno inserire tra a i membri di una eventuale classe per gestire i processi stocastici, un generatore di numeri pseudo-casuali con distribuzione uniforme (e/o gaussiana). La gerarchia riportata in g. 4.9, per la gestione dei processe stocastici, parte da una classe astratta padre (Process) che si divide in due ussi: Process eq per i processi stocastici riguardanti le azioni e Process IR per descrivere levoluzione aleatoria dei tassi di interesse. Nel presente volume approfondiremo unicamente le classi associate a processi stocastici azionari. Non verr quindi denita in magggior dettaglio a la parte riguardante i processi stocastici su tasso 4 . Inne sempre in questa macrosezione della libreria nanziaria, vengono introdotte tre ulteriori classi: Random numbers, Schedule e Path (vedi gura 4.10), in quanto strettamente collegate alla gerarchia delle classi riguardanti e i processi stocastici. In particolare Random numbers una semplice classe per trattare un vettore di double, la sua nalit sar quella di a a archiviare i random numbers necessari ad un generico processo stocastico per ottenere un futuro valore del (o dei) sottostanti a partire da un punto dato (il prezzo o i prezzi dellazione oggi). Ad esempio nel caso di un processo stocastico log-normale per una singola azione, Random numbers conterr un vettore di lunghezza pari a 1, infata e ti suciente ununica variabile casuale estratta da una distribuzione gaussiana per generare un nuovo punto a partire da un punto dato (cio il valore iniziale dellazione). Nel caso invece di un processo stoe castico lognormale multivariato per n azioni, Random numbers dovr a ospitare un vettore di double di lunghezza pari a n. La classe Path permette di descrivere un cammino (spezzato) seguito da uno o pi sottostanti azionari. Rappresenta cio un possibile sceu e nario evolutivo per le azioni sottostanti ad un contratto opzionale.
4 Per una discussione approfondita su questo tema rimandiamo allottimo testo di Brigo e Mercurio [30].

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++

245

Inne la classe Schedule consente di rappresentare un insieme di date (tipicamente le date di xing di un contratto opzionale) e risulta importante in uno dei costruttori di Path. Il diagramma di questo settore della libreria e riportato nelle gure 4.9 e 4.10.

Process
Process ~Process Get_random_uniform Get_random_gaussian

Process_IR

Process_eq

Equity_prices Random_numbers
random_numbers dim

Process_eq Get_random_structure Get_new_prices

Random_numbers ~Random_numbers Set_element Get_element

Process_eq_lognormal
Equity_description

Process_eq_lognormal_multivariate
dim correlation_matrix w_correlated

Process_eq_lognormal Get_new_equity_price Get_random_structure Get_new_prices

Process_eq_lognormal_multivariate ~Process_eq_lognormal_multivariate Generate_correlations Get_random_structure Get_new_prices

Figura 4.9: Schema generale per la gerarchia di classi riguardanti i processi stocastici.

246CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING 4.1.8.a Classe: Process

Nome classe: Process Signicato: Classe astratta per gestire i processi stocastici Scheletro della classe (le .hpp)
// ------------------ Begin process.hpp --------------------------class Process { private: . . public: // Default constructor // Process(void) { }; // Destructor // virtual ~Process(void) { }; // Random number generators // double Get_random_uniform(void) ; double Get_random_gaussian(vodi) ; } ; // ------------------ End process.hpp -----------------------------

(1) Get random uniform: funzione che restituisce un numero casuale distribuito uniformemente tra [0,1] ; (1) Get random gaussian: funzione che restituisce un numero casuale distribuito normalmente con media zero e varianza unitaria. Relativamente alle funzioni per la generazione di numeri casuali (con distribuzione uniforme e/o gaussiana), degli ottimi algortimi sono presenti nella libreria matematica GSL.

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ 4.1.8.b Classe: Process eq

247

Nome classe: Process eq Signicato: Classe astratta per gestire i processi per le azioni Scheletro della classe (le .hpp)
// ------------------ Begin process_eq.hpp ------------------------

class Process_eq { private: . . public: // Constructors & destructors // Default constructor // Process_eq(void) { }; // Destructor // virtual ~Process_eq(void) { };

virtual Random_numbers *w Get_random_structure(void) = 0 ; virtual Equity_prices *Get_new_prices(Equity_prices *eq_prices_in, Random_numbers *w, double delta_t) = 0 ; } ;

// ------------------ End process_eq.hpp --------------------------

248CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING 4.1.8.c Classe: Process eq lognormal

Nome classe: Process eq lognormal Signicato: Classe per descrivere un processo lognormale per una singola azione. Lelemento fondamentale di questa classe la funzione e Get new equity price che restituisce il valore assunto dallazione ad un istante futuro t end, quando in input siano forniti: (a) lanagraca dellazione Equity *equity description (da cui si ricava il dividend yield, la volatilit e la curva dei tassi associata allazione); (b) il vala ore iniziale dellazione (equity price), allistante t start; (c) la variabile aleatoria w; (d) il tempo iniziale t start e (e) il tempo nale t end. Pi precisamente tale funzione implementa la formula (2.36) con luniu ca accortezza di sostituire con il tasso risk free (essendo la valutazione dei derivati eettuata in un mondo neutrale al rischio). Scheletro della classe (le .hpp)
// ------------------ Begin process_eq_lognormal.hpp ---------------

class Process_eq_lognormal { public: // Default constructor // Process_eq_lognormal(void) { }; static double Get_new_equity_price( Equity_description *equity_description, double equity_price, double w, double t_start, double t_end ) ; virtual Random_numbers *w Get_random_structure(void) ; virtual Equity_prices *Get_new_prices(Equity_prices *eq_prices_in, Random_numbers *w, double delta_t) ; } ;

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++

249

// ------------------ End process_eq_lognormal.hpp -----------------

Signicato dei membri della classe (1) Get new equity price: e la funzione che restituisce il nuovo prezzo dellazione (descritta dallanagraca equity description) al tempo t end, partendo dal prezzo dellequity equity price al tempo t start. La variabile stocastica w dovr essere passata in input. a Implementazione di alcune funzioni della classe (le .cpp)
// ------------------ Begin process_eq_lognormal.cpp ---------------

double Process_eq_lognormal::Get_new_equity_price( Equity *equity_description, double equity_price, double w, double t_start, double t_end ) { Yield_curve *yc = equity_description->Get_yc() ; double r = yc->Get_forward_rate(t_start, t_end) ; double dividend_yield = equity_description->Get_dividend_yield() ; double sigma = equity_description->Get_vol() ; double delta_t = t_end - t_start ; return equity_price * exp( (r - dividend_yield - 0.5*sigma*sigma) * delta_t + sigma * sqrt(delta_t) * w ) ; }

Random_numbers *Process_eq_lognormal::Get_random_structure(void) { Random_numbers *w = new Random_numbers(1) ; w->Set_element(0, Get_random_gaussian() ) ; return w ; }

Equity_prices *Process_eq_lognormal::Get_new_prices(

250CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING


Equity_prices *eq_prices_in, Random_numbers *w, double delta_t) { Equity_prices *eq_prices_out ; eq_prices_out = new Equity_prices(1) ; new_equity_price = Get_new_equity_price( eq_prices_in->Get_equity_description(0), eq_prices_in->Get_equity_price(0), w->Get_element(0), eq_prices_in->Get_time(), eq_prices_in->Get_time() + delta_t) ; eq_prices_out->Set_equity_prices(0, new_equity_price) ; eq_prices_out->Set_time(eq_prices_in->Get_time() + delta_t) ; eq_prices_out->Set_equity_description(0, eq_prices_in->Get_equity_description(0)) ; return eq_prices_out ; }

// ------------------ End process_eq_lognormal.cpp -----------------

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ 4.1.8.d Classe: Process eq lognormal multivariate

251

Nome classe: Process eq lognormal multivariate Signicato: Classe per descrivere un processo lognormale per un set di azioni. Scheletro della classe (le .hpp)
// ---------- Begin process_eq_lognormal_multivariate.hpp ---------

class Process_eq_lognormal_multivariate { private: int dim ; double **correlation_matrix ; Random_numbers *w_correlated ; . . . public: // Default constructor // Process_eq_lognormal_multivariate(void) ; Process_eq_lognormal_multivariate(int dim_init) ; // Destructor // virtual ~Process_eq_lognormal_multivariate(void) ; int Generate_correlations(Random_numbers *w_out, Random_numbers *w_in) ; virtual Random_numbers *Get_random_structure(void) ; virtual Equity_prices *Get_new_prices(Equity_prices *in, Random_numbers *w, double delta_t) ; } ;

// ---------- End process_eq_lognormal_multivariate.hpp -----------

252CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING Signicato dei membri della classe (1) Get new equity price: e la funzione che rerstiutisce il nuovo prezzo dellazione (descritta dallanagraca equity description) al tempo t end, partendo dal prezzo dellequity equity price al tempo t start. Implementazione di alcune funzioni della classe (le .cpp)
// ------------- Begin process_eq_lognormal_multivariate.cpp ------Random_numbers *Process_eq_lognormal_multivariate::Get_random_structure( void) { Random_numbers *w = Random_numbers(dim) ; for(int i=0; i<dim; i++) { w->Set_element(i, Get_random_gaussian() ) ; } return w ; } Equity_prices *Process_eq_lognormal_multivariate::Get_new_prices( Equity_prices *eq_prices_in, Random_numbers *w, double delta_t) { int i ; Equity_prices *eq_prices_out ; eq_prices_out = new Equity_prices(dim) ; // Introduce correlations // Generate_correlations(w_correlated, w) ; for(i=0; i<dim; i++) { new_equity_price = Process_eq_lognormal::Get_new_equity_price( eq_prices_in->Get_equity_description(i), eq_prices_in->Get_equity_price(i), w_correlated->Get_element(i), eq_prices_in->Get_time(), eq_prices_in->Get_time()+ delta_t) ; eq_prices_out->Set_equity_prices(i, new_equity_price) ; eq_prices_out->Set_time(eq_prices_in->Get_time() + delta_t) ;

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++


eq_prices_out->Set_equity_description(i, eq_prices_in->Get_equity_description(i)) ; } return eq_prices_out ; };

253

// ------------- End process_eq_lognormal_multivariate.cpp ---------

Esercizio Si completi la classe in oggetto, implementando le funzioni mancanti. Particolare cura dovr essere posta nella gestione della matrice di variana za covarianza (si dovranno in particolare scrivere le funzioni di interfaccia necessarie e si dovr prevedere nel costruttore della classe, lopportuna ina izializzazione della matrice correlation matrix) e nella denizione della funzione Generate correlations il cui compito consiste nel creare una n-upla di variabili correlate normali partendo da una n-upla di variabili scorrelate normali (si dovr implementare a questo scopo lalgoritmo di decomposizione a di Cholesky, si veda a tal proposito lottimo libro di Jackel [27]).

254CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING 4.1.8.e Classe: Process IR

Nome classe: Process IR Signicato: Classe astratta per gestire i processi per i tassi Scheletro della classe (le .hpp)
// ------------------ Begin process_IR.hpp ------------------------

class Process_IR { private: . . public: // Constructors & destructors // Default constructor // Process_IR(void) { }; // Destructor // virtual ~Process_IR(void) { };

} ;

// ------------------ End process_IR.hpp --------------------------

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++


dim+1

255

Path
dim starting_point equity_prices_scenario random_numbers_scenario dim 0..*

Equity_prices Random_numbers
random_numbers dim Random_numbers Random_numbers ~Random_numbers Set_element Get_element

Process_eq
Path Path ~Path Get_starting_point Get_equity_prices Get_random_numbers Get_dim

Schedule
t dim Schedule Schedule ~Schedule Get_t Get_dim

Figura 4.10:

Schema in cui viene rappresentata la classe path e la sua relazione con

altre classi delle libreria.

4.1.8.f

Classe: Random numbers

Nome classe: Random numbers Signicato: Classe per gestire i numeri random necessari in un generico processo stocastico. Scheletro della classe (le .hpp)
// ------------------ Begin random_numbers.hpp ---------------------

class Random_numbers { private: double *random_numbers ; int dim ; public: // Constructors & destructors // Default constructor // Random_numbers(void) ; Random_numbers(int dim) ;

256CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING

// Destructor // virtual ~Random_numbers(void) ; int Set_element(int i, double value) ; double Get_element(int i) ; } ;

// ------------------ End random_numbers.hpp -----------------------

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ 4.1.8.g Classe: Schedule

257

Nome classe: Schedule Signicato: Questa classe ha lobiettivo di rappresentare un insieme di date ordinate cronologicamente. La classe conterr quindi come a elemento base un vettore di double di lunghezza dim. Ogni elemento del vettore rappresenter una data futura espressa come intervallo di a tempo (in unit di year fraction) rispetto ad una data di riferimento a arbitraria presa come punto zero (ad es. il 1 gennaio 2000). A titolo esemplicativo, supponiamo di voler rappresentare tramite un oggetto della classe Schedule, le seguenti tre date: 1 luglio 2005, 1 gennaio 2006 e 1 gennaio 2007. Si supponga di utilizzare come data di riferimento dellasse dei tempi il 1 gennaio 2000, loggetto Schedule dovr contenere i setuenti tre numeri: a 5.5 = 6.0 = 7.0 = 1 luglio 20051 gennaio 2000
365

1 gennaio 20061 gennaio 2000


365

1 gennaio 20071 gennaio 2000


365

Un elemento importante che dovr caratterizzare la classe sar il fatto a a che lordinamento cronologico andr sempre garantito. Questo siga nica che gli eventuali costruttori di questa classe dovranno sempre vericare lordinamento crescente degli istanti temporali considerati. Scheletro della classe (le .hpp)
// ------------------ Begin schedule.hpp --------------------------class Schedule { private: double *t ; int dim ; public: // Constructors & destructors // Default constructor Schedule(void) ; Schedule(double t_ref, double delta_t, int dim_init) ; Schedule(double *t_init, int dim_init) ;

258CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING

// Destructor virtual ~Schedule(void) ;

// Funzioni di interfaccia // double *Get_t(int i) ; int Get_dim(vodi) ; } ;

// ------------------ End schedule.hpp -----------------------------

Signicato dei membri della classe (1) t: un pointer ad un vettore di tipo double, contenente una successione e di tempi (in year fraction) ordinati cronologicamente. (2) dim: la dimensione del vettore t. e (3) Schedule(double t ref, double delta t, int dim init): uno dei costrute tore della classe. Permette di descrivere un set di punti temporali equispaziati in cui lintervallo di tempo che separa due punti successivi pari a t, ovvero: t[i] = tref + (i + 1) t, con i = 0, 1....dim-1. I e punti t[i] sono generati a partire da un punto iniziale t ref. (4) Schedule(double *t init, int dim init): uno dei costruttore della e classe. Permette di inizializzare il vettore t a partire dal vettore t init passato dallesterno. (5) Get t(int i): restituisce le coordinate temporali del punto i-esimo espresse in termini di year fraction. (6) Get dim(void): restituisce il numero complessivo di date archiviate nelloggetto Schedule (ovvero la dimensione del vettore t).

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ 4.1.8.h Classe: Path

259

Nome classe: Path Signicato: Legata strettamente alla classe Process eq (e nel seguito e alla classe Option pricer monte carlo), vi la classe deputata a rappresentare i cammini di una o pi azioni (tipicamente generati da una u simulazione Monte Carlo). La classe in questione, Path, denita dale lo scheletro riportato sotto. In generale un cammino seguito da una o pi azioni completamente u e denito nel momento in cui si specica: il punto di partenza, il quale rappresenta il/i prezzi delle azioni al tempo iniziale. Nello scheletro della classe, questo rappresene tato dal pointer starting point che punta ad un oggetto di tipo Equity prices. i valori assunti dalla/dalle azioni in una serie discreta di tempi futuri (il cui numero totale rappresentato nella classe dalla e variabile intera dim). Nello scheletro della classe questi punti, che rappresentano un possibile scenario evolutivo, sono identicati da equity prices scenario, un pointer a pointer di tipo Equity prices. Linterpretazione di questa struttura ben rappresentata in gue ra 4.11. In aggiunta nella classe presente un pointer a pointer ad oggetti di e e tipo Random numbers, il cui scopo quello di raccogliere i dim oggetti di tipo Random numbers utilizzati dal processo stocastico per la generazione del cammino. Ad esempio nel caso di un processo lognormale per una singola azione, random numbers scenario[0] un pointer ad e un oggetto di tipo Random numbers contenente ununica variabile di tipo double, la quale rappresenta la componente stocastica w utilizzata nella formula (2.36) per ottenere il prezzo dellazione S(t1 ) al tempo t1 partendo dal valore dellazione S(t0 ) al tempo iniziale. Analogamente i pointer successivi random numbers scenario[i], rappresentano le altre variabili stocastiche wi necessarie per ottenere i successivi punti S(ti ), no al completamento del cammino (la cui lunghezza sar pari a dim). a La memorizzazione del vettore di oggetti Random numbers, utilizzati nella costruzione del cammino si rivela particolarmente preziosa nel momento in cui si debba implementare un Monte Carlo con luso della variabile antitetica (vedi paragrafo 3.1.4.e). Scheletro della classe (le .hpp)

260CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING


Prezzi dei sottostanti al variare del tempo
Equity_price object #1

Equity_price object #4 Equity_price object #2 Equity_price object #3

Equity_price object #0

time

pointer to #0

pointer to #1

pointer to #2

pointer to #3

pointer to #4

equity_prices_array
(pointer a pointer di tipo Equity_prices)

Figura 4.11:

Schema graco in cui viene rappresentato il signicato di un pointer a

pointer ad oggetti di tipo Equity prices.

// ------------------ Begin path.hpp -----------------------------class Path { private: Equity_prices *starting_point ; Equity_prices **equity_prices_scenario ; Random_numbers **random_numbers_scenario ; int dim ; public: // Constructors & destructors // Default constructor Path(void) ; Path(Equity_prices *starting_point_init, Schedule *schedule, Process_eq *process_eq) ; Path(Path *path) ; // Destructor virtual ~Path(void) ;

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++

261

Equity_prices *Get_starting_point(void) ; Equity_prices *Get_equity_prices(int i) ; Random_numbers *Get_random_numbers(int i) ; int Get_dim(vodi) ; } ;

// ------------------ End path.hpp --------------------------------

Signicato dei membri della classe

(1) Path(Equity prices *starting point init, Schedule *schedule, Process eq *process eq) il costruttore principale della classe Path. e Poich i punti di un cammino (rappresentati nella nostra classe da equie ty prices scenario) si ottengano applicando iterativamente un processo stocastico, in modo da ottenere un nuovo punto a partire dal precedente, il costruttore in questione prende in input il punto di partenza (ovvero i prezzi delle azioni allistante iniziale del cammino), il processo stocastico che ne governa levoluzione e linsieme dei tempi che deniscono i punti temporali del cammino (ricordiamo infatti che il cammino di cui voliamo dare una rappresentazione sempre formato e da un insieme discreto di punti, di istantanee fotograche prese in momenti dierenti). Il costruttore utilizzer il pointer starting point init a per inizializzare starting point e attraverso lapplicazione ricorsiva del processo stocastico process eq, andr a costruire il cammino formato a dai punti specicati da schedule (ovviamente verranno generati eettivamente solo i punti di Schedule che appartengono al futuro rispetto alla data odierna presente nel campo time delloggetto puntato da starting point init). (2) Path(Path *path): il costruttore utilizzato per realizzare un came mino antitetico a partire dal quello contenuto in path. In sostanza lalgoritmo di generazione del cammino sar identico a quello utiliza zato nel costruttore di cui al punto precedente, con lunica (importante) dierenza che i numeri random necessari ad ottenere il nuovo punto equity prices scenario[i] partendo dal punto precedente equity prices scenario[i-1], non saranno generati ma verranno presi da random numbers scenario contenuto nelloggetto puntato da path, invertendone i segni (vedi paragrafo 3.1.4.e).

262CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING (3) Get starting point(void): questa funzione restituisce il pointer al punto iniziale da cui si sviluppa il cammino. (4) Get equity prices(int i): questa funzione restituisce il punto i-esimo del cammino. (5) Get random numbers(int i): restituisce il pointer random numbers scenario[i], utilizzato per costuire loggetto puntato da equity prices scenario[i], partendo dalloggetto puntato da equity prices scenario[i-1] 5 . Esercizio / laboratorio Si implementino tutte le funzioni membro necessarie al corretto funzionamento della classe Path.

5 Ovviamente per i = 0 si dovr prendere come punto di partenza loggetto il cui a indirizzo contenuto in starting point. e

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++

263

4.1.9

Anagraca opzioni

Descrizione: le classi sviluppate sotto, implementano il concetto di contratto opzionale. La struttura parte da una classe astratta (Contract option) da cui vengono derivati due tronconi principali: Contract equity option (utilizzata come classe astratta per generare contratti opzionali scritti su una o pi azioni) e Contract IR option (utiu lizzata come classe astratta per generare contratti scritti su tassi di interesse). Il diagramma di questo settore della libreria e riportato nella gura sottostante.

Contract_option
Contract_option ~Contract_option

Contract_eq_option
equity_prices schedule Contract_eq_option ~Contract_eq_option Pay_off

Contract_eq_option_plain_vanilla
strike_price contract_type Contract_eq_option_plain_vanilla ~Contract_eq_option_plain_vanilla Get_strike_price Set_strike_price Get_contract_type Set_contract_type Pay_off

Contract_eq_option_barrier

Path

barrier_level barrier_type Contract_eq_option_barrier ~Contract_eq_option_barrier Get_barrier_level Set_barrier_level Get_barrier_type Set_barrier_type Pay_off

Contract_IR_option

Contract_eq_option_asian
Contract_eq_option_asian ~Contract_eq_option_asian Pay_off

Figura 4.12: Schema anagraca opzioni

264CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING 4.1.9.a Classe: Contract option

Nome classe: Contract option Signicato: Classe astratta per gestire lanagraca delle opzioni. Scheletro della classe (le .hpp)
// ------------------ Begin contract_option.hpp -------------------class Contract_option { private: Schedule *schedule ; . . public: // Default constructor // Contract_option(void) ; Contract_option(Schedule *schedule_init) ; // Destructor // virtual ~Contract_option(void) { };

} ;

// ------------------ End contract_option.hpp ----------------------

Signicato dei membri della classe (1) schedule: il pointer ad un oggetto di tipo Schedule contenente lelenco e delle date di xing che caratterizzano il contratto opzionale.

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ 4.1.9.b Classe: Contract eq option

265

Nome classe: Contract eq option Signicato: Classe astratta per gestire lanagraca delle opzioni su equity. Questa classe viene derivata da Contract option. La classe Contract eq option dovr avere tra i suoi membri un puna tatore ad un oggetto di tipo Equity prices che ne rappresenta il sottostante (in particolare lanagraca del o dei sottostanti sar facilmente a raggiungibile utilizzando il campo equity description contenuto in ogni oggetto di tipo Equity prices). Un altro elemento cruciale nella denizione di questa classe sar la presenza di una funzione di pay-o a che denisca il premio pagato a scadenza dallopzione. Essendo Contract eq option una classe astratta il cui ne semplicemente quello e di fare da capostipite di una gerarchia di opzioni eettive, la funzione di pay-o allinterno di questa classe verr dichiarata di tipo virtuale a pura. Scheletro della classe (le .hpp)
// ---------------- Begin contract_eq_option.hpp ------------------class Contract_eq_option { private: Equity_prices *equity_prices ; . public: // Default constructor // Contract_eq_option(void) { }; Contract_eq_option(Equity_prices *equity_prices_init, Schedule *schedule_init) ; // Destructor // virtual ~Contract_eq_option(void) ;

virtual double Pay_off(Path *path) = 0 ; } ;

266CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING


// ---------------- End contract_eq_option.hpp ---------------------

Signicato dei membri della classe (1) equity prices: puntatore ad un oggetto di tipo Equity prices. Questo membro permette di accedere al prezzo dei sottostanti ed alle relative anagrache (ricordiamo infatti che la classe Equity prices contiene un pointer alla classe Equity description). (2) Pay o(Path *path): funzione che restituisce il pay-o pagato dallopzione a scadenza. In input dovr ricevere il cammino del (o dei) a sottostanti, path, in corrispondenza delle date di xing specicate in schedule. (3) Contract equity option(Equity prices *equity prices init, Schedule *schedule init): costruttore della classe Contract equity option, che inizializza le strutture: equity prices e schedule. Esercizio / laboratorio Si implementino tutte le funzioni membro necessarie al corretto funzionamento della classe Contract eq option.

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ 4.1.9.c Classe: Contract eq option plain vanilla

267

Nome classe: Contract eq option plain vanilla Signicato: Denisce la classe che descrive unopzione plain vanilla. Questa classe viene derivata dalla classe padre Contract eq option Scheletro della classe (le .hpp)
// ------------ Begin contract_eq_option_plain_vanilla.hpp --------class Contract_eq_option_plain_vanilla : public Contract_eq_option { private: double strike_price ; char contract_type ; public: // Default constructor // Contract_eq_option_plain_vanilla(void) { }; // Constructor // Contract_eq_option_plain_vanilla(Equity *equity, Schedule *schedule_init) ; // Destructor // virtual ~Contract_eq_option_plain_vanilla(void) ; // Pay off definition // virtual double Pay_off(Path *path) ; } ; // ------------ End contract_eq_option_plain_vanilla.hpp -----------

Signicato dei membri della classe (1) strike price: variabile double contenente lo strike price dellopzione. (2) contract type: variabile di tipo char per denire il tipo di contratto (ovvero P per le opzioni di tipo put e C per quelle di tipo call).

268CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING Esercizio / laboratorio Si implementino tutte le funzioni membro necessarie al corretto funzionamento della classe Contract eq option plain vanilla. Inne partendo dalla classe per le opzioni di tipo plain vanilla, si derivino due classi per la gestione delle opzioni con barriera di tipo down & in, down & out, up & in e up & out e per le opzioni di tipo asiatico.

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++

269

4.1.10

Metodi per il pricing di opzioni

In questa sezione vengono esposte le classi necessarie a gestire i metodi (analitici e numerici) per la determinazione del prezzo di unopzione. In particolare le classi riportate consentiranno di gestire le seguenti metodologie numeriche: Monte Carlo, Alberi binamiali e metodo alle dierenze nite e le seguenti metodologie analitiche: formula chiusa (ad es. per le opzioni plain vanilla la classica formula di Black & Scholes) e formula chiusa approssimata (ad es. nel caso in cui fosse disponibile una formula analitica frutto di una qualche approssimazione). Il capostipite dei vari tipi di pricer, contiene dei riferimenti (pointer) al tipo di contratto da prezzare e al tipo di processo stocastico che domina levoluzione del sottostante. Sono infatti questi i due elementi comuni a tutti i vari tipi di pricer. Il diagramma di questo settore della libreria e riportato nella gura sottostante.

Option_pricer Option_pricer_monte_carlo
contract process N Option_pricer_monte_carlo ~Option_pricer_monte_carlo Get_error Option_pricer Option_pricer ~Option_pricer Get_price

Option_pricer_binomial_tree
Option_pricer_binomial_tree ~Option_pricer_binomial_tree

Option_pricer_finite_difference
Option_pricer_finite_difference ~Option_pricer_finite_difference

Option_pricer_closed_formula
Option_pricer_closed_formula ~Option_pricer_closed_formula

Option_pricer_approx_closed_formula
Option_pricer_approx_closed_formula ~Option_pricer_approx_closed_formula

Figura 4.13: Schema pricer di opzioni

270CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING 4.1.10.a Classe: Option pricer

Nome classe: Option pricer Signicato: Classe astratta da cui verranno derivati tutti i diversi tipi di pricer. Scheletro della classe (le .hpp)
// ------------------ Begin option_pricer.hpp ----------------------class Option_pricer { private: Contract_option *contract_option ; Process *process ; . . public: // Constructors & destructors // Default constructor // Option_pricer(void) { }; // Constructor // Option_pricer(Contract_option *contract_option_init, Process *process_init) { contract_option = contract_option_init ; process = process_init ; }; // Destructor // virtual ~Option_pricer(void) { }; double Get_price(void) ; } ; // ------------------ End option_pricer.hpp ------------------------

Signicato dei membri della classe

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++

271

(1) contract: puntatore ad un oggetto di tipo Contract; rappresenta il contratto di cui si vule determinare il prezzo tramite il metodo in oggetto. (2) process: puntatore ad un oggetto di tipo Process; rappresenta il processo stocastico che descrive levoluzione aleatoria del sottostante. (3) Option pricer(Contract *contract init, Process *process init): il costrute tore per la classe Pricer. Prende in input il contratto di cui si vuole determinare il prezzo ed il processo che governa levoluzione del sottostante il contratto. Nel costruttore si dovr vericare la coerenza tra a il contratto ed il processo passati in input, in particolare se il processo di tipo multivariato, la dimensione del processo (ovvero il numero e di sottostanti azionari che governa) deve essere uguale al numero di azioni presenti nelloggetto puntato da equity prices (pi precisamente u dato dal campo dim delloggetto di tipo Equity prices puntato da equity prices) che gura in contract (dopo aver provveduto allopportuno cast esplicito a Contract eq option) 6 . (3) Get price(void): funzione che restituisce il prezzo dellopzione cos come stimato dal pricer. Esercizio / laboratorio Relativamente al controllo a cui si accennato nel punto (3) riportato e sopra, si trovi un modo per stabilire (modicando opportunamente le classi Process) il sotto-tipo di processo puntato da process, prima di eseguire indiscriminatamente un eventuale cast esplicito. Questo al ne di poter gestire in maniera sicura loperazione di cast che gura nella stringa (4.2). Un analogo discorso pu essere ripetuto per la conversione di contract al sottoo tipo Contract eq option ed in generale per ogni situazione in cui si debba ricorrere ad un cast esplicito.

In altri termini nel caso di un processo multivariato: ((Contract eq option *)contract) Get equity prices() Get dim() , (4.1)

deve essere uguale a: ((Process eq lognormal multivariate *process)) Get dim() . (4.2)

272CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING 4.1.10.b Classe: Option pricer monte carlo

Nome classe: Option pricer monte carlo Signicato: Classe per gestire il pricing con il metodo Monte Carlo. Tale classe costruir N cammini (secondo lalgoritmo denito a in 3.1.4.b) su ciascuno dei quali verr calcolato il pay-o. La mea dia e la standard deviation forniranno il valore e lerrore sulla stima del prezzo dellopzione. Scheletro della classe (le .hpp)
// -------------- Begin option_pricer_monte_carlo.hpp -------------class Option_pricer_monte_carlo : public Option_pricer { private: // Number of simulation // int N ; . . public: // Default constructor // Option_pricer_monte_carlo(void) : };

Option_pricer() {

Option_pricer(Contract_option *contract_option_init, Process *process_init, int N_init) ; // Destructor // virtual ~Option_pricer_monte_carlo(void) { };

double Get_error(void) ;

} ;

// -------------- End option_pricer_monte_carlo.hpp ----------------

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ Signicato dei membri della classe (1) N: numero di simulazioni Monte Carlo.

273

(2) Option pricer(Contract option *contract option init, ....): il costruttore di questa classe deputato a realizzare la simulazione Monte Care lo descritta nel paragrafo 3.1.4. Di fatto lalgortimo verr implementato reiternado N volte i seguenti a passi: Si campiona lo spazio dei cammini stocastici S(t) generando un oggetto di tipo Path. A tal ne si utilizzer il costruttore di Path a che consente di realizzare un nuovo cammino partendo da: (1) un dato punto iniziale (in pratica il pointer equity prices contenuto nelloggetto contract option, estraibile dopo aver eseguito un opportuno cast esplicito di contract option al tipo Contract eq option); (2) da un set di date denite dal pointer ad un oggetto Schedule che denisce le date di xing del contratto opzionale (e precisamente il pointer Contract option::schedule); (3) dal pointer al processo stocastico che governa levoluzione del o dei sottostanti (passato al costruttore del pricer tramite il pointer process init). Si valuta il pay-o lungo il cammino generato tramite la funzione di pay-o contenuta in contract option (accedibile dopo aver eseguito un cast esplicito di questo pointer al tipo Contract eq option). Si cumula il pay-o calcolato (scontato ad oggi) ed il suo quadrato, in due variabili. Una volta completato il ciclo sar suciente calcolare media e varianza a per avere una stima del prezzo dellopzione con il relativo errore. (3) Get error(void): funzione che restituisce lerrore commesso nella stima Monte Carlo del prezzo (espresso percentualmente in maniera relativa rispetto al valore dellopzione). Esercizio / laboratorio Si implementino tutte le funzioni membro necessarie al corretto funzionamento della classe Option pricer monte carlo.

274CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING 4.1.10.c Classe: Option pricer binamial tree

Nome classe: Option pricer binamial tree Signicato: Classe per gestire il pricing con il metodo dellalbero binomiale. Scheletro della classe (le .hpp)
// -------------- Begin option_pricer_binomial_tree.hpp -----------class Option_pricer_binomial_tree private: . . public: // Default constructor // Option_pricer_binomial_tree(void) : }; : public Option_pricer {

Option_pricer() {

// Destructor // virtual ~Option_pricer_binomial_tree(void) ; } ;

// -------------- End option_pricer_binomial_tree.hpp --------------

Esercizio / laboratorio Si completi la classe Option pricer binamial tree e si implementino tutte le funzioni membro necessarie al suo corretto funzionamento. In particolare si faccia riferimento al paragrafo 3.2.6 per quanto riguarda lalgoritmo da implementare.

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ 4.1.10.d Classe: Option pricer nite dierence

275

Nome classe: Option pricer nite dierence Signicato: Classe per gestire il pricing con il metodo delle dierenze nite. Scheletro della classe (le .hpp)
// ------------- Begin option_pricer_finite_difference.hpp --------class Option_pricer_finite_difference private: . . public: // Default constructor // Option_pricer_finite_difference(void) : }; : public Option_pricer {

Option_pricer() {

// Destructor virtual ~Option_pricer_finite_difference(void) { };

} ;

// ------------- End option_pricer_finite_difference.hpp -----------

Esercizio / laboratorio Si completi la classe Option pricer nite dierence e si implementino tutte le funzioni membro necessarie al suo corretto funzionamento. In particolare si faccia riferimento al capitolo 3.3 per quanto riguarda lalgoritmo da implementare.

276CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING 4.1.10.e Classe: Option pricer exact closed formula

Nome classe: Option pricer exact closed formula Signicato: Classe per gestire il pricing tramite formula chiusa. Scheletro della classe (le .hpp)
// ------------- Begin option_pricer_closed_formula.hpp -----------class Option_pricer_closed_formula private: . . public: // Constructors & destructors // Default constructor Option_pricer_closed_formula(void) : }; : public Option_pricer {

Option_pricer() {

// Destructor virtual ~Option_pricer_closed_formula(void) { };

} ; // ------------- End option_pricer_closed_formula.hpp --------------

Esercizio / laboratorio Si completi la classe Option pricer exact closed formula e si implementino tutte le funzioni membro necessarie al suo corretto funzionamento. In particolare nel caso in cui il contratto sottostante sia di tipo plain vanilla, si implementi la formula chiusa di Black & Scholes illustrata nel paragrafo 2.3.5.

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++ 4.1.10.f Classe: Option pricer approx closed formula

277

Nome classe: Option pricer approx closed formula Signicato: Classe per gestire il pricing tramite formula approssimata Scheletro della classe (le .hpp)
// ---------- Begin option_pricer_approx_closed_formula.hpp -------class Option_pricer_approx_closed_formula private: . . public: // Constructors & destructors // Default constructor Option_pricer_approx_closed_formula(void): Option_pricer() { }; // Destructor virtual ~Option_pricer_approx_closed_formula(void) { }; : public Option_pricer {

} ;

// ---------- End option_pricer_approx_closed_formula.hpp ----------

Esercizio / laboratorio Si completi la classe Option pricer approx closed formula e si implementino tutte le funzioni membro necessarie al suo corretto funzionamento. In particolare nel caso in cui il contratto sottostante sia di tipo asiatico, si implementi la formula chiusa approssimata illustrata nel capitolo 2.5.

278CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING

4.1.11

Schema complessivo della libreria (limitatamente al pricing di opzioni su equity)

Lo schema generale della libreria denito in gura 4.14 . I collegamenti e presenti nel graco indicano le relazioni tra i dierenti oggetti. Ad esempio, la linea direzionale che connette Equity description a Yield curve, indica che la classe Equity description contiene un riferimento (e precisamente un puntatore) a Yield curve. Alcune classi minori ed alcuni collegamenti sono stati omessi per semplicare il diagramma. Lo schema complessivo non fa altro che riassumere in una visione di insieme le singole macroaree che abbiamo illustrato nei paragra precedenti. Partendo dalla classe Pricer (che pu essere di 5 dierenti sotto-tipi a seconda o della metodologia di pricing scelta), questa contiene due riferimenti: uno al contratto opzionale tramite un pointer Contract option (il cui sotto-tipo determina eettivamente la tipologia del contratto in oggetto) ed uno al processo che governa levoluzione del sottostante il contratto (il processo viene a sua volta scelto allinterno di una gerarchia, di cui il processo loge normale, rappresentato da Process eq lognormal, un esempio). La classe Contract option contiene poi un pointer ad un oggetto di tipo Schedule (che ne denisce le date di xing) ed un pointer ad un oggetto di tipo Equity prices. Questultimo contiene il prezzo del o dei sottostanti allistante attuale nonch i riferimenti alle relative anagrache. Lanagraca di unazione e poi in relazione con due altre classi: quella che descrive la curva dei tassi e risk free e la classe deputata a gestire la supercie di volatilit che carattera izza lazione. Nel caso in cui il pricer sia di tipo Monte Carlo, la simulazione consister nella creazione di N cammini (su cui si valuter media e varianza). a a I cammini sono generati attraverso la reiterazione del processo stocastico (necessariamente di tipo Process eq 7 ) lungo le date specicate dalloggetto schedule contenuto in contract. Ogni cammino conterr un riferimento a (pointer) al punto di partenza (e precisamente ad un oggetto di tipo Equity prices con il/i prezzo/i della/delle azione/i al tempo iniziale) ed un vettore di pointer (di dimensione dim) ad oggetti di tipo Equity prices rappresentanti levoluzione stocastica del/dei sottostanti. Su ogni singolo cammino generato si eettuer la valutazione del pay-o tramite la funzione Pay o a presente nella classe Contract eq option e nelle sue derivate (si noti a questo proposito il collegamento tra la classe Contract eq option 8 e Path).

Sar quindi necessario eseguire un cast esplicito del pointer process ad un pointer di a tipo Process eq. 8 Anche in questo caso sar quindi necessario eseguire un cast esplicito del pointer a contract dal tipo Contract option al tipo Contract eq option.

Yield_curve Process
1 1 Yield_curve_flat

Vol_surface

Process_equity
Yield_curve_term_structure Process_eq_lognormal 0..*

0..*

Equity_description dim 0..* 1 0..* 1 0..* 0..* dim+1

Process_eq_lognormal_multivariate

Path

Equity_prices
0..*

Contract_option

Option_pricer

Option_pricer_monte_carlo

Schedule
1

Contract_eq_option
Option_pricer_binomial_tree Contract_eq_option_plain_vanilla Option_pricer_finite_difference Contract_eq_option_asian Option_pricer_exact_closed_formula Contract_eq_option_barrier Option_pricer_approx_closed_formula

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++

Figura 4.14: Schema generale delle libreria per il pricing di opzioni su equity.

279

280CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING

4.1.12

Schema di usso per il pricing di unopzione scritta su di un sottostante azionario)

Lo schema di usso da seguire per il pricing di unopzione scritta su di un sottostante azionario riportata in g. 4.15. Tale schema andr quindi ime a plementato in un eventuale le main che andr poi compilato utilizzando la a libreria costruita nei paragra precedenti. Schema di usso per il pricing (main) (1) Allocazione curva dei tassi Scopo: allocazione di un oggetto Yield curve (di tipo at o con una struttura a termine completa) al ne di denire una curva dei tassi risk free. Input esterno: il tasso risk free con eventuale struttura a termine. Link ad oggetti precedentemente allocati: nessuno. Propedeuticit: nessuna. a (2) Allocazione curva di volatilit a Scopo: allocazione di un oggetto di tipo Vol surface al ne di denire una curva di volatilit. a Input esterno: la volatilit del sottostante del contratto opzionale. a Link ad oggetti precedentemente allocati: nessuno Propedeuticit: nessuna. a (3) Allocazione anagraca dellazione Scopo: allocazione di un oggetto di tipo Equity description al ne di denire lanagraca del sottostante su cui scritta lopzione. e Input esterno: isin code, nome per esteso, currency di riferimento e dividend yield del titolo azionario. Link ad oggetti precedentemente allocati: la curva dei tassi di cui al punto (1) e la curva di volatilit di cui al punto (2). a Propedeuticit: punti (1) e (2). a (4) Prezzo azionario attuale Scopo: allocazione di un oggetto di tipo Equity prices al ne di denire il prezzo corrente del sottostante su cui scritto il e contratto opzionale. Input esterno: prezzo attuale dellazione e istante temporale (espresso in termini di year fraction rispetto ad una data di riferimento standard) a cui tale prezzo si riferisce .

4.1. PROGETTO PER UNA LIBRERIA FINANZIARIA IN C++

281

Link ad oggetti precedentemente allocati: lanagraca dellazione di cui al punto (3). Propedeuticit: punto (3). a (5) Date di xing del contratto opzionale Scopo: allocazione di un oggetto di tipo Schedule al ne di denire il set delle date di xing che caratterizzano lopzione (ad es. nel caso di una call plain vanilla, tale set sar costituito unicamente a dalla data di maturity dellopzione). Input esterno: linsieme delle date di xing (espresse in termini di year fraction rispetto ad una data di riferimento standard). Link ad oggetti precedentemente allocati: nessuno. Propedeuticit: nessuna. a (6) Anagraca del contratto opzionale Scopo: allocazione di un oggetto il cui tipo derivato dalla classe e Contract eq option (ad es. Contract eq option plain vanilla, Contract eq option asian, Contract eq option barrier ecc.) al ne di denire lanagraca dellopzione di cui si desidera calcolare il prezzo. Input esterno: le caratteristiche contrattuali dellopzione (ad es. per una plain vanilla: lo strike price e il tipo di opzione call/put). Link ad oggetti precedentemente allocati: il prezzo del sottostante di cui al punto (4) e le date di xing del contratto di cui al punto (5). Propedeuticit: punti (4) e (5). a (7) Processo stocastico Scopo: allocazione di un oggetto di tipo Process eq lognormal al ne di denire il processo stocastico lognormale che governa levoluzione stocastica di unazione. Input esterno: nessuno. Link ad oggetti precedentemente allocati: nessuno. Propedeuticit: nessuna. a (8) Pricer Scopo: allocazione di un oggetto di tipo Option pricer al ne calcolare il prezzo dellopzione. A seconda del tipo di pricer allocato si potr determinare il prezzo dellopzione tramite formula chiusa a

282CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING (se esiste), albero binomiale, metodo alle dierenze nite o simulazione Monte Carlo. Lesecuzione del pricing verr eettuata richiamando nel main la a funzione Option pricer::Get price() che restituir il prezzo. Nel a caso del Monte Carlo sar possibile avere una stima dellerrore a commesso tramite la funzione Option pricer monte carlo::Get error(). Input esterno: parametri specici per il tipo di pricer allocato (ad es. nel caso del Monte Carlo: numero totale di simulazioni e ag per denire luso o meno della variabile antitetica). Link ad oggetti precedentemente allocati: il processo stocastico di cui al punto (7) e lanagraca dellopzione di cui al punto (6). Propedeuticit: punti (6) e (7). a In gura 4.15 riportato un diagramma che mostra gracamente lo e svilupparsi dei vari punti con le loro propedeuticit. a
step sequenziali (propedeuticit)

yield curve (1)

volatility curve (2)

anagrafica equity (3)

Schedule date di fixing (5)

Processo stocastico (7)

prezzo equity (4)

anagrafica opzione (6)

Pricer (calcolo del prezzo dell'opzione) (8)

Figura 4.15: Schema di un ipotetico programma main, con lallocazione dei vari oggetti
e le relative propedeuticit. a

4.2. LINK IN EXCEL DI UNA LIBRERIA C++

283

4.2

Link in Excel di una libreria C++

Un punto essenziale nel lavoro di un ingegnere nanziario collegare le lie brerie scritte in C++ allinterno di un foglio excel (il quale far da front a end). A titolo di esempio, vedremo come costruire un collegamento tra un foglio excel ed una libreria dll in C, al ne di calcolare il prezzo di unopzione asiatica (potremo pensare a questo proposito di utilizzare la formula analitica approssimata ottenuta nel capitolo 2.5). Lattivit pu essere suddivisa nei seguenti passi: a o Denire un foglio Excel. Nel worksheet principale (che chiamiamo main), le righe della prima colonna riportano le seguenti informazioni: B:1 = prezzo attuale del sottostante B:2 = tasso di interesse privo di rischio B:3 = volatilit a B:4 = strike price dellopzione B:5 = tipo opzione (0 = call, 1 = put) B:6 = numero date di rilevazione B:7 = prima data di rilevazione B:8 = seconda data di rilevazione B:n = ultima data di rilevazione, dove n e pari a 7+B:6. Dentro il foglio Excel, accedere allapplicazione VBA, aggiungedo un modulo dal nome module pricing.bas con il codice riportato nelle pagine successive. Tale codice verr richimato tramite un pulsante a aggiunto al foglio excel. Salvare il foglio excel con il relativo codice Denire un progetto per la creazione di una libreria di tipo dll. Nel progetto verr inserito un le dll interface.cpp (vedi codice riportate a sotto). Allinterno del le dll interface.cpp, viene denita una funzione che corrisponde a quella dichiarata e richiamata allinterno del codice Visual Basic di Excel (precisamente nel nostro esempio la funzione Interface Pricing). Questa funzione avr come input i vettori e le variabili a provenienti da Visual Basic (vedi codice riportato sotto). Lunica accortezza a questo punto convertire le strutture dati provenienti da e Visual Basic in strutture dati accessibili da C. Tale compito viene assolto ad es. dalla funzione Get vector(). Per quanto riguarda le

284CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING variabili, non sono necessari accorgimenti particolari, si noti solo che le strutture provenienti da Visual Basic sono sempre costituite da puntatori. Inoltre bene ricordare che lanalogo VBA delle variabili int e di C il Long (su questo punto ritorneremo alla ne del capitolo). e Compilare la libreria dll

4.2. LINK IN EXCEL DI UNA LIBRERIA C++

285

4.2.1

le dll interface.cpp

// -------------------- Begin dll_interface.cpp -------------------#include <windows.h> #include <stdio.h> #include <ole2.h>

#pragma pack(1) BOOL APIENTRY Dll_test( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; }

// EXAMPLES extern "C" int __stdcall Interface_Pricing_asian ( di mercato * vba_S_0, * vba_r, * vba_vol,

// dati // double double double

// anagrafica contratto // double * vba_strike_price, int * vba_contract_type, int * vba_num_fixing_date, LPSAFEARRAY FAR * vba_fixing_date, // Output // double * vba_result ) {

// Dichiarazioni variabili // double S_0; double r ; double vol; double strike_price ; int contract_type ; int num_fixing_date ;

286CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING


double *fixing_date ; // Output // double result ;

S_0 = *vba_S_0 ; r = *vba_r ; vol = *vba_vol ; strike_price = *vba_strike_price ; contract_type = *vba_contract_type ; num_fixing_date = *vba_num_fixing_date ; fixing_date= Convert_vector(vba_fixing_date) ; result = Pricing_asian(S_0, r, vol, strike_price, contract_type, num_fixing_date, fixing_date) ; *vba_result = result ; delete fixing_date ; } double * Convert_vector(LPSAFEARRAY FAR *pointer) { double *pdata ; pdata = (double *)((*pointer)->pvData); double *vector = new double[((*pointer)->rgsabound->cElements)] ; for (int i=0;i<((*pointer)->rgsabound->cElements);i++) { vector[i] = *pdata ; pdata++ ; } return vector ; } // -------------------- End dll_interface.cpp ----------------------

4.2. LINK IN EXCEL DI UNA LIBRERIA C++

287

4.2.2

le module pricing.bas

// -------------------- Begin module_pricing.bas ------------------ CODICE VISUAL BASIC

Attribute VB_Name = "Module_pricing_asian"

Declare Sub Interface_Pricing_asian Lib "lib_excel_c.dll" ( _ vba_S_0 As Double, _ vba_r As Double, _ vba_vol As Double, _ vba_strike_price As Double, _ vba_contract_type As Long, _ vba_num_fixing_date As Long, _ vba_fixing_date() As Double, _ vba_result As Double) Sub Pricing_asian() Dim Dim Dim Dim Dim Dim Dim Dim Dim Dim vba_S_0 As Double vba_r As Double vba_vol As Double vba_strike_price As Double vba_contract_type As Long vba_num_fixing_date As Long vba_fixing_date() As Double vba_result As Double j as Integer wk_main As String

wk_main = "main" Reading data vba_S_0 = Worksheets(wk_main).Cells(1, 2).value vba_r = Worksheets(wk_main).Cells(2, 2).value vba_vol = Worksheets(wk_main).Cells(3, 2).value vba_strike_price = Worksheets(wk_main).Cells(4, 2).value vba_contract_type = Worksheets(wk_main).Cells(5, 2).value vba_num_fixing_date = Worksheets(wk_main).Cells(6, 2).value ReDim vba_fixing_date(vba_num_fixing_date - 1) As Double For j = 0 To vba_num_fixing_date - 1 vba_num_fixing_date(j) = Worksheets(wk_main).Cells(7 + j, 2).value Next j

288CAPITOLO 4. PROGETTO DI UNA LIBRERIA IN C++ PER IL PRICING

Stop Call Interface function Interface_Pricing_asian Lib vba_S_0, _ vba_r, _ vba_vol, _ vba_strike_price, _ vba_contract_type, _ vba_num_fixing_date, _ vba_fixing_date(), _ vba_result Worksheets(wk_main).Cells(1, 4) = vba_result End Sub // -------------------- End module_pricing.bas ---------------------

Si noti che la chiamata alla funzione di C, fatta dal modulo di excel, utilizza come variabili intere delle variabili di tipo Long, questo perch gli e Integer di Visual Basic non corrispondono, come lunghezza, alle variabili int di C. Pi precisamente si dovranno usare a tale scopo le variabili Long di u Visual Basic.

Capitolo 5

Laboratorio ed esercitazioni pratiche

289

290 CAPITOLO 5. LABORATORIO ED ESERCITAZIONI PRATICHE

Laboratorio - introduzione
Nei successivi capitolo verranno presentate alcune esercitazioni, con lobiettivo di testare e collaudare la libreria di pricing illustrata nel capitolo 4.1. In tali esercitazioni lobiettivo consister nelleettuare il pricing di opzioni a esotiche, scrivendo inizialmente il codice necessario e successivamente sviluppando lesercitazione lungo le linee guida indicate.

5.1. ESERCIZIO 1

291

5.1
5.1.1

Esercizio 1
Introduzione

Il presente capitolo dedicato allesposizione e discussione di una sessione e di laboratorio / esercitazione relativa al metodo Monte Carlo presentato nel capitolo 3.1. Nel primo paragrafo verr presentato il contratto di una opzione esotica di a cui ci proponiamo di calcolare il prezzo tramite una simulazione Monte Carlo. Nel par. 5.1.3 vengono presentate una serie di considerazioni. Inne nel par. 5.1.4 vengono esposti i punti su cui focalizzare lesercitazione. Lobiettivo della presente esercitazione non solo quello di svolgere un seme plice esercizio di programmazione, implementando un Monte Carlo, ma di mostrare piuttosto come lintegrazione di un approccio numerico con considerazioni qualitative e analitiche in grado di portare a migliori risultati. e

5.1.2

Denizione del problema

Si consideri un contratto opzionale con le seguenti caratteristiche: Opzione con esercizio europeo (ovvero il diritto pu essere fatto valere o unicamente alla data di scadenza); Sia T la data di maturit e t = 0 la data attuale. Il sottostante a dellopzione unazione, il cui prezzo al tempo t sia indicato con S(t); e Supponiamo che il prezzo S dellazione segua un processo log-normale, con costante e volatilit costante (lusuale modello utilizzato in a nanza); Il pay-o pagato a scadenza sia: M ax [0, S(T ) (E + n K)] ; (5.1)

dove: E e K sono due costanti positive e n rappresenta la percentuale di volte in cui, nellintervallo (0, T ), il ritorno giornaliero del sottostante, S(t + 1)/S(t) 1, sia stato inferiore alla costante L. In altri termini il pay-o quello di una normale call option in cui per e o lo strike price non costante ma tanto pi grande quanto maggiore e e u e la percentuale di volte in cui il sottostante ha avuto una performance giornaliera negativa superiore in valore assoluto a L.

5.1.3

Discussione qualitativa

Dal punto di vista della nomenclatura, si tratta di unopzione call con strike variabile ed esercizio di tipo europeo. E ovviamente unopzione path dependent, in quanto il pay-o dipende non solo dal valore del sottostante alla

292 CAPITOLO 5. LABORATORIO ED ESERCITAZIONI PRATICHE maturity date, ma anche dalla sua storia precedente. E interessante osservare che nel limite in cui L (o K 0) il pay-o si riduce a quello di una semplice opzione call plain vanilla. In tal caso il prezzo dellopzione in ogni istante dato dalla formula di BS ed in base al e lemma di Ito, il prezzo stesso dellopzione segue un processo stocastico di Ito. Ci signica che per il mercato lunica cosa che conti nellevoluzione di o questo prezzo il valore che esso assume oggi (processo markoviano). e Pi interessante quanto accade per L (o K) nito. In tale situazione u e lopzione diventa path dependent, in altri termini la storia del sottostante importante per prezzare correttamente il contratto. E ovvio che a parte e situazioni limite, non possibile ottenere una formula chiusa per il pricing di e questo contratto. Bisogna quindi ricorrere ad una simulazione Monte Carlo, che lobiettivo della presente esercitazione. E comunque possibile denire e delle disuguaglianze a cui il prezzo dellopzione deve sempre ubbidire. Infatti abbastanza ovvio che il toccare la barriera negativa L nei ritorni, e ha leetti di alzare ogni volta lo strike price di una quantit pari a K. Se a indichiamo con: C un generico cammino da (0, T ) (soddisfacente il vincolo S(t = 0) = S0 ); nC la percentuale di volte nellintervallo (0, T ) in cui lazione, lungo il cammino C, ha avuto un ritorno giornaliero minore di L; Pay-ovanilla (C, E) il pay-o su C di una opzione call europea con strike E; Pay-o(C) il pay-o dellopzione in esame; allora: Pay-o(C) = Pay-ovanilla (C, E + nC K) ; e quindi: Pay-ovanilla (C, E + K) Pay-o(C) Pay-ovanilla (C, E) ; (5.3) (5.2)

ne consegue che il prezzo P dellopzione soddisfa la seguente disuguaglianza: Pcall vanilla (E + K) P Pcall vanilla (E) ; (5.4)

Ritorniamo ora alla questione del processo stocastico seguito dal prezzo dellopzione. Dimostreremo la seguente aermazione: Proposizione Il processo stocastico seguito dal prezzo dellopzione denita sopra, non markoviano. e Dimostriamo prima il seguente lemma: Lemma: Supponiamo di conoscere levoluzione del prezzo dellopzione, P (t),

5.1. ESERCIZIO 1

293

per ogni t (0, T ). Indichiamo con S(t) il prezzo del sottostante e con n(t) il rapporto tra il numero di volte in cui i ritorni giornalieri del sottostante siano stati inferiori a L nellintervallo (0, t) ed il numero di giorni in (0, T ). Allora a partire dalla conoscenza di P (t) possibile determinare le funzioni e n(t) e S(t). Dim. Dalle caratteristiche del contratto, immediato dedurre che il prezzo e dellopzione, in ogni istante t, funzione unicamente delle variabili: t, S(t) e e n(t), ovvero P (t) = P (t, S, n). Dimostriamo il lemma procedendo per induzione. Per t = 0, n(0) = 0 in base alla denizione data. Inoltre dallequazione P (0, S(0), 0) = P (0) possiamo ricavare, invertendola, S(0). Supponiamo ora di conoscere n e S al tempo t1 e proponiamoci di ricavare n(t) e S(t). Al tempo t, essendo noto il prezzo dellopzione, P (t), possiamo scrivere lequazione: P (t, S(t), n(t)) = P (t) (5.5) dove: n(t) = n(t 1) + 1/D se [S(t)/S(t 1) 1] < L n(t 1) diversamente

e D rappresenta il numero di giorni contenuti nellintervallo (0, T ). Allora poich n(t1) e S(t1) sono noti, n(t) una funzione della sola varie e abile S(t). Pertanto leq. (5.5) si riduce ad unequazione nella sola incognita S(t). E altres facile dimostrare che tale funzione monotona decrescente. e Lequazione (5.5) pu allora essere invertita per trovare S(t) (e perci anche o o n(t)). Rimane quindi dimostrata la tesi. Passiamo ora alla dimostrazione della proposizione principale. Dim. Supponiamo di considerare un tempo t (0, T ) e sia P (t) il prezzo dellopzione. Se ora consideriamo listante temporale t + dt, il prezzo dellopzione varier unicamente in base alle variazioni di prezzo del sottostante. a Quindi se desideriamo poter determinare la distribuzione probabilistica di P allistante t + dt, dobbiamo necessariamente inferire il prezzo del sottostante S al tempo t per poi poter costruire la distribuzione probabilistica di S al tempo t + dt (a tal riguardo ricordiamo che log(S) segue un processo di Wiener generalizzato). Una volta nota tale distribuzione quasi immediato e ricavare dalla funzione P (t, S, n) la distribuzione statistica del prezzo dellopzione allistante t + dt. Ovviamente per poter dedurre il valore di S(t) dal prezzo P (t) dobbiamo necessariamente conoscere n(t) e questo possie bile solo conoscendo la serie storica dei prezzi di P (vedi lemma precedente). Ecco quindi che la distribuzione statistica di P (t + dt) viene a dipendere non solo da P (t) ma anche da tutti i prezzi precedenti. Rimane quindi dimostrato che:

294 CAPITOLO 5. LABORATORIO ED ESERCITAZIONI PRATICHE il prezzo dellopzione in ogni istante dipende dalla storia del sottostante; se riguardiamo il prezzo dellopzione, come una variabile stocastica, questa non solo non segue un processo di Ito, ma addirittura non e markoviana. In particolare levoluzione stocastica futura del prezzo dellopzione al tempo t dipende dalla serie di tutti i prezzi nellintervallo (0, t). Esistono quindi sul mercato oggetti nanziari, il cui prezzo non segue un processo markoviano. Ugualmente, per tale opzione vale il principio di non arbitraggio, nel senso che non possibile realizzare un guadagno superiore al tasso di e mercato risk free, assumendo una posizione qualsiasi su questo strumento. Ci dimostra che lipotesi di non markovianit non viola, o a necessariamente, il principio di non arbitraggio.

5.1.4

Obiettivi dellesercitazione

Si richiede di: (A) Sviluppare un programma in C che implementi una simulazione Monte Carlo per il pricing dellopzione esotica descritta nel paragrafo 5.1.2. Tale programma deve prendere come input un le con la seguente struttura: # Numero di simulazioni Monte Carlo N = # Valore dellazione allistante iniziale S_0 = # Valore del tasso risk free r = # Valore della volatilita, su base annua, del sottostante sigma = # Barriera per la performance giornaliera L = # Strike price dellopzione nel caso in cui la # barriera non venga mai toccata E =

5.1. ESERCIZIO 1 # Incremento dello strike price nel caso in cui la # barriera venga toccata il 100% delle volte K = # Intervallo di tempo espresso in numero di giorni T =

295

le linee che iniziano con il carattere # devono essere considerate di commento. Come suggerimento sui valori numerici da utilizzare per i primi run, si considerino i seguenti: N = 100.000 , S0 = 100 , r = 4% , = 30% , L = 4% , E = 100 , K = 10 , T = 100 business days . (5.6) (B) Implementare il metodo Monte Carlo descritto nel paragrafo 3.1.4, in un primo momento attraverso la discretizzazione del processo stocastico denita dallequazione (3.14) e successivamente utilizzando la versione migliorata (3.18). i) Si verichi quindi che per K = 0 o L il programma riproduca correttamente il pricing di una opzione call europea con strike E; ii) partendo dal punto precedente, si discutano nei due casi (discretizzazione (3.14) e versione migliorata (3.18)), le dierenze nelle stime del prezzo dellopzione (eventualmente anche cambiando i parametri T e N ). Per tutti i successivi punti si faccia sempre riferimento alla formula (3.18). (C) Al ne di ridurre gli errori statistici, si utilizzino: la tecnica della variabile antitetica (vedi par. 3.1.4.e) e la tecnica della variabile di controllo (vedi par. 3.1.4.e). Relativamente alla scelta della variabile di controllo, possibile eettuare, nel presente caso, una scelta migliore e che non sia quella di una call plain vanilla con strike price pari ad E? Si richiede di riportare nelloutput del programma la stima del prezzo dellopzione: i) senza i miglioramenti ottenuti con lutilizzo delle due tecniche; ii) la stima con lutilizzo della sola variabile antitetica; iii)

296 CAPITOLO 5. LABORATORIO ED ESERCITAZIONI PRATICHE la stima con lutilizzo della sola variabile di controllo; vi) la stima ottenuta con entrambe le tecniche. Calcolare e discutere la riduzione degli errori statistici (ovvero le deviazioni standard sui pay-o) ottenuta con luso delle due tecniche. (D) Vericare che il pricing ottenuto soddis la disuguaglianza (5.4). (E) Calcolare il numero medio di volte in cui il ritorno giornaliero del sottostante tocca il limite L; determinare anche la deviazione standard di questa stima. Discutere come tali stime si comportino al crescere di T . (F) Stimare il valore medio dello strike price E + n K e determinarne la deviazione standard. Discutere come tali grandezze si comportino al crescere di T . (G) Discutere qualitativamente quale sia leetto sul pricing, considerando valori di T (maturit dellopzione) molto alti. In particolare si osservia no i dati ottenuti ai punti (E) e (F), con valori grandi di T , e li si utilizzi per inferire una valutazione analitica approssimata (valida nel limite T ) del prezzo dellopzione. Vericare poi numericamente la validit di tale approssimazione. a I risulti ottenuti devono essere presentati sotto forma di breve discussione scritta, con lausilio eventuale di graci e tabelle.

5.2. ESERCIZIO 2

297

5.2
5.2.1

Esercizio 2
Introduzione

Il presente capitolo dedicato allesposizione e discussione di una sessione e di laboratorio / esercitazione relativa al metodo Monte Carlo presentato nel capitolo 3.1. Nel primo paragrafo verr presentato il contratto di una opzione esotica di a cui ci proponiamo di calcolare il prezzo tramite una simulazione Monte Carlo. Nel par. 5.2.3 vengono presentate una serie di considerazioni. Inne nel par. 5.2.4 vengono esposti i punti su cui focalizzare lesercitazione. Lobiettivo della presente esercitazione non solo quello di svolgere un seme plice esercizio di programmazione, implementando una simulazione Monte Carlo, ma di mostrare piuttosto come lintegrazione di un approccio numerico con considerazioni qualitative e analitiche in grado di portare a risultati e migliori.

5.2.2

Denizione del problema

Si consideri un contratto opzionale con le seguenti caratteristiche: Opzione con esercizio europeo (ovvero il diritto pu essere fatto valere o unicamente alla data di scadenza); Sia T la data di maturit e t = 0 la data attuale. Il sottostante a dellopzione sia unazione, il cui prezzo al tempo t venga indicato con S(t); Supponiamo che il prezzo S(t) dellazione segua un processo log-normale, con costante e volatilit costante (ovvero lusuale modello browna iano utilizzato in nanza); Il pay-o pagato a scadenza sia: Pay-oRev. cliquet 1 = Max L, H + m
m

Min
i=1

Si Si1 ,0 Si1

, (5.7)

dove m e il numero di intervalli (periodi) considerati; Si il prezzo e del sottostante alla ne del periodo i-esimo (ti1 , ti ); S0 e lo spot price (ovvero il prezzo ad oggi dellazione); L il oor globale (usuale mente posto a zero) e corrisponde al minimo ammontare che linvestitore ricever alla data di scadenza; H il massimo coupon pagabile a e dallopzione. Si tratta quindi di unopzione il cui pay-o risulta limitato allinterno della banda: [L, H]. Lopzione denita dal pay-o riportato sopra, prende il nome di reverse cliquet.

298 CAPITOLO 5. LABORATORIO ED ESERCITAZIONI PRATICHE

5.2.3

Alcune considerazioni

Si1 Si osservi che allinterno dellequazione (5.7), il termine SiSi1 rappresenta la performance dellazione relativamente al periodo i-esimo. Perci la o sommatoria presente nellequazione che denisce il pay-o, va interpretata come la media delle performance negative dellazione. Queste ultime, vanno calcolate su un intervallo di lunghezza T /m. Il termine reverse che gura nel nome dellopzione, sta ad indicare che il termine costante H viene decrementato di una quantit legata allandamena to dellazione (ovvero la media delle performance negative). Le opzioni reverse cliquet, sono un tipico esempio di opzioni path depen dent. E inutile sottolineare che non esistono formule chiuse esatte per la valutazione di questo tipo di opzione.

5.2.4

Obiettivi dellesercitazione

Si richiede di: (A) Sviluppare un programma ad oggetti in C++ che implementi una simulazione Monte Carlo per il pricing dellopzione esotica descritta nel paragrafo 5.2.2. Tale programma deve prendere come input i seguenti dati: Numero di simulazioni Monte Carlo N = 10.000 - 100.000 Valore dellazione allistante iniziale S_0 = 100 Valore del tasso risk free r = 9 % Valore della volatilita, su base annua, del sottostante sigma = 30 % Minimo garantito dallopzione L = 0 % Massimo coupon pagabile dallopzione H = 4 % Intervallo di tempo su cui calcolare le performance azionarie: T/m = 1/12 anno Numero di intervalli

5.2. ESERCIZIO 2 m = 1, 3, 6, 9, 12, 15, 18, 60, 120

299

(B) Implementare il metodo Monte Carlo descritto nel paragrafo 3.1.4 utilizzando la versione migliorata (3.18). (C) Si ottenga una formula chiusa per il prezzo dellopzione nel caso in cui m = 1. Vericare poi numericamente la validit di tale derivazione. a (D) Mantenendo ssa la lunghezza dellintervallo su cui si calcolano le performance dellazione, ovvero T /m, discutere il caso in cui il numero di intervalli m diventi molto alto (al limite innito). In particolare, si ricavi una formula asintotica per il prezzo dellopzione, valida nel limite m . Vericare poi numericamente, con lausilio delle simulazioni Monte Carlo, la validit di tale approssimazione. a (E) In base ai risultati di cui al punto (C), si esaminino delle possibili scelte per la variabile di controllo, al ne di migliorare la stima delle simulazioni Monte Carlo. (F) Allo scopo di ridurre gli errori statistici, si utilizzino: la tecnica della variabile antitetica 1 e la tecnica della variabile di controllo 2 sulla base delle indicazioni emerse nel punto precedente. Si richiede di valutare il prezzo dellopzione: i) senza i miglioramenti ottenuti con lutilizzo delle due tecniche; ii) la stima con lutilizzo della sola variabile antitetica; iii) la stima con lutilizzo della sola variabile di controllo; vi) la stima ottenuta con entrambe le tecniche. Calcolare e discutere la riduzione degli errori statistici (ovvero le deviazioni standard sui pay-o) ottenuta con luso delle due tecniche. I risulti ottenuti devono essere presentati sotto forma di breve discussione scritta, con lausilio eventuale di graci 3 e tabelle.

Vedi par. 3.1.4.e Vedi par. 3.1.4.e 3 Ad esempio mostrando landamento del prezzo dellopzione al variare di m, e la sua convergenza ai due limiti estremi m = 1 e m = , ricavati ai punti (C) e (D).
2

300 CAPITOLO 5. LABORATORIO ED ESERCITAZIONI PRATICHE

5.3
5.3.1

Esercizio 3
Introduzione

Il presente capitolo dedicato allesposizione e discussione di una sessione e di laboratorio / esercitazione relativa al metodo Monte Carlo presentato nel capitolo 3.1. Nel primo paragrafo verr presentato il contratto di una opzione esotica di a cui ci proponiamo di calcolare il prezzo tramite una simulazione Monte Carlo. Nel par. 5.3.3 vengono presentate una serie di considerazioni. Inne nel par. 5.3.4 vengono esposti i punti su cui focalizzare lesercitazione. Lobiettivo della presente esercitazione non solo quello di svolgere un seme plice esercizio di programmazione, implementando una simulazione Monte Carlo, ma di mostrare piuttosto come lintegrazione di un approccio numerico con considerazioni qualitative e analitiche in grado di portare a risultati e migliori.

5.3.2

Denizione del problema

Si consideri un contratto opzionale con le seguenti caratteristiche: Opzione con esercizio europeo (ovvero il diritto pu essere fatto valere o unicamente alla data di scadenza); Sia T la data di maturit e t = 0 la data attuale. Il sottostante a dellopzione sia unazione, il cui prezzo al tempo t venga indicato con S(t); Supponiamo che il prezzo S(t) dellazione segua un processo log-normale, con costante e volatilit costante (ovvero lusuale modello browna iano utilizzato in nanza); Il pay-o pagato a scadenza sia: Pay-oAverage perf. = Max [0, X E] , (5.8)

dove X la somma delle performance del sottostante sugli m intervalli e equispaziati di ampiezza T /m, in cui suddiviso lintevallo temporale e (0, T ), da oggi alla data di maturit dellopzione. Ovvero: a
m

X=
i=1

S(ti ) S(ti1 ) , S(ti1 )

(5.9)

dove ti = i T /m per i = 0, ......, m.

5.3. ESERCIZIO 3

301

5.3.3

Alcune considerazioni

Il pay-o dellopzione denita sopra identico al classico pay-o di una e call con limportante dierenza che la variabile X risulta essere data dalla somma delle performance del sottostante sugli m intervalli in cui suddiviso e lintervallo (0, T ). Si noti anche che lo strike price denito in percentuale e essendo X un numero puro. Lopzione chiaramente path dependent, in quanto X denito in base al e e percorso seguito dal sottostante durante la vita dellopzione (in particolare dipende dai valori assunti dal sottostante in corrispondenza delle date di xing {ti }.

5.3.4

Obiettivi dellesercitazione

Si richiede di: (A) Sviluppare un programma ad oggetti in C++ che implementi una simulazione Monte Carlo per il pricing dellopzione esotica descritta nel paragrafo 5.3.2. Tale programma deve prendere come input i seguenti dati: Numero di simulazioni Monte Carlo N = 10.000 N = 20.000 N = 40.000 Valore dellazione allistante iniziale S_0 = 100 Valore dello strike price (in %) E = 4 % Valore del tasso risk free r = 4 % Valore della volatilita, su base annua, del sottostante sigma = 30 % Durata dellopzione T pari a: T = 0.5 anni T = 1.0 anni T = 1.5 anni T = 2.0 anni T = 2.5 anni

302 CAPITOLO 5. LABORATORIO ED ESERCITAZIONI PRATICHE T T T T = = = = 3.0 anni 3.5 anni 4.0 anni 10.0 anni

Numero di intervalli m pari a: m = 2 m = 5 m = 10 m = 20 m = 50 m = 100 m = 200

In particolare si implementi il metodo Monte Carlo descritto nel paragrafo 3.1.4 utilizzando la versione migliorata (3.18). (B) Produrre un insieme di graci che mostrino landamento del prezzo dellopzione per dierenti valori di T (in particolare si faccia riferimento ai valori di T specicati nel punto A) al variare di m (ovvero in ascissa il graco riporter il tempo a maturit T , in ordinata il valore a a dellopzione e ciascun graco si riferir ad un dierente valore di m; i a valori di m per cui produrre i graci sono specicati nel punto A). (C) Produrre un insieme analogo di graci (come nel punto B) che mostrino landamento dellerrore nella stima del prezzo dellopzione per dierenti valori di T e m (ssato N = 10.000). (D) Discutere il comportamento dei graci e la loro interpretazione nanziaria quando il numero di intervalli m diventa molto grande (in linea di principio innito). Fornire uninterpretazione teorica dei risultati ottenuti per m molto grande, in particolare: i) possibile derivare una formula analitica asintotica per il calcolo e del prezzo dellopzione nel limite m ? ii) si confrontino i risultati ottenuti dalla formula asintotica con le stime Monte Carlo. (E) Allo scopo di ridurre gli errori statistici, si utilizzi: la tecnica della variabile antitetica 4 . In particolare si richiede di: i) valutare il prezzo dellopzione ed il relativo errore utilizzando la tecnica della variabile antitetica; ii) calcolare e discutere la riduzione degli errori statistici (ovvero le deviazioni standard sui pay-o) ottenuta tramite luso della variabile antitetica.
4

Vedi par. 3.1.4.e

5.3. ESERCIZIO 3

303

(F) i) Ricavare una formula analitica esatta per lopzione nel caso in cui m = 1. ii) Confrontare i risultati ottenuti dalla formula esatta con le stime Monte Carlo per m = 1. (G) Rispetto al metodo standard della variabile di controllo 5 , in cui: xMC new = xMC + y yMC , (5.10)

si sviluppi una variante della formula sopra riportata al ne di sfruttare pienamente linformazione contenuta nella variabile di controllo. (H) Sfruttando il risultato ottenuto nel punto (F), allo scopo di ridurre gli errori statistici, si ricorra alla tecnica della variabile di controllo, nella sua versione migliorata, derivata nel punto precedente, utilizzando come variabile il prezzo della seguente opzione: Pay-oAverage perf. m=1 = Max 0, S(T ) S(t0 ) E S(t0 ) , (5.11)

In particolare si richiede di: i) di valutare il prezzo dellopzione ed il relativo errore utilizzando la variabile di controllo introdotta sopra. ii) calcolare e discutere la riduzione degli errori statistici (ovvero le deviazioni standard sui pay-o) ottenuta tramite luso della variabile di controllo al variare di m. I risulti ottenuti devono essere presentati sotto forma di breve discussione scritta, con lausilio eventuale di graci e tabelle.

Vedi par. 3.1.4.e

304 CAPITOLO 5. LABORATORIO ED ESERCITAZIONI PRATICHE

5.4
5.4.1

Esercizio 4
Introduzione

Il presente capitolo dedicato allesposizione e discussione di una sessione e di laboratorio / esercitazione relativa al metodo Monte Carlo presentato nel capitolo 3.1. Nel primo paragrafo verr presentato il contratto di una opzione esotica di a cui ci proponiamo di calcolare il prezzo tramite una simulazione Monte Carlo. Nel par. 5.4.3 vengono presentate una serie di considerazioni. Inne nel par. 5.4.4 vengono esposti i punti su cui focalizzare lesercitazione. Lobiettivo della presente esercitazione non solo quello di svolgere un seme plice esercizio di programmazione, implementando una simulazione Monte Carlo, ma di mostrare piuttosto come lintegrazione di un approccio numerico con considerazioni qualitative e analitiche in grado di portare ad una e migliore comprensione del problema e da un punto di vista pi operativo a u stime migliori.

5.4.2

Denizione dellopzione Counter Positive Performance

Si consideri un contratto opzionale con le seguenti caratteristiche: Opzione con esercizio europeo (ovvero il diritto pu essere fatto valere o unicamente alla data di scadenza); Sia T la data di maturit e t = 0 la data attuale. Il sottostante a dellopzione sia unazione, il cui prezzo al tempo t venga indicato con S(t); Supponiamo che il prezzo S(t) dellazione segua un processo log-normale, con costante e volatilit costante (ovvero il modello browniano base a utilizzato in nanza); Il pay-o pagato a scadenza sia: Pay-ocounter perf. = K Max n p0 , 0 , m (5.12)

dove K una costante espressa in unit di valuta (ad es. euro), m+1 e a e il numero delle date di xing, p0 un numero compreso nellintervallo e [0, 1] e pu essere interpretato come una percentuale e n il numero di o e volte in cui lungo il cammino si verica che S(ti ) sia maggiore o uguale a S(ti1 ) con i = 1, .....m. Si suppone che gli intervalli (ti1 , ti ) siano tutti equispaziati e di ampiezza T /m, dove T la durata complessiva e dellopzione, ovvero: ti = i T /m per i = 0, ......, m.

5.4. ESERCIZIO 4

305

5.4.3

Alcune considerazioni

Lopzione descritta sopra, che potremmo chiamare Counter positive performance, chiaramente di tipo path dependent in quanto il pay-o corrispose to alla data di scadenza denito in base al percorso seguito dal sottostante e durante la vita dellopzione (in particolare dipende dai valori assunti dal sottostante in corrispondenza delle date di xing {ti }. Il rapporto n/m che gura nella formula di pay-o rappresenta la percentuale di volte in cui lazione ha avuto una performance positiva lungo il cammino. Le performance sono calcolate relativamente ai vari intervalli (ti1 , ti ). La costante p0 pu essere interpretata come una sorta di strike price in riferimento alla o percentuale di cui sopra; ovvero: se la percentuale di performance positive, p = n/m, lungo il cammino maggiore di p0 viene pagato un premio pari e alla dierenza tra p e p0 , diversamente non viene pagato nulla. E naturale perci considerare valori di p0 compresi nellintervallo [0, 1], interpretando o questa grandezza come una percentuale.

5.4.4

Obiettivi dellesercitazione

Si richiede di:

(A) Sviluppare una libreria nanziaria in base alla traccia fornita nel capitolo 4.1, limitatamente alla parte di option pricing su singoli sottostanti azionari e per il solo metodo Monte Carlo. In particolare si implementi il metodo Monte Carlo descritto nel paragrafo 3.1.4, utilizzando la versione migliorata (3.18). (B) Introdurre nella libreria una classe per descrivere lanagraca dellopzione descritta nel paragrafo 5.4.2. Sviluppare quindi un main (ovvero un programma) in grado di calcolare una stima del prezzo dellopzione, con il relativo errore 6 . (C) Testare il programma ottenuto utilizzando come dati di input i seguenti valori: Numero di simulazioni Monte Carlo N = 10.000 N = 20.000 N = 40.000 Valore dellazione allistante iniziale S_0 = 100
Nota bene: le stime dellerrore nel prezzo dellopzione vanno espresse in forma percentuale sul prezzo stesso, ovvero: = errore assoluto %. stima prezzo
6

306 CAPITOLO 5. LABORATORIO ED ESERCITAZIONI PRATICHE

Valore della costante K (in euro) K = 1 euro Valore della costante p0 (in euro) p0 = 0.5 Valore del tasso risk free r = 4 % Valore della volatilita, su base annua, del sottostante sigma = 30 % Durata dellopzione T pari a: T = 1.0 anni Numero di intervalli m pari a: m = 1 m = 5 m = 10 m = 20 m = 50 m = 100 m = 200

(D) Allo scopo di ridurre gli errori statistici, si utilizzi: la tecnica della variabile antitetica 7 . In particolare si richiede di: i) valutare il prezzo dellopzione ed il relativo errore utilizzando la tecnica della variabile antitetica; ii) calcolare e discutere la riduzione degli errori statistici (ovvero le deviazioni standard sui pay-o) ottenuta tramite luso della variabile antitetica. (E) Produrre un graco che mostri landamento del prezzo dellopzione per dierenti valori di m (in particolare si faccia riferimento ai valori di m specicati nel punto (C). Il graco riporter in ascissa il numero di a date di xing, m + 1, e in ordinata il valore dellopzione. (F) Produrre un insieme analogo di graci (come nel punto (E)) che mostrino landamento dellerrore nella stima del prezzo dellopzione per differenti valori di m (ssato ad es. N = 10.000).
7

Vedi par. 3.1.4.e

5.4. ESERCIZIO 4

307

(G) Discutere il comportamento dei graci e la loro interpretazione nanziaria quando il numero di intervalli m diventa molto grande (in linea di principio innito). Fornire uninterpretazione teorica dei risultati ottenuti per m molto grande, in particolare: i) possibile derivare una formula analitica asintotica per il calcolo e del prezzo dellopzione nel limite m ? ii) si confrontino i risultati ottenuti dalla formula asintotica con le stime Monte Carlo. (H) i) Ricavare una formula analitica esatta per lopzione nel caso in cui m = 1. ii) Confrontare i risultati ottenuti dalla formula esatta con le stime Monte Carlo per m = 1. (I) Ottenere una formula semi-analitica/semi-numerica per il calcolo del prezzo dellopzione per un valore generico di m. Si confrontino quindi i risultati ottenuti con le stime Monte Carlo. (L) Rispetto al metodo standard della variabile di controllo 8 , in cui: xMC new = xMC + y yMC , (5.13)

si sviluppi una variante della formula sopra riportata al ne di sfruttare pienamente linformazione contenuta nella variabile di controllo. (M) Sfruttando il risultato ottenuto nel punto (H), allo scopo di ridurre gli errori statistici, si ricorra alla tecnica della variabile di controllo, nella sua versione migliorata, derivata nel punto precedente, utilizzando come variabile il prezzo dellopzione Counter Positive Performance con m = 1. In particolare si richiede di: i) di valutare il prezzo dellopzione ed il relativo errore utilizzando la variabile di controllo introdotta sopra. ii) calcolare e discutere la riduzione degli errori statistici (ovvero le deviazioni standard sui pay-o) ottenuta tramite luso della variabile di controllo al variare di m. I risulti ottenuti devono essere presentati sotto forma di breve discussione scritta, con lausilio eventuale di graci e tabelle. Queste ultime devono avere come nalit quella di dare un supporto allinterpretazione ed a alla discussione dei risultati, in generale quindi buona norma evitare di e riportare numerose tabelle e graci se questi non servono alleconomia generale della relazione. Inoltre tutti i graci e le tabelle vanno commentati ed integrati nella relazione.

Vedi par. 3.1.4.e

308 CAPITOLO 5. LABORATORIO ED ESERCITAZIONI PRATICHE

5.5
5.5.1

Esercizio 5
Introduzione

Il presente capitolo dedicato allesposizione e discussione di una sessione e di laboratorio / esercitazione relativa al metodo Monte Carlo presentato nel capitolo 3.1. Nel primo paragrafo verr presentato il contratto di una opzione esotica di a cui ci proponiamo di calcolare il prezzo tramite una simulazione Monte Carlo. Nel par. 5.5.3 vengono presentate una serie di considerazioni. Inne nel par. 5.5.4 vengono esposti i punti su cui focalizzare lesercitazione. Lobiettivo della presente esercitazione non solo quello di svolgere un seme plice esercizio di programmazione, implementando una simulazione Monte Carlo, ma di mostrare piuttosto come lintegrazione di un approccio numerico con considerazioni qualitative e analitiche in grado di portare a risultati e migliori.

5.5.2

Denizione del problema

Si consideri un contratto opzionale con le seguenti caratteristiche: Opzione con esercizio europeo (ovvero il diritto pu essere fatto valere o unicamente alla data di scadenza); Sia T la data di maturit e t = 0 la data attuale. Il sottostante a dellopzione sia unazione, il cui prezzo al tempo t venga indicato con S(t); Supponiamo che il prezzo S(t) dellazione segua un processo log-normale, con costante e volatilit costante (ovvero lusuale modello browna iano utilizzato in nanza); Il pay-o pagato a scadenza sia: Pay-oDierence with corridor = Max [X, 0] , (5.14)

dove X la somma delle variabili Di denite sotto e legate allane damento del sottostante sugli m intervalli equispaziati di ampiezza t = T /m, in cui suddiviso lintevallo temporale (0, T ), da oggi alla e data di maturit dellopzione. Ovvero: a
m

X=
i=1

Di ,

(5.15) (5.16)

Di = Min [Max [S(ti ) S(ti1 ), li ] , ui ] ,

5.5. ESERCIZIO 5 dove: li = S(ti1 )


er t 1 , k

309

(5.17) (5.18)

ui = S(ti1 ) er t 1 k ,

e ti = i T /m per i = 0, ......, m. Le grandezze li e ui rappresentano rispettivamente il valore minimo e massimo assunto dalla variabile Di . Di legato alla dierenza nel e prezzo del sottostante calcolato sullintervallo i-esimo, limitato inferiormente e superiormente da li e ui . r un parametro specicato nel contratto derivato. Nel seguito, per e semplicit, si supporr sempre che r sia uguale al tasso risk free e a a quindi implicitamente che la curva dei tassi risk free sia piatta, ovvero che il tasso risk free non dipenda dalla scadenza considerata. k un parametro in grado di restringere o allargare il gap (li , ui ) e e soddisfa sempre il seguente vincolo: k >= 1 . (5.19)

Si noti che per k = 1 il gap si stringe completamente e Di vincolato e ad assumere il valore: er t 1 ; viceversa per k = , Di coincide con la variazione nel prezzo del sottostante sullintervallo i-esimo.

5.5.3

Alcune considerazioni

Il pay-o dellopzione denita sopra identico al classico pay-o di una e call con limportante dierenza che la variabile X risulta pi complessa di u quanto non avvenga in unordinaria plain vanilla option. Inoltre per m > 1, il contratto diventa di tipo path-dependent, in quanto X denito in base al e percorso seguito dal sottostante durante la vita dellopzione (in particolare dipende dai valori assunti dal sottostante in corrispondenza delle date di xing {ti }). Si noti come nel caso limite k = + e m = 1, il pay-o divenga: Pay-odierence with corridor = Max [S(t1 ) S(t0 ), 0] , (5.20)

ovvero sia quello di una call ordinaria con strike price uguale al valore di partenza dellazione allistante iniziale.

5.5.4

Obiettivi dellesercitazione

Alla ne di ogni punto viene riportato quanto segue: Propedeuticit. a

310 CAPITOLO 5. LABORATORIO ED ESERCITAZIONI PRATICHE Grado di dicolt: (Basso, Medio, Alto, Molto Alto) a Tempo di sviluppo atteso: (Breve, Medio, Lungo) Richiesta ai ni dellesame: (Obbligatorio, Facoltativo) Si richiede di sviluppare e risolvere i seguenti punti: (A) Pricing Monte Carlo (A-1) Sviluppare un programma ad oggetti in C++ che implementi una simulazione Monte Carlo per il pricing dellopzione esotica descritta nel paragrafo 5.5.2. Tale programma deve prendere come input i seguenti dati: Numero N = N = N = di simulazioni Monte Carlo 10.000 20.000 40.000

(in generale i valori riportati sopra sono solo indicativi. E lasciata allo studente la scelta di quali valori assumere per tale grandezza). Valore dellazione allistante iniziale S_0 = 100 Valore k = k = k = k = k = k = k = k = k = k = k = k = dello strike price (in %) 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 10

(in generale i valori riportati sopra sono solo indicativi. E lasciata allo studente la scelta di quali valori assumere per tale grandezza). Valore del tasso risk free r = 2 %

5.5. ESERCIZIO 5

311

Valore della volatilita, su base annua, del sottostante sigma = 30 % Durata T = T = T = T = T = T = T = T = T = dellopzione T pari a: 0.5 anni 1.0 anni 1.5 anni 2.0 anni 2.5 anni 3.0 anni 3.5 anni 4.0 anni 10.0 anni

(in generale i valori riportati sopra sono solo indicativi. E lasciata allo studente la scelta di quali valori assumere per tale grandezza).

Numero m = m = m = m = m = m = m =

di intervalli m pari a: 2 5 10 20 50 100 200

(in generale i valori riportati sopra sono solo indicativi. E lasciata allo studente la scelta di quali valori assumere per tale grandezza).

In particolare si implementi il metodo Monte Carlo descritto nel paragrafo 3.1.4 utilizzando: a) il metodo approssimato di Eulero e b) la formula integrale esatta (3.18). Caratteristiche del punto: Propedeuticit: nessuna. a Grado di dicolt: Medio a Tempo di sviluppo atteso: Lungo Ai ni dellesame: obbligatorio

(A-2) Produrre un insieme di graci che mostrino landamento del prezzo dellopzione per dierenti valori di T e k (in particolare si faccia

312 CAPITOLO 5. LABORATORIO ED ESERCITAZIONI PRATICHE riferimento ai valori di T e k specicati nel punto A-1) al variare di m (ovvero in ascissa il graco riporter il tempo a maturit T o a a k, in ordinata il valore dellopzione e ciascun graco si riferir ad a un dierente valore di m; i valori di m per cui produrre i graci sono specicati nel punto A). Caratteristiche del punto: Propedeuticit: (A-1). a Grado di dicolt: Medio a Tempo di sviluppo atteso: Lungo Ai ni dellesame: obbligatorio

(A-3) Produrre un insieme analogo di graci (come nel punto A-2) che mostrino landamento dellerrore nella stima del prezzo dellopzione per dierenti valori di T /k e m (ssato N = 10.000). N.B. Lerrore va calcolato percentualmente ed in forma relativa, ovvero: errore MC assoluto / prezzo opzione, espresso in %. Caratteristiche del punto: Propedeuticit: (A-1). a Grado di dicolt: Medio a Tempo di sviluppo atteso: Lungo Ai ni dellesame: obbligatorio

(B) Formule di valutazione esatte (B-1) i) Ricavare una formula analitica esatta per lopzione nel caso in cui m = 1 (con k e qualunque). ii) Confrontare i risultati ottenuti dalla formula esatta con le stime Monte Carlo per m = 1. Caratteristiche del punto: Propedeuticit: (A) per quanto riguarda il confronto a con i dati Monte Carlo. Nessuna per quanto riguarda la derivazione della formula analitica. Grado di dicolt: Medio/Alto a Tempo di sviluppo atteso: Breve Ai ni dellesame: Facoltativo (B-2) i) Ricavare una formula analitica esatta per lopzione nel caso in cui k = 1 (con m e qualunque). ii) Confrontare i risultati ottenuti dalla formula esatta con le stime Monte Carlo per k = 1. Caratteristiche del punto: Propedeuticit: (A) per quanto riguarda il confronto a con i dati Monte Carlo. Nessuna per quanto riguarda la derivazione della formula analitica.

5.5. ESERCIZIO 5 Grado di dicolt: Medio a Tempo di sviluppo atteso: Breve Ai ni dellesame: Facoltativo

313

(B-3) i) Ricavare una formula analitica esatta per lopzione nel caso in cui k = (con m e qualunque). ii) Confrontare i risultati ottenuti dalla formula esatta con le stime Monte Carlo per k = . Caratteristiche del punto: Propedeuticit: (A) per quanto riguarda il confronto a con i dati Monte Carlo. Nessuna per quanto riguarda la derivazione della formula analitica. Grado di dicolt: Basso a Tempo di sviluppo atteso: Breve Ai ni dellesame: Facoltativo (B-4) i) Ricavare una formula analitica esatta per lopzione nel caso in cui = 0 (con m e k qualunque). Caratteristiche del punto: Propedeuticit: nessuna. Pu essere daiuto aver a o risolto il punto (B-2). Grado di dicolt: Medio/Basso a Tempo di sviluppo atteso: Breve Ai ni dellesame: Facoltativo (C) Formule di valutazione approssimate (C-1) Discutere il comportamento dei graci e la loro interpretazione nanziaria quando il numero di intervalli m diventa molto grande (in linea di principio innito). Fornire uninterpretazione teorica dei risultati ottenuti per m molto grande, in particolare: i) derivare una formula analitica asintotica per il calcolo del prezzo dellopzione nel limite m ; ii) si confrontino i risultati ottenuti dalla formula asintotica con le stime Monte Carlo. Caratteristiche del punto: Propedeuticit: (A) per quanto riguarda il confrona to con i dati Monte Carlo. Per la derivazione della formula analitica asintotica, si suggerisce di risolvere prima i punti (B-2) e (B-3). Grado di dicolt: Molto alto a Tempo di sviluppo atteso: Medio Ai ni dellesame: Facoltativo (D) Tecniche di riduzione dellerrore

314 CAPITOLO 5. LABORATORIO ED ESERCITAZIONI PRATICHE (D-1) Allo scopo di ridurre gli errori statistici, si utilizzi: la tecnica della variabile antitetica 9 . In particolare si richiede di: i) valutare il prezzo dellopzione ed il relativo errore utilizzando la tecnica della variabile antitetica; ii) calcolare e discutere la riduzione degli errori statistici (ovvero le deviazioni standard sui pay-o) ottenuta tramite luso della variabile antitetica. Caratteristiche del punto: Propedeuticit: (A). a Grado di dicolt: Basso a Tempo di sviluppo atteso: Medio Ai ni dellesame: Obbligatorio

(D-2) Rispetto al metodo standard della variabile di controllo 10 , in cui: xMC new = xMC + y yMC , (5.21)

si sviluppi una variante della formula sopra riportata al ne di sfruttare pienamente linformazione contenuta nella variabile di controllo. Caratteristiche del punto: Propedeuticit: Nessuna. a Grado di dicolt: Medio/Alto a Tempo di sviluppo atteso: Medio Ai ni dellesame: Facoltativo

(D-3) Sfruttando il risultato ottenuto nei punti (B1) e/o (B2) e/o (B3), allo scopo di ridurre gli errori statistici, si ricorra alla tecnica della variabile di controllo, nella sua versione migliorata, derivata nel punto precedente. In particolare si richiede di: i) di valutare il prezzo dellopzione ed il relativo errore utilizzando la variabile di controllo. ii) calcolare e discutere la riduzione degli errori statistici (ovvero le deviazioni standard sui pay-o) ottenuta tramite luso della variabile di controllo al variare di m. Caratteristiche del punto: Propedeuticit: (B-1) e/o (B-2) e/o (B-3) e (D-2). a Grado di dicolt: Basso a Tempo di sviluppo atteso: Medio
9 10

Vedi par. 3.1.4.e Vedi par. 3.1.4.e

5.5. ESERCIZIO 5 Ai ni dellesame: Facoltativo (E) Processi stocastici

315

(E-1) Sviluppare una classe per gestire un processo alternativo a quello lognormale standard, in particolare tale processo denito sose tituendo nella formula (2.36), al posto della variabile gaussiana w a media nulla e varianza unitaria, una variabile stocastica alternativa z (sempre a media nulla e varianza unitaria), denita come segue: +1 con probabilit 0.5 a z= (5.22) 1 con probabilit 0.5 a Il prezzo dellazione denito da: e
  t+ t z

S(t) = S(0) e

r 2

(5.23)

Il processo in questione ha natura binaria, nel senso che consente unicamente un movimento al ribasso o al rialzo dellazione su un certo intervallo di tempo t. Si verichi che la libreria sia strutturata in maniera tale da consentire lutilizzo del nuovo processo senza apportare modiche alla libreria (a parte naturalmente laggiunta e la denizione della nuova classe per la descrizione del processo binario). Si discuta quali siano i vantaggi di un tale risultato e se questo sia o meno ottenibile nellambito di una programmazione procedurale. Caratteristiche del punto: Propedeuticit: punto (A). a Grado di dicolt: Basso a Tempo di sviluppo atteso: Basso Ai ni dellesame: Facoltativo

(E-2) Si consideri il pricing di unopzione plain vanilla, spezzando lintervallo (0, T ) (T essendo la data di maturit dellopzione) in m a intervalli. Eettuare la valutazione del prezzo dellopzione plain vanilla con metodo Monte Carlo, utilizzando rispettivamente il processo lognormale standard e quello binario. Si utilizzino i dati anagraci e di mercato riportati nel punto (A). Confrontare e discutere i risultati ottenuti al variare di m, fornendone una adeguata spiegazione. Caratteristiche del punto: Propedeuticit: punti (A) e (E-1). a Grado di dicolt: Medio a

316 CAPITOLO 5. LABORATORIO ED ESERCITAZIONI PRATICHE Tempo di sviluppo atteso: Basso Ai ni dellesame: Facoltativo I risulti ottenuti devono essere presentati sotto forma di breve discussione scritta, con lausilio eventuale di graci e tabelle. La relazione deve contenere in appendice il listato integrale del codice. La relazione (in formato .pdf o .doc) e lintera libreria (le .hhp, .cpp e diagramma della libreria) vanno prodotti anche in formato elettronico (le .zip).

Bibliograa
[1] Guido Buzzi-Ferraris, Dal Fortran al C++ - Introduzione alla programmazione orientata agli oggetti applicata a problemi numerici, Addison Wesley. [2] Bruce Eckel, Thinking in C++, Prentice Hall Inc. Pearson Higher Education. [3] Gamma, Helm, Johnson e Vlissides Design Patterns, Pearson Addison Wesley. [4] Per un corso on-line sulla programmazione ad oggetti, si faccia riferimento a: http://www.science.unitn.it/ iori/java/INDEXCPP.html [5] Sulle convenzioni stilistiche da adottare per una buona programmazione ad oggetti si faccia riferimento a: http://geosoft.no/development/cppstyle.html [6] Sulla gestione ed utilizzazione degli smart pointer, una descrizione sintetica data in: e http://ootips.org/yonat/4dev/smart-pointers.html [7] J. C. Hull, Opzioni, Futures e altri derivati, III edizione, Il Sole 24 Ore Libri. In alternativa: J. C. Hull, Options, Futures and other derivatives, V edizione USA, Prentice Hall. [8] P. Wilmott, S. Howison and J. Dewynne, The Mathematics of Financial Derivatives : A Student Introduction, Cambridge University Press (1995). [9] P. Wilmott, Paul Wilmott on Quantitative Finance, 2 volumi, John Wiley and Sons Ltd (2000). [10] R. N. Mantegna and H. E. Stanley, An Introduction to Econophysics: Correlations and Complexity in Finance, Cambridge University Press (1999). 317

318

BIBLIOGRAFIA [11] J. M. Pimbley, Physicists in Finance, Physics Today, Jan., 42 (1997). [12] L. Bachelier, Thorie de la spculation (Ph.D. thesis in mathe e ematics), Annales Scientiques de lEcole Normale Suprieure e III-17, 2186 (1900). [13] B. B. Mandelbrot, The Variation of Certain Speculative Prices, Journal of Business, 36, 394419 (1963). [14] B. B. Mandelbrot, Fractals and Scaling in Finance, Springer Verlag, New York, (1997). [15] V. Plerou, P. Gopikrishnan, B. Rosenow, L. A. N. Amaral and H. E. Stanley, Econophysics: Financial Time Series from a Statistical Physics Point of View, Physica A, 279, 443456 (2000). [16] R. N. Mantegna and H. E. Stanley, Scaling Behavior in the Dynamics of an Economic Index, Nature, 376, 4649 (1995). [17] R. N. Mantegna and H. E. Stanley, Turbulence and Financial Markets, Nature, 383. 587588 (1996). [18] R. N. Mantegna and H. E. Stanley, Stock Market Dynamics and Turbulence: Parallel Analysis of Fluctuation Phenomena, Physica A, 239, 255266 (1997). [19] F. Black e M. Scholes, The Pricing of Options and Corporate Liabilities, Journal of Political Economy, 81, 637654 (1973). [20] Molti articoli sono stati pubblicati su questo tema. Alcuni esempi sono: J. Cox and S. Ross, The valuation of options for alternative stochastic processes, Journal of Financial Economics, 3, 145166 (1976); B. M. Bibby and M. Srensen, A hyperbolic diusion model for stock prices, Finance and Stochastic, 1, 2542 (1997). [21] S. M. Turnbull and L. M. Wakeman, A quick algorithm for pricing European average options, Journal of Financial and Quantitative Finance, 26, 377389, (1991). [22] L. Bouaziz, E. Briys, M. Crouhy The pricing of forwardstarting asian options, Journal of Banking and Finance, 18, n. 5, 823839, (1994). [23] M. Esposito, Valutazione di opzioni su medie aritmetiche discrete: una soluzione in forma (quasi) chiusa, Capital Market Notes, 1998.

BIBLIOGRAFIA

319

[24] M. Airoldi, A moment expansion approach to option pricing, Quantitative Finance, (2005). [25] T. W. Lim, Performance of recursive integration for pricing European-style Asian options, preprint. [26] E. D. Weinberger, How Close in Close Enough? The Limitations of Monte Carlo in Computing VaR, preprint (1999). [27] P. Jackel, Monte Carlo Methods in Finance, Wiley Finance, (2002). [28] P. Glasserman, Monte Carlo Methods in Financial Engineering, Springer. [29] W. H. Press, S. A. Teukolsky, W. T. Vetterling, B. P. Flannery, Numerical Recipes in C++ - The Art of Scientic Computing, Cambridge University Press, (2002), (www.numerical-recipes.com). [30] D. Brigo, F. Marcurio, Interest Rate Models: Theory and Practice, Springer.

Indice analitico
Alberi binomiali, 157, 194196, 199, 200, 274 Black e Scholes, 154, 159, 161, 164, 269, 276 Cholesky, 253 Curva dei tassi, 135, 138 Dierenze nite, 202, 204209, 213 Distribuzione gaussiana, 145, 146, 148, 150, 153 Eetto leva delle opzioni, 142 Fattore di sconto, 138 Lemma di Ito, 148 Libreria nanziaria, 216, 278 Libreria GSL, 216, 246 Matrice varianza covarianza, 253 Mondo neutrale al rischio, 157, 187 Monte Carlo, 180, 184, 186, 187, 189, 191, 269, 272, 278, 282 Numeri casuali, 188, 246 Numerical Recipes, 216 Opzioni, 139, 166, 172 Opzioni americane, 140 Opzioni asiatiche, 166, 174 Opzioni bermudane, 140 Opzioni cliquet, 169 Opzioni con barriera, 166 Opzioni digitali, 166, 173 Opzioni europee, 140 320 Opzioni Opzioni Opzioni Opzioni Opzioni lookback, 170 plain vanilla, 139 reverse cliquet, 169, 297 su basket, 170 su indici, 171

Path integral, 187 Principio di non arbitraggio, 135, 155 Processi di Ito, 147 Processi di Markov, 150 Processi di Wiener, 147 Processi stocastici, 144 Processo log-normale, 151, 248, 251 Random walk, 144, 147 Sottostante, 139, 140 Tasso risk free, 136 UML, 217 Variabile antitetica, 192, 259 Variabile di controllo, 184, 192