Python e Finance: potenzia i tuoi fogli di calcolo

Pubblicato: 2022-03-11

Sintesi

Perché Python è un ottimo linguaggio di programmazione da imparare per i professionisti della finanza?
  • Python è un linguaggio di programmazione di alto livello, il che significa che astrae e gestisce molti degli aspetti tecnici della programmazione, come la gestione della memoria, che devono essere gestiti esplicitamente in altri linguaggi. Questo rende Python facile da usare per chi non ha un background tecnico.
  • Poiché la lingua è stata progettata pensando alla leggibilità e alla facilità d'uso, è una delle lingue più facili da imparare. Il codice Python è conciso e vicino al semplice inglese.
  • Python è l'ideale per la prototipazione e lo sviluppo rapido e iterativo. I suoi strumenti di interprete interattivo forniscono ambienti in cui è possibile scrivere ed eseguire ogni riga di codice in isolamento e visualizzare immediatamente i risultati.
  • Allo stesso tempo, Python è robusto e performante, il che lo rende una scelta praticabile anche per sistemi core e applicazioni più grandi.
  • Oltre alla sua ampia libreria standard di strumenti utili, Python ha ottime librerie di terze parti per l'analisi finanziaria e l'informatica, come le librerie Pandas e NumPy utilizzate in questo tutorial.
Quali sono alcuni casi d'uso per implementare Python e finanziare insieme?
  • Gli script Python possono essere utilizzati per automatizzare attività e flussi di lavoro ripetitivi, risparmiando tempo e riducendo il rischio di errori manuali.
  • Gli script consentono agli utenti di estrarre facilmente dati da fogli di calcolo, database e API, o persino di raschiare dati Web, che possono quindi essere elaborati e analizzati utilizzando potenti strumenti statistici e analitici.
  • Vari plug-in per Excel consentono agli utenti di creare collegamenti bidirezionali in tempo reale tra i fogli di calcolo e il codice Python.
  • Python consente nuovi tipi di analisi, come le simulazioni Monte Carlo, che non sono facilmente disponibili nei fogli di calcolo standard.
  • Il trading algoritmico non è più dominio esclusivo degli hedge fund e delle grandi banche di investimento. Con Python, puoi sviluppare, testare e implementare le tue strategie di trading in breve tempo e a basso costo.

Per le professioni che da tempo si basano sulla pesca a strascico attraverso i fogli di calcolo, Python è particolarmente prezioso. Citigroup, una banca americana, ha introdotto un corso accelerato in Python per i suoi analisti in formazione. - L'economista

I professionisti della finanza hanno da tempo accesso a VBA (Visual Basic for Applications) in Excel per creare funzionalità personalizzate e automatizzare i flussi di lavoro. Con l'emergere negli ultimi anni di Fogli Google come un serio concorrente nello spazio dei fogli di calcolo, Google Apps Script offre ora un'ulteriore scelta.

Tuttavia, vorrei attirare l'attenzione su una terza opzione, il linguaggio di programmazione Python, che è diventato estremamente popolare in numerosi campi.

In questo articolo, fornirò alcuni esempi di ciò che puoi ottenere con Python, iniziando con una panoramica del linguaggio stesso e del perché è diventato così popolare in una così ampia varietà di campi, che vanno dallo sviluppo web, all'apprendimento automatico, alla finanza, scienza e istruzione, solo per citarne alcuni. La seconda parte consisterà quindi in un tutorial passo dopo passo.

Lo scopo di scrivere questo è aiutarti a decidere se Python sembra abbastanza intrigante da farti considerare di aggiungerlo alla tua cassetta degli attrezzi finanziaria. Se fai il salto, ci sono molte app, corsi, video, articoli, libri e post di blog disponibili per imparare la lingua. Alla fine del pezzo, ho elencato alcune risorse che mi hanno aiutato lungo il percorso.

Casi d'uso: esempi di ciò per cui ho usato Python

La mia introduzione alla programmazione è stata l'apprendimento del BASIC su un Oric 1 a metà degli anni '80. All'epoca il BASIC era la lingua per principianti più comune. Altri linguaggi con cui mi sono dilettato alla fine degli anni '80 fino alla metà degli anni '90 sono stati il ​​Pascal e il C, ma non li ho mai usati a titolo professionale e non mi aspettavo di aver bisogno o utilizzare abilità di programmazione. Per quanto ne so, alla fine degli anni '90, finanza e programmazione erano campi molto diversi, quando scelsi di intraprendere un percorso professionale in finanza.

