Python og finans – Styrk dine regneark

Sammendrag

Hvorfor er Python et fantastisk programmeringssprog for finansprofessionelle at lære?
  • Python er et programmeringssprog på højt niveau, hvilket betyder, at det abstraherer og håndterer mange af de tekniske aspekter af programmering, såsom hukommelseshåndtering, som eksplicit skal håndteres på andre sprog. Dette gør Python nem at bruge for dem uden teknisk baggrund.
  • Fordi sproget er designet med læsbarhed og brugervenlighed i tankerne, er det et af de nemmeste sprog at lære. Python-koden er kortfattet og tæt på almindeligt engelsk.
  • Python er ideel til prototyping og hurtig, iterativ udvikling. Dens interaktive tolkeværktøjer giver miljøer, hvor du kan skrive og udføre hver linje kode isoleret og se resultaterne med det samme.
  • Samtidig er Python robust og ydeevne, hvilket gør det til et levedygtigt valg også for kernesystemer og større applikationer.
  • Ud over sit store standardbibliotek med nyttige værktøjer har Python fantastiske tredjepartsbiblioteker til finansiel analyse og databehandling, såsom Pandas- og NumPy-bibliotekerne, der bruges i denne øvelse.
Hvad er nogle use-cases til at implementere Python og finans sammen?
  • Python-scripts kan bruges til at automatisere gentagne opgaver og arbejdsgange, hvilket sparer tid og reducerer risikoen for manuelle fejl.
  • Scripts giver brugerne mulighed for nemt at trække data fra regneark, databaser og API'er eller endda skrabe webdata, som derefter kan behandles og analyseres ved hjælp af kraftfulde statistiske og analytiske værktøjer.
  • Forskellige plugins til Excel giver brugerne mulighed for at oprette tovejslinks i realtid mellem dine regneark og Python-kode.
  • Python muliggør nye typer analyser, såsom Monte Carlo-simuleringer, som ikke er let tilgængelige i standardregneark.
  • Algorithmisk handel er ikke længere det eksklusive domæne for hedgefonde og store investeringsbanker. Med Python kan du udvikle, backteste og implementere dine egne handelsstrategier på kort tid og til en lav pris.

For erhverv, der længe har været afhængige af at trawle gennem regneark, er Python særligt værdifuldt. Citigroup, en amerikansk bank, har introduceret et lynkursus i Python for sine analytikere. - The Economist

Finansprofessionelle har længe haft adgang til VBA (Visual Basic for Applications) i Excel for at opbygge tilpasset funktionalitet og automatisere arbejdsgange. Med fremkomsten i de senere år af Google Sheets som en seriøs udfordrer på regnearksområdet, tilbyder Google Apps Script nu et ekstra valg.

Jeg vil dog gerne henlede opmærksomheden på en tredje mulighed, Python-programmeringssproget, som er blevet enormt populært på en række områder.

I denne artikel vil jeg give nogle eksempler på, hvad du kan opnå med Python, begyndende med et overblik over selve sproget, og hvorfor det er blevet så populært inden for så mange forskellige områder, lige på tværs af webudvikling, maskinlæring, økonomi, videnskab og uddannelse, for blot at nævne nogle få. Anden halvdel vil så bestå af en trin-for-trin vejledning.

Målet med, at jeg skriver dette, er at hjælpe dig med at beslutte, om Python ser spændende nok ud til, at du kan overveje at tilføje det til din økonomiske værktøjskasse. Hvis du tager springet, er der mange apps, kurser, videoer, artikler, bøger og blogindlæg tilgængelige for at lære sproget. I slutningen af ​​stykket har jeg listet nogle ressourcer, der har hjulpet mig på vej.

Use Cases:Eksempler på, hvad jeg har brugt Python til

