Python și finanțe – Îmbunătățiți-vă foile de calcul

Publicat: 2022-03-11

Rezumat

De ce este Python un limbaj de programare grozav pe care să îl învețe profesioniștii din domeniul financiar?
  • Python este un limbaj de programare la nivel înalt, ceea ce înseamnă că face abstractie și se ocupă de multe dintre aspectele tehnice ale programării, cum ar fi gestionarea memoriei, care trebuie gestionate în mod explicit în alte limbaje. Acest lucru face ca Python să fie ușor de utilizat pentru cei fără cunoștințe tehnice.
  • Deoarece limbajul a fost conceput pentru lizibilitate și ușurință în utilizare, este una dintre cele mai ușor de învățat. Codul Python este concis și aproape de limba engleză simplă.
  • Python este ideal pentru prototipare și dezvoltare rapidă, iterativă. Instrumentele sale de interpretare interactive oferă medii în care puteți scrie și executa fiecare linie de cod izolat și puteți vedea rezultatele imediat.
  • În același timp, Python este robust și performant, ceea ce îl face o alegere viabilă și pentru sistemele de bază și aplicațiile mai mari.
  • Pe lângă biblioteca sa standard mare de instrumente utile, Python are biblioteci excelente de la terți pentru analiză financiară și calcul, cum ar fi bibliotecile Pandas și NumPy utilizate în acest tutorial.
Care sunt câteva cazuri de utilizare pentru implementarea Python și finanțare împreună?
  • Scripturile Python pot fi folosite pentru a automatiza sarcinile repetitive și fluxurile de lucru, economisind timp și reducând riscul erorilor manuale.
  • Scripturile permit utilizatorilor să extragă cu ușurință date din foi de calcul, baze de date și API-uri, sau chiar să răzuie date web, care apoi pot fi procesate și analizate folosind instrumente statistice și analitice puternice.
  • Diverse pluginuri pentru Excel permit utilizatorilor să creeze legături bidirecționale în timp real între foile de calcul și codul Python.
  • Python permite noi tipuri de analiză, cum ar fi simulările Monte Carlo, care nu sunt ușor disponibile în foile de calcul standard.
  • Tranzacționarea algoritmică nu mai este domeniul exclusiv al fondurilor speculative și al marilor bănci de investiții. Cu Python, puteți dezvolta, testa și implementa propriile strategii de tranzacționare într-un timp scurt și la un cost scăzut.

Pentru profesiile care s-au bazat de mult pe traul prin foi de calcul, Python este deosebit de valoros. Citigroup, o bancă americană, a introdus un curs intensiv în Python pentru analiștii săi stagiari. - Economistul

Profesioniștii din domeniul financiar au de multă vreme acces la VBA (Visual Basic for Applications) în Excel pentru a construi funcționalități personalizate și a automatiza fluxurile de lucru. Odată cu apariția în ultimii ani a Google Sheets ca un concurent serios în spațiul foilor de calcul, Google Apps Script oferă acum o alegere suplimentară.

Cu toate acestea, aș dori să atrag atenția asupra unei a treia opțiuni, limbajul de programare Python, care a devenit extrem de popular în mai multe domenii.

În acest articol, voi oferi câteva exemple de ceea ce puteți realiza cu Python, începând cu o prezentare generală a limbajului în sine și de ce a devenit atât de popular într-o varietate atât de mare de domenii, variind de la dezvoltarea web, învățarea automată, finanțele, știință și educație, pentru a numi doar câteva. A doua jumătate va consta apoi într-un tutorial pas cu pas.

Scopul meu să scriu acest lucru este să vă ajut să decideți dacă Python pare suficient de intrigant pentru a vă gândi să îl adăugați în setul dvs. de instrumente financiare. Dacă faci un salt, există multe aplicații, cursuri, videoclipuri, articole, cărți și postări pe blog disponibile pentru a învăța limba. La finalul piesei, am enumerat câteva resurse care m-au ajutat pe parcurs.