Avanti veloce fino al 2012 e stavo cercando di riprendere la programmazione come hobby, quindi ho iniziato a cercare i linguaggi disponibili in quel momento. Si è scoperto che era successo un bel po', e quando mi sono imbattuto in Python sono rimasto affascinato, per molte delle ragioni che illustrerò nella prossima sezione. Da allora ho utilizzato Python per un'ampia gamma di attività, da piccoli script a progetti più grandi, sia personalmente che professionalmente. Molti, ma non tutti, hanno coinvolto i fogli di calcolo, il banco di lavoro di molti professionisti della finanza.

Ecco alcuni esempi di come i fogli di calcolo e Python possono andare insieme:

1. Monitoraggio di centinaia di attività nel tempo in una configurazione PMO di integrazione M&A

Mi occupo di tutti gli aspetti delle operazioni di fusione e acquisizione, non solo l'esecuzione, ma anche l'integrazione. In un caso recente, il team PMO ha deciso un programma ibrido e un approccio di gestione del progetto, utilizzando la pianificazione a cascata e i diagrammi di Gantt per piani di alto livello per ciascuno dei dodici flussi di lavoro di integrazione, oltre a una scheda Kanban per tenere traccia delle centinaia di attività in corso in qualsiasi momento, nel primo piano di 100 giorni e oltre. Lo strumento Kanban scelto, MeisterTask, ha una serie di funzionalità statistiche e di reporting, ma le nostre esigenze sono andate oltre in termini di analisi e presentazione, che richiedevano una soluzione personalizzata. Questo è il flusso di lavoro che ho automatizzato usando Python:

  1. Salva lo stato dell'intera scheda settimanalmente come file CSV.
  2. Leggi tutti i file CSV storici in un Pandas DataFrame.
  3. Ordina, filtra, raggruppa e manipola i dati in formati concordati su come vogliamo monitorare i progressi (in base allo stato dell'attività, flusso di lavoro, ecc.).
  4. Scrivete l'output in un file Excel con i dati di ciascuna analisi all'interno del proprio foglio, formattato in modo tale da poterlo semplicemente copiare e incollare nei grafici think-cell.
  5. Creare tabelle e grafici per il pacchetto di report per la riunione mensile del comitato direttivo.

Lo sviluppo della sceneggiatura ha richiesto un investimento iniziale di alcune ore, ma ora l'aggiornamento del reporting pack per le riunioni del comitato direttivo o l'analisi ad hoc richiede pochi minuti. Letteralmente, circa 30 secondi per passare alla cartella corretta ed eseguire lo script con un comando a riga singola, quindi alcuni minuti per copiare e incollare l'output nella presentazione. Con circa 500 attività (schede) in dodici flussi di lavoro già da circa un mese in esecuzione, il monitoraggio settimanale di come si muovono, all'interno di una sequenza temporale del programma di due anni, ti ritrovi rapidamente a dover gestire migliaia e alla fine decine di migliaia di punti dati in dozzine di file. Senza automazione, stiamo parlando di alcuni compiti molto noiosi qui.

Il compromesso del "valore temporale del denaro" tra il semplice andare avanti con le cose o l'aggiunta di più carico di lavoro iniziale impostando l'automazione è un tema comune nella finanza. Ho preso una decisione simile con il primo passaggio di questo processo, esportando i dati come file CSV. MeisterTask, come molte moderne applicazioni Web, ha un'API, che può essere collegata alla tua applicazione Python, ma il tempo impiegato per configurarla supererebbe di gran lunga il risparmio di tempo per il nostro caso d'uso qui.

Quindi, come vedi, spesso la soluzione ottimale è automatizzare alcuni passaggi di un flusso di lavoro e mantenerne altri manuali.

2. Analisi delle statistiche sui prezzi delle abitazioni utilizzando Web Scraping, API di Google Maps ed Excel

Un altro esempio è qualcosa che ho fatto per interesse personale ma voglio evidenziarlo perché contiene altri elementi interessanti dell'utilità di Python:

  1. Raschiare i dati degli annunci immobiliari, inclusi indirizzo, dimensioni, numero di stanze, prezzo richiesto e altre caratteristiche, per una determinata area; da poche centinaia a forse mille righe in totale.
  2. Salva in una struttura dati Python.
  3. Collegati all'API di Google Maps e, per ogni annuncio, recupera la distanza tra la struttura e i principali punti di riferimento come il mare, il centro città, la stazione ferroviaria più vicina, l'aeroporto più vicino, ecc.
  4. Esporta i dati in un file Excel.
  5. Usa la funzionalità standard di Excel per eseguire regressioni, calcolare statistiche e creare grafici su metriche standard come il prezzo per metro quadrato e la distanza dai punti di riferimento.

I risultati qui potrebbero essere combinati con le tue ponderazioni personali in termini di preferenze e limitazioni finanziarie quando cerchi immobili.

Questi sono solo due esempi, incentrati sull'automazione del lavoro relativo ai fogli di calcolo e sull'aggiunta di funzionalità, ma le opportunità con Python sono quasi infinite. Nella prossima sezione, illustrerò i motivi per cui è diventato così popolare, prima di passare a un tutorial passo passo di simulazione Monte Carlo in Python.

Perché Python è un'ottima scelta per i professionisti della finanza

Il linguaggio di programmazione Python è in circolazione dal 1990, ma è solo negli ultimi anni che la sua popolarità è esplosa.

python è il linguaggio di programmazione più ricercato

Ci sono diversi motivi per questo, diamo un'occhiata a ciascuno a turno.

1. Python è un linguaggio di programmazione di alto livello

Un linguaggio di programmazione di alto livello è quello che astrae molti dei dettagli del funzionamento interno del computer. Un buon esempio è la gestione della memoria. I linguaggi di programmazione di livello inferiore richiedono una comprensione dettagliata delle complessità di come viene disposta, allocata e rilasciata la memoria del computer, oltre al tempo impiegato e alle righe di codice necessarie per gestire le attività. Python astrae e gestisce automaticamente molti di questi dettagli, lasciandoti concentrare su ciò che vuoi ottenere.

2. È conciso

Poiché Python è un linguaggio di programmazione di alto livello, il codice è più conciso e quasi interamente incentrato sulla logica aziendale di ciò che si desidera ottenere, piuttosto che sui dettagli tecnici di implementazione. Le scelte di progettazione del linguaggio contribuiscono a questo: ad esempio, Python non richiede l'uso di parentesi graffe o punto e virgola per delineare funzioni, loop e linee come fanno molti altri linguaggi, il che lo rende più conciso e, come alcuni sostengono, migliora leggibilità.

3. Facile da imparare e da capire

Un'osservazione che ha influenzato le scelte di progettazione del linguaggio in Python è che i programmi vengono letti più spesso di quanto non vengano scritti. Python eccelle qui poiché il suo codice sembra molto simile all'inglese semplice, specialmente se dai un nome ai diversi componenti del tuo script o programma in modo sensato.

4. Adatto per uno sviluppo rapido e iterativo

I tentativi e gli errori illuminati superano la pianificazione di intelletti impeccabili. - David Kelley

Python è l'ideale per la prototipazione e lo sviluppo iterativo rapido (e, sì, per tentativi ed errori) perché gli strumenti di interprete interattivi come la shell Python, IPython e i notebook Jupyter sono in primo piano nella toolchain di Python. In questi ambienti interattivi, puoi scrivere ed eseguire ogni riga di codice in isolamento e vedere immediatamente i risultati (o un utile messaggio di errore). Anche altri linguaggi lo hanno, ma nella maggior parte dei casi non nella stessa misura di Python.

5. Può essere utilizzato sia per la prototipazione che per il codice di produzione

Oltre ad essere ottimo per la prototipazione, Python è anche un linguaggio eccellente e potente per applicazioni di produzione di grandi dimensioni. Alcune delle più grandi società di software del mondo fanno un uso massiccio di Python in una varietà di applicazioni e casi d'uso.

6. Viene fornito con "Batterie incluse:" La libreria standard di Python

Tutto il necessario per le operazioni di base è integrato direttamente nel linguaggio, ma in aggiunta a ciò, la libreria standard Python dispone di strumenti per lavorare con file, media, networking, informazioni su data e ora e molto altro. Ciò consente di eseguire un'ampia varietà di attività senza dover cercare pacchetti di terze parti.

7. Grandi biblioteche di terze parti per l'analisi finanziaria

Per i professionisti della finanza, Pandas con i suoi oggetti DataFrame e Series e Numpy con il suo ndarray sono i cavalli di battaglia dell'analisi finanziaria con Python. In combinazione con matplotlib e altre librerie di visualizzazione, hai ottimi strumenti a tua disposizione per aiutare la produttività.

8. Python è gratuito!

Python è sviluppato sotto una licenza open source che lo rende gratuito anche per uso commerciale.

Tutorial passo passo sull'uso di Python e Finance insieme

Quello che segue è un tutorial passo passo che mostra come creare una versione semplificata della simulazione Monte Carlo descritta nel mio precedente post sul blog, ma usando Python invece del plugin @RISK per Excel.

I metodi Monte Carlo si basano sul campionamento casuale per ottenere risultati numerici. Una di queste applicazioni consiste nel trarre campioni casuali da una distribuzione di probabilità che rappresenta potenziali stati futuri incerti del mondo in cui variabili o ipotesi possono assumere un intervallo di valori.

È utile eseguire la simulazione Monte Carlo su un modello di valutazione DCF semplificato invece degli esempi più comuni che vedi che mostrano la valutazione di opzioni o altri derivati, poiché per questo non abbiamo bisogno di alcuna matematica oltre alle basi del calcolo del bilancio e scontando i flussi di cassa, consentendoci di concentrarci sui concetti e sugli strumenti di Python. Si noti tuttavia che questo modello di tutorial di base ha lo scopo di illustrare i concetti chiave e non è utile così com'è per scopi pratici. Inoltre, non toccherò nessuno degli aspetti più accademici delle simulazioni Monte Carlo.

Il tutorial presuppone che tu abbia familiarità con gli elementi costitutivi di base della programmazione, come variabili e funzioni. In caso contrario, potrebbe essere utile impiegare 10 minuti per verificare i concetti chiave, ad esempio in questa introduzione.

Il punto di partenza e il risultato desiderato

Comincio con lo stesso modello di valutazione DCF molto semplificato utilizzato nel tutorial di simulazione Monte Carlo. Ha alcune voci chiave dei tre rendiconti finanziari e tre celle di input evidenziate, che nella versione Excel hanno stime puntuali che ora vogliamo sostituire con distribuzioni di probabilità per iniziare a esplorare potenziali intervalli di risultati.

esempio di proiezioni finanziarie

Un approccio in due fasi per lo sviluppo di un piccolo script

Fallo funzionare, fallo bene, fallo velocemente - Kent Beck

L'intenzione di questo tutorial è fornire ai professionisti della finanza che non conoscono Python un'introduzione non solo all'aspetto di un programma utile, ma anche al processo iterativo che è possibile utilizzare per svilupparlo. Si compone, quindi, di due parti:

  1. In primo luogo, sviluppo un prototipo funzionante utilizzando un approccio semplice che penso sia facile da seguire e non del tutto diverso dal processo che si potrebbe utilizzare per iniziare questo progetto se dovessi iniziare da zero.
  2. Quindi, dopo aver sviluppato il prototipo funzionante, passo attraverso il processo di refactoring, modificando la struttura del codice senza cambiarne la funzionalità. Potresti voler rimanere per quella parte: è una soluzione più elegante della prima e, come bonus, è circa 75 volte più veloce in termini di tempo di esecuzione.

1. Sviluppo di un prototipo funzionante

Configurazione del notebook Jupyter

Il notebook Jupyter è un ottimo strumento per lavorare con Python in modo interattivo. È un interprete Python interattivo con celle che possono contenere codice, testo Markdown, immagini o altri dati. Per questo tutorial ho usato Python Quant Platform, ma posso consigliare anche Colaboratory di Google, che è gratuito e gira nel cloud. Una volta lì, seleziona semplicemente "Nuovo Python 3 Notebook" nel menu "File" e sei pronto per partire.

Fatto ciò, il passaggio successivo è importare i pacchetti di terze parti di cui abbiamo bisogno per la manipolazione e la visualizzazione dei dati e dire al programma che vogliamo vedere i grafici in linea nel nostro taccuino, invece che in finestre separate:

 import numpy as np import pandas as pd import matplotlib.pyplot as plt %matplotlib inline

Una nota prima di iniziare a nominare le nostre prime variabili. Come ho già evidenziato, la leggibilità è uno dei punti di forza di Python. La progettazione del linguaggio fa molto per supportarlo, ma chiunque scriva codice è responsabile di renderlo leggibile e comprensibile, non solo per gli altri ma anche per se stesso. Come afferma la legge di Eagleson, "Qualsiasi codice che non guardi per sei o più mesi potrebbe anche essere stato scritto da qualcun altro".

Una buona regola pratica è nominare i componenti del programma in modo tale da ridurre al minimo la necessità di commenti separati che spieghino cosa fa il programma.

Con questo in mente, andiamo avanti.

Creazione del bilancio

Ci sono molti modi in cui possiamo lavorare con i dati del foglio di calcolo esistenti in Python. Potremmo, ad esempio, leggere un foglio in un Pandas DataFrame con una riga di codice usando il comando read_excel . Se desideri un'integrazione più stretta e un collegamento in tempo reale tra il foglio di calcolo e il codice Python, sono disponibili opzioni sia gratuite che commerciali per fornire tale funzionalità.

Poiché il modello qui è molto semplice e per concentrarci sui concetti di Python, lo ricreeremo da zero nel nostro script. Alla fine della prima parte, mostrerò come puoi esportare ciò che abbiamo creato in un foglio di calcolo.

Come primo passo verso la creazione di una rappresentazione Python del bilancio, avremo bisogno di una struttura dati adeguata. Ce ne sono molti tra cui scegliere, alcuni integrati in Python, altri da varie librerie, oppure possiamo crearne uno nostro. Per ora, utilizziamo una serie dalla libreria Pandas per dare un'occhiata alle sue funzionalità:

 years = ['2018A', '2019B', '2020P', '2021P', '2022P', '2023P'] sales = pd.Series(index=years) sales['2018A'] = 31.0 sales

Questo ingresso e l'uscita corrispondente sono mostrati di seguito:

creare una serie da una libreria Python

Con le prime tre righe abbiamo creato una struttura dati con un indice composto da anni (ciascuno contrassegnato per mostrare se è effettivo, budget o previsto), un valore iniziale (in milioni di euro, come nel modello DCF originale) e celle vuote (NaN, "Non un numero") per le proiezioni. La quarta riga stampa una rappresentazione dei dati: in generale, digitando il nome di una variabile o di altri oggetti nell'interprete interattivo di solito si ottiene una rappresentazione sensata di essi.

Successivamente, dichiariamo una variabile per rappresentare la crescita annuale delle vendite prevista. In questa fase, è una stima puntuale, la stessa cifra del nostro modello DCF originale. Vogliamo prima utilizzare gli stessi input e confermare che la nostra versione di Python ha le stesse prestazioni e fornisce lo stesso risultato della versione di Excel, prima di sostituire le stime puntuali con le distribuzioni di probabilità. Utilizzando questa variabile, creiamo un ciclo che calcola le vendite in ogni anno delle proiezioni in base all'anno precedente e al tasso di crescita:

 growth_rate = 0.1 for year in range(1, 6): sales[year] = sales[year - 1] * (1 + growth_rate) sales

Ora abbiamo previsto le vendite, invece di NaN:

python e finanza: proiezione dei dati di vendita

Utilizzando lo stesso approccio, continuiamo con il bilancio, dichiarando le variabili di cui abbiamo bisogno ed eseguendo i calcoli necessari per arrivare alla fine al flusso di cassa libero. Una volta arrivati, possiamo verificare che ciò che abbiamo corrisponda a ciò che dice la versione Excel del modello DCF.

 ebitda_margin = 0.14 depr_percent = 0.032 ebitda = sales * ebitda_margin depreciation = sales * depr_percent ebit = ebitda - depreciation nwc_percent = 0.24 nwc = sales * nwc_percent change_in_nwc = nwc.shift(1) - nwc capex_percent = depr_percent capex = -(sales * capex_percent) tax_rate = 0.25 tax_payment = -ebit * tax_rate tax_payment = tax_payment.apply(lambda x: min(x, 0)) free_cash_flow = ebit + depreciation + tax_payment + capex + change_in_nwc free_cash_flow

Questo ci dà i flussi di cassa gratuiti:

output di flusso di cassa scontato da Python

L'unica riga sopra che forse ha bisogno di un commento in questa fase è il secondo riferimento tax_payment . Qui, applichiamo una piccola funzione per garantire che negli scenari in cui l'utile prima delle tasse diventa negativo, non avremo un pagamento delle tasse positivo. Questo mostra quanto efficacemente puoi applicare funzioni personalizzate a tutte le celle in una serie Pandas o DataFrame. La funzione effettivamente applicata è, ovviamente, una semplificazione. Un modello più realistico per un esercizio di valutazione più ampio avrebbe un modello fiscale separato che calcola le imposte in contanti effettive pagate in base a una serie di fattori specifici dell'azienda.

Esecuzione della valutazione DCF

Essendo arrivati ​​ai flussi di cassa previsti, ora possiamo calcolare un semplice valore terminale e attualizzare tutti i flussi di cassa al presente per ottenere il risultato DCF. Il codice seguente introduce l'indicizzazione e lo slicing, che ci consente di accedere a uno o più elementi in una struttura dati, come l'oggetto Pandas Series.

Si accede agli elementi scrivendo parentesi quadre subito dopo il nome della struttura. L'indicizzazione semplice accede agli elementi in base alla loro posizione, a partire da zero, il che significa che free_cash_flow[1] ci darebbe il secondo elemento. [-1] è un'abbreviazione per accedere all'ultimo elemento (il flusso di cassa dell'ultimo anno viene utilizzato per calcolare il valore terminale) e utilizzando i due punti si ottiene una fetta, il che significa che [1:] ci fornisce tutti gli elementi tranne il primo, poiché non vogliamo includere l'anno storico 2018A nella nostra valutazione DCF.

 cost_of_capital = 0.12 terminal_growth = 0.02 terminal_value = ((free_cash_flow[-1] * (1 + terminal_growth)) / (cost_of_capital - terminal_growth)) discount_factors = [(1 / (1 + cost_of_capital)) ** i for i in range (1,6)] dcf_value = (sum(free_cash_flow[1:] * discount_factors) + terminal_value * discount_factors[-1]) dcf_value 