Min introduktion til programmering var at lære BASIC på en Oric 1 i midten af ​​1980'erne. Dengang BASIC var det mest almindelige begyndersprog. Andre sprog, som jeg dyttede med i slutningen af ​​80'erne indtil midten af ​​90'erne, var Pascal og C, men jeg brugte dem aldrig i nogen professionel kapacitet, og jeg forventede ikke at skulle bruge eller bruge programmeringsevner. Så vidt jeg ved dengang i slutningen af ​​90'erne, var økonomi og programmering meget forskellige områder, da jeg valgte at gå i gang med en karriere inden for finans.

Spol frem til 2012, og jeg søgte at vælge programmering tilbage som en hobby, så jeg begyndte at undersøge de sprog, der var tilgængelige på det tidspunkt. Det viste sig, at der var sket en del, og da jeg stødte på Python, blev jeg hooked, af mange af de grunde, som jeg vil skitsere i næste afsnit. Siden da har jeg brugt Python til en lang række opgaver, fra små scripts til større projekter, både personligt og professionelt. Mange, men ikke alle, har involveret regneark, arbejdsbordet for mange finansprofessionelle.

Her er et par eksempler på, hvor godt regneark og Python kan gå sammen:

1. Sporing af hundredvis af aktiviteter over tid i en M&A-integrations-PMO-opsætning

Jeg arbejder med alle aspekter af M&A transaktioner, ikke kun udførelsen, men også integrationen. I en nylig sag besluttede PMO-teamet sig for en hybrid program- og projektledelsestilgang ved at bruge vandfaldsplanlægning og Gantt-diagrammer til planer på højt niveau for hver af de tolv integrationsarbejdsstrømme, foruden en Kanban-tavle til sporing af de hundredvis af aktiviteter, der foregår. på til enhver tid, i den første 100-dages plan og derefter. Kanban-værktøjet, der blev valgt, MeisterTask, har en række statistiske og rapporteringsfunktioner, men vores behov gik ud over det med hensyn til analyse og præsentation, hvilket krævede en tilpasset løsning. Dette er arbejdsgangen, som jeg automatiserede ved hjælp af Python:

  1. Gem status for hele bestyrelsen ugentligt som en CSV-fil.
  2. Læs alle historiske CSV-filer i en Pandas DataFrame.
  3. Sorter, filtrer, grupper og manipuler dataene til aftalte formater for, hvordan vi ønsker at spore fremskridt (efter status for aktivitet, arbejdsstrøm osv.).
  4. Skriv outputtet til en Excel-fil med dataene fra hver analyse i sit eget ark, formateret på en sådan måde, at det nemt kan kopieres og indsættes i tænkecellediagrammer.
  5. Opret tabeller og diagrammer til rapporteringspakken til det månedlige styregruppemøde.

Udvikling af scriptet krævede en forudgående investering på et par timer, men nu tager det kun få minutter at opdatere rapporteringspakken til styregruppemøder eller ad hoc-analyser. Bogstaveligt talt omkring 30 sekunder til at gå til den rigtige mappe og køre scriptet med en kommando på én linje, og derefter et par minutter til at kopiere og indsætte outputtet i slide-dækket. Med omkring 500 aktiviteter (kort) på tværs af tolv arbejdsstrømme, der allerede er omkring en måned til udførelse, ugentlig sporing af, hvordan de bevæger sig, inden for en programtidslinje på to år, finder du hurtigt ud af, at du har at gøre med tusinder og til sidst titusindvis af datapunkter på tværs af snesevis af filer. Uden automatisering taler vi om nogle meget kedelige opgaver her.

"Tidsværdien af ​​penge"-afvejningen mellem bare at komme videre med tingene eller tilføje mere indledende arbejdsbyrde ved at opsætte automatisering er et almindeligt tema inden for økonomi. Jeg tog en lignende beslutning med det første trin i denne proces, ved at eksportere dataene som CSV-filer. MeisterTask har, ligesom mange moderne webapplikationer, en API, som kan forbindes til din Python-applikation, men den tid, der bruges på at opsætte den, ville langt opveje tidsbesparelsen for vores use case her.

Så som du kan se, er den optimale løsning ofte at automatisere visse trin i en arbejdsgang og holde andre manuelle.