Cazuri de utilizare: exemple pentru ce am folosit Python

Introducerea mea în programare a fost învățarea BASIC pe un Oric 1 la mijlocul anilor 1980. Pe atunci BASIC era cel mai comun limbaj pentru începători. Alte limbi cu care m-am bătut la sfârșitul anilor 80 până la mijlocul anilor 90 au fost Pascal și C, dar nu le-am folosit niciodată în nicio calitate profesională și nu mă așteptam să am nevoie sau să folosesc abilități de programare. Din câte știam la vremea aceea, la sfârșitul anilor 90, finanțele și programarea erau domenii foarte diferite, când am ales să încep o carieră în finanțe.

Înainte rapid până în 2012 și căutam să reia programarea ca hobby, așa că am început să cercetez limbajele disponibile la acea vreme. Sa dovedit că s-au întâmplat destul de multe, iar când am dat peste Python am fost cucerit, din multe dintre motivele pe care le voi sublinia în secțiunea următoare. De atunci am folosit Python pentru o gamă largă de sarcini, de la scripturi mici la proiecte mai mari, atât personal, cât și profesional. Mulți, dar nu toți, au implicat foi de calcul, bancul de lucru al multor profesioniști în finanțe.

Iată câteva exemple despre cât de bine pot merge împreună foile de calcul și Python:

1. Urmărirea a sute de activități de-a lungul timpului într-o configurare PMO de integrare M&A

Lucrez cu toate aspectele tranzacțiilor de fuziuni și achiziții, nu doar execuția, ci și integrarea. Într-un caz recent, echipa PMO a decis asupra unei abordări hibride de management al programului și al proiectelor, folosind planificarea în cascadă și diagramele Gantt pentru planuri la nivel înalt pentru fiecare dintre cele douăsprezece fluxuri de lucru de integrare, în plus față de un panou Kanban pentru urmărirea sutelor de activități care se desfășoară. activat în orice moment, în primul plan de 100 de zile și ulterior. Instrumentul Kanban care a fost ales, MeisterTask, are o serie de caracteristici statistice și de raportare, dar nevoile noastre au mers dincolo de asta în ceea ce privește analiza și prezentarea, ceea ce necesita o soluție personalizată. Acesta este fluxul de lucru pe care l-am automatizat folosind Python:

  1. Salvați starea întregului forum săptămânal ca fișier CSV.
  2. Citiți toate fișierele CSV istorice într-un Pandas DataFrame.
  3. Sortați, filtrați, grupați și manipulați datele în formate convenite despre modul în care dorim să urmărim progresul (după starea activității, fluxul de lucru etc.).
  4. Scrieți rezultatul într-un fișier Excel cu datele din fiecare analiză în propria foaie, formatată astfel încât să poată fi pur și simplu copiat și lipit în diagrame think-cell.
  5. Creați tabele și diagrame pentru pachetul de raportare pentru ședința lunară a comitetului de conducere.

Dezvoltarea scenariului a necesitat o investiție inițială de câteva ore, dar acum, actualizarea pachetului de raportare pentru reuniunile comitetului de conducere sau analiza ad-hoc durează câteva minute. Literal, aproximativ 30 de secunde pentru a merge în folderul potrivit și a rula scriptul cu o comandă pe o linie, apoi câteva minute pentru a copia și lipi rezultatul în pachetul de diapozitive. Cu aproximativ 500 de activități (carduri) din douăsprezece fluxuri de lucru deja la aproximativ o lună de execuție, urmărirea săptămânală a modului în care acestea se mișcă, într-o cronologie a programului de doi ani, te trezești rapid de a face cu mii și, în cele din urmă, cu zeci de mii de puncte de date din zeci a dosarelor. Fără automatizare, vorbim aici despre niște sarcini foarte obositoare.