output dcf dal calcolo del flusso di cassa scontato di Python

Questo conclude la prima parte del nostro prototipo: ora abbiamo un modello DCF funzionante, anche se molto rudimentale, in Python.

Esportazione dei dati

Prima di passare all'effettiva simulazione Monte Carlo, questo potrebbe essere un buon momento per menzionare le capacità di esportazione disponibili nel pacchetto Pandas. Se hai un oggetto Pandas DataFrame, puoi scriverlo in un file Excel con una riga usando il metodo to_excel . Esiste anche una funzionalità simile per l'esportazione in più di una dozzina di altri formati e destinazioni.

 output = pd.DataFrame([sales, ebit, free_cash_flow], index=['Sales', 'EBIT', 'Free Cash Flow']).round(1) output.to_excel('Python DCF Model Output.xlsx') output 

esempio di output della tabella excel generato con python

Creazione di distribuzioni di probabilità per la nostra simulazione Monte Carlo

Ora siamo pronti per affrontare la prossima sfida: sostituire alcuni degli input di stima puntuale con distribuzioni di probabilità. Sebbene i passaggi fino a questo punto possano essere sembrati alquanto ingombranti rispetto alla creazione dello stesso modello in Excel, queste righe successive ti daranno un'idea di quanto possa essere potente Python.

