Python과 금융 – 스프레드시트를 강화하세요

경영진 요약

Python이 재무 전문가가 배울 수 있는 훌륭한 프로그래밍 언어인 이유는 무엇입니까?
  • Python은 고급 프로그래밍 언어입니다. 즉, 다른 언어에서 명시적으로 처리해야 하는 메모리 관리와 같은 프로그래밍의 많은 기술적 측면을 추상화하고 처리합니다. 따라서 기술적 배경이 없는 사람들도 Python을 쉽게 사용할 수 있습니다.
  • 가독성과 사용 편의성을 염두에 두고 설계되었기 때문에 가장 배우기 쉬운 언어 중 하나입니다. Python 코드는 간결하고 일반 영어에 가깝습니다.
  • Python은 프로토타이핑과 신속하고 반복적인 개발에 이상적입니다. 인터랙티브 인터프리터 도구는 각 코드 줄을 별도로 작성 및 실행하고 결과를 즉시 확인할 수 있는 환경을 제공합니다.
  • 동시에 Python은 강력하고 성능이 뛰어나 핵심 시스템 및 대규모 애플리케이션에서도 실행 가능한 선택입니다.
  • Python에는 유용한 도구의 대규모 표준 라이브러리 외에도 이 튜토리얼에서 사용된 Pandas 및 NumPy 라이브러리와 같은 재무 분석 및 컴퓨팅을 위한 훌륭한 타사 라이브러리가 있습니다.
Python과 금융을 함께 구현하기 위한 몇 가지 사용 사례는 무엇입니까?
  • Python 스크립트는 반복적인 작업과 워크플로를 자동화하여 시간을 절약하고 수동 오류의 위험을 줄이는 데 사용할 수 있습니다.
  • 스크립트를 사용하면 스프레드시트, 데이터베이스 및 API에서 데이터를 쉽게 가져오거나 웹 데이터를 스크랩할 수도 있습니다. 그런 다음 강력한 통계 및 분석 도구를 사용하여 처리 및 분석할 수 있습니다.
  • 다양한 Excel용 플러그인을 사용하면 스프레드시트와 Python 코드 간에 실시간 양방향 링크를 만들 수 있습니다.
  • Python을 사용하면 표준 스프레드시트에서는 쉽게 사용할 수 없는 Monte Carlo 시뮬레이션과 같은 새로운 유형의 분석이 가능합니다.
  • 알고리즘 거래는 더 이상 헤지펀드와 대형 투자은행의 전유물이 아닙니다. Python을 사용하면 짧은 시간에 저렴한 비용으로 자신의 거래 전략을 개발, 백테스트 및 배포할 수 있습니다.
<블록 인용>

오랫동안 스프레드시트를 통한 트롤링에 의존해 온 직업의 경우 Python이 특히 유용합니다. 미국 은행인 씨티그룹(Citigroup)은 연수생 분석가를 위해 파이썬 집중 과정을 도입했습니다. - 이코노미스트

재무 전문가는 오랫동안 Excel의 VBA(Visual Basic for Applications)에 액세스하여 사용자 지정 기능을 구축하고 워크플로를 자동화했습니다. 최근 몇 년 동안 스프레드시트 분야에서 진지한 경쟁자로 Google 스프레드시트가 등장하면서 Google Apps Script는 이제 추가 선택을 제공합니다.

그러나 여러 분야에서 엄청난 인기를 얻고 있는 세 번째 옵션인 Python 프로그래밍 언어에 주목하고 싶습니다.

이 기사에서는 언어 자체에 대한 개요와 웹 개발, 기계 학습, 금융, 과학, 교육 등을 예로 들 수 있습니다. 후반부는 단계별 자습서로 구성됩니다.

이 글을 쓰는 목적은 Python이 재무 도구 상자에 추가하는 것을 고려할 만큼 충분히 흥미롭게 보이는지 여부를 결정하는 데 도움이 되는 것입니다. 도약하면 언어를 배울 수 있는 많은 앱, 코스, 비디오, 기사, 책 및 블로그 게시물이 있습니다. 이 글의 끝 부분에는 그 과정에서 저에게 도움이 된 몇 가지 리소스를 나열했습니다.

사용 사례:Python을 사용한 사례