2. Analyse af husprisstatistikker ved hjælp af Web Scraping, Google Maps API og Excel

Et andet eksempel er noget, jeg gjorde af personlig interesse, men jeg vil fremhæve det, fordi det indeholder nogle andre interessante elementer af Pythons værktøj:

  1. Skrap data fra ejendomsoversigter, inklusive adresse, størrelse, antal værelser, udbudspris og andre funktioner, for et givet område; et par hundrede til måske tusind linjer i alt.
  2. Gem i en Python-datastruktur.
  3. Opret forbindelse til Google Maps API, og hent for hver fortegnelse afstanden mellem ejendommen og vigtige vartegn, såsom havet, byens centrum, nærmeste togstation, nærmeste lufthavn osv.
  4. Eksporter dataene til en Excel-fil.
  5. Brug standard Excel-funktionalitet til at køre regressioner, beregne statistik og oprette diagrammer på standardmålinger såsom pris pr. kvadratmeter og afstand til vartegn.

Resultaterne her kan kombineres med dine egne personlige vægtninger i form af præferencer og økonomiske begrænsninger, når du leder efter fast ejendom.

Dette er kun to eksempler, der fokuserer på at automatisere regnearksrelateret arbejde og tilføje funktioner, men mulighederne med Python er næsten uendelige. I det næste afsnit vil jeg skitsere årsagerne til, at det er blevet så populært, før jeg går videre til en trin-for-trin Monte Carlo-simuleringsvejledning i Python.

Hvorfor Python er et godt valg for finansprofessionelle

Programmeringssproget Python har eksisteret siden 1990, men det er først de seneste år, at dets popularitet er eksploderet.

Der er flere grunde til dette, lad os se på hver efter tur.

1. Python er et programmeringssprog på højt niveau

Et programmeringssprog på højt niveau er et, der abstraherer mange af detaljerne i computerens indre funktioner. Et godt eksempel er hukommelseshåndtering. Programmeringssprog på lavere niveau kræver en detaljeret forståelse af kompleksiteten af, hvordan computerens hukommelse er lagt ud, allokeret og frigivet, foruden den tid, der bruges og de kodelinjer, der kræves for at håndtere opgaver. Python abstraherer og håndterer mange af disse detaljer automatisk, så du kan fokusere på det, du ønsker at opnå.

2. Det er kortfattet

Fordi Python er et programmeringssprog på højt niveau, er koden mere kortfattet og næsten udelukkende fokuseret på forretningslogikken i det, du ønsker at opnå, snarere end tekniske implementeringsdetaljer. Valg af sprogdesign bidrager til dette:Som et eksempel kræver Python ikke brugen af ​​krøllede seler eller semikolon til at afgrænse funktioner, sløjfer og linjer, som mange andre sprog gør, hvilket gør det mere kortfattet og, som nogle hævder, forbedrer læsbarhed.

3. Let at lære og forstå

En observation, der har påvirket valg af sprogdesign i Python, er, at programmer læses oftere, end de er skrevet. Python udmærker sig her, da dens kode ser meget tæt på almindeligt engelsk, især hvis du navngiver de forskellige komponenter i dit script eller program på en fornuftig måde.

4. Velegnet til hurtig, iterativ udvikling

Oplyst trial and error overgår planlægningen af ​​fejlfrie intellekter. - David Kelley

Python er ideel til prototyping og hurtig, iterativ udvikling (og ja, prøv-og-fejl), fordi interaktive tolkeværktøjer såsom Python-skallen, IPython og Jupyter-notebooks er forreste og centrale i Python-værktøjskæden. I disse interaktive miljøer kan du skrive og udføre hver linje kode isoleret og se resultaterne (eller en nyttig fejlmeddelelse) med det samme. Andre sprog har dette også, men i de fleste tilfælde ikke i samme grad som Python.

5. Kan bruges både til prototyping og produktionskode

Ud over at være fantastisk til prototyping er Python også et fremragende og kraftfuldt sprog til store produktionsapplikationer. Nogle af de største softwarevirksomheder i verden gør stor brug af Python i en række forskellige applikationer og brugssager.