Il nostro primo passo è decidere quante iterazioni vogliamo eseguire nella simulazione. L'utilizzo di 1.000 come punto di partenza raggiunge un equilibrio tra l'ottenimento di punti dati sufficienti per ottenere grafici di output sensati e il completamento della simulazione entro un intervallo di tempo ragionevole. Successivamente, generiamo le distribuzioni effettive. Per semplicità, ho generato qui tre distribuzioni normali, ma la libreria NumPy ha un gran numero di distribuzioni tra cui scegliere e ci sono anche altri posti in cui cercare, inclusa la libreria standard Python. Dopo aver deciso quale distribuzione utilizzare, è necessario specificare i parametri necessari per descrivere la loro forma, come la media e la deviazione standard, e il numero di risultati desiderati.

 iterations = 1000 sales_growth_dist = np.random.normal(loc=0.1, scale=0.01, size=iterations) ebitda_margin_dist = np.random.normal(loc=0.14, scale=0.02, size=iterations) nwc_percent_dist = np.random.normal(loc=0.24, scale=0.01, size=iterations) plt.hist(sales_growth_dist, bins=20) plt.show() 

output di simulazione monte carlo da python

Qui si potrebbe sostenere che l'EBITDA non dovrebbe essere una variabile casuale separata e indipendente dalle vendite, ma piuttosto correlata alle vendite in una certa misura. Sono d'accordo con questo e aggiungo che dovrebbe essere guidato da una solida comprensione della dinamica della struttura dei costi (costi variabili, semivariabili e fissi) e dei principali fattori di costo (alcuni dei quali possono avere le proprie distribuzioni di probabilità, come ad esempio i prezzi delle materie prime di input), ma lascio queste complessità da parte qui per motivi di spazio e chiarezza.