Compartimentul „valoarea banilor în timp” între a continua lucrurile sau a adăuga mai multă sarcină de lucru inițială prin configurarea automatizării este o temă comună în finanțe. Am luat o decizie similară cu primul pas al acestui proces, prin exportarea datelor ca fișiere CSV. MeisterTask, la fel ca multe aplicații web moderne, are un API, care poate fi conectat la aplicația dvs. Python, dar timpul petrecut pentru configurare ar depăși cu mult economiile de timp pentru cazul nostru de utilizare aici.

Deci, după cum vedeți, de multe ori soluția optimă este automatizarea anumitor pași ai unui flux de lucru și păstrarea altora manuale.

2. Analiza statisticilor prețurilor caselor folosind Web Scraping, API-ul Google Maps și Excel

Un alt exemplu este ceva pe care l-am făcut din interes personal, dar vreau să îl evidențiez deoarece conține alte elemente interesante ale utilitarului Python:

  1. Scurgeți datele înregistrărilor imobiliare, inclusiv adresa, dimensiunea, numărul de camere, prețul cerut și alte caracteristici, pentru o anumită zonă; câteva sute până la o mie de rânduri în total.
  2. Salvați într-o structură de date Python.
  3. Conectați-vă la API-ul Google Maps și, pentru fiecare înregistrare, preluați distanța dintre proprietate și repere cheie precum mare, centrul orașului, cea mai apropiată gară, cel mai apropiat aeroport etc.
  4. Exportați datele într-un fișier Excel.
  5. Utilizați funcționalitatea standard Excel pentru a rula regresii, a calcula statistici și a crea diagrame pe valori standard, cum ar fi prețul pe metru pătrat și distanța până la repere.

Rezultatele de aici ar putea fi combinate cu propriile ponderi personale în ceea ce privește preferințele și limitările financiare atunci când căutați proprietăți imobiliare.

Acestea sunt doar două exemple, concentrate pe automatizarea muncii legate de foile de calcul și pe adăugarea de funcții, dar oportunitățile cu Python sunt aproape nesfârșite. În secțiunea următoare, voi sublinia motivele pentru care a devenit atât de popular, înainte de a trece la un tutorial de simulare Monte Carlo pas cu pas în Python.

De ce Python este o alegere excelentă pentru profesioniștii din domeniul finanțelor

Limbajul de programare Python există din 1990, dar popularitatea sa a explodat abia în ultimii ani.

python este cel mai căutat limbaj de programare

Există mai multe motive pentru aceasta, să ne uităm la fiecare pe rând.

1. Python este un limbaj de programare la nivel înalt

Un limbaj de programare de nivel înalt este unul care abstrage multe dintre detaliile funcționării interioare a computerului. Un bun exemplu este gestionarea memoriei. Limbajele de programare de nivel inferior necesită o înțelegere detaliată a complexității modului în care este așezată, alocată și eliberată memoria computerului, în plus față de timpul petrecut și liniile de cod necesare pentru a gestiona sarcini. Python retrage și gestionează automat multe dintre aceste detalii, lăsându-vă să vă concentrați pe ceea ce doriți să realizați.

2. Este concis

Deoarece Python este un limbaj de programare de nivel înalt, codul este mai concis și aproape în întregime concentrat pe logica de afaceri a ceea ce doriți să realizați, mai degrabă decât pe detaliile tehnice de implementare. Alegerile de proiectare a limbajului contribuie la aceasta: de exemplu, Python nu necesită utilizarea acoladelor sau punctului și virgulă pentru a delimita funcții, bucle și linii așa cum o fac multe alte limbi, ceea ce îl face mai concis și, după cum susțin unii, îl îmbunătățește. lizibilitatea.

3. Ușor de învățat și de înțeles

O observație care a influențat alegerile de proiectare a limbajului în Python este că programele sunt citite mai des decât sunt scrise. Python excelează aici, deoarece codul său arată foarte aproape de limba engleză simplă, mai ales dacă denumiți diferitele componente ale scriptului sau programului dvs. într-un mod rezonabil.

4. Potrivit pentru dezvoltare rapidă, iterativă

