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

게시 됨: 2022-03-11

요약

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. 웹 스크래핑, 구글 맵스 API, 엑셀을 이용한 주택 가격 통계 분석

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

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

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

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

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

프로그래밍 언어 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. 재무 분석을 위한 훌륭한 타사 라이브러리

재무 전문가의 경우 DataFrameSeries 개체가 포함된 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

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

  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 버전이 말하는 것과 일치하는지 확인할 수 있습니다.

 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:] 은 첫 번째 요소를 제외한 모든 요소를 ​​제공하고, DCF 평가에 역사적 연도 2018A 를 포함하고 싶지 않기 때문입니다.

 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 출력

이것으로 프로토타입의 첫 번째 부분이 끝났습니다. 이제 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() 

python의 몬테카를로 시뮬레이션 출력

여기에서 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() 

python 스크립트의 몬테카를로 시뮬레이션 출력

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

이 버전과 이전 버전 간의 주요 차이점은 for i in range(iterations) 루프가 없다는 것입니다. NumPy의 배열 작업을 사용하여 이 버전은 프로토타입 버전의 1.35초와 비교하여 약 75배 빠른 18밀리초 만에 실행됩니다.

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

NumPy 배열 연산 예제

이 튜토리얼의 목적을 위해 짧은 시간에 프로토타입과 세련된 버전을 모두 모았기 때문에 추가 최적화가 가능하다고 확신합니다.

더 나아가

이 튜토리얼은 파이썬의 강력한 기능 중 일부를 보여주었으며, 이것을 더 발전시킨다면 기회는 거의 무한합니다. 예를 들면 다음과 같습니다.

  • 가정 및 확률 분포 선택에 도움이 되도록 웹 페이지 또는 기타 데이터 소스에서 관련 회사 또는 부문 통계를 스크랩하거나 다운로드하십시오.
  • 기본 및/또는 거시경제적 요인을 기반으로 하는 자동 거래 알고리즘과 같은 양적 금융 애플리케이션에서 Python을 사용합니다.
  • 내부 거래 검토 및 승인 프로세스의 일부로 사용하거나 외부 프레젠테이션에 사용할 스프레드시트 및/또는 프레젠테이션 형식으로 출력을 생성하는 내보내기 기능을 구축합니다.

Python의 성공에 기여한 다양한 웹, 데이터 과학 및 기계 학습 응용 프로그램으로 무엇을 할 수 있는지에 대해서는 언급조차 하지 않았습니다.

요약: 재무 도구 상자에 유용한 언어

이 기사에서는 Python 프로그래밍 언어를 소개하고 금융 분야에서 인기 있는 몇 가지 이유를 나열하고 작은 Python 스크립트를 빌드하는 방법을 보여주었습니다. 단계별 자습서에서 저는 Python을 반복 프로토타이핑, 대화형 재무 분석, 평가 모델, 알고리즘 거래 프로그램 등에 대한 애플리케이션 코드에 사용하는 방법을 살펴보았습니다.

나에게 있어 결국 파이썬 기술의 가장 큰 특징은 작업하는 것이 재미있다는 것입니다! 문제 해결, 구축 및 워크플로를 보다 효율적으로 만드는 것을 즐긴다면 시도해 보시기 바랍니다. 나는 당신이 그것으로 무엇을 했거나 그것으로 하고 싶은지 듣고 싶습니다.

재무 전문가가 Python을 배우기 위한 권장 리소스

  • 오라일리 책. 특히 다음을 추천할 수 있습니다.
    • 금융을 위한 파이썬(Yves Hilpisch)
    • Learning Python by Mark Lutz
    • Fluent Python by Luciano Ramalho
  • The Python Quants
  • PyCon talks on YouTube
  • 유데미