Meno dati hai per informare la tua scelta di distribuzione e parametri, più dovrai fare affidamento sui risultati dei tuoi vari flussi di lavoro di due diligence, combinati con l'esperienza, per formare una visione consensuale su intervalli di scenari probabili. In questo esempio, con le proiezioni dei flussi di cassa, ci sarà un'ampia componente soggettiva, il che significa che la visualizzazione delle distribuzioni di probabilità diventa importante. Qui possiamo ottenere una visualizzazione di base, che mostra la distribuzione della crescita delle vendite, con solo due brevi righe di codice. In questo modo possiamo visualizzare rapidamente qualsiasi distribuzione nel bulbo oculare che riflette al meglio la visione collettiva della squadra.

Ora abbiamo tutti gli elementi costitutivi di cui abbiamo bisogno per eseguire la simulazione, ma non sono in un formato conveniente per eseguire la simulazione. Ecco lo stesso codice con cui abbiamo lavorato finora, ma tutto raccolto in una cella e riorganizzato in una funzione per comodità:

 def run_mcs(): # Create probability distributions sales_growth_dist = np.random.normal(loc=0.1, scale=0.01, size=iterations) ebitda_margin_dist = np.random.normal(loc=0.14, scale=0.02, size=iterations) nwc_percent_dist = np.random.normal(loc=0.24, scale=0.01, size=iterations) # Calculate DCF value for each set of random inputs output_distribution = [] for i in range(iterations): for year in range(1, 6): sales[year] = sales[year - 1] * (1 + sales_growth_dist[0]) ebitda = sales * ebitda_margin_dist[i] depreciation = (sales * depr_percent) ebit = ebitda - depreciation nwc = sales * nwc_percent_dist[i] change_in_nwc = nwc.shift(1) - nwc capex = -(sales * capex_percent) tax_payment = -ebit * tax_rate tax_payment = tax_payment.apply(lambda x: min(x, 0)) free_cash_flow = ebit + depreciation + tax_payment + capex + change_in_nwc # DCF valuation terminal_value = (free_cash_flow[-1] * 1.02) / (cost_of_capital - 0.02) free_cash_flow[-1] += terminal_value discount_factors = [(1 / (1 + cost_of_capital)) ** i for i in range (1,6)] dcf_value = sum(free_cash_flow[1:] * discount_factors ) output_distribution.append(dcf_value) return output_distribution