6. Leveres med "Batterier inkluderet:" Python Standard Library

Alt, hvad der er nødvendigt til grundlæggende operationer, er indbygget direkte i sproget, men derudover har Python-standardbiblioteket værktøjer til at arbejde med filer, medier, netværk, dato- og tidsinformation og meget mere. Dette giver dig mulighed for at udføre en lang række opgaver uden at skulle lede efter tredjepartspakker.

7. Fantastiske tredjepartsbiblioteker til finansiel analyse

For finansprofessionelle, Pandas med sin DataFrame og Serie objekter og Numpy med dens ndarray er arbejdshestene i økonomisk analyse med Python. Kombineret med matplotlib og andre visualiseringsbiblioteker har du fantastiske værktøjer til din rådighed for at hjælpe produktiviteten.

8. Python er gratis!

Python er udviklet under en open source-licens, hvilket gør den gratis også til kommerciel brug.

Trin-for-trin vejledning i at bruge Python og Finance sammen

Det følgende er en trin-for-trin vejledning, der viser, hvordan man opretter en forenklet version af Monte Carlo-simuleringen beskrevet i mit tidligere blogindlæg, men ved at bruge Python i stedet for @RISK-plugin til Excel.

Monte Carlo metoder er afhængige af tilfældige stikprøver for at opnå numeriske resultater. En sådan applikation er at trække tilfældige stikprøver fra en sandsynlighedsfordeling, der repræsenterer usikre potentielle fremtidige tilstande i verden, hvor variabler eller antagelser kan antage en række værdier.

Det er nyttigt at lave Monte Carlo-simuleringen på en forenklet DCF-værdiansættelsesmodel i stedet for de mere almindelige eksempler, du ser, der viser værdiansættelse af optioner eller andre derivater, da vi ikke har brug for nogen matematik ud over det grundlæggende i beregning af regnskaber og diskontering af pengestrømme, så vi kan fokusere på Python-koncepterne og værktøjerne. Bemærk dog, at denne grundlæggende selvstudiemodel er beregnet til at illustrere nøglebegreberne og ikke er nyttig, som den er, til praktiske formål. Jeg vil heller ikke komme ind på nogen af ​​de mere akademiske aspekter af Monte Carlo-simuleringer.

Selvstudiet forudsætter, at du er fortrolig med de grundlæggende byggeklodser i programmering, såsom variabler og funktioner. Hvis ikke, kan det være nyttigt at bruge 10 minutter på at tjekke nøglebegreberne i f.eks. denne introduktion.

Udgangspunktet og det ønskede resultat

Jeg starter med den samme meget forenklede DCF-vurderingsmodel, der blev brugt i Monte Carlo-simuleringsvejledningen. Den har nogle centrale linjeposter fra de tre regnskaber og tre fremhævede inputceller, som i Excel-versionen har punktestimater, som vi nu ønsker at erstatte med sandsynlighedsfordelinger for at begynde at udforske potentielle udfaldsområder.

En to-trins tilgang til udvikling af et lille script

Få det til at fungere, gør det rigtigt, gør det hurtigt - Kent Beck

Hensigten med denne tutorial er at give finansprofessionelle nye til Python en introduktion ikke kun til, hvordan et nyttigt program kan se ud, men også en introduktion til den iterative proces, du kan bruge til at udvikle det. Den har derfor to dele:

  1. For det første udvikler jeg en fungerende prototype ved hjælp af en ligetil tilgang, som jeg synes er nem at følge og ikke helt ulig den proces, man kunne bruge til at starte dette projekt, hvis man skulle starte fra bunden.
  2. Derefter, efter at have udviklet den fungerende prototype, går jeg gennem processen med refaktorering - ændring af kodens struktur uden at ændre dens funktionalitet. Du vil måske blive ved med den del - det er en mere elegant løsning end den første, og som en bonus er den omkring 75 gange hurtigere med hensyn til udførelsestid.

1. Udvikling af en fungerende prototype