Încercarea și eroarea iluminată depășește planificarea unor intelecturi fără cusur. - David Kelley

Python este ideal pentru crearea de prototipuri și dezvoltarea rapidă, iterativă (și, da, încercare și eroare), deoarece instrumentele de interpretare interactive, cum ar fi shell-ul Python, IPython și notebook-urile Jupyter sunt în fața și în centrul lanțului de instrumente Python. În aceste medii interactive, puteți scrie și executa fiecare linie de cod izolat și puteți vedea rezultatele (sau un mesaj de eroare util) imediat. Și alte limbi au acest lucru, dar în cele mai multe cazuri nu în același grad ca Python.

5. Poate fi folosit atât pentru prototipare, cât și pentru codul de producție

Pe lângă faptul că este excelent pentru prototipare, Python este, de asemenea, un limbaj excelent și puternic pentru aplicații mari de producție. Unele dintre cele mai mari companii de software din lume folosesc intens Python într-o varietate de aplicații și cazuri de utilizare.

6. Vine cu „Baterie incluse:” Biblioteca standard Python

Tot ceea ce este necesar pentru operațiunile de bază este încorporat chiar în limbaj, dar în plus, biblioteca standard Python are instrumente pentru lucrul cu fișiere, media, rețele, informații despre dată și oră și multe altele. Acest lucru vă permite să îndepliniți o mare varietate de sarcini fără a fi nevoie să căutați pachete terțe.

7. Biblioteci mari terțe pentru analiză financiară

Pentru profesioniștii din domeniul finanțelor, Pandas cu obiectele sale DataFrame și Series și Numpy cu ndarray -ul său sunt calitățile de lucru ale analizei financiare cu Python. În combinație cu matplotlib și alte biblioteci de vizualizare, aveți la dispoziție instrumente excelente pentru a ajuta productivitatea.

8. Python este gratuit!

Python este dezvoltat sub o licență open source, ceea ce îl face gratuit și pentru uz comercial.

Tutorial pas cu pas despre utilizarea Python și Finance împreună

Ceea ce urmează este un tutorial pas cu pas care arată cum să creați o versiune simplificată a simulării Monte Carlo descrisă în postarea mea anterioară de blog, dar folosind Python în loc de pluginul @RISK pentru Excel.

Metodele Monte Carlo se bazează pe eșantionarea aleatorie pentru a obține rezultate numerice. O astfel de aplicație este extragerea de eșantioane aleatoare dintr-o distribuție de probabilitate reprezentând stări viitoare potențiale incerte ale lumii în care variabilele sau ipotezele pot lua o serie de valori.

Este util să faceți simularea Monte Carlo pe un model de evaluare DCF simplificat în loc de exemplele mai frecvente pe care le vedeți care arată evaluarea opțiunilor sau a altor instrumente derivate, deoarece pentru aceasta nu avem nevoie de nicio matematică în afară de elementele de bază ale calculării situațiilor financiare și reducerea fluxurilor de numerar, permițându-ne să ne concentrăm asupra conceptelor și instrumentelor Python. Vă rugăm să rețineți, totuși, că acest model de tutorial de bază este menit să ilustreze conceptele cheie și nu este util așa cum este pentru niciun scop practic. De asemenea, nu voi atinge niciunul dintre aspectele mai academice ale simulărilor Monte Carlo.

Tutorialul presupune că sunteți familiarizat cu elementele de bază ale programării, cum ar fi variabilele și funcțiile. Dacă nu, ar putea fi util să vă luați 10 minute pentru a verifica conceptele cheie, de exemplu, în această introducere.

Punctul de plecare și rezultatul dorit

Încep cu același model de evaluare DCF foarte simplificat folosit în tutorialul de simulare Monte Carlo. Are câteva elemente-cheie din cele trei situații financiare și trei celule de intrare evidențiate, care în versiunea Excel au estimări punctuale pe care acum dorim să le înlocuim cu distribuții de probabilitate pentru a începe să explorăm intervalele potențiale de rezultate.