프로그래밍 입문은 1980년대 중반 Oric 1에서 BASIC을 배우는 것이었습니다. 당시 BASIC은 가장 일반적인 초보자용 언어였습니다. 80년대 후반부터 90년대 중반까지 제가 손본 다른 언어는 Pascal과 C였지만 전문적인 능력으로 사용해본 적이 없었고 프로그래밍 기술이 필요하거나 사용할 것이라고 기대하지 않았습니다. 90년대 후반에 제가 아는 한 금융과 프로그래밍은 매우 다른 분야였습니다. 제가 금융 분야에서 진로를 선택하기로 결정했을 때였습니다.

2012년으로 빨리 돌아가서 프로그래밍을 취미로 다시 선택하려고 했기 때문에 당시 사용 가능한 언어를 조사하기 시작했습니다. 꽤 많은 일이 일어났고, 내가 Python을 만났을 때 나는 다음 섹션에서 설명할 많은 이유 때문에 푹 빠졌습니다. 그 이후로 저는 개인적으로나 직업적으로 작은 스크립트에서 더 큰 프로젝트에 이르기까지 광범위한 작업에 Python을 사용했습니다. 전부는 아니지만 많은 재무 전문가의 작업대인 스프레드시트를 사용하는 경우가 많습니다.

다음은 스프레드시트와 Python이 얼마나 잘 어울리는지 보여주는 몇 가지 예입니다.

1. M&A 통합 PMO 설정에서 시간에 따른 수백 가지 활동 추적

저는 M&A 거래의 실행뿐만 아니라 통합까지 모든 측면에서 일합니다. 최근 사례에서 PMO 팀은 진행 중인 수백 가지 활동을 추적하기 위한 Kanban 보드 외에도 12개의 통합 워크스트림 각각에 대한 상위 수준 계획을 위해 폭포수 계획 및 Gantt 차트를 사용하여 하이브리드 프로그램 및 프로젝트 관리 접근 방식을 결정했습니다. 주어진 시간에 처음 100일 계획 및 그 이후에 사용할 수 있습니다. 선택한 Kanban 도구인 MeisterTask에는 여러 통계 및 보고 기능이 있지만 우리의 요구는 분석 및 프레젠테이션 측면에서 그 이상이어서 맞춤형 솔루션이 필요했습니다. 다음은 Python을 사용하여 자동화한 워크플로입니다.

  1. 매주 전체 게시판의 상태를 CSV 파일로 저장합니다.
  2. 모든 과거 CSV 파일을 Pandas DataFrame으로 읽습니다.
  3. 진행 상황, 작업 흐름 등의 상태에 따라 진행 상황을 추적하려는 합의된 형식으로 데이터를 정렬, 필터링, 그룹화 및 조작합니다.
  4. 각 분석의 데이터를 자체 시트에 포함하여 Excel 파일에 출력을 작성하고, 단순히 복사하여 씽크 셀 차트에 붙여넣을 수 있는 형식을 지정합니다.
  5. 월간 운영 위원회 회의 보고 패키지에 대한 표와 차트를 만듭니다.

스크립트를 개발하려면 몇 시간의 선행 투자가 필요했지만 지금은 운영 위원회 회의 또는 임시 분석을 위해 보고 팩을 업데이트하는 데 몇 분이 걸립니다. 말 그대로 올바른 폴더로 이동하여 한 줄 명령으로 스크립트를 실행하는 데 약 30초가 소요되고, 슬라이드 데크에 출력을 복사하여 붙여넣는 데 몇 분이 소요됩니다. 12개 워크스트림에 걸쳐 약 500개의 활동(카드)이 실행된 지 약 한 달이 지났고, 2년의 프로그램 타임라인 내에서 이동 방법에 대한 주간 추적을 통해 수십 개의 데이터 포인트를 빠르게 처리하고 결국에는 수만 개의 데이터 포인트를 처리하게 됩니다. 파일의. 자동화가 없으면 여기에서 매우 지루한 작업에 대해 이야기하고 있습니다.

단순히 일을 처리하는 것과 자동화를 설정하여 초기 워크로드를 더 추가하는 것 사이의 "돈의 시간 가치" 절충안은 금융의 일반적인 주제입니다. 이 프로세스의 첫 번째 단계에서 데이터를 CSV 파일로 내보내 비슷한 결정을 내렸습니다. 많은 최신 웹 애플리케이션과 마찬가지로 MeisterTask에는 Python 애플리케이션에 연결할 수 있는 API가 있지만 설정에 소요되는 시간은 여기에서 사용하는 경우의 시간 절약보다 훨씬 큽니다.