Opsætning af Jupyter Notebook

Jupyter-notesbogen er et fantastisk værktøj til at arbejde med Python interaktivt. Det er en interaktiv Python-fortolker med celler, der kan indeholde kode, Markdown-tekst, billeder eller andre data. Til denne tutorial brugte jeg Python Quant Platform, men jeg kan også anbefale Colaboratory by Google, som er gratis og kører i skyen. Når du er der, skal du blot vælge "Ny Python 3 Notebook" i menuen "Filer", og du er klar til at gå.

Når du har gjort det, er næste trin at importere de tredjepartspakker, vi har brug for til datamanipulation og visualiseringer, og fortælle programmet, at vi ønsker at se diagrammer inline i vores notesbog, i stedet for i separate vinduer:

importer numpy som npimport pandaer som pdimport matplotlib.pyplot som plt%matplotlib inline 

En note før vi begynder at navngive vores første variable. Som jeg allerede har fremhævet, er læsbarhed en af ​​Pythons styrker. Sprogdesign understøtter i høj grad det, men alle, der skriver kode, er ansvarlige for at gøre den læsbar og forståelig, ikke kun for andre, men også for sig selv. Som Eaglesons lov siger:"Enhver egen kode, som du ikke har kigget på i seks eller flere måneder, kan lige så godt være skrevet af en anden."

En god tommelfingerregel er at navngive komponenterne i dit program på en sådan måde, at du minimerer behovet for separate kommentarer, der forklarer, hvad dit program gør.

Med det i tankerne, lad os gå videre.

Oprettelse af årsregnskabet

Der er mange måder, hvorpå vi kan arbejde med eksisterende regnearksdata i Python. Vi kunne for eksempel læse et ark ind i en Pandas DataFrame med en linje kode ved hjælp af read_excel kommando. Hvis du ønsker en tættere integration og realtidslink mellem dit regneark og Python-kode, er der både gratis og kommercielle muligheder for at levere denne funktionalitet.

Da modellen her er meget enkel, og for at fokusere os på Python-koncepterne, vil vi genskabe den fra bunden i vores script. I slutningen af ​​første del vil jeg vise, hvordan du kan eksportere det, vi har lavet, til et regneark.

Som et første skridt mod at skabe en Python-repræsentation af regnskabet, har vi brug for en passende datastruktur. Der er mange at vælge imellem, nogle indbygget i Python, andre fra forskellige biblioteker, eller vi kan lave vores eget. Lad os indtil videre bruge en serie fra Pandas-biblioteket til at se på dens funktionalitet:

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

Dette input og dets tilsvarende output er vist nedenfor:

Med de første tre linjer har vi lavet en datastruktur med et indeks bestående af år (hver markeret for at vise, om det er Faktisk, Budget eller Projekteret), en startværdi (i millioner af euro, som i den oprindelige DCF-model) og tomme (NaN, "Not a Number") celler for projektionerne. Den fjerde linje udskriver en repræsentation af dataene - generelt vil det at skrive navnet på en variabel eller andre objekter i den interaktive fortolker give dig en fornuftig repræsentation af det.

Dernæst erklærer vi en variabel, der repræsenterer den forventede årlige salgsvækst. På dette stadium er det et punktestimat, det samme tal som i vores originale DCF-model. Vi vil først bruge de samme input og bekræfte, at vores Python-version udfører det samme og giver det samme resultat som Excel-versionen, før vi ser på at erstatte punktestimater med sandsynlighedsfordelinger. Ved hjælp af denne variabel opretter vi en løkke, der beregner salget i hvert år af fremskrivningerne baseret på det foregående år og vækstraten:

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

Vi har nu forventet salg i stedet for NaN:

Ved at bruge samme tilgang fortsætter vi gennem regnskabet, deklarerer variabler, efterhånden som vi har brug for dem, og udfører de nødvendige beregninger for til sidst at nå frem til frit cash flow. Når vi når dertil, kan vi kontrollere, at det, vi har, svarer til, hvad Excel-versionen af ​​DCF-modellen siger.