exemplu de proiecții financiare

O abordare în doi pași pentru dezvoltarea unui scenariu mic

Faceți-l să funcționeze, faceți-l corect, faceți-l repede - Kent Beck

Intenția acestui tutorial este de a oferi profesioniștilor din domeniul finanțelor nou la Python o introducere nu numai despre cum ar putea arăta un program util, ci și o introducere în procesul iterativ pe care îl puteți utiliza pentru a-l dezvolta. Prin urmare, are două părți:

  1. În primul rând, dezvolt un prototip de lucru folosind o abordare simplă, care cred că este ușor de urmat și nu complet diferit de procesul pe care l-ar putea folosi pentru a începe acest proiect dacă ar fi să porniți de la zero.
  2. Apoi, după ce am dezvoltat prototipul de lucru, parcurg procesul de refactorizare - schimbarea structurii codului fără a-i schimba funcționalitatea. Poate doriți să rămâneți pentru acea parte - este o soluție mai elegantă decât prima și, ca bonus, este de aproximativ 75 de ori mai rapidă în ceea ce privește timpul de execuție.

1. Dezvoltarea unui prototip de lucru

Configurarea notebook-ului Jupyter

Notebook-ul Jupyter este un instrument excelent pentru a lucra cu Python în mod interactiv. Este un interpret Python interactiv cu celule care pot conține cod, text Markdown, imagini sau alte date. Pentru acest tutorial am folosit Python Quant Platform, dar pot recomanda și Colaboratory by Google, care este gratuit și rulează în cloud. Odată ajuns acolo, pur și simplu selectați „New Python 3 Notebook” în meniul „Fișier” și sunteți gata de plecare.

După ce am făcut asta, următorul pas este să importam pachetele terțe de care avem nevoie pentru manipularea și vizualizarea datelor și să spunem programului că vrem să vedem diagrame în linie în blocnotes, în loc să fie în ferestre separate:

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

O notă înainte de a începe să numim primele noastre variabile. După cum am subliniat deja, lizibilitatea este unul dintre punctele forte ale lui Python. Designul limbajului merge mult pentru a sprijini acest lucru, dar toți cei care scriu cod sunt responsabili pentru a-l face lizibil și de înțeles, nu numai pentru alții, ci și pentru ei înșiși. După cum afirmă Legea lui Eagleson, „Orice cod al tău pe care nu l-ai privit timp de șase luni sau mai multe ar fi putut la fel de bine să fi fost scris de altcineva.”

O regulă generală bună este să numiți componentele programului dvs. în așa fel încât să minimizați nevoia de comentarii separate care să explice ce face programul dvs.

Având în vedere asta, să mergem mai departe.

Intocmirea situatiilor financiare

Există multe moduri prin care putem lucra cu datele existente ale foilor de calcul în Python. Am putea, de exemplu, să citim o foaie într-un Pandas DataFrame cu o linie de cod folosind comanda read_excel . Dacă doriți o integrare mai strânsă și o legătură în timp real între foaia de calcul și codul Python, există atât opțiuni gratuite, cât și comerciale disponibile pentru a oferi această funcționalitate.

Deoarece modelul de aici este foarte simplu și pentru a ne concentra asupra conceptelor Python, îl vom recrea de la zero în scriptul nostru. La sfârșitul primei părți, voi arăta cum puteți exporta ceea ce am creat într-o foaie de calcul.

Ca prim pas spre crearea unei reprezentări Python a situațiilor financiare, vom avea nevoie de o structură de date adecvată. Există multe dintre care să alegeți, unele încorporate în Python, altele din diferite biblioteci sau ne putem crea propria noastră. Deocamdată, să folosim o serie din biblioteca Pandas pentru a ne uita la funcționalitatea acesteia:

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

Această intrare și ieșirea ei corespunzătoare sunt prezentate mai jos:

crearea unei serii dintr-o bibliotecă python

