Python и финансы — улучшите свои электронные таблицы

Резюме

Почему Python — отличный язык программирования для специалистов в области финансов?
  • Python – это язык программирования высокого уровня. Это означает, что он абстрагируется и обрабатывает многие технические аспекты программирования, такие как управление памятью, которые в других языках должны выполняться явно. Это упрощает использование Python для тех, у кого нет технического образования.
  • Поскольку язык был разработан с учетом удобочитаемости и простоты использования, он является одним из самых простых языков для изучения. Код Python лаконичен и близок к простому английскому языку.
  • Python идеально подходит для создания прототипов и быстрой итеративной разработки. Его интерактивные инструменты интерпретатора предоставляют среду, в которой вы можете писать и выполнять каждую строку кода изолированно и сразу же видеть результаты.
  • В то же время Python надежен и эффективен, что делает его приемлемым выбором также для основных систем и крупных приложений.
  • Помимо большой стандартной библиотеки полезных инструментов, в Python есть отличные сторонние библиотеки для финансового анализа и вычислений, такие как библиотеки Pandas и NumPy, используемые в этом руководстве.
Каковы примеры использования Python и финансов вместе?
  • Сценарии Python можно использовать для автоматизации повторяющихся задач и рабочих процессов, что экономит время и снижает риск ручных ошибок.
  • Скрипты позволяют пользователям легко извлекать данные из электронных таблиц, баз данных и API или даже извлекать веб-данные, которые затем можно обрабатывать и анализировать с помощью мощных статистических и аналитических инструментов.
  • Различные подключаемые модули для Excel позволяют пользователям создавать двусторонние связи в режиме реального времени между вашими электронными таблицами и кодом Python.
  • Python поддерживает новые типы анализа, такие как моделирование методом Монте-Карло, которые недоступны в стандартных электронных таблицах.
  • Алгоритмическая торговля больше не является исключительной прерогативой хедж-фондов и крупных инвестиционных банков. С помощью Python вы можете разрабатывать, тестировать и развертывать собственные торговые стратегии за короткое время и с низкими затратами.
<цитата>

Для профессий, которые долгое время полагались на просмотр электронных таблиц, Python особенно ценен. Citigroup, американский банк, представил ускоренный курс по Python для своих аналитиков-стажеров. - Экономист

Финансовые специалисты уже давно имеют доступ к VBA (Visual Basic для приложений) в Excel для создания пользовательских функций и автоматизации рабочих процессов. С появлением в последние годы Google Sheets в качестве серьезного соперника в области электронных таблиц Google Apps Script теперь предлагает дополнительный выбор.

Однако я хотел бы обратить внимание на третий вариант — язык программирования Python, который стал чрезвычайно популярным в ряде областей.

В этой статье я приведу несколько примеров того, чего вы можете достичь с помощью Python, начиная с обзора самого языка и того, почему он стал таким популярным в столь широком спектре областей:веб-разработка, машинное обучение, финансы и т. д. наука и образование, и это лишь некоторые из них. Вторая половина будет состоять из пошагового руководства.

Я пишу это, чтобы помочь вам решить, выглядит ли Python достаточно интригующе, чтобы вы подумали о том, чтобы добавить его в свой набор финансовых инструментов. Если вы сделаете шаг вперед, есть много приложений, курсов, видео, статей, книг и сообщений в блогах, доступных для изучения языка. В конце статьи я перечислил некоторые ресурсы, которые помогли мне на этом пути.

Случаи использования:примеры того, для чего я использовал Python

Мое знакомство с программированием началось с изучения BASIC на Oric 1 в середине 1980-х. В то время Бейсик был самым распространенным языком для начинающих. Другими языками, которыми я баловался с конца 80-х до середины 90-х, были Pascal и C, но я никогда не использовал их в каких-либо профессиональных целях, и я не ожидал, что мне понадобятся навыки программирования. Насколько мне известно, в конце 90-х финансы и программирование были очень разными областями, когда я решил начать карьеру в области финансов.

Перенесемся в 2012 год, и я хотел вернуться к программированию в качестве хобби, поэтому я начал исследовать языки, доступные в то время. Оказалось, что произошло совсем немного, и когда я наткнулся на Python, я попался на крючок по многим причинам, которые я опишу в следующем разделе. С тех пор я использую Python для решения широкого круга задач, от небольших скриптов до крупных проектов, как в личных, так и в профессиональных целях. Многие, но не все, использовали электронные таблицы, рабочий стол многих финансовых специалистов.

Вот несколько примеров того, как хорошо могут сочетаться электронные таблицы и Python:

1. Отслеживание сотен действий с течением времени в настройке PMO интеграции слияний и поглощений