ebitda_margin =0,14depr_percent =0,032ebitda =sales * ebitda_margindepreciation =sales * depr_percentebit =ebitda - depreciationnwc_percent =0,24nwc =sales * nwc_percentcshift =exprcent cap ncrct =expct cap ncrct. )tax_rate =0,25tax_payment =-ebit * tax_ratetax_payment =tax_payment.apply(lambda x:min(x, 0))free_cash_flow =ebit + afskrivning + tax_payment + capex + change_in_nwcfree_cash_flow 

Dette giver os de frie pengestrømme:

Den ene linje ovenfor, der måske kræver en kommentar på dette stadium, er den anden tax_payment reference. Her anvender vi en lille funktion for at sikre, at vi i scenarier, hvor resultatet før skat bliver negativt, så ikke får en positiv skattebetaling. Dette viser, hvor effektivt du kan anvende brugerdefinerede funktioner til alle celler i en Pandas Series eller DataFrame. Selve den anvendte funktion er naturligvis en forenkling. En mere realistisk model for en større værdiansættelsesøvelse ville have en separat skattemodel, der beregner faktisk betalte kontante skatter baseret på en række virksomhedsspecifikke faktorer.

Udførelse af DCF-vurderingen

Når vi er nået frem til forventede pengestrømme, kan vi nu beregne en simpel terminalværdi og diskontere alle pengestrømme tilbage til nutiden for at få DCF-resultatet. Følgende kode introducerer indeksering og udsnit, som giver os adgang til et eller flere elementer i en datastruktur, såsom Pandas Series-objektet.

Vi får adgang til elementer ved at skrive firkantede parenteser direkte efter navnet på strukturen. Simpel indeksering får adgang til elementer efter deres position, startende med nul, hvilket betyder at free_cash_flow[1] ville give os det andet element. [-1] er en forkortelse for at få adgang til det sidste element (det sidste års pengestrøm bruges til at beregne terminalværdien), og brug af et kolon giver os et udsnit, hvilket betyder at [1:] giver os alle elementer undtagen det første, da vi ikke ønsker at inkludere det historiske år 2018A i vores DCF-vurdering.