Cu primele trei linii am creat o structură de date cu un index format din ani (fiecare marcat pentru a arăta dacă este Actual, Buget sau Proiectat), o valoare de pornire (în milioane de euro, ca în modelul DCF original) și celule goale (NaN, „Nu este un număr”) pentru proiecții. A patra linie tipărește o reprezentare a datelor - în general, tastarea numelui unei variabile sau a altor obiecte în interpretul interactiv vă va oferi de obicei o reprezentare sensibilă a acesteia.

În continuare, declarăm o variabilă care reprezintă creșterea anuală a vânzărilor proiectată. În această etapă, este o estimare punctuală, aceeași cifră ca și în modelul nostru DCF original. Dorim să folosim mai întâi aceleași intrări și să confirmăm că versiunea noastră Python funcționează la fel și dă același rezultat ca și versiunea Excel, înainte de a ne uita la înlocuirea estimărilor punctuale cu distribuții de probabilitate. Folosind această variabilă, creăm o buclă care calculează vânzările în fiecare an ale proiecțiilor pe baza anului precedent și a ratei de creștere:

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

Acum avem vânzări proiectate, în loc de NaN:

python și finanțe: proiectarea cifrelor de vânzări

Folosind aceeași abordare, continuăm prin situațiile financiare, declarând variabilele pe măsură ce avem nevoie de ele și efectuând calculele necesare pentru a ajunge în cele din urmă la fluxul de numerar liber. Odată ajuns acolo putem verifica dacă ceea ce avem corespunde cu ceea ce spune versiunea Excel a modelului 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

Aceasta ne oferă fluxurile de numerar gratuite:

fluxul de numerar redus de la python

Singura linie de deasupra care poate avea nevoie de un comentariu în această etapă este a doua referință tax_payment . Aici, aplicăm o mică funcție pentru a ne asigura că, în scenariile în care profitul înainte de impozitare devine negativ, nu vom avea apoi o plată pozitivă a impozitului. Aceasta arată cât de eficient puteți aplica funcții personalizate tuturor celulelor dintr-o serie Pandas sau DataFrame. Funcția efectivă aplicată este, desigur, o simplificare. Un model mai realist pentru un exercițiu de evaluare mai amplu ar avea un model fiscal separat care calculează impozitele efective în numerar plătite pe baza unui număr de factori specifici companiei.

Efectuarea evaluării DCF

După ce am ajuns la fluxurile de numerar proiectate, acum putem calcula o valoare terminală simplă și putem reduce toate fluxurile de numerar înapoi la prezent pentru a obține rezultatul DCF. Următorul cod introduce indexarea și tăierea, ceea ce ne permite să accesăm unul sau mai multe elemente dintr-o structură de date, cum ar fi obiectul Pandas Series.

Accesăm elemente scriind paranteze drepte după numele structurii. Indexarea simplă accesează elementele după poziția lor, începând cu zero, ceea ce înseamnă că free_cash_flow[1] ne-ar oferi al doilea element. [-1] este prescurtarea pentru accesarea ultimului element (fluxul de numerar al anului trecut este folosit pentru a calcula valoarea terminală), iar folosirea punctelor două puncte ne oferă o felie, adică [1:] ne oferă toate elementele, cu excepția primului, deoarece nu dorim să includem anul istoric 2018A în evaluarea noastră 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 

ieșire dcf din calculul fluxului de numerar actualizat python

Aceasta încheie prima parte a prototipului nostru - acum avem un model DCF funcțional, deși unul foarte rudimentar, în Python.

Exportarea datelor

Înainte de a trece la simularea Monte Carlo reală, acesta ar putea fi un moment bun pentru a menționa capacitățile de export disponibile în pachetul Pandas. Dacă aveți un obiect Pandas DataFrame, îl puteți scrie într-un fișier Excel cu o singură linie folosind metoda to_excel . Există o funcționalitate similară de exportat în peste o duzină de alte formate și destinații.

 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 