따라서 종종 최적의 솔루션은 워크플로의 특정 단계를 자동화하고 나머지는 수동으로 유지하는 것입니다.

2. 웹 스크래핑, Google Maps API 및 Excel을 사용하여 주택 가격 통계 분석

또 다른 예는 개인적 관심으로 한 것이지만 Python 유틸리티의 다른 흥미로운 요소가 포함되어 있기 때문에 강조하고 싶습니다.

  1. 특정 지역에 대한 주소, 크기, 방 수, 호가 및 기타 기능을 포함한 부동산 목록의 스크랩 데이터 총 수백에서 수천 줄입니다.
  2. Python 데이터 구조에 저장합니다.
  3. Google Maps API에 연결하고 각 목록에 대해 속성과 바다, 도심, 가장 가까운 기차역, 가장 가까운 공항 등과 같은 주요 랜드마크 사이의 거리를 검색합니다.
  4. 데이터를 Excel 파일로 내보냅니다.
  5. 표준 Excel 기능을 사용하여 회귀를 실행하고, 통계를 계산하고, 평방 미터당 가격 및 명소까지의 거리와 같은 표준 측정항목에 대한 차트를 생성합니다.

여기서 얻은 결과는 선호도 측면에서 자신의 개인적인 가중치와 부동산을 찾을 때 재정적 제한과 결합될 수 있습니다.

이것은 스프레드시트 관련 작업을 자동화하고 기능을 추가하는 데 중점을 둔 두 가지 예에 불과하지만 Python의 기회는 거의 끝이 없습니다. 다음 섹션에서는 Python의 단계별 Monte Carlo 시뮬레이션 자습서로 넘어가기 전에 왜 이것이 인기를 얻었는지 간략하게 설명하겠습니다.

파이썬이 재무 전문가에게 탁월한 선택인 이유

프로그래밍 언어 Python은 1990년부터 사용되었지만 인기가 폭발적으로 증가한 것은 최근 몇 년이 아닙니다.

여기에는 몇 가지 이유가 있습니다. 차례로 각각 살펴보겠습니다.

1. Python은 고급 프로그래밍 언어입니다.

고급 프로그래밍 언어는 컴퓨터 내부 작동의 많은 세부 사항을 추상화하는 언어입니다. 좋은 예는 메모리 관리입니다. 저수준 프로그래밍 언어는 작업을 처리하는 데 소요되는 시간과 코드 줄 외에도 컴퓨터 메모리가 어떻게 배치, 할당 및 해제되는지에 대한 복잡성에 대한 자세한 이해가 필요합니다. Python은 이러한 세부 사항의 대부분을 추상화하고 자동으로 처리하므로 수행하려는 작업에 집중할 수 있습니다.

2. 간결합니다

Python은 고급 프로그래밍 언어이기 때문에 코드가 더 간결하고 기술 구현 세부 사항보다는 달성하고자 하는 비즈니스 로직에 거의 전적으로 초점을 맞춥니다. 언어 디자인 선택은 이에 기여합니다. 예를 들어 Python은 다른 많은 언어와 같이 함수, 루프 및 라인을 묘사하기 위해 중괄호나 세미콜론을 사용할 필요가 없습니다. 가독성.

3. 배우고 이해하기 쉬움

Python의 언어 디자인 선택에 영향을 미친 한 가지 관찰은 프로그램이 작성된 것보다 더 자주 읽혀진다는 것입니다. Python은 코드가 일반 영어와 매우 유사해 보이기 때문에 특히 스크립트나 프로그램의 다른 구성 요소 이름을 합리적인 방식으로 지정할 때 탁월합니다.

4. 신속하고 반복적인 개발에 적합

<블록 인용>

계몽된 시행착오는 흠잡을 데 없는 지성의 계획을 능가합니다. - 데이비드 켈리

Python은 Python 셸, IPython 및 Jupyter 노트북과 같은 대화형 인터프리터 도구가 Python 도구 체인의 전면 및 중앙에 있기 때문에 Python은 프로토타이핑 및 신속하고 반복적인 개발(예, 시행착오)에 이상적입니다. 이러한 대화형 환경에서는 각 코드 줄을 별도로 작성하고 실행할 수 있으며 결과(또는 유용한 오류 메시지)를 즉시 볼 수 있습니다. 다른 언어에도 이 기능이 있지만 대부분의 경우 Python과 같은 정도는 아닙니다.