cost_of_capital =0,12terminal_growth =0,02terminal_value =((free_cash_flow[-1] * (1 + terminal_growth)) / (cost_of_capital - terminal_growth))rabat_faktorer =[(1 / (1 + cost_of_**ital) for i i området (1,6)]dcf_value =(sum(free_cash_flow[1:] * discount_factors) + terminal_value * discount_factors[-1])dcf_value 

Det afslutter den første del af vores prototype - vi har nu en fungerende DCF-model, omend en meget rudimentær, i Python.

Eksport af dataene

Før du går videre til den faktiske Monte Carlo-simulering, kan dette være et godt tidspunkt at nævne de eksportmuligheder, der er tilgængelige i Pandas-pakken. Hvis du har et Pandas DataFrame-objekt, kan du skrive det til en Excel-fil med én linje ved hjælp af to_excel metode. Der er lignende funktionalitet til at eksportere til mere end et dusin andre formater og destinationer også.

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 

Oprettelse af sandsynlighedsfordelinger til vores Monte Carlo-simulering

Nu er vi klar til at tackle den næste udfordring:at erstatte nogle af punktestimatinput med sandsynlighedsfordelinger. Selvom trinene op til dette punkt kan have virket noget besværlige sammenlignet med at bygge den samme model i Excel, vil disse næste par linjer give dig et indblik i, hvor kraftfuld Python kan være.

Vores første skridt er at beslutte, hvor mange iterationer vi vil køre i simuleringen. Brug af 1.000 som udgangspunkt skaber en balance mellem at få nok datapunkter til at få fornuftige outputplot, kontra at få simuleringen færdig inden for en fornuftig tidsramme. Dernæst genererer vi de faktiske distributioner. For nemheds skyld genererede jeg tre normaldistributioner her, men NumPy-biblioteket har et stort antal distributioner at vælge imellem, og der er også andre steder at kigge efter, inklusive Python-standardbiblioteket. Efter at have besluttet, hvilken fordeling der skal bruges, skal vi specificere de parametre, der kræves for at beskrive deres form, såsom middelværdi og standardafvigelse og antallet af ønskede resultater.

iterations =1000sales_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 =np.random.normal(loc=0,24, scale=0,01, size=iterations)plt.hist(sales_growth_dist, bins=20)plt.show() 

Her kan man argumentere for, at EBITDA ikke skal være en separat tilfældig variabel uafhængig af salget, men i stedet korreleret med salget til en vis grad. Jeg er enig i dette og tilføjer, at det bør være drevet af en solid forståelse af dynamikken i omkostningsstrukturen (variable, semi-variable og faste omkostninger) og de vigtigste omkostningsdrivere (hvoraf nogle kan have deres egne sandsynlighedsfordelinger, som f.eks. råvarepriser), men jeg lader disse kompleksiteter ligge til side her for pladsens og klarhedens skyld.

Jo færre data du har til at informere om dit valg af distribution og parametre, jo mere bliver du nødt til at stole på resultatet af dine forskellige due diligence-arbejdsstrømme, kombineret med erfaring, for at danne et konsensussyn på rækker af sandsynlige scenarier. I dette eksempel vil der med pengestrømsfremskrivninger være en stor subjektiv komponent, hvilket betyder, at visualisering af sandsynlighedsfordelingerne bliver vigtig. Her kan vi få en grundlæggende visualisering, der viser salgsvækstfordelingen, med kun to korte linjer kode. På denne måde kan vi hurtigt se enhver distribution til øjeæble, der bedst afspejler holdets kollektive syn.

Nu har vi alle de byggeklodser, vi skal bruge for at køre simuleringen, men de er ikke i et praktisk format til at køre simuleringen. Her er den samme kode, som vi hidtil har arbejdet med, men alt samlet i én celle og omarrangeret til en funktion for nemheds skyld:

def run_mcs():# Opret sandsynlighedsfordelinger 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 , størrelse=iterationer) nwc_percent_dist =np.random.normal(loc=0,24, skala=0,01, størrelse=iterationer) # Beregn DCF-værdi for hvert sæt tilfældige input output_distribution =[] for i i område(iterationer):for år i interval(1, 6):salg[år] =salg[år - 1] * (1 + salgsvækst_dist[0]) ebitda =salg * ebitda_margin_dist[i] afskrivning =(salg * afskr_procent) ebit =ebitda - afskrivning nwc =salg * nwc_percent_dist[i] change_in_nwc =nwc.shift(1) - nwc capex =-(salg * capex_percent) tax_payment =-ebit * tax_rate tax_payment =tax_payment.apply(lambda x:min(x, 0)) freeciebit +_cash + tax_payment + capex + change_in_nwc # DCF-vurderingstermina l_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 i området (1,6)] dcf_value =sum(free_cash_flow[1:] * discount_factors ) output_distribution.append(dcf_value) return output_distribution 

Vi kan nu køre hele simuleringen og plotte outputfordelingen, som vil være den diskonterede pengestrømsværdi for denne virksomhed i hver af de 1.000 iterationer, med følgende kode. %time kommandoen er ikke Python-kode, men en notebook-stenografi, der måler tiden til at køre noget (du kan i stedet bruge Python-funktionen fra standardbiblioteket). Det afhænger af den computer, du kører den på, men denne version har brug for 1-2 sekunder for at køre de 1.000 iterationer og visualisere resultatet.

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

2. Forfining af prototypen

Den lurende mistanke om, at noget kunne forenkles, er verdens rigeste kilde til givende udfordringer. - Edsger Dijkstra

Refactoring refererer til processen med at omskrive eksisterende kode for at forbedre dens struktur uden at ændre dens funktionalitet, og det kan være et af de sjoveste og mest givende elementer ved kodning. Der kan være flere grunde til at gøre dette. Det kan være at:

  1. Organiser de forskellige dele på en mere fornuftig måde.
  2. Omdøb variabler og funktioner for at gøre deres formål og funktion tydeligere.
  3. Tillad og forbered dig på fremtidige funktioner.
  4. Forbedre udførelseshastigheden, hukommelsesfodaftrykket eller anden ressourceudnyttelse.

For at vise, hvordan et trin i den proces kunne se ud, ryddede jeg op i prototypen, som vi lige gik igennem, ved at samle alle indledende variabler ét sted i stedet for spredt ud over det som i prototypescriptet, og optimerede dens udførelseshastighed gennem en proces kaldet vektorisering .

Brug af NumPy-arrays giver dig mulighed for at udtrykke mange slags databehandlingsopgaver som kortfattede array-udtryk, der ellers kunne kræve skrivningsløkker. Denne praksis med at erstatte eksplicitte loops med array-udtryk omtales almindeligvis som vektorisering. Wes McKinney

Det ser nu renere ud og lettere at forstå:

meget =0.02nwc_std_dev =0.01
def run_mcs():# Generer sandsynlighedsfordelinger sales_growth_dist =np.random.normal(loc=sales_growth, scale=sales_std_dev, size=(år, iterationer)) ebitda_margin_dist =np.random.da_normal(loc=ebit , scale=ebitda_std_dev, size=(år, iterationer)) nwc_percent_dist =np.random.normal(loc=nwc_percent, scale=nwc_std_dev, size=(år, iterationer)) # Beregn frit cash flow sales_growth_dist in range 1 for i +=(1, len(sales_growth_dist)):sales_growth_dist[i] *=sales_growth_dist[i-1] sales =sales_growth_dist * start_sales ebitda =sales * ebitda_margin_dist ebit =ebitda - (sales * tax depr -_percent )pr. clip(tax, a_min=Ingen, a_max=0) nwc =nwc_perce nt_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 

The main difference you will notice between this version and the previous one is the absence of the for i in range(iterations) loop. Using NumPy’s array operation, this version runs in 18 milliseconds compared to the 1.35 seconds for the prototype version - roughly 75x faster.

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

I’m sure that further optimization is possible, since I put together both the prototype and refined version in a short time solely for the purpose of this tutorial.

Taking it Further

This tutorial showed some of the powerful features of Python, and if you were to develop this further the opportunities are almost endless. You could for example:

  • Scrape or download relevant company or sector statistics from web pages or other data sources, to help inform your choice of assumptions and probability distributions.
  • Use Python in quantitative finance applications, such as in an automated trading algorithm based on fundamental and/or macroeconomic factors.
  • Build exporting capabilities that generate output in a spreadsheet and/or presentation format, to be used as part of your internal transaction review and approval process, or for external presentations.

I haven’t even touched upon what you could also do with the various web, data science, and machine learning applications that have contributed to Python’s success.

In Summary:A Useful Language for Your Financial Toolbox

This article gave an introduction to the Python programming language, listed some of the reasons why it has become so popular in finance and showed how to build a small Python script. In a step-by-step tutorial, I walked through how Python can be used for iterative prototyping, interactive financial analysis, and for application code for valuation models, algorithmic trading programs and more.

For me, at the end of the day, the killer feature of Python technology is that it is simply fun to work with! If you enjoy problem-solving, building things and making workflows more efficient, then I encourage you to try it out. I would love to hear what you have done with it or would like to do with it.

  • O’Reilly books. I can especially recommend:
    • Python for Finance by Yves Hilpisch
    • Learning Python by Mark Lutz
    • Fluent Python by Luciano Ramalho
  • The Python Quants
  • PyCon talks on YouTube
  • Udemy

Virksomhedsfinansiering
  1. Regnskab
  2. Forretningsstrategi
  3. Forretning
  4. Administration af kunderelationer
  5. finansiere
  6. Lagerstyring
  7. Personlig økonomi
  8. investere
  9. Virksomhedsfinansiering
  10. budget
  11. Opsparing
  12. forsikring
  13. gæld
  14. gå på pension