Я работаю со всеми аспектами сделок M&A, не только исполнением, но и интеграцией. В недавнем случае команда PMO выбрала гибридный подход к управлению программой и проектом, используя каскадное планирование и диаграммы Ганта для высокоуровневых планов для каждого из двенадцати рабочих потоков интеграции, в дополнение к доске Канбан для отслеживания сотен выполняемых действий. в любое время, в течение первого 100-дневного плана и далее. Выбранный инструмент канбан, MeisterTask, имеет ряд статистических и отчетных функций, но наши потребности вышли за рамки этого с точки зрения анализа и представления, что потребовало индивидуального решения. Это рабочий процесс, который я автоматизировал с помощью Python:

  1. Еженедельно сохранять статус всей доски в виде файла CSV.
  2. Считайте все исторические CSV-файлы в Pandas DataFrame.
  3. Сортировка, фильтрация, группировка и обработка данных в соответствии с согласованными форматами того, как мы хотим отслеживать прогресс (по статусу активности, рабочему потоку и т. д.).
  4. Запишите выходные данные в файл Excel с данными каждого анализа на отдельном листе, отформатировав их таким образом, чтобы их можно было просто скопировать и вставить в диаграммы think-cell.
  5. Создайте таблицы и диаграммы для пакета отчетов для ежемесячного заседания руководящего комитета.

Разработка сценария потребовала первоначальных инвестиций в несколько часов, но теперь обновление пакета отчетов для заседаний руководящего комитета или специального анализа занимает считанные минуты. Буквально около 30 секунд, чтобы зайти в нужную папку и запустить скрипт однострочной командой, а затем несколько минут, чтобы скопировать-вставить вывод в презентацию. Имея около 500 действий (карточек) в двенадцати рабочих потоках уже около месяца выполнения, еженедельное отслеживание того, как они перемещаются, в течение двух лет программы, вы быстро обнаружите, что имеете дело с тысячами, а в конечном итоге десятками тысяч точек данных в десятках. файлов. Без автоматизации мы говорим об очень утомительных задачах.

Компромисс «ценность денег во времени» между простым выполнением задач или увеличением первоначальной рабочей нагрузки за счет настройки автоматизации является распространенной темой в финансах. Я принял аналогичное решение на первом этапе этого процесса, экспортировав данные в виде файлов CSV. MeisterTask, как и многие современные веб-приложения, имеет API, который можно подключить к вашему приложению Python, но время, потраченное на его настройку, намного перевешивает экономию времени для нашего варианта использования здесь.

Итак, как видите, часто оптимальным решением является автоматизация одних этапов рабочего процесса и выполнение других вручную.

2. Анализ статистики цен на жилье с помощью веб-скрейпинга, Google Maps API и Excel

Другой пример — это то, что я сделал из личного интереса, но я хочу выделить его, потому что он содержит некоторые другие интересные элементы утилиты Python:

  1. Извлекать данные из списков недвижимости, включая адрес, размер, количество комнат, запрашиваемую цену и другие характеристики для заданного района; всего от нескольких сотен до тысячи строк.
  2. Сохранить в структуру данных Python.
  3. Подключитесь к Google Maps API и для каждого объявления получите расстояние между объектом размещения и ключевыми ориентирами, такими как море, центр города, ближайшая железнодорожная станция, ближайший аэропорт и т. д.
  4. Экспорт данных в файл Excel.
  5. Используйте стандартные функции Excel для выполнения регрессий, расчета статистики и создания диаграмм по стандартным показателям, таким как цена за квадратный метр и расстояние до ориентиров.

Результаты здесь могут быть объединены с вашими личными весами с точки зрения предпочтений и финансовых ограничений при поиске недвижимости.

Это только два примера, посвященных автоматизации работы с электронными таблицами и добавлению функций, но возможности Python практически безграничны. В следующем разделе я расскажу о причинах, по которым он стал таким популярным, прежде чем перейти к пошаговому руководству по моделированию методом Монте-Карло на Python.

Почему Python — отличный выбор для профессионалов в области финансов

Язык программирования Python существует с 1990 года, но только в последние годы его популярность резко возросла.

На это есть несколько причин, давайте рассмотрим каждую по очереди.

1. Python — язык программирования высокого уровня

Язык программирования высокого уровня — это язык, который абстрагирует многие детали внутренней работы компьютера. Хороший пример — управление памятью. Языки программирования более низкого уровня требуют подробного понимания сложности того, как память компьютера размещается, распределяется и освобождается, в дополнение к затраченному времени и строкам кода, необходимым для обработки задач. Python абстрагируется и обрабатывает многие из этих деталей автоматически, позволяя вам сосредоточиться на том, чего вы хотите достичь.