5. 프로토타입 및 프로덕션 코드 모두에 사용할 수 있음

Python은 프로토타이핑에 탁월할 뿐만 아니라 대규모 프로덕션 애플리케이션을 위한 우수하고 강력한 언어이기도 합니다. 세계에서 가장 큰 소프트웨어 회사 중 일부는 다양한 응용 프로그램과 사용 사례에서 Python을 많이 사용합니다.

6. "배터리 포함"과 함께 제공:Python 표준 라이브러리

기본 작업에 필요한 모든 것이 언어에 바로 내장되어 있지만, 그 외에도 Python 표준 라이브러리에는 파일, 미디어, 네트워킹, 날짜 및 시간 정보 등을 작업하기 위한 도구가 있습니다. 이를 통해 타사 패키지를 찾을 필요 없이 다양한 작업을 수행할 수 있습니다.

7. 재무 분석을 위한 훌륭한 타사 라이브러리

재무 전문가의 경우 DataFrame이 있는 Pandas 및 시리즈 개체 및 ndarray가 있는 Numpy Python을 사용한 재무 분석의 핵심 요소입니다. matplotlib 및 기타 시각화 라이브러리와 결합하여 생산성을 지원하는 훌륭한 도구를 마음대로 사용할 수 있습니다.

8. 파이썬은 무료입니다!

Python은 상업적 용도로도 무료로 제공되는 오픈 소스 라이선스 하에 개발되었습니다.

Python과 Finance를 함께 사용하는 단계별 자습서

다음은 이전 블로그 게시물에서 설명한 Monte Carlo 시뮬레이션의 단순화된 버전을 만드는 방법을 보여주는 단계별 자습서입니다. 그러나 Excel용 @RISK 플러그인 대신 Python을 사용합니다.

Monte Carlo 방법은 수치 결과를 얻기 위해 무작위 샘플링에 의존합니다. 이러한 응용 프로그램 중 하나는 변수 또는 가정이 값 범위를 취할 수 있는 불확실한 잠재적 미래 상태를 나타내는 확률 분포에서 무작위 샘플을 추출하는 것입니다.

옵션이나 기타 파생 상품의 가치 평가를 보여주는 보다 일반적인 예 대신 단순화된 DCF 평가 모델에서 몬테카를로 시뮬레이션을 수행하는 것이 도움이 됩니다. 현금 흐름을 할인하여 Python 개념과 도구에 집중할 수 있습니다. 이 기본 튜토리얼 모델은 주요 개념을 설명하기 위한 것이며 실제적인 목적으로는 유용하지 않습니다. 또한 Monte Carlo 시뮬레이션의 보다 학문적인 측면은 다루지 않을 것입니다.

이 자습서에서는 사용자가 변수 및 함수와 같은 프로그래밍의 기본 빌딩 블록에 익숙하다고 가정합니다. 그렇지 않은 경우 10분 정도 시간을 내어 이 소개에서 핵심 개념을 확인하는 것이 도움이 될 수 있습니다.

출발점 및 원하는 결과

Monte Carlo 시뮬레이션 자습서에서 사용된 것과 동일한 매우 단순화된 DCF 평가 모델로 시작합니다. 여기에는 세 가지 재무제표의 몇 가지 핵심 항목과 세 개의 강조 표시된 입력 셀이 있습니다. Excel 버전에서는 이제 잠재적인 결과 범위를 탐색하기 시작하기 위해 확률 분포로 대체하려는 점 추정치가 있습니다.

작은 스크립트 개발을 위한 2단계 접근 방식

<블록 인용>

제대로 하고, 제대로 하고, 빠르게 하라 - Kent Beck