Ora possiamo eseguire l'intera simulazione e tracciare la distribuzione dell'output, che sarà il valore del flusso di cassa scontato di questa società in ciascuna delle 1.000 iterazioni, con il codice seguente. Il comando %time non è un codice Python ma una scorciatoia per notebook che misura il tempo necessario per eseguire qualcosa (potresti invece usare la funzione Python dalla libreria standard). Dipende dal computer su cui lo esegui, ma questa versione richiede 1-2 secondi per eseguire le 1.000 iterazioni e visualizzare il risultato.

 %time plt.hist(run_mcs(), bins=20, color='r') plt.show() 

output di simulazione monte carlo da script python

2. Perfezionamento del prototipo

Il sospetto in agguato che qualcosa possa essere semplificato è la fonte più ricca di sfide gratificanti al mondo. - Edsger Dijkstra

Il refactoring si riferisce al processo di riscrittura del codice esistente per migliorarne la struttura senza cambiarne la funzionalità e può essere uno degli elementi più divertenti e gratificanti della codifica. Ci possono essere diversi motivi per farlo. Potrebbe essere per:

  1. Organizza le diverse parti in modo più sensato.
  2. Rinominare le variabili e le funzioni per chiarirne lo scopo e il funzionamento.
  3. Consenti e preparati per le funzionalità future.
  4. Migliora la velocità di esecuzione, l'ingombro della memoria o l'utilizzo di altre risorse.