2. Это лаконично

Поскольку Python — это язык программирования высокого уровня, его код более лаконичен и почти полностью сосредоточен на бизнес-логике того, чего вы хотите достичь, а не на деталях технической реализации. Этому способствует выбор языкового дизайна:например, Python не требует использования фигурных скобок или точек с запятой для обозначения функций, циклов и линий, как это делают многие другие языки, что делает его более кратким и, как утверждают некоторые, улучшает удобочитаемость.

3. Легко учиться и понимать

Одно наблюдение, которое повлияло на выбор языкового дизайна в Python, заключается в том, что программы чаще читаются, чем пишутся. Здесь Python превосходен, так как его код выглядит очень близко к простому английскому языку, особенно если вы правильно называете различные компоненты своего скрипта или программы.

4. Подходит для быстрой итеративной разработки

<цитата>

Просвещенный метод проб и ошибок превосходит планирование безупречного интеллекта. - Дэвид Келли

Python идеально подходит для создания прототипов и быстрой итеративной разработки (и, конечно же, методом проб и ошибок), поскольку интерактивные инструменты интерпретатора, такие как оболочка Python, IPython и блокноты Jupyter, занимают центральное место в цепочке инструментов Python. В этих интерактивных средах вы можете писать и выполнять каждую строку кода изолированно и сразу же видеть результаты (или полезное сообщение об ошибке). В других языках это тоже есть, но в большинстве случаев не в такой степени, как в Python.

5. Может использоваться как для прототипирования, так и для производственного кода

Помимо того, что Python отлично подходит для прототипирования, он также является отличным и мощным языком для крупных производственных приложений. Некоторые из крупнейших компаний-разработчиков программного обеспечения в мире активно используют Python в различных приложениях и вариантах использования.

6. Поставляется с «Батареями в комплекте»:Стандартная библиотека Python

Все необходимое для базовых операций встроено прямо в язык, но помимо этого в стандартной библиотеке Python есть инструменты для работы с файлами, мультимедиа, сетью, информацией о дате и времени и многим другим. Это позволяет выполнять широкий спектр задач без необходимости искать сторонние пакеты.

7. Отличные сторонние библиотеки для финансового анализа

Для профессионалов в области финансов Pandas с его DataFrame и Серии объектов, а Numpy с его ndarray являются рабочими лошадками финансового анализа с Python. В сочетании с matplotlib и другими библиотеками визуализации у вас есть отличные инструменты для повышения производительности.

8. Python бесплатный!

Python разработан под лицензией с открытым исходным кодом, что делает его бесплатным и для коммерческого использования.

Пошаговое руководство по совместному использованию Python и финансов

Далее следует пошаговое руководство, показывающее, как создать упрощенную версию симуляции Монте-Карло, описанную в моем предыдущем сообщении в блоге, но с использованием Python вместо подключаемого модуля @RISK для Excel.

Методы Монте-Карло основаны на случайной выборке для получения числовых результатов. Одним из таких приложений является получение случайных выборок из распределения вероятностей, представляющих неопределенные потенциальные будущие состояния мира, где переменные или предположения могут принимать различные значения.

Полезно выполнить моделирование Монте-Карло на упрощенной модели оценки DCF вместо более распространенных примеров, которые вы видите, показывая оценку опционов или других деривативов, поскольку для этого нам не нужна никакая математика, кроме основ расчета финансовой отчетности и дисконтирования денежных потоков, что позволяет нам сосредоточиться на концепциях и инструментах Python. Обратите внимание, однако, что эта базовая учебная модель предназначена для иллюстрации ключевых понятий и бесполезна как есть для каких-либо практических целей. Я также не буду касаться академических аспектов моделирования Монте-Карло.

В руководстве предполагается, что вы знакомы с основными строительными блоками программирования, такими как переменные и функции. Если нет, может быть полезно потратить 10 минут на проверку ключевых понятий, например, в этом введении.

Отправная точка и желаемый результат

Я начну с той же очень упрощенной модели оценки DCF, которая использовалась в учебном пособии по моделированию методом Монте-Карло. В нем есть несколько ключевых строк из трех финансовых отчетов и три выделенные входные ячейки, которые в версии Excel содержат точечные оценки, которые мы теперь хотим заменить распределениями вероятностей, чтобы начать изучение возможных диапазонов результатов.

Двухэтапный подход к разработке небольшого скрипта

<цитата>

Заставьте это работать, сделайте это правильно, сделайте это быстро - Кент Бек