이 튜토리얼의 목적은 파이썬을 처음 접하는 재무 전문가에게 유용한 프로그램이 어떻게 생겼는지 소개할 뿐만 아니라 개발에 사용할 수 있는 반복적인 프로세스에 대한 소개를 제공하는 것입니다. 따라서 두 부분으로 구성됩니다.

  1. 먼저, 저는 따르기 쉽고 처음부터 시작하는 경우 이 프로젝트를 시작하는 데 사용할 수 있는 프로세스와 완전히 다르지 않다고 생각하는 간단한 접근 방식을 사용하여 작업 프로토타입을 개발합니다.
  2. 그런 다음 작동하는 프로토타입을 개발한 후 기능을 변경하지 않고 코드 구조를 변경하는 리팩토링 프로세스를 진행합니다. 이 부분을 계속 사용하고 싶을 수도 있습니다. 첫 번째 솔루션보다 더 우아한 솔루션이며 보너스로 실행 시간 면에서 약 75배 더 빠릅니다.

1. 작동하는 프로토타입 개발

Jupyter 노트북 설정

Jupyter 노트북은 Python을 대화식으로 작업할 수 있는 훌륭한 도구입니다. 코드, 마크다운 텍스트, 이미지 또는 기타 데이터를 포함할 수 있는 셀이 있는 대화형 Python 인터프리터입니다. 이 튜토리얼에서는 Python Quant Platform을 사용했지만 무료이며 클라우드에서 실행되는 Colaboratory by Google도 추천할 수 있습니다. 여기에서 "파일" 메뉴에서 "새 Python 3 노트북"을 선택하기만 하면 준비가 완료됩니다.

이를 수행한 후 다음 단계는 데이터 조작 및 시각화에 필요한 타사 패키지를 가져오고 별도의 창 대신 노트북에서 차트를 인라인으로 보고 싶다고 프로그램에 알리는 것입니다.

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

첫 번째 변수의 이름을 지정하기 전에 참고하세요. 이미 강조했듯이 가독성은 Python의 강점 중 하나입니다. 언어 설계는 이를 지원하는 데 많은 도움이 되지만 코드를 작성하는 모든 사람은 다른 사람뿐만 아니라 자신도 코드를 읽고 이해할 수 있도록 만들 책임이 있습니다. Eagleson의 법칙에 따르면 "6개월 이상 보지 않은 자신의 코드는 다른 사람이 작성했을 수도 있습니다."

경험에 따르면 프로그램의 기능을 설명하는 별도의 설명이 필요하지 않도록 프로그램 구성 요소의 이름을 지정하는 것이 좋습니다.

이를 염두에 두고 계속 진행해 보겠습니다.

재무제표 작성

Python에서 기존 스프레드시트 데이터로 작업할 수 있는 방법에는 여러 가지가 있습니다. 예를 들어 read_excel을 사용하여 한 줄의 코드로 Pandas DataFrame으로 시트를 읽을 수 있습니다. 명령. 스프레드시트와 Python 코드 간의 긴밀한 통합 및 실시간 링크를 원하는 경우 해당 기능을 제공하는 데 사용할 수 있는 무료 및 상용 옵션이 있습니다.

여기의 모델은 매우 간단하고 Python 개념에 집중하기 위해 스크립트에서 처음부터 다시 만들 것입니다. 첫 번째 부분의 끝 부분에서 우리가 만든 것을 스프레드시트로 내보내는 방법을 보여 드리겠습니다.

재무제표의 Python 표현을 만들기 위한 첫 번째 단계로 적절한 데이터 구조가 필요합니다. 선택할 수 있는 것이 많이 있습니다. 일부는 Python에 내장되어 있고, 다른 일부는 다양한 라이브러리에서 제공하거나 직접 만들 수 있습니다. 지금은 Pandas 라이브러리의 Series를 사용하여 기능을 살펴보겠습니다.

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

이 입력과 해당 출력은 다음과 같습니다.

처음 세 줄을 사용하여 연도(각각이 실제, 예산 또는 예상인지 표시하도록 표시됨), 시작 값(원래 DCF 모델에서와 같이 수백만 유로)으로 구성된 인덱스가 있는 데이터 구조를 만들었습니다. 투영을 위한 빈(NaN, "숫자가 아님") 셀. 네 번째 줄은 데이터의 표현을 인쇄합니다. 일반적으로 대화형 인터프리터에서 변수 또는 기타 개체의 이름을 입력하면 일반적으로 이에 대한 합리적인 표현을 얻을 수 있습니다.