Per mostrare come potrebbe essere un passaggio di quel processo, ho ripulito il prototipo che abbiamo appena esaminato raccogliendo tutte le variabili iniziali in un unico posto, anziché sparse ovunque come nello script del prototipo, e ho ottimizzato la sua velocità di esecuzione attraverso un processo chiamato vettorizzazione .

L'uso degli array NumPy consente di esprimere molti tipi di attività di elaborazione dati come espressioni di array concise che potrebbero altrimenti richiedere la scrittura di cicli. Questa pratica di sostituzione di cicli espliciti con espressioni di matrice viene comunemente definita vettorizzazione. Wes McKinney

Ora sembra più pulito e più facile da capire:

 # Key inputs from DCF model years = 5 starting_sales = 31.0 capex_percent = depr_percent = 0.032 sales_growth = 0.1 ebitda_margin = 0.14 nwc_percent = 0.24 tax_rate = 0.25 # DCF assumptions r = 0.12 g = 0.02 # For MCS model iterations = 1000 sales_std_dev = 0.01 ebitda_std_dev = 0.02 nwc_std_dev = 0.01
 def run_mcs(): # Generate probability distributions sales_growth_dist = np.random.normal(loc=sales_growth, scale=sales_std_dev, size=(years, iterations)) ebitda_margin_dist = np.random.normal(loc=ebitda_margin, scale=ebitda_std_dev, size=(years, iterations)) nwc_percent_dist = np.random.normal(loc=nwc_percent, scale=nwc_std_dev, size=(years, iterations)) # Calculate free cash flow sales_growth_dist += 1 for i in range(1, len(sales_growth_dist)): sales_growth_dist[i] *= sales_growth_dist[i-1] sales = sales_growth_dist * starting_sales ebitda = sales * ebitda_margin_dist ebit = ebitda - (sales * depr_percent) tax = -(ebit * tax_rate) np.clip(tax, a_min=None, a_max=0) nwc = nwc_percent_dist * sales starting_nwc = starting_sales * nwc_percent prev_year_nwc = np.roll(nwc, 1, axis=0) prev_year_nwc[0] = starting_nwc delta_nwc = prev_year_nwc - nwc capex = -(sales * capex_percent) free_cash_flow = ebitda + tax + delta_nwc + capex # Discount cash flows to get DCF value terminal_value = free_cash_flow[-1] * (1 + g) / (r - g) discount_rates = [(1 / (1 + r)) ** i for i in range (1,6)] dcf_value = sum((free_cash_flow.T * discount_rates).T) dcf_value += terminal_value * discount_rates[-1] return dcf_value