exemplu de ieșire a tabelului Excel generat cu python

Crearea distribuțiilor de probabilitate pentru simularea Monte Carlo

Acum suntem gata să facem față următoarei provocări: să înlocuim unele dintre intrările de estimare punctuală cu distribuții de probabilitate. În timp ce pașii până în acest punct ar fi putut părea oarecum greoi în comparație cu construirea aceluiași model în Excel, aceste câteva rânduri vă vor oferi o privire asupra cât de puternic poate fi Python.

Primul nostru pas este să decidem câte iterații vrem să rulăm în simulare. Utilizarea 1.000 ca punct de plecare atinge un echilibru între obținerea de suficiente puncte de date pentru a obține diagrame de ieșire sensibile, față de finalizarea simulării într-un interval de timp sensibil. În continuare, generăm distribuțiile reale. De dragul simplității, am generat aici trei distribuții normale, dar biblioteca NumPy are un număr mare de distribuții din care să alegeți și există și alte locuri în care să căutați, inclusiv biblioteca standard Python. După ce am decis ce distribuție să folosim, trebuie să specificăm parametrii necesari pentru a descrie forma lor, cum ar fi media și abaterea standard și numărul de rezultate dorite.

 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() 

ieșire de simulare monte carlo din python

Aici ați putea argumenta că EBITDA nu ar trebui să fie o variabilă aleatorie separată, independentă de vânzări, ci să fie corelat cu vânzările într-o oarecare măsură. Aș fi de acord cu aceasta și aș adăuga că ar trebui să fie condusă de o înțelegere solidă a dinamicii structurii costurilor (costuri variabile, semivariabile și fixe) și a factorilor cheie ai costurilor (dintre care unele pot avea propriile distribuții de probabilitate, cum ar fi, de exemplu, prețurile mărfurilor de intrare), dar las aceste complexități deoparte aici de dragul spațiului și al clarității.

Cu cât aveți mai puține date pentru a vă informa alegerea distribuției și a parametrilor, cu atât mai mult va trebui să vă bazați pe rezultatul diferitelor fluxuri de lucru de due diligence, combinate cu experiența, pentru a forma o viziune de consens asupra gamelor de scenarii probabile. În acest exemplu, cu proiecțiile fluxului de numerar, va exista o componentă subiectivă mare, ceea ce înseamnă că vizualizarea distribuțiilor de probabilitate devine importantă. Aici, putem obține o vizualizare de bază, care arată distribuția creșterii vânzărilor, cu doar două linii scurte de cod. În acest fel, putem vizualiza rapid orice distribuție către globul ocular care reflectă cel mai bine viziunea colectivă a echipei.

Acum avem toate blocurile de care avem nevoie pentru a rula simularea, dar nu sunt într-un format convenabil pentru rularea simulării. Iată același cod cu care am lucrat până acum, dar toate adunate într-o singură celulă și rearanjate într-o funcție pentru comoditate:

 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

Acum putem rula întreaga simulare și reprezentam grafic distribuția producției, care va fi valoarea actualizată a fluxului de numerar al acestei companii în fiecare dintre cele 1.000 de iterații, cu următorul cod. Comanda %time nu este cod Python, ci o prescurtare pentru notebook care măsoară timpul necesar pentru a rula ceva (puteți folosi în schimb funcția Python din biblioteca standard). Depinde de computerul pe care îl rulați, dar această versiune are nevoie de 1-2 secunde pentru a rula cele 1.000 de iterații și a vizualiza rezultatul.

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

ieșire de simulare monte carlo din scriptul python

2. Rafinarea Prototipului

Suspiciunea la pândă că ceva ar putea fi simplificat este cea mai bogată sursă de provocări plină de satisfacții din lume. - Edsger Dijkstra