Цель этого руководства — познакомить финансовых специалистов, плохо знакомых с Python, не только с тем, как может выглядеть полезная программа, но и с итеративным процессом, который вы можете использовать для ее разработки. Таким образом, он состоит из двух частей:

  1. Во-первых, я разрабатываю рабочий прототип, используя простой подход, который, как мне кажется, прост для понимания и мало чем отличается от процесса, который можно было бы использовать для запуска этого проекта, если бы вы начинали с нуля.
  2. Затем, после разработки рабочего прототипа, я прохожу процесс рефакторинга — изменение структуры кода без изменения его функциональности. Возможно, вы захотите подождать с этой частью — это более элегантное решение, чем первое, и, в качестве бонуса, оно примерно в 75 раз быстрее с точки зрения времени выполнения.

1. Разработка рабочего прототипа

Настройка блокнота Jupyter

Блокнот Jupyter — отличный инструмент для интерактивной работы с Python. Это интерактивный интерпретатор Python с ячейками, которые могут содержать код, текст Markdown, изображения или другие данные. Для этого урока я использовал платформу Python Quant, но я также могу порекомендовать Colaboratory от Google, которая бесплатна и работает в облаке. Оказавшись там, просто выберите «Новый блокнот Python 3» в меню «Файл», и все готово.

Сделав это, следующим шагом будет импорт сторонних пакетов, необходимых для обработки данных и визуализации, и указание программе, что мы хотим видеть диаграммы в блокноте, а не в отдельных окнах:

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

Примечание, прежде чем мы начнем называть наши первые переменные. Как я уже подчеркивал, удобочитаемость — одна из сильных сторон Python. Языковой дизайн в значительной степени поддерживает это, но каждый, кто пишет код, несет ответственность за то, чтобы сделать его читабельным и понятным не только для других, но и для себя. Согласно закону Иглсона:«Любой ваш собственный код, на который вы не смотрели в течение шести или более месяцев, с тем же успехом мог быть написан кем-то другим».

Хорошее эмпирическое правило — называть компоненты вашей программы таким образом, чтобы свести к минимуму потребность в отдельных комментариях, объясняющих, что делает ваша программа.

Имея это в виду, давайте двигаться дальше.

Создание финансовой отчетности

Есть много способов, которыми мы можем работать с существующими данными электронной таблицы в Python. Мы могли бы, например, прочитать лист в Pandas DataFrame с помощью одной строки кода, используя read_excel команда. Если вам нужна более тесная интеграция и связь в режиме реального времени между электронной таблицей и кодом Python, существуют как бесплатные, так и коммерческие варианты, обеспечивающие эту функциональность.

Поскольку модель здесь очень проста, и чтобы сосредоточиться на концепциях Python, мы будем воссоздавать ее с нуля в нашем скрипте. В конце первой части я покажу, как можно экспортировать то, что мы создали, в электронную таблицу.

В качестве первого шага к созданию представления финансовой отчетности на языке Python нам потребуется подходящая структура данных. Есть из чего выбрать, некоторые встроены в Python, другие из разных библиотек, или мы можем создать свои собственные. А пока давайте воспользуемся серией из библиотеки Pandas, чтобы посмотреть на ее функциональность:

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.

Мы обращаемся к элементам, записывая квадратные скобки сразу после имени структуры. При простом индексировании доступ к элементам осуществляется по их положению, начиная с нуля, что означает, что 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

На этом первая часть нашего прототипа завершена — теперь у нас есть работающая модель DCF, хотя и очень рудиментарная, на Python.

Экспорт данных

Прежде чем перейти к моделированию методом Монте-Карло, самое время упомянуть о возможностях экспорта, доступных в пакете Pandas. Если у вас есть объект Pandas DataFrame, вы можете записать его в файл Excel одной строкой, используя to_excel метод. Существует аналогичная функциональность для экспорта в более чем дюжину других форматов и мест назначения.

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.

Наш первый шаг — решить, сколько итераций мы хотим запустить в моделировании. Использование 1000 в качестве отправной точки обеспечивает баланс между получением достаточного количества точек данных для получения разумных выходных графиков и завершением моделирования в разумные сроки. Далее мы генерируем фактические дистрибутивы. Для простоты я сгенерировал здесь три обычных дистрибутива, но в библиотеке 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

Теперь мы можем запустить всю симуляцию и построить выходное распределение, которое будет дисконтированным значением денежного потока этой компании в каждой из 1000 итераций, с помощью следующего кода. %time command — это не код Python, а сокращение для записной книжки, которое измеряет время выполнения чего-либо (вместо этого вы можете использовать функцию Python из стандартной библиотеки). Это зависит от компьютера, на котором вы ее запускаете, но этой версии требуется 1–2 секунды, чтобы выполнить 1000 итераций и визуализировать результат.

%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) петля. 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. долг
  14. выходить на пенсию