La principale differenza che noterai tra questa versione e la precedente è l'assenza del ciclo for i in range(iterations) . Utilizzando il funzionamento dell'array di NumPy, questa versione viene eseguita in 18 millisecondi rispetto agli 1,35 secondi della versione prototipo, circa 75 volte più veloce.

 %time plt.hist(run_mcs(), bins=20, density=True, color="r") plt.show() 

Esempio di operazione con l'array NumPy

Sono sicuro che è possibile un'ulteriore ottimizzazione, poiché ho messo insieme sia il prototipo che la versione perfezionata in breve tempo esclusivamente allo scopo di questo tutorial.

Portarlo oltre

Questo tutorial ha mostrato alcune delle potenti funzionalità di Python e, se dovessi svilupparlo ulteriormente, le opportunità sono quasi infinite. Potresti ad esempio:

  • Raschia o scarica le statistiche rilevanti dell'azienda o del settore da pagine Web o altre fonti di dati, per aiutarti a scegliere le ipotesi e le distribuzioni di probabilità.
  • Usa Python in applicazioni di finanza quantitativa, ad esempio in un algoritmo di trading automatizzato basato su fattori fondamentali e/o macroeconomici.
  • Crea funzionalità di esportazione che generano output in un foglio di calcolo e/o in un formato di presentazione, da utilizzare come parte del processo di revisione e approvazione delle transazioni interne o per presentazioni esterne.

Non ho nemmeno accennato a cosa potresti fare anche con le varie applicazioni web, data science e machine learning che hanno contribuito al successo di Python.

In sintesi: un linguaggio utile per la tua cassetta degli attrezzi finanziaria

Questo articolo ha fornito un'introduzione al linguaggio di programmazione Python, ha elencato alcuni dei motivi per cui è diventato così popolare in finanza e ha mostrato come costruire un piccolo script Python. In un tutorial passo dopo passo, ho spiegato come utilizzare Python per la prototipazione iterativa, l'analisi finanziaria interattiva e per il codice applicativo per modelli di valutazione, programmi di trading algoritmico e altro ancora.

Per me, alla fine, la caratteristica killer della tecnologia Python è che è semplicemente divertente lavorarci! Se ti piace risolvere i problemi, costruire cose e rendere più efficienti i flussi di lavoro, allora ti incoraggio a provarlo. Mi piacerebbe sentire cosa ne hai fatto o vorresti farne.

Risorse consigliate per i professionisti della finanza per imparare Python

  • Libri di O'Reilly. Posso consigliare in particolare:
    • Python for Finance by Yves Hilpisch
    • Learning Python by Mark Lutz
    • Fluent Python by Luciano Ramalho
  • The Python Quants
  • PyCon talks on YouTube
  • Udemy