다음으로 예상 연간 매출 성장을 나타내는 변수를 선언합니다. 이 단계에서는 원래 DCF 모델과 동일한 수치인 점 추정치입니다. 포인트 추정치를 확률 분포로 대체하기 전에 먼저 동일한 입력을 사용하고 Python 버전이 Excel 버전과 동일한 성능과 동일한 결과를 제공하는지 확인하고 싶습니다. 이 변수를 사용하여 전년도 및 성장률을 기반으로 예측의 각 연도 매출을 계산하는 루프를 만듭니다.

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

이제 NaN 대신 예상 판매액이 있습니다.

동일한 접근 방식을 사용하여 재무제표를 계속 살펴보고 필요할 때 변수를 선언하고 결국 잉여 현금 흐름에 도달하는 데 필요한 계산을 수행합니다. 일단 거기에 도착하면 우리가 가지고 있는 것이 DCF 모델의 Excel 버전이 말하는 것과 일치하는지 확인할 수 있습니다.

*expre>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

이것은 우리에게 무료 현금 흐름을 제공합니다:

이 단계에서 주석이 필요할 수 있는 위의 한 줄은 두 번째 tax_payment입니다. 참조. 여기에서 세전 이익이 음수가 되는 시나리오에서 긍정적인 세금 납부가 발생하지 않도록 하기 위해 작은 함수를 적용합니다. 이것은 Pandas 시리즈 또는 DataFrame의 모든 셀에 사용자 정의 함수를 얼마나 효과적으로 적용할 수 있는지 보여줍니다. 실제로 적용된 기능은 물론 단순화입니다. 더 큰 가치 평가를 위한 보다 현실적인 모델은 여러 회사별 요소를 기반으로 지불한 실제 현금 세금을 계산하는 별도의 세금 모델을 사용하는 것입니다.

DCF 평가 수행

예상 현금 흐름에 도달했으므로 이제 간단한 최종 가치를 계산하고 모든 현금 흐름을 현재로 다시 할인하여 DCF 결과를 얻을 수 있습니다. 다음 코드는 Pandas Series 개체와 같은 데이터 구조의 하나 이상의 요소에 액세스할 수 있도록 하는 인덱싱 및 슬라이싱을 소개합니다.

구조체 이름 바로 뒤에 대괄호를 작성하여 요소에 액세스합니다. 단순 인덱싱은 0부터 시작하여 위치별로 요소에 액세스합니다. 즉, free_cash_flow[1] 두 번째 요소를 제공합니다. [-1] 마지막 요소에 액세스하기 위한 약어이며(지난 해의 현금 흐름은 최종 가치를 계산하는 데 사용됨) 콜론을 사용하면 슬라이스가 제공됩니다. 즉, [1:] 역사적 연도 2018A를 포함하고 싶지 않기 때문에 첫 번째 요소를 제외한 모든 요소를 ​​제공합니다. 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
 

이것으로 프로토타입의 첫 번째 부분이 끝났습니다. 이제 Python에서 매우 기초적인 모델이기는 하지만 작동하는 DCF 모델이 있습니다.

데이터 내보내기

실제 Monte Carlo 시뮬레이션으로 이동하기 전에 Pandas 패키지에서 사용할 수 있는 내보내기 기능에 대해 언급하는 것이 좋습니다. Pandas DataFrame 개체가 있는 경우 to_excel을 사용하여 한 줄로 Excel 파일에 쓸 수 있습니다. 방법. 12개 이상의 다른 형식 및 대상으로 내보내는 유사한 기능도 있습니다.

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
 

몬테카를로 시뮬레이션을 위한 확률 분포 생성

이제 우리는 다음 과제를 해결할 준비가 되었습니다. 포인트 추정 입력의 일부를 확률 분포로 대체하는 것입니다. 여기까지의 단계는 Excel에서 동일한 모델을 작성하는 것에 비해 다소 번거롭게 보일 수 있지만 다음 몇 줄을 통해 Python이 얼마나 강력한지 알 수 있습니다.

첫 번째 단계는 시뮬레이션에서 실행할 반복 횟수를 결정하는 것입니다. 1,000을 시작점으로 사용하는 것은 합리적인 출력 플롯을 얻기에 충분한 데이터 포인트를 얻는 것과 합리적인 시간 프레임 내에 시뮬레이션을 끝내는 것 사이의 균형을 유지합니다. 다음으로 실제 분포를 생성합니다. 간단하게 하기 위해 여기에서 3개의 정규 분포를 생성했지만 NumPy 라이브러리에는 선택할 수 있는 분포가 많고 Python 표준 라이브러리를 포함하여 다른 곳도 살펴볼 수 있습니다. 사용할 분포를 결정한 후 평균 및 표준 편차와 같은 모양을 설명하는 데 필요한 매개변수와 원하는 결과의 수를 지정해야 합니다.

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