Refactorizarea se referă la procesul de rescrie a codului existent pentru a-și îmbunătăți structura fără a-i schimba funcționalitatea și poate fi unul dintre cele mai distractive și pline de satisfacții elemente de codare. Pot exista mai multe motive pentru a face acest lucru. Ar putea fi:

  1. Organizați diferitele părți într-un mod mai sensibil.
  2. Redenumiți variabilele și funcțiile pentru a le clarifica scopul și funcționarea.
  3. Permiteți și pregătiți-vă pentru funcțiile viitoare.
  4. Îmbunătățiți viteza de execuție, amprenta memoriei sau utilizarea altor resurse.

Pentru a arăta cum ar putea arăta un pas din acel proces, am curățat prototipul pe care tocmai l-am parcurs, colectând toate variabilele inițiale într-un singur loc, mai degrabă decât împrăștiate în întregime ca în scriptul prototipului și i-am optimizat viteza de execuție printr-un proces numit vectorizare .

Utilizarea matricelor NumPy vă permite să exprimați multe tipuri de sarcini de procesare a datelor ca expresii matrice concise care altfel ar putea necesita bucle de scriere. Această practică de înlocuire a buclelor explicite cu expresii matrice este denumită în mod obișnuit vectorizare. Wes McKinney

Acum pare mai curat și mai ușor de înțeles:

 # 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

Principala diferență pe care o veți observa între această versiune și cea anterioară este absența buclei for i in range(iterations) . Folosind operația de matrice NumPy, această versiune rulează în 18 milisecunde, comparativ cu 1,35 secunde pentru versiunea prototip - de aproximativ 75 de ori mai rapid.

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

Exemplu de operație cu matrice NumPy

Sunt sigur că o optimizare suplimentară este posibilă, deoarece am pus împreună atât versiunea prototip, cât și versiunea rafinată într-un timp scurt, exclusiv în scopul acestui tutorial.

Ducând-o mai departe

Acest tutorial a arătat câteva dintre caracteristicile puternice ale Python și, dacă ar fi să dezvoltați acest lucru în continuare, oportunitățile sunt aproape nesfârșite. Ai putea de exemplu:

  • Răzuiți sau descărcați statistici relevante ale companiei sau sectorului de pe paginile web sau din alte surse de date, pentru a vă ajuta să vă informați alegerea de ipoteze și distribuții de probabilitate.
  • Utilizați Python în aplicații financiare cantitative, cum ar fi un algoritm de tranzacționare automat bazat pe factori fundamentali și/sau macroeconomici.
  • Construiți capabilități de export care generează rezultate într-o foaie de calcul și/sau format de prezentare, pentru a fi utilizate ca parte a procesului intern de revizuire și aprobare a tranzacțiilor sau pentru prezentări externe.

Nici măcar nu am atins ce ați putea face cu diferitele aplicații web, știința datelor și învățare automată care au contribuit la succesul Python.

În rezumat: un limbaj util pentru setul dvs. de instrumente financiare

Acest articol a oferit o introducere în limbajul de programare Python, a enumerat câteva dintre motivele pentru care a devenit atât de popular în finanțe și a arătat cum să construiți un mic script Python. Într-un tutorial pas cu pas, am explicat modul în care Python poate fi utilizat pentru prototipuri iterative, analiză financiară interactivă și pentru codul de aplicație pentru modele de evaluare, programe de tranzacționare algoritmică și multe altele.

Pentru mine, la sfârșitul zilei, caracteristica ucigașă a tehnologiei Python este că este pur și simplu distractiv să lucrezi! Dacă vă place să rezolvați probleme, să construiți lucruri și să faceți fluxurile de lucru mai eficiente, atunci vă încurajez să îl încercați. Mi-ar plăcea să aud ce ați făcut cu el sau ați dori să faceți cu el.

Resurse recomandate pentru profesioniștii din finanțe pentru a învăța Python

  • Cărțile O'Reilly. Pot recomanda in special:
    • Python for Finance by Yves Hilpisch
    • Learning Python by Mark Lutz
    • Fluent Python by Luciano Ramalho
  • The Python Quants
  • PyCon talks on YouTube
  • Udemy