여기에서 EBITDA는 매출과 별개의 임의 변수가 아니라 매출과 어느 정도 상관관계가 있어야 한다고 주장할 수 있습니다. 나는 이에 동의하고 비용 구조(가변, 반가변 및 고정 비용)의 역학과 주요 비용 동인(일부는 고유한 확률 분포, 예를 들어 입력 상품 가격), 하지만 공간과 명확성을 위해 이러한 복잡성은 제쳐두고 여기에 남겨둡니다.

분포 및 매개변수 선택에 필요한 데이터가 적을수록 가능한 시나리오 범위에 대한 합의 보기를 형성하기 위해 경험과 결합된 다양한 실사 작업 흐름의 결과에 더 많이 의존해야 합니다. 이 예에서 현금 흐름 예측에는 주관적인 구성 요소가 크므로 확률 분포를 시각화하는 것이 중요합니다. 여기서 우리는 두 줄의 짧은 코드로 매출 성장 분포를 보여주는 기본 시각화를 얻을 수 있습니다. 이런 식으로 우리는 팀의 전체적 관점을 가장 잘 반영하는 안구 분포를 빠르게 볼 수 있습니다.

이제 시뮬레이션을 실행하는 데 필요한 모든 구성 요소가 있지만 시뮬레이션 실행에 편리한 형식이 아닙니다. 다음은 지금까지 작업한 것과 동일한 코드이지만 모두 하나의 셀에 모여 편의를 위해 함수로 재배열되었습니다.

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
 

이제 전체 시뮬레이션을 실행하고 다음 코드를 사용하여 1,000번의 반복마다 이 회사의 할인된 현금 흐름 가치가 되는 출력 분포를 그릴 수 있습니다. %time 명령은 Python 코드가 아니라 무언가를 실행하는 데 걸리는 시간을 측정하는 노트북 축약형입니다(대신 표준 라이브러리의 Python 함수를 사용할 수 있음). 실행하는 컴퓨터에 따라 다르지만 이 버전은 1,000번의 반복을 실행하고 결과를 시각화하는 데 1-2초가 필요합니다.

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

2. 프로토타입 개선

<블록 인용>

뭔가 단순화될 수 있다는 은밀한 의심은 보람 있는 도전의 세계에서 가장 풍부한 원천입니다. - 에즈거 다익스트라

리팩토링은 기존 코드를 다시 작성하여 기능을 변경하지 않고 구조를 개선하는 과정을 말하며, 코딩에서 가장 재미있고 보람 있는 요소 중 하나입니다. 이렇게 하는 데에는 여러 가지 이유가 있을 수 있습니다. 다음과 같을 수 있습니다.

  1. 다양한 부분을 보다 합리적인 방식으로 구성합니다.
  2. 변수와 함수의 이름을 변경하여 목적과 작업을 더 명확하게 합니다.
  3. 향후 기능을 허용하고 준비합니다.
  4. 실행 속도, 메모리 공간 또는 기타 리소스 활용도를 개선합니다.

그 과정의 한 단계가 어떤 모습일지 보여주기 위해 프로토타입 스크립트처럼 흩어져 있지 않고 모든 초기 변수를 한곳에 모아 방금 진행한 프로토타입을 정리하고 이라는 프로세스를 통해 실행 속도를 최적화했습니다. 벡터화 .

<블록 인용>

NumPy 배열을 사용하면 여러 종류의 데이터 처리 작업을 루프 작성이 필요할 수 있는 간결한 배열 표현식으로 표현할 수 있습니다. 명시적 루프를 배열 표현식으로 바꾸는 이러한 관행을 일반적으로 벡터화라고 합니다. 웨스 맥키니

이제 더 깔끔하고 이해하기 쉬워졌습니다.

# 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
 

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

기업 자금 조달
  1. 회계
  2. 사업 전략
  3. 사업
  4. 고객 관계 관리
  5. 재원
  6. 주식 관리
  7. 개인 금융
  8. 투자하다
  9. 기업 자금 조달
  10. 예산
  11. 저금
  12. 보험
  13. 은퇴하다