Python для финансистов
Қосымшада ыңғайлырақҚосымшаны жүктеуге арналған QRRuStore · Samsung Galaxy Store
Huawei AppGallery · Xiaomi GetApps

автордың кітабын онлайн тегін оқу  Python для финансистов

 

Ив Хилпиш
Python для финансистов
2023

Переводчик С. Черников


 

Ив Хилпиш

Python для финансистов. — СПб.: Питер, 2023.

 

ISBN 978-5-4461-2250-9

© ООО Издательство "Питер", 2023

 

Все права защищены. Никакая часть данной книги не может быть воспроизведена в какой бы то ни было форме без письменного разрешения владельцев авторских прав.

 

Введение

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

Киндман и Тейлор (2021)

Почему именно эта книга?

Эта книга обучает финансам и языку программирования Python (http://python.org/) с нуля. Сейчас финансы и программирование — тесно переплетенные дисциплины, а Python — один из наиболее часто используемых в финансовой отрасли языков программирования. Здесь комплексно изложены основы математики, финансов и программирования в понятном для обычных людей виде. Долгое время теория финансов и финансовая инженерия были отдельными дисциплинами. Однако то, что программирование (например, на Python и C++) стало неотъемлемой частью магистратуры по финансовой инженерии и подобных университетских программ, доказывает, насколько важным стал этот навык в данной области.

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

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

Несколько человек, прочитавших одну из моих предыдущих книг, «Python для финансовых расчетов»2, справедливо отметили, что она не подходит тем, кто только начинает знакомство с теорией финансов и программированием на Python. Действительно, предполагается, что читатель той книги имеет хотя бы небольшой опыт в данных сферах. Книга «Python для финансистов» восполняет этот пробел, поскольку фокусируется на основах и тем самым естественным образом подготавливает к прочтению «Python для финансовых расчетов», что в дальнейшем позволит развиваться и совершенствовать навыки работы с Python применительно к финансовым расчетам. Более подробно об этом рассказано в последней главе.

Целевая аудитория

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

Эта же книга знакомит читателя с данными темами с нуля, и ему нужны лишь базовые знания в области математики, в частности математического анализа, линейной алгебры и теории вероятностей. Материал содержит практически полную информацию обо всех описанных в нем математических понятиях. Тем не менее может пригодиться вводный учебник математики, например учебник Пембертона и Рау3, 4.

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

Даже если читатель не собирается переходить к более сложным темам финансовой инженерии, вычислительных финансов, алгоритмической торговли или управления активами, знания по Python и финансам, которые он почерпнет из этой книги, можно использовать при выполнении стандартных финансовых задач, например, при составлении инвестиционных портфелей в соответствии с современной портфельной теорией (modern portfolio theory, MPT). Книга также рассказывает об оценке опционов и других деривативов с помощью стандартных методов, таких как портфельная репликация или риск-нейтральный подход к ценообразованию.

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

Краткое описание книги

Книга состоит из следующих глав.

  • Глава 1. Финансы и Python. Эта глава формирует основу всей книги. В ней кратко излагается история финансов, освещается подход к Python как к инструменту для финансовых расчетов, показывается, как работать с базовой инфраструктурой Python, на примере кода, представленного в интерактивных блокнотах Jupyter.
  • Глава 2. Экономика с двумя состояниями. Здесь рассматривается наиболее простая модель экономики, в которой возможен финансовый анализ в условиях неопределенности, когда есть только две релевантные даты и два неопределенных состояния в будущем. Иногда ее называют статической экономикой с двумя состояниями. Несмотря на свою простоту, она позволяет представить такие базовые финансовые понятия, как чистая приведенная стоимость, ожидаемая доходность, волатильность, условные требования, репликация опционов, арбитражное ценообразование, мартингальная мера, полнота рынка, риск-нейтральный подход к ценообразованию и портфели Марковица.
  • Глава 3. Экономика с тремя состояниями. В этой главе в модель добавляется третье неопределенное состояние в будущем и анализируется статическая экономика с тремя состояниями, что позволяет рассмотреть такие понятия, как неполнота рынка, неопределенность мартингальных мер, суперрепликация условных требований и аппроксимирующая репликация условных требований. Вдобавок здесь представлена модель ценообразования капитальных активов (Capital Asset Pricing Model, CAPM) в качестве подхода к равновесному ценообразованию финансовых активов.
  • Глава 4. Оптимальность и равновесие. Основной темой здесь являются экономические агенты с их индивидуальными проблемами принятия решений. Анализ здесь опирается на доминирующую парадигму финансов для принятия решений в условиях неопределенности — максимизацию ожидаемой полезности. Через так называемого репрезентативного агента вводятся понятия равновесия, демонстрируется связь между оптимальностью и равновесием, с одной стороны, и мартингальными мерами и риск-нейтральным подходом к ценообразованию — с другой. Ко всему прочему, использование концепции репрезентативного агента представляет собой один из способов преодоления трудностей, возникающих в экономиках с неполными рынками.
  • Глава 5. Статическая экономика. Обобщает рассмотренные понятия и сводит полученные результаты к конечному (возможно, большому) числу неопределенных будущих состояний. Для анализа такой обобщенной статической экономики требуется немного больше математических формул.
  • Глава 6. Динамическая экономика. Основываясь на анализе обобщенной статической экономики, здесь в финансовое моделирование добавляется динамика, что позволяет рассмотреть два частных случая динамической экономики в дискретном времени. Основная идея заключается в том, что неопределенность относительно будущих состояний экономики в целом разрешается постепенно с течением времени. Это можно смоделировать с помощью стохастических процессов, например биномиального процесса, который можно представить в виде биномиального дерева.
  • Глава 7. Что дальше? В заключительной главе приводится множество дополнительных материалов для изучения из области математики, теории финансов и программирования на Python, также читателю даются рекомендации о дальнейших действиях.

Условные обозначения

В книге используются следующие условные обозначения.

Курсив

  1. Служит для выделения новых понятий.

    Интерфейс

  2. Применяется для выделения URL-адресов, электронных адресов.

    Моноширинный шрифт

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

    Этот рисунок обозначает обычное примечание.

    А этот — предупреждение или предостережение.

    Этим рисунком обозначена важная информация.

Примеры кода, использованные в книге

Все вспомогательные материалы — примеры кода, упражнения и т.д. — можно скачать здесь: https://finpy.pqp.io.

По техническим вопросам или проблемам, связанным с примерами кода, можно обращаться по адресу bookquestions@oreilly.com.

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

Мы рекомендуем, но не требуем добавлять ссылку на первоисточник при цитировании. Под ссылкой на первоисточник мы подразумеваем указание авторов, издательства и ISBN.

За получением разрешения на использование значительных объемов программного кода из книги обращайтесь по адресу permissions@oreilly.com.

Благодарности

В книге приведены ценные отзывы участников наших сертификационных программ по Python для финансовых расчетов.

Благодарю научных редакторов за их полезные комментарии. Они помогли внести многочисленные улучшения.

Я также признателен всей команде O’Reilly за помощь и поддержку.

Эта книга посвящена моей жене Сандре. Ты — любовь всей моей жизни.

От издательства

Ваши замечания, предложения, вопросы отправляйте по адресу comp@piter.com (издательство «Питер», компьютерная редакция).

Мы будем рады узнать ваше мнение!

На веб-сайте издательства www.piter.com вы найдете подробную информацию о наших книгах.


1 Kindman A., Taylor Т. Why We Rewrote Our USD30 Billion Asset Management Platform in Python. March 29, 2021. https://oreil.ly/GghS6.

2 Хилпиш И. Python для финансовых расчетов. — 2021.

3 Pemberton M., Rau N. Mathematics for Economists: An Introductory Textbook. 4th ed. — Manchester University Press, 2016.

4 Русскоязычным читателям рекомендуем главную книгу по финансовой математике в России: Ширяев А.Н. Основы стохастической финансовой математики. В двух томах. Том 1. Факты. Модели. Том 2. Теория. — М.: МЦНМО, 2016. — Примеч. науч. ред.

Pemberton M., Rau N. Mathematics for Economists: An Introductory Textbook. 4th ed. — Manchester University Press, 2016.

Русскоязычным читателям рекомендуем главную книгу по финансовой математике в России: Ширяев А.Н. Основы стохастической финансовой математики. В двух томах. Том 1. Факты. Модели. Том 2. Теория. — М.: МЦНМО, 2016. — Примеч. науч. ред.

3, 4
3, 4

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

Несколько человек, прочитавших одну из моих предыдущих книг, «Python для финансовых расчетов»2, справедливо отметили, что она не подходит тем, кто только начинает знакомство с теорией финансов и программированием на Python. Действительно, предполагается, что читатель той книги имеет хотя бы небольшой опыт в данных сферах. Книга «Python для финансистов» восполняет этот пробел, поскольку фокусируется на основах и тем самым естественным образом подготавливает к прочтению «Python для финансовых расчетов», что в дальнейшем позволит развиваться и совершенствовать навыки работы с Python применительно к финансовым расчетам. Более подробно об этом рассказано в последней главе.

Kindman A., Taylor Т. Why We Rewrote Our USD30 Billion Asset Management Platform in Python. March 29, 2021. https://oreil.ly/GghS6.

Хилпиш И. Python для финансовых расчетов. — 2021.

Глава 1. Финансы и Python

История теории финансов — интересный пример взаимосвязи между абстрактным теоретизированием и практическим применением.

Франк Мильне (1995)

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

Лоуренс Флетчер (2020)

Цель главы 1 состоит в том, чтобы заложить основы для последующих глав, поэтому в ней дается краткий обзор освещаемых тем. Она начинается с раздела «Краткая история финансов», в котором в общих чертах рассказывается об истории развития и современном состоянии финансов. В разделе «Главные тенденции в области финансов» рассматриваются основные тенденции, касающиеся математики, технологий, данных, искусственного интеллекта и определяющие развитие финансов в долгосрочной перспективе. В связи с этим раздел «Четырехъязычная сфера» говорит о том, что финансы в наше время — это дисциплина, состоящая из четырех тесно связанных между собой типов языков: естественного (в большей мере английского), языка финансов, математического и языка программирования. Далее объясняется, как устроена книга (раздел «Структура книги»). А в последнем разделе, «Вводная информация о Python», рассказывается об установке окружения Python на компьютер и об альтернативном варианте работы с ним: весь код может использоваться и исполняться через обычный браузер на Quant Platform.

Краткая история финансов

Чтобы лучше понять текущее состояние финансов и финансовой отрасли, нужно взглянуть, как они развивались. В 2006 году Рубинштейн условно разделил историю финансов как науки на три периода.

  • Древний период (до 1950 года). Период, характеризующийся в основном неформальными рассуждениями, эмпирическими правилами и опытом субъектов финансового рынка.
  • Классический период (1950–1980 годы). В это время произошло внедрение в финансы более строгих обоснований и математики. Были разработаны финансовые модели, например модель ценообразования опционов Блэка — Шоулза (1973), а также заложены некоторые основы, например риск-нейтральный подход к ценообразованию Харрисона и Крепса (1979).
  • Современный период (1980–2000 годы). Это период прогресса в отдельных областях финансов, например в финансовой инженерии, и решения проблем, связанных с важными эмпирическими явлениями на финансовых рынках, такими как стохастическая модель процентных ставок (Кокс, Ингерсолл и Росс, 1985) или модель стохастической волатильности (Хестон, 1993).

Сейчас, спустя 15 лет после публикации книги Рубинштейна, можно выделить четвертый и пятый периоды, которые обеспечили появление и нынешнюю популярность Python в финансах.

  • Вычислительный период (2000–2020 годы). В это время произошел переход от теоретической направленности финансов к вычислительной, что обусловлено развитием программно-технических средств. Эту смену парадигмы хорошо иллюстрирует численный алгоритм для оценки американских опционов методом Монте-Карло, представленный в работе Лонгстаффа и Шварца в 2001 году. Алгоритм требует больших вычислительных ресурсов, поскольку для оценки стоимости всего одного опциона нужны сотни тысяч численных моделирований и анализ множества обычных регрессий методом наименьших квадратов (см.: Хилпиш, 2018).
  • Период использования искусственного интеллекта (после 2020 года). Прогресс в области искусственного интеллекта (ИИ) и связанные с ним истории успеха подстегнули интерес к использованию возможностей ИИ в финансовой сфере. Несмотря на существование эффективных приложений в данной области (см.: Хилпиш, 2020), можно предположить, что с 2020 года парадигма планомерно смещается в сторону финансовых систем, основанных на ИИ. Таким образом, мы становимся свидетелями перехода от простых, в основном линейных, финансовых моделей к сложным моделям и использованию алгоритмов ИИ (глубоких нейронных сетей или обучения с подкреплением) для фиксации, описания и объяснения финансовых явлений.

Главные тенденции в области финансов

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

  • Математика. Начиная с 1950-х годов наука о финансах становится все более формализованной дисциплиной, в которой систематически используются знания из различных областей математики, например линейной алгебры и стохастического исчисления. Появление портфельной теории Марковица (1952) стало прорывом в количественном анализе и точкой перехода от древнего периода с его неформальными рассуждениями к классическому периоду.
  • Технологии. Благодаря рабочим станциям, серверам и компьютерам, которые начали широко использоваться в конце 1980-х — начале 1990-х годов, технологии стали проникать и в финансовую отрасль. И если сначала техника имела довольно небольшую вычислительную мощность, то сейчас даже самые сложные финансовые задачи можно решить с помощью специальной программы, не прибегая к специальным моделям и методам, характерным для классического и современного периодов. Кредо стало таким: «Обновляйте оборудование и используйте современное программное обеспечение вместе с правильными вычислительными методами». При этом большинство современных компьютеров, предназначенных для использования массовым потребителем, уже обладает мощностью, необходимой для высокопроизводительной работы (например, для параллельной обработки), что значительно упрощает изучение финансовой инженерии и взаимодействие с финансовыми системами, основанными на ИИ.
  • Данные. Если в древний и классический периоды теоретики и практики черпали информацию, касающуюся финансов, в основном из специализированных печатных изданий (здесь можно вспомнить Wall Street Journal или Financial Times), то сегодня возросла доступность массива финансовых данных в электронном виде. Массивы высокочастотных внутридневных данных стали нормой и заменили цены на момент закрытия биржи в качестве основной базы для эмпирических исследований. Каждый торговый день одна акция может генерировать массивы внутридневных данных, содержащие более 100 000 значений, что приблизительно эквивалентно ценам на момент закрытия биржи для той же акции за 400 лет (250 торговых дней в году умножить на 400 лет). Вдобавок с недавнего времени наблюдается распространение открытых массивов данных, что также значительно снижает порог входа в финансовую инженерию, алгоритмическую торговлю или финансовую эконометрику.
  • Искусственный интеллект. Увеличение объема финансовых данных (возникновение «больших финансовых данных») в наши дни делает применение алгоритмов искусственного интеллекта: алгоритмов машинного обучения, глубокого обучения или обучения с подкреплением (см.: Хилпиш, 2020) — не только возможным, но и во многих случаях необходимым подходом к работе с финансами. Традиционные статистические методы из финансовой эконометрики уже не подходят для решения большинства современных проблем, возникающих на финансовых рынках. В условиях нелинейной, многомерной, постоянно меняющейся финансовой среды алгоритмы на основе искусственного интеллекта нередко становятся единственным средством обнаружения релевантных взаимосвязей и закономерностей, получения важных данных и использования улучшенных возможностей прогнозирования.

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

Python и финансы

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

Четырехъязычная сфера

На фоне перечисленных выше тенденций финансы стали сферой применения четырех языков.

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

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

Структура книги

Как в издании совмещается использование всех этих четырех языков? С естественным языком все понятно: можно либо читать книгу в оригинале, либо пользоваться переводом на родной язык. Осталось решить вопрос с остальными.

К примеру, книга не может подробно объяснить каждый отдельный раздел математики, необходимый в финансах, или представить все концепции программирования (Python), использующиеся в финансовой инженерии. Тем не менее в ней была сделана попытка связать понятия из финансов, математики и программирования между собой.

Начиная с главы 2, информация в книге будет подаваться через введение финансового понятия (или концепции) вместе с его математическим представлением и реализацией на Python. К примеру, в таблице из главы 3 перечислены финансовые понятия, о которых будет идти речь, соответствующие им основные математические элементы и основная структура данных Python, используемая для реализации финансовой математики.

Финансы

Математика

Python

Неопределенность

Вероятностное пространство

ndarray

Финансовые активы

Векторы, матрицы

ndarray

Достижимые условные требования

Линейная оболочка векторов, базис векторного пространства

ndarray

Чтобы проиллюстрировать общую структуру книги, далее приведу пример описания финансового понятия, который будет рассматриваться подробнее в следующих главах.

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

2. Векторное пространство — это набор объектов (векторов), для которых определены сложение и скалярное умножение. Формально вектор v можно представить следующим образом:

.

Здесь предполагается, что оба векторных элемента являются неотрицательными вещественными (действительными) числами vu, vd

0. Другими словами, если неопределенная, зависящая от состояния экономики цена акций, на которые выписан европейский колл-опцион, определяется как:

,

а цена исполнения опциона K = 15, то выплата C по европейскому колл-опциону будет равна:

.

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

Как же все это перевести на Python? Во-первых, вещественные числа в нем представлены как числа с плавающей запятой или объекты float:

In [1]: vu = 1.5

In [2]: vd = 3.75

In [3]: type(vu)

Out[3]: float

In [4]: vu + vd

Out[4]: 5.25

Определение переменной vu и ее значения 1.5.

Определение переменной vd и ее значения 3.75.

Поиск и вывод типа объекта vu (float).

Сложение значений vu и vd.

Во-вторых, наборы объектов одного типа в программировании обычно называются массивами. Поддержку таких структур данных в Python обеспечивает библиотека NumPy (http://numpy.org/). Основной структурой данных в ней является ndarray — аббревиатура для n-мерного массива (n-dimensional array). NumPy легко моделирует векторы с вещественными значениями:

In [5]: import numpy as np

In [6]: v = np.array((vu, vd))

In [7]: v

Out[7]: array([1.5 , 3.75])

In [8]: v.dtype

Out[8]: dtype('float64')

In [9]: v.shape

Out[9]: (2,)

In [10]: v + v

Out[10]: array([3. , 7.5])

In [11]: 3 * v

Out[11]: array([ 4.5 , 11.25])

Импорт библиотеки NumPy.

Создание объекта ndarray.

Вывод хранимых в объекте данных.

Поиск и вывод типа данных всех элементов.

Поиск и вывод формы объекта.

Сложение векторов.

Скалярное умножение.

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

In [12]: S = np.array((20, 5))

In [13]: K = 15

In [14]: C = np.maximum(S - K, 0)

In [15]: C

Out[15]: array([5, 0])

Обозначение неопределенной цены акции как объект ndarray.

Определение цены исполнения опциона через переменную Python с целочисленным значением (объект int).

Поэлементное вычисление функции максимума.

Итоговые данные, хранящиеся в объекте ndarray, обозначенном C.

Таким образом, при написании книги использовался следующий подход.

  1. Вводятся финансовые понятия и концепции.
  2. Дается их математическое представление и модель.
  3. Математическая модель переводится в исполняемый код Python.

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

Вводная информация о Python

Одним из преимуществ Python является открытый исходный код, который облегчает его установку на все основные операционные системы — macOS, Windows и Linux. При этом для работы с кодом из этой книги и финансов в целом в дополнение к базовому интерпретатору Python необходимы всего несколько основных пакетов и библиотек, тоже имеющих открытый исходный код.

  • NumPy (http://numpy.org/). Позволяет эффективно работать с большими n-мер­ными массивами числовых данных.
  • pandas (http://pandas.pydata.org/). Предназначен в первую очередь для эффективной работы с табличными наборами данных и финансовыми временными рядами. В данной книге pandas не будет задействован, однако стоит отметить его особую популярность в области финансов.
  • SciPy (http://scipy.org/). Является набором научных функций, необходимых, например, для решения типичных задач, связанных с оптимизацией.
  • SymPy (http://sympy.org/). Позволяет использовать символьную математику, что иногда бывает полезно в работе с финансовыми моделями и алгоритмами.
  • matplotlib (http://matplotlib.org/). Представляет собой стандартную библиотеку Python для визуализации данных. Она позволяет создавать и настраивать различные типы графиков, например линейные графики, столбчатые диаграммы и гистограммы.

Кроме того, для начала работы с интерактивным кодированием на Python требуются еще два инструмента.

  • IPython (http://ipython.org/). Самая популярная среда для интерактивного кодирования на Python в командной строке (в терминале, оболочке shell).
  • JupyterLab (http://jupyter.org/). Интерактивная среда для интерактивного кодирования и разработки на Python в браузере.

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

  • Quant Platform. На бесплатной платформе Quant Platform (http://finpy.pqp.io/) находится полноценная среда для интерактивной финансовой аналитики с помощью Python. На ней можно запускать код из данной книги через браузер, что делает ненужной установку программы на компьютер. После бесплатной регистрации вы получаете автоматический доступ ко всему коду и всем блокнотам Jupyter Notebook, используемым в книге, что дает возможность сразу выполнять код в браузере.
  • Локальная среда Python. В настоящее время несложно установить локальную среду Python, которая позволит вам погрузиться в финансовую аналитику и выполнить код из книги на своем компьютере. Далее описано, как произвести установку.

    Выбор между локальной средой Python и Quant Platform

    Практика показывает, что локальная установка правильной среды Python иногда может вызвать сложности у новичков в программировании. Поэто­му, если на начальном этапе установка Python на компьютер вызывает какие-то проблемы, лучше не тратить слишком много времени на нее, а воспользоваться платформой Quant Platform (http://finpy.pqp.io/). К установке Python на компьютер можно вернуться позже, когда у вас будет больше опыта.

Простым и современным способом установки Python является использование менеджера пакетов и среды под названием conda (рис. 1.1).

Рис. 1.1. Веб-страница conda

Обычно conda и базовый интерпретатор Python устанавливаются с помощью дистрибутива Miniconda (https://oreil.ly/NI0Wi). На странице загрузки (https://oreil.ly/gaWTP) представлены установочные пакеты последних версий Python для основных операционных систем (рис. 1.2). Дополнительные опции, например, для чипов Apple M1 (из серии Apple Silicon) предоставляются Miniforge (https://oreil.ly/gKeo3).

После установки Miniconda или Miniforge необходимо открыть оболочку или командную строку и проверить доступность conda. Вот, например, результат, полученный на базе conda, установленной через Miniforge на компьютере Apple Mac с чипом M1:

(base) minione:finpy yves$ conda --version

conda 4.10.3

(base) minione:finpy yves$

Рис. 1.2. Страница загрузки Miniconda

Обратите внимание на основную часть запроса, которая характерна для установки Python посредством conda. Следующим шагом будет создание новой среды Python (с подтверждением запросов с помощью значения y):

pro:finpy yves$ conda create --name finpy python=3.9

...

Preparing transaction: done

Verifying transaction: done

Executing transaction: done

#

# To activate this environment, use

#

#     $ conda activate finpy

#

# To deactivate an active environment, use

#

#     $ conda deactivate

Затем следует активизировать среду:

(base) minione:finpy yves$ conda activate finpy

(finpy) minione:finpy yves$

Обратите внимание на то, как изменился запрос. Далее устанавливаем инструменты IPython и JupyterLab и подтверждаем появляющиеся запросы с помощью значения y:

(finpy) minione:finpy yves$ conda install ipython jupyterlab

...

После этого следует установить основные библиотеки и пакеты Python, необходимые для работы с финансовыми данными (флаг -y позволяет избежать запроса на подтверждение):

(finpy) minione:finpy yves$ conda install -y numpy pandas matplotlib scipy sympy

...

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

(finpy) minione:finpy yves$ conda list

# packages in environment at /Users/yves/Python/envs/finpy:

#

# Name                    Version                   Build    Channel

anyio                     3.3.0            py39h2804cbe_0    conda-forge

appnope                   0.1.2            py39h2804cbe_1    conda-forge

argon2-cffi               20.1.0           py39h5161555_2    conda-forge

...

jupyterlab                3.1.12             pyhd8ed1ab_0    conda-forge

...   

numpy                     1.21.2           py39h1f3b974_0    conda-forge

...

python                    3.9.7        h54d631c_1_cpython    conda-forge

...

zipp                      3.5.0              pyhd8ed1ab_0    conda-forge

zlib                      1.2.11            h31e879b_1009    conda-forge

zstd                      1.5.0                h861e0a7_0    conda-forge

(finpy) minione:finpy yves$

Затем с помощью команды python можно запустить интерактивную сессию Python:

(finpy) minione:finpy yves$ python

Python 3.9.7 | packaged by conda-forge | (default, Sep 14 2021, 01:14:24)

[Clang 11.1.0 ] on darwin

Type "help", "copyright", "credits" or "license" for more information.

>>> print('Hello Finance World.')

Hello Finance World.

>>> exit()

(finpy) minione:finpy yves$

IPython предоставляет расширенную интерактивную оболочку, которую можно запустить командой ipython:

(finpy) minione:finpy yves$ ipython

Python 3.9.7 | packaged by conda-forge | (default, Sep 14 2021, 01:14:24)

Type 'copyright', 'credits' or 'license' for more information

IPython 7.27.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from numpy.random import default_rng

In [2]: rng = default_rng(100)

In [3]: rng.random(10)

Out[3]:

array([0.83498163, 0.59655403, 0.28886324, 0.04295157, 0.9736544 ,

       0.5964717 , 0.79026316, 0.91033938, 0.68815445, 0.18999147])

In [4]: exit

(finpy) minione:finpy yves$

Однако начинающим пользователям рекомендуется работать в браузерном JupyterLab. Для этого необходимо ввести команду jupyter lab в оболочке операционной системы, которая должна выдать сообщение, похожее на следующее:

(finpy) minione:finpy yves$ jupyter lab

...

[I 2021-09-16 14:18:21.774 ServerApp] Jupyter Server 1.11.0 is running at:

[I 2021-09-16 14:18:21.774 ServerApp] http://localhost:8888/lab

[I 2021-09-16 14:18:21.774 ServerApp]  or http://127.0.0.1:8888/lab

[I 2021-09-16 14:18:21.774 ServerApp] Use Control-C to stop this server

         and shut down all kernels (twice to skip confirmation).

Как правило, эта команда автоматически открывает новую вкладку браузера со стартовой страницей JupyterLab (рис. 1.3).

Теперь можно открыть новый блокнот Jupyter Notebook и начать интерактивное кодирование на Python (рис. 1.4). Осталось щелкнуть на ячейке, ввести в нее код и выполнить его, нажав Shift+Enter, Ctrl+Enter или Alt+Enter (вы заметите разницу).

Рис. 1.3. Стартовая страница JupyterLab

Рис. 1.4. Новый блокнот Jupyter Notebook

Кроме того, можно открыть уже существующий блокнот Jupyter Notebook, представленный в этой книге (рис. 1.5).

Рис. 1.5. Блокнот Jupyter Notebook из книги

В этом разделе представлены лишь самые основы начала работы с Python и связанными с ним инструментами IPython и JupyterLab. Более подробную информацию (например, о том, как работать с IPython) можно получить из книги Вандерпласа5 (2016).

Резюме

Наука о финансах может похвастаться длинной историей. Период с 1950 по 1980 год характеризуется внедрением строгого математического анализа в эту область. Начиная с 1980-х годов, и особенно в 2000-х, роль компьютеров и финансовой инженерии значительно возросла. Тенденция дальнейшей компьютеризации будет только усиливаться в связи с распространением искусственного интеллекта с его алгоритмами машинного (machine lear­ning, ML) и глубокого обучения (deep learning, DL), требующими больших вычислительных ресурсов.

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

Книга построена таким образом, чтобы познакомить читателя с параллельными понятиями из финансов, математики и программирования. Требования для использования Python минимальны, при этом основным инструментом управления средой чаще всего является conda.

Теперь можно перейти к главе 2, в которой рассматривается самая простая финансовая модель и вводится бо́льшая часть базовых финансовых понятий. После работы с такой финансовой моделью, как правило, вырабатывается профессиональное чутье, которое должно облегчить переход к более сложным моделям и методам работы с финансами из главы 3.

Справочные материалы

В этой главе были упомянуты следующие статьи и книги.

  • Cox J., Ingersoll J., Ross S. A Theory of the Term Structure of Interest Rates // Econometrica, 1985. — № 53 (2). — Р. 385–407.
  • Fletcher L. Hedge Funds Exploit Technology to Reduce Cost and Waste. Financial Times, December 15, 2020. https://oreil.ly/HE4Cc.
  • Heston S. A Closed-Form Solution for Options with Stochastic Volatility with Applications to Bond and Currency Options // The Review of Financial Studies, 1993. — № 6 (2). — Р. 327–343.
  • Hilpisch Y. Python for Finance: Mastering Data-Driven Finance. 2nd ed. — O’Reilly, 20186.
  • Hilpisch Y. Artificial Intelligence in Finance: A Python-Based Guide. — O’Reilly, 2020.
  • Longstaff F., Schwartz E. Valuing American Options by Simulation: A Simple Least Squares Approach // Review of Financial Studies, 2001. — № 14 (1). — Р. 113–147.
  • Markowitz H. Portfolio Selection // Journal of Finance, 1952. — № 7 (1). — Р. 77–91.
  • Milne F. Finance Theory and Asset Pricing. — N.Y.: Oxford University Press, 1995.
  • Rubinstein M. A History of the Theory of Investments. — Wiley Finance, 2006.

5 Vanderplas J. Python Data Science Handbook. — O’Reilly, 2016.

6 Хилпиш И. Python для финансовых расчетов.

Хилпиш И. Python для финансовых расчетов.

Vanderplas J. Python Data Science Handbook. — O’Reilly, 2016.

В этом разделе представлены лишь самые основы начала работы с Python и связанными с ним инструментами IPython и JupyterLab. Более подробную информацию (например, о том, как работать с IPython) можно получить из книги Вандерпласа5 (2016).

  • Hilpisch Y. Python for Finance: Mastering Data-Driven Finance. 2nd ed. — O’Reilly, 20186.
  • Глава 2. Экономика с двумя состояниями

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

    Даррелл Дуффи (1988)

    Понятие арбитража играет крайне важную роль в современной теории финансов.

    Дельбаен и Шахермайер (2006)

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

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

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

    Финансы

    Математика

    Python

    Время

    Натуральные числа ℕ

    int, type

    Деньги (валюта)

    Вещественные числа ℝ

    float

    Денежный поток

    Кортеж

    tuple, list

    Доход, проценты

    Вещественные числа ℝ

    abs

    (Чистая) приведенная стоимость

    Функция

    def, return

    Неопределенность

    Векторное пространство ℝ2

    NumPy, ndarray, np.array

    Финансовый актив

    Процесс

    ndarray, tuple

    Риск

    Вероятность, пространство состояний, булеан (показательное множество), отображение

    ndarray

    Ожидание, ожидаемая доходность

    Скалярное произведение

    np.dot

    Волатильность

    Дисперсия, стандартное отклонение

    np.sqrt

    Условные требования

    Случайная величина

    np.arange, np.maximum, plt.plot

    Репликация, арбитраж

    Линейные уравнения, матричная форма

    ndarray(2d), np.linalg.solve, np.dot

    Полнота рынка, ценные бумаги Эрроу — Дебре

    Линейная независимость, линейная оболочка

    np.linalg.solve

    Ценообразование по мартингалу

    Мартингал, мартингальная мера

    np.dot

    Среднее отклонение

    Математическое ожидание, дисперсия, стандартное отклонение

    np.linspace, .std(), [x for y in z]

    Экономика

    Основой финансовой модели является идея экономики. Экономика — это абстрактное понятие, включающее в себя отдельные элементы финансовой модели: активы (реальные и финансовые), агентов (люди и учреждения) или деньги. Как и в реальном мире, экономику нельзя увидеть или потрогать. Ее невозможно представить в какой-то одной определенной форме — обобщающий термин служит скорее для упрощения коммуникации8.

    Реальные активы

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

    Агенты

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

    Время

    Экономическая деятельность, как и торговля реальными активами, возможна только в дискретные моменты времени. Формально это можно представить как t 0, 1, 2, 3… или t

    0. Однако в дальнейшем мы рассмотрим лишь два момента времени — t = 0 и t = 1, которые обозначают «сегодня» и «ровно через год» соответственно. Это не единственная возможная интерпретация: например, во многих ситуациях под t = 0 и t = 1 подразумеваются «сегодня» и «завтра». В любом случае если в экономической модели рассматриваются только два релевантных момента времени, то согласно финансовой теории она является статической.

    В Python натуральные числа

    представлены типом данных int (от integers — «целые числа»). С целыми числами можно проводить основные арифметические действия — сложение, вычитание, умножение и другие операции:

    In [1]: 1 + 3

    Out[1]: 4

    In [2]: 3 * 4

    Out[2]: 12

    In [3]: t = 0

    In [4]: t

    Out[4]: 0

    In [5]: t = 1

    In [6]: type(t)

    Out[6]: int

    Сложение двух целых чисел.

    Умножение двух целых чисел.

    Присваивание переменной t значения 0.

    Вывод значения переменной t.

    Присваивание переменной t нового значения 1.

    Поиск и вывод типа данных t.

    Деньги

    В экономике деньги (или валюта) характеризуются неограниченностью и бесконечной делимостью. Необходимо понимать, что деньги и валюта рассматриваются здесь как абстрактное явление, а не с точки зрения наличных денег — физических монет или купюр.

    Деньги в целом служат мерой стоимости, поскольку стоимость одной денежной единицы, например доллара США, евро, фунта стерлингов и т.д., приравнена к единице. Цены на все товары выражены в соответствии с этими единицами. Формально денежные единицы представлены в виде неотрицательных вещественных чисел c

    0.

    В Python вещественные числа

    представлены стандартным типом данных float в форме чисел с плавающей запятой. Как и int, float, помимо прочего, позволяет выполнять обычные арифметические действия, такие как сложение и вычитание:

    In [7]: 1 + 0.5

    Out[7]: 1.5

    In [8]: 10.5 – 2

    Out[8]: 8.5

    In [9]: c = 2 + 0.75

    In [10]: c

    Out[10]: 2.75

    In [11]: type(c)

    Out[11]: float

    Сложение двух чисел.

    Вычитание двух чисел.

    Обозначение результата сложения через переменную c.

    Вывод значения переменной c.

    Поиск и печать типа данных переменной c.

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

    Денежный поток

    Время и деньги в совокупности образуют денежный поток. Рассмотрим инвестиционный проект, который требует вложения, скажем, 9,50 денежной единицы сегодня и возвращает 11,75 денежной единицы через год. Инвестиции обычно считаются оттоком денежных средств и часто являются отрицательными вещественными числами, c

    <0, или в нашем случае c = −9,50. Возврат инвестированных средств — это приток и, следовательно, положительное вещественное число, c
    0, или c = +11,75.

    Для обозначения моментов времени, когда происходят отток и приток денежных средств, используются отметки времени. В нашем случае это ct = 0 = −9,50 и ct = 1 = 11,75, или сокращенно c0 = −9,50 и c1 = 11,75.

    Денежный поток сейчас и денежный поток через год математически моделируются как упорядоченная пара, или кортеж, объединяющий эту пару в один объект: c

    2, где c = (c0, c1) и c0, c1
    .

    В Python есть несколько структур данных для такого математического объекта, основными из которых являются tuple и list. Они различаются тем, что объекты типа tuple нельзя изменить после создания, а объекты типа list — можно. Сначала посмотрим на объекты типа tuple (обозначены круглыми скобками):

    In [12]: c0 = -9.5

    In [13]: c1 = 11.75

    In [14]: c = (c0, c1)

    In [15]: c

    Out[15]: (-9.5, 11.75)

    In [16]: type(c)

    Out[16]: tuple

    In [17]: c[0]

    Out[17]: -9.5

    In [18]: c[1]

    Out[18]: 11.75

    Определение оттока денежных средств сегодня.

    Определение оттока денежных средств ровно через год.

    Определение объекта tuple через с (обратите внимание на круглые скобки).

    Вывод пары денежных потоков (обратите внимание на круглые скобки).

    Поиск и вывод типа объекта с.

    Вывод первого элемента объекта c.

    Вывод второго элемента объекта c.

    Перейдем к объекту list (обозначенному квадратными скобками):

    In [19]: c = [c0, c1]

    In [20]: c

    Out[20]: [-9.5, 11.75]

    In [21]: type(c)

    Out[21]: list

    In [22]: c[0]

    Out[22]: -9.5

    In [23]: c[1]

    Out[23]: 11.75

    In [24]: c[0] = 10

    In [25]: c

    Out[25]: [10, 11.75]

    Определение объекта list через с (обратите внимание на квадратные скобки).

    Вывод пары денежных потоков (обратите внимание на квадратные скобки).

    Поиск и вывод типа объекта с.

    Вывод первого элемента объекта c.

    Вывод второго элемента объекта c.

    Перезапись значения в первой позиции объекта c.

    Вывод результатов изменения.

    Доходность

    Доходность, R

    , инвестиционного проекта с денежными потоками c = (c0, c1) = (−10, 12) равна сумме этих денежных потоков, или R = c0 + + c1 = −10 + 12 = 2. Ставка доходности, r
    , — это доход R, деленный на инвестиционные затраты сегодня по модулю |c0|:

    .

    В Python данное вычисление сводится к следующим арифметическим операциям:

    In [26]: c = (-10, 12)

    In [27]: R = sum(c)

    In [28]: R

    Out[28]: 2

    In [29]: r = R / abs(c[0])

    In [30]: r

    Out[30]: 0.2

    Определение пары денежных потоков через объект tuple.

    Вычисление дохода R путем сложения всех элементов c и…

    …Вывод результата.

    Вычисление ставки доходности r через функцию abs(x), возвращающую абсолютное значение x

    …Вывод результата.

    Проценты

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

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

    Предположим, сегодня агент размещает в банке депозит c0 = −10 денежных единиц. Согласно депозитному договору через год он получит от банка c1 = 11 денежных единиц. Процент по вкладу, I

    , равен I = c0 + c1 = −10 + 11 = 1. Следовательно, процентная ставка, i
    , составляет
    .

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

    Приведенная стоимость

    Доступность кредитования и депонирования влекут за собой альтернативные издержки при вложении денег в инвестиционный проект. К примеру, денежный поток c1 = 12,1 через год нельзя напрямую сравнивать по стоимости с денежным потоком c0 = 12,1 сегодня, поскольку на деньгах, не вложенных в проект, можно заработать проценты.

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

    ,
    , которая сопоставляет одно вещественное число (денежный поток через год) с другим вещественным числом (денежным потоком сегодня). С учетом процентной ставки i = 0,1 приведенная стоимость составит

    .

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

    .

    Представление дисконтирования и подобных ему математических функций реализовано в Python довольно просто:

    In [31]: i = 0.1

    In [32]: def D(c1):

                 return c1 / (1 + i)

    In [33]: D(12.1)

    Out[33]: 10.999999999999998

    In [34]: D(11)

    Out[34]: 10.0

    Фиксирование процентной ставки i.

    Определение функции через оператор def, где D — название функции, c1 — имя параметра.

    Вывод приведенной стоимости через оператор return.

    Расчет приведенной стоимости 12.1 (обратите внимание на ошибку округления из-за внутренних проблем представления чисел с плавающей запятой).

    Расчет приведенной стоимости 11 (здесь получилось целое число).

    Чистая приведенная стоимость

    Как агенту решить, стоит ли реализовывать инвестиционный проект? Одним из критериев является чистая приведенная стоимость. Чистая приведенная стоимость, NPV

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

    .

    Расчет чистой приведенной стоимости представляет собой функцию NPV:

    2
    , сопоставляющую кортеж денежного потока с вещественным числом. Если чистая приведенная стоимость проекта имеет положительное значение, то проект следует реализовать, если отрицательное — нет, поскольку в таком случае альтернатива в виде банковского депозита более выгодна.

    Рассмотрим инвестиционный проект с денежными потоками cA = (−10,5, 12,1). Чистая приведенная стоимость NPV(cA) = −10,5 + D(12,1) = −10,5 + 11 = = 0,5, то есть данный проект выгоден. Другой инвестиционный проект, cB = (−10,5, 11), имеет отрицательную чистую приведенную стоимость NPV(cB) = −10,5 + D(11) = −10,5 + 10 = −0,5, поэтому агенту стоит отказаться от него.

    Эти примеры легко реализуются в Python через соответствующую функцию:

    In [35]: def NPV(c):

                 return c[0] + D(c[1])

    In [36]: cA = (-10.5, 12.1)

    In [37]: cB = (-10.5, 11)

    In [38]: NPV(cA)

    Out[38]: 0.4999999999999982

    In [39]: NPV(cB)

    Out[39]: -0.5

    Проект с положительной чистой приведенной стоимостью.

    Проект с отрицательной чистой приведенной стоимостью.

    Неопределенность

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

    Предположим, что через год экономика будет находиться в одном из двух состояний, u и d9, или, другими словами, в состоянии роста (хорошем) или спада (плохом). Тогда денежный поток проекта через год c1 можно выразить вектором:

    с двумя различными значениями:

    ,

    представляющими соответствующие денежные потоки для каждого состояния экономики. Формально данный денежный поток представлен так называемым вектором-столбцом:

    .

    Математическими операциями над такими векторами являются скалярное умножение и сложение, например:

    .

    Еще одной важной операцией над векторами является создание линейных комбинаций векторов. Рассмотрим два вектора, c1, d1

    2. Их линейная комбинация составляется следующим образом:

    .

    Следует отметить, что здесь и ранее предполагается α, β

    .

    Наиболее распространенным способом моделирования векторов и матриц в Python является библиотека NumPy. Для следующего примера кода рассмотрим инвестиционный проект с денежными потоками c0 = −10 и c1 = (20,5)T, где T обозначает транспонирование вектора — преобразование горизонтального вектора (вектора-строки) в вертикальный вектор (вектор-столбец). Основной класс, используемый для моделирования векторов, — ndarray (n-мерный массив):

    In [40]: import numpy as np

    In [41]: c0 = -10

    In [42]: c1 = np.array((20, 5))

    In [43]: type(c1)

    Out[43]: numpy.ndarray

    In [44]: c1

    Out[44]: array([20, 5])

    In [45]: c = (c0, c1)

    In [46]: c

    Out[46]: (-10, array([20, 5]))

    In [47]: 1.5 * c1 + 2

    Out[47]: array([32. , 9.5])

    In [48]: c1 + 1.5 * np.array((10, 4))

    Out[48]: array([35., 11.])

    Импорт библиотеки numpy.

    Отток денежных средств сегодня.

    Приток денежных средств неопределенного размера через год: одномерные объекты ndarray не различают строки (горизонталь) и столбцы (вертикаль).

    Поиск и вывод типа с1.

    Вывод вектора денежного потока.

    Объединение денежных потоков в объект tuple.

    Объект tuple, как и объект list, может содержать другие сложные структуры данных.

    Линейное преобразование вектора путем скалярного умножения и сложения (векторная числовая операция и трансляция).

    Линейная комбинация двух объектов ndarray (векторов).

    Финансовые активы

    Финансовыми активами называются финансовые инструменты (контракты), которые имеют фиксированную цену сегодня и неопределенную цену через год. К примеру, доля в собственном капитале фирмы, реализующей инвестиционный проект, может быть доступна по цене сегодня S0

    >0. Ее стоимость через год зависит от успеха инвестиционного проекта, то есть от того, каков будет приток денежных средств: высокий в состоянии u или низкий в состоянии d. Формально это выражается как
    при
    .

    Процесс ценообразования финансового актива

    заключается в установлении цены финансового актива на основании времени и состояния экономики. Следует отметить, что, в отличие от цены сегодня
    , цена через год полностью зависит от состояния экономики, что можно выразить формулой
    или ее укороченной версией S = (S0, S1). Для моделирования процесса ценообразования используется также библиотека NumPy:

    In [49]: S0 = 10

    In [50]: S1 = np.array((12.5, 7.5))

    In [51]: S = (S0, S1)

    In [52]: S

    Out[52]: (10, array([12.5, 7.5]))

    In [53]: S[0]

    Out[53]: 10

    In [54]: S[1][0]

    Out[54]: 12.5

    In [55]: S[1][1]

    Out[55]: 7.5

    Цена финансового актива сегодня.

    Неопределенная цена финансового актива через год в виде вектора (объекта ndarray).

    Процесс ценообразования в виде объекта tuple.

    Вывод информации касательно процесса ценообразования.

    Вывод цены финансового актива сегодня.

    Вывод цены финансового актива через год при u (первом) состоянии.

    Вывод цены финансового актива через год при d (втором) состоянии.

    Риск

    Часто неявно предполагается равновероятность двух состояний экономики, то есть при бесконечном многократном повторении рассматриваемого эксперимента в экономике наблюдается, что в одной половине случаев реализуется состояние u, а в другой — d.

    При определении вероятности на основе частоты вероятность реализации состояния рассчитывается как соотношение частоты наблюдения состояния к общему числу испытаний. Если состояние u наблюдается в 30 экспериментах из 50, то вероятность p

    0 при 0 p 1 составляет p = 30 / 50 = 0,6, или 60 %.

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

    Вероятностная мера

    Совокупность вероятностей физически возможных событий образует вероятностную меру с функцией

    , отображающей на еди­ничном интервале все элементы булеана (показательного множества) {u, d} при
    . В данном случае булеан представляет собой все физически возможные события (множество всех подмножеств).

    В нашем случае множество {u, d} является пространством состояний и обозначается символом Ω. Тройка (Ω, ℘(Ω), P) называется вероятностным пространством.

    Функция P, представляющая вероятностную меру, должна удовлетворять трем условиям.

    1. .
    2. .
    3. .

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

    В простой модельной экономике с двумя состояниями вероятность можно выразить как pP(u) и на основе третьего условия посчитать P(d) = 1 – p. Таким образом, вероятностная мера P определяется через значение вероятности p.

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

    Как правило, вероятностная мера моделируется через вектор и объект ndarray. По крайней мере это возможно в условиях дискретного пространства состоя­ний с конечным числом элементов:

    In [56]: p = 0.4

    In [57]: 1 - p

    Out[57]: 0.6

    In [58]: P = np.array((p, 1-p))

    In [59]: P

    Out[59]: array([0.4, 0.6])

    Понятие неопределенности

    Неопределенность в финансовой экономике может принимать различные формы. Риск в целом относится к ситуации, когда известно (предполагается, что известно) полное распределение вероятностей по будущим состоя­ниям экономики. Неопределенность относится к ситуациям, в которых такое распределение неизвестно. Практически всегда финансы опираются на модельную экономику в условиях риска, однако существует ряд исследований, посвященных финансовым проблемам именно в условиях неопределенности. См. соответствующую научную литературу в разделе «Справочные материалы» в конце главы.

    Математическое ожидание

    На основе вероятностной меры можно рассчитать математическое ожидание случайной величины — например, стоимости финансового актива через год. Математическое ожидание можно интерпретировать как средневзвешенное значение, где вес задается вероятностями, а усредненность обусловлена тем, что все вероятности в сумме должны составлять 1.

    Рассмотрим финансовый актив с процессом ценообразования S = (S0, S1). Математическое ожидание цены S1 через год по вероятностной мере P составляет:

    ,

    где pP(u). Если S1 = (20,5)T и p = 0,4, то значение ожидания:

    .

    Математическое ожидание можно выразить скалярным произведением (или внутренним произведением) двух векторов. При x, y

    2 скалярное произведение определяется как:

    .

    Таким образом, при P = (p, 1 − p)T и

    математическое ожидание можно рассчитать как:

    .

    В Python скалярное произведение определяется в виде функции через объект ndarray:

    In [60]: P

    Out[60]: array([0.4, 0.6])

    In [61]: S0 = 10

    In [62]: S1 = np.array((20, 5))

    In [63]: np.dot(P, S1)

    Out[63]: 11.0

    Ранее определенная вероятностная мера.

    Цена финансового актива сегодня.

    Вектор неопределенной цены финансового актива через год.

    Скалярное произведение двух векторов, рассчитывающее ожидание.

    Ожидаемая доходность

    В условиях неопределенности необходимо подкорректировать понятия дохода и ставки доходности. Ожидаемая доходность финансового актива равна разности ожидаемой цены через год и фактической цены сегодня. В этом можно убедиться, если взять математическое ожидание дохода R = (Ru, Rd)T и пре­образовать его следующим образом:

    Подставляем полученные ранее значения и получаем:

    .

    Таким образом, ожидаемая ставка доходности — это обычное соотношение ожидаемой доходности к цене сегодня:

    ,

    которое можно получить, выполнив аналогичные преобразования для ожидаемой доходности. В дальнейшем ожидаемая ставка доходности для краткости будет обозначаться выражением μ ≡ EP(r).

    В Python смоделировать расчет ожидаемой доходности и ожидаемой ставки доходности можно с помощью двух простых функций:

    In [64]: def ER(x0, x1):

                 return np.dot(P, x1) - x0

    In [65]: ER(S0, S1)

    Out[65]: 1.0

    In [66]: def mu(x0, x1):

                 return (np.dot(P, x1) - x0) / x0

    In [67]: mu(S0, S1)

    Out[67]: 0.1

    Определение ожидаемой доходности.

    Ожидаемая доходность определенного ранее финансового актива.

    Определение ожидаемой ставки доходности.

    Ожидаемая ставка доходности для определенного актива.

    Волатильность

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

    ,

    где

    . Поскольку волатильность определяется как стандартное (среднеквадратическое) отклонение ставок доходности, она представляет собой квадратный корень из дисперсии:

    .

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

    In [68]: def r(x0, x1):

                 return (x1 - x0) / x0

    In [69]: r(S0, S1)

    Out[69]: array([ 1. , -0.5])

    In [70]: mu = np.dot(P, r(S0, S1))

    In [71]: mu

    Out[71]: 0.10000000000000003

    In [72]: def sigma2(P, r, mu):

                 return np.dot(P, (r - mu) ** 2)

    In [73]: sigma2(P, r(S0, S1), mu)

    Out[73]: 0.54

    In [74]: def sigma(P, r, mu):

                 return np.sqrt(np.dot(P, (r - mu) ** 2))

    In [75]: sigma(P, r(S0, S1), mu)

    Out[75]: 0.7348469228349535

    Векторное вычисление ставки доходности.

    Применение функции к ранее определенному финансовому активу.

    Ожидаемая ставка доходности через скалярное произведение и…

    …Вывод результата.

    Определение дисперсии ставок доходности.

    Применение функции к вектору ставок доходности.

    Определение волатильности.

    И ее применение к вектору ставок доходности.

    Векторы, матрицы и библиотека NumPy

    Финансы как прикладная математическая дисциплина в значительной степени опираются на линейную алгебру и теорию вероятностей. Для дискретной модели экономики оба эти раздела прекрасно обрабатываются с помощью библиотеки NumPy (в частности, посредством объекта ndarray). Помимо моделирования, NumPy подходит для обработки информации, расчетов, оптимизации, визуализации и др. Практически все примеры в книге являются подтверждением этого.

    Условные требования

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

    , сопоставляющей события с (положительными) вещественными числами.

    Допустим, в экономике торгуются два финансовых актива: безрисковая облигация с процессом ценообразования B = (B0, B1) и рисковая акция с процессом ценообразования:

    .

    Выплата по колл-опциону (то есть опциону на покупку) на акцию через год составляет C1(S1(ω)) = max(S1(ω) − K, 0) и ω Ω. K

    0 называется ценой исполнения опциона.

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

    также является случайной величиной10.

    Следующий код Python визуализирует на отрезке вещественной оси вы­плату по колл-опциону. Предполагается, что существует только два состояния экономики и соответственно два соответствующих им значения. Для наглядности на рис. 2.1 графически представлена функция выплаты:

    In [76]: S1 = np.arange(20)

    In [77]: S1[:7]

    Out[77]: array([0, 1, 2, 3, 4, 5, 6])

    In [78]: K = 10

    In [79]: C1 = np.maximum(S1 - K, 0)

    In [80]: C1

    Out[80]: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

    In [81]: from pylab import mpl, plt

             # plotting configuration

             plt.style.use('seaborn')

             mpl.rcParams['savefig.dpi'] = 300

             mpl.rcParams['font.family'] = 'serif'

    In [82]: plt.figure(figsize=(10, 6))

             plt.plot(S1, C1, lw = 3.0, label='$C_1 = \max(S_1 - K, 0)$')

             plt.legend(loc=0)

             plt.xlabel('$S_1$')

             plt.ylabel('$C_1$');

    Генерация объекта ndarray с числами от 0 до 19.

    Вывод первых нескольких чисел.

    Установление цены исполнения колл-опциона.

    Векторный способ расчета выплат по колл-опциону.

    Вывод полученных значений: многие из них равны 0.

    Импорт основного графического модуля из matplotlib.

    Построение графика выплат по колл-опциону на основании стоимости акции, установка ширины линии 3 пиксела и подписи к ней в виде объекта-строки с записью формулы в формате LaTeX.

    Размещение условных обозначений, используемых в графике, в оптимальном месте (там, где они меньше всего закрывают элементы графика).

    Размещение подписи на оси X

    …На оси Y.

    Рис. 2.1. Выплата по колл-опциону

    Репликация

    При введении в экономику условного требования возникает важный вопрос: является ли выплата по условному требованию избыточной? С математической точки зрения вектор выплат по условному требованию может быть линейно зависимым или линейно независимым.

    Выплата по колл-опциону считается линейно зависимой (или избыточной), если существует решение задачи:

    при b, s

    .

    Ее можно представить в виде системы линейных уравнений:

    При условии

    эту систему можно развернуть так:

    и

    .

    Предположим, как и прежде, что торгуются два финансовых актива: безрисковая облигация B = (10, 11) и рисковая акция S = (10, (20, 5)T). Предположим также, что K = 15, в результате чего C1 = (5, 0)T. Подставив в приведенные ранее формулы эти числа, мы получим:

    и

    .

    Другими словами, покупка одной трети акции и продажа 5/33 облигации без покрытия полностью реплицирует (имитирует) выплату по колл-опциону. Следовательно, выплата по колл-опциону линейно зависит от векторов выплат по облигации и по акции.

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

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

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

    Рассмотрим квадратную матрицу

    с четырьмя элементами при условии
    :

    .

    Векторы будущих выплат по облигации и по акции представляют собой значения в первом и втором столбцах матрицы соответственно. Первая строка содержит выплаты по обоим финансовым активам в состоянии u, а вторая — выплаты при реализации состояния d. С учетом этих условностей задача репликации может быть представлена в матричной форме как:

    ,

    где φ

    2 — вектор, содержащий позиции портфеля облигации и акции для репликации φ ≡ (b, s)T. Как правило, φ называют просто портфелем или торговой стратегией. Таким образом:

    ,

    в связи с чем умножение матриц определяется как:

    ,

    что показывает равенство между этим способом представления задачи репликации и предыдущим.

    Матрицы в Python моделируются посредством класса ndarray. Модуль np.linalg в библиотеке NumPy предоставляет множество функций для выполнения операций линейной алгебры, среди которых есть и функция для решения систем линейных уравнений в матричной форме — именно то, что нужно в нашем случае:

    In [83]: B = (10, np.array((11, 11)))

    In [84]: S = (10, np.array((20, 5)))

    In [85]: M = np.array((B[1], S[1])).T

    In [86]: M

    Out[86]: array([[11, 20],

                    [11,  5]])

    In [87]: K = 15

    In [88]: C1 = np.maximum(S[1] - K, 0)

    In [89]: C1

    Out[89]: array([5, 0])

    In [90]: phi = np.linalg.solve(M, C1)

    In [91]: phi

    Out[91]: array([-0.15151515, 0.33333333])

    Определение процесса ценообразования безрисковой облигации.

    Определение процесса ценообразования рисковой акции.

    Определение матрицы (двумерного объекта ndarray) с векторами будущих выплат.

    Отображение матрицы с числовыми значениями.

    Установление цены исполнения колл-опциона и…

    …Вычисление значения вектора выплат через год.

    Отображение числовых значений вектора выплат.

    Решение задачи репликации в матричной форме для получения оптимальной позиции портфеля.

    Арбитражное ценообразование

    Сколько стоит реплицировать (имитировать) выплату по колл-опциону? На этот вопрос можно легко ответить после выведения реплицирующего портфеля. Определим стоимость реплицирующего портфеля сегодня V0(φ) через скалярное произведение:

    ,

    или, если перевести в числовую форму:

    .

    Случайная стоимость реплицирующего портфеля через год V1(φ) может быть представлена умножением матриц:

    .

    В совокупности процесс формирования стоимости портфеля выглядит как V(φ) = (V0(φ), V1(φ)), или V = (V0, V1) для краткости, если нет неопределенности относительно портфеля.

    Наличие портфеля, идеально реплицирующего будущие выплаты по условному требованию, поднимает следующий вопрос: что, если цена условного требования сегодня отличается от затрат на создание реплицирующего портфеля? Ответ одновременно прост и сложен: значит, в экономике существует арбитраж или арбитражная возможность. Арбитраж — это торговая стратегия φ, которая создает безрисковую прибыль из инвестиций, равных нулю. Формально φ является арбитражем, если:

    или

    .

    Предположим, что цена колл-опциона составляет C0 = 2, что выше затрат на создание реплицирующего портфеля. Торговая стратегия продажи колл-опциона на рынке за 2 и покупки реплицирующего его портфеля за 1,818181 приносит немедленную прибыль в размере разницы этих двух чисел. По определению реплицирующего портфеля, через год выплаты по нему и колл-опциону компенсируют друг друга:

    .

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

    Модель экономики, допускающую возможность арбитража, можно считать нежизнеспособной. Поэтому C0 = 1,818181 — единственная цена, которая согласуется с отсутствием арбитража, то есть является арбитражной ценой колл-опциона. Если существует портфель φ, реплицирующий выплаты по условному требованию V1(φ) = C1, то арбитражная цена условного требования C0 = V0(φ).

    Формально арбитражная цена — это скалярное произведение реплициру­ющего портфеля и вектора цен реплицируемых финансовых активов, которое формирует безарбитражный процесс ценообразования для условного требования C = (C0, C1):

    .

    В Python арбитражная цена представлена одним расчетом, основанным на предыдущих определениях и вычислениях:

    In [92]: C0 = np.dot(phi, (B[0], S[0]))

    In [93]: C0

    Out[93]: 1.8181818181818183

    In [94]: 10/3 - 50/33

    Out[94]: 1.8181818181818183

    Полнота рынка

    Работает ли арбитражное ценообразование для каждого условного требования? Да, по крайней мере для тех, которые реплицируются портфелями финансовых активов, торгуемых в экономике. Набор достижимых условных требований

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

    ,

    если продажа без покрытия запрещена, и:

    ,

    если разрешена в неограниченном объеме.

    Вернемся к ранее представленным безрисковой облигации и рисковой акции с процессами ценообразования B = (B0, B1) и

    соответственно, где
    и
    . Явно видно, что задача репликации:

    имеет для любого

    одно решение:

    или

    .

    Это решение было выведено при осуществлении репликации выплат по определенному колл-опциону и может считаться универсальным, поскольку не было задано никаких специальных условий относительно выплат, кроме

    .

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

    имеет единственное решение

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

    Свойство линейной оболочки может быть визуализировано в Python посредством библиотеки matplotlib. Для этого моделируется 1000 случайных структур портфеля. Первое ограничение заключается в том, что позиции портфеля должны быть положительными и суммарно равными единице. На рис. 2.2 показан результат:

    In [95]: from numpy.random import default_rng

             rng = default_rng(100)

    In [96]: n = 1000

    In [97]: b = rng.random(n)

    In [98]: b[:5]

    Out[98]: array([0.83498163, 0.59655403, 0.28886324, 0.04295157, 0.9736544 ])

    In [99]: s = (1 - b)

    In [100]: s[:5]

    Out[100]: array([0.16501837, 0.40344597, 0.71113676, 0.95704843, 0.0263456 ])

    In [101]: def portfolio(b, s):

                  A = [b[i] * B[1] + s[i] * S[1] for i in range(n)]

                  return np.array(A)

    In [102]: A = portfolio(b, s)

    In [103]: A[:3]

    Out[103]: array([[12.48516533, 10.00988978],

                     [14.63101376,  8.57932416],

                     [17.40023082,  6.73317945]])

    In [104]: plt.figure(figsize=(10, 6))

              plt.plot(A[:, 0], A[:, 1], 'r.');

    Установление начального числа для генератора случайных чисел.

    Количество значений для моделирования.

    Моделирование позиции облигации для значений от 0 до 1 с помощью равномерного распределения.

    Определение позиции акции через разницу между 1 и позицией облигации.

    Вычисление векторов выплат по всем случайным портфелям с последу­ющим сбором результатов в объект list (это выражение языка Python называется генерацией списков).

    Функция возвращает ndarray-версию результатов.

    Начало вычисления.

    Вывод результатов вычисления на экран.

    Рис. 2.2. Случайные портфели, расположенные на одномерной линии

    На рис. 2.3 показаны результаты, когда позиции портфеля не должны быть равны 1:

    In [105]: s = rng.random(n)

    In [106]: b[:5] + s[:5]

    Out[106]: array([1.36885777, 1.5863474 , 0.71245805, 0.32077672, 1.5401562 ])

    In [107]: A = portfolio(b, s)

    In [108]: plt.figure(figsize=(10, 6))

              plt.plot(A[:, 0], A[:, 1], 'r.');

    Свободное моделирование акций для значений от 0 до 1.

    Вычисление векторов выплат портфеля.

    Рис. 2.3. Случайные портфели, расположенные на двумерной области (ромб)

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

    In [109]: b = rng.standard_normal(n)

    In [110]: s = rng.standard_normal(n)

    In [111]: b[:5] + s[:5]

    Out[111]: array([-0.23046605, -3.45760465, 1.10260637, -2.44445777,

               1.05866637])

    In [112]: A = portfolio(b, s)

    In [113]: plt.figure(figsize=(10, 6))

              plt.plot(A[:, 0], A[:, 1], 'r.');

    Положительные и отрицательные позиции портфеля моделируются средствами стандартного нормального распределения.

    Рис. 2.4. Случайные портфели, расположенные в двумерной области вокруг начала координат

    Если b и s могут принимать произвольные значения на вещественной прямой, b, s

    , то получаемые портфели полностью покрывают векторное пространство
    2. Как говорилось ранее, векторы выплат торгуемых финансовых активов в таком случае порождают пространство
    2.

    Ценные бумаги Эрроу — Дебре

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

    и

    имеют (уникальные) решения, и обе ценные бумаги имеют уникальные арбитражные цены.

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

    2. Любой вектор этого пространства может быть однозначно выражен (реплицирован) как линейная комбинация векторов, образующих стандартный базис. С финансовой точки зрения замена исходных векторов будущих цен облигации и акции на ценные бумаги Эрроу — Дебре в качестве базиса для модельной экономики значительно упрощает задачу репликации для всех остальных условных требований.

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

    Рассмотрим две ценные бумаги Эрроу — Дебре с процессами ценообразования

    и
    и определим:

    .

    Общее условное требование с вектором будущих выплат будет иметь вид:

    .

    Следовательно, реплицирующий портфель φγ для условного требования тривиально задается через формулу

    , так как:

    .

    Получается, что арбитражную цену условного требования можно рассчитать через:

    .

    Таким образом мы продемонстрировали, как ценные бумаги Эрроу — Дебре упрощают репликацию условных требований и процесс арбитражного ценообразования.

    Ценообразование по мартингалу

    Особым вариантом вероятностной меры является мартингальная мера

    , которая преобразует процесс дисконтирования цены финансового актива в мартингал. Акция становится мартингалом Q, если:

    .

    При

    данное выражение тривиально выполнено для безрисковой облигации:

    .

    Также можно говорить о том, что в случае мартингала процессы ценообразования дрейфуют (в среднем) с безрисковой ставкой:

    Если обозначим

    , то получим следующее равенство:

    и после простых преобразований:

    .

    Учитывая изложенные ранее условия, для того чтобы q определяло вероятностную меру, необходимо, чтобы выполнялось условие

    , в результате которого появляется новое вероятностное пространство (Ω, ℘(Ω), Q), где Q заменяет P.

    Но что, если эти соотношения не выполняются для S1? Тогда простой арбитраж заключается либо в покупке рискового актива при условии

    , либо в его продаже при другом условии —
    .

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

    Если брать за основу процессы ценообразования из примеров выше, расчет q в Python подразумевает простую арифметическую операцию над числами с плавающей запятой:

    In [114]: i = (B[1][0] - B[0]) / B[0]

    In [115]: i

    Out[115]: 0.1

    In [116]: q = (S[0] * (1 + i) - S[1][1]) / (S[1][0] - S[1][1])

    In [117]: q

    Out[117]: 0.4

    Первая фундаментальная теорема ценообразования финансовых активов

    Рассуждения в конце предыдущего раздела наводят на мысль о связи между мартингальными мерами и арбитражем. В финансовой математике эти, казалось бы, несвязанные понятия формально объединены первой фундаментальной теоремой цено­образования финансовых активов. Первые работы по этой теме были опубликованы Коксом и Россом (1976), Харрисоном и Крепсом (1979) и Харрисоном и Плиской (1981).

    Первая фундаментальная теорема ценообразования финансовых активов. Эквивалентны следующие утверждения.

    1. Мартингальная мера существует.
    2. Экономика является безарбитражной.

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

    Из утверждения 1 следует утверждение 2: если мартингальная мера существует, то процессы ценообразования не допускают простых (слабых) арбитражей. Поскольку два вектора будущих цен линейно независимы, каждое условное требование может быть реплицировано через торговлю двумя финансовыми активами, что подразумевает уникальность арбитражных цен. Следовательно, арбитража не существует.

    Из утверждения 2 следует утверждение 1: как было показано ранее, если модельная экономика свободна от арбитража, то мартингальная мера существует.

    Ценообразование через математическое ожидание

    Следствием первой фундаментальной теоремы является то, что любое достижимое условное требование C1

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

    Другими словами, процесс дисконтирования ценообразования колл-опциона (и любого другого условного требования) является мартингалом с мартингальной мерой:

    В Python ценообразование по мартингалу сводится к вычислению скалярного произведения:

    In [118]: Q = (q, 1 - q)

    In [119]: np.dot(Q, C1) / (1 + i)

    Out[119]: 1.8181818181818181

    Определение мартингальной меры Q в виде объекта tuple.

    Реализация формулы ценообразования по мартингалу.

    Вторая фундаментальная теорема ценообразования финансовых активов

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

    Вторая фундаментальная теорема ценообразования финансовых активов. Эквивалентны следующие утверждения.

    1. Мартингальная мера уникальна.
    2. Модель рынка является полной.

    Данная теорема также подходит для простой модельной экономики из пре­дыдущих обсуждений. Более подробно полнота рынка анализируется в главе 3.

    Портфель Марковица

    Крупным прорывом в области финансов стала формализация и квантификация портфельных инвестиций с помощью портфельной теории (mean-variance portfolio theory, MVP), впервые предложенной Марковицем в 1952 году. В какой-то степени данную теорию можно считать началом зарождения количественных финансов и, следовательно, расширения использования математики в финансовой сфере.

    Портфельная теория сводит финансовый актив к первому и второму моменту его случайной доходности, а именно к среднему значению ожидаемой ставки доходности и дисперсии ставок доходности (или волатильности), определяемой как стандартное отклонение ставок доходности. Хотя этот подход обычно называют анализом среднего отклонения, часто используется также словосочетание «средняя волатильность».

    Вернемся к безрисковой облигации и рисковой акции с процес­сами ценообразования

    и
    и матрице будущих цен
    , для которой два столбца заданы векторами будущих цен двух финансовых активов. Каковы ожидаемая ставка доходности и волатильность портфеля φ, состоящего из b процентов, вложенных в облигацию, и s процентов, вложенных в акцию? Обратите внимание на то, что сейчас предполагается ситуация, для которой b + s = 1, причем b, s
    0. Конечно, это условие можно смягчить, но оно упрощает объяснение, приводимое в данном разделе.

    Ожидаемая доходность портфеля имеет следующий вид:

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

    Определив

    как матрицу ставок доходности при:

    ,

    мы получаем ставку ожидаемой доходности портфеля:

    .

    Другими словами, ожидаемая ставка доходности портфеля — это сумма b-кратной безрисковой процентной ставки и s-кратной ожидаемой ставки доходности акции.

    Далее вычислим дисперсию портфеля:

    Иными словами, дисперсия портфеля в s2 раз больше дисперсии акции, что интуитивно понятно, поскольку облигация не подвержена риску и никак не влияет на отклонение портфеля. Следовательно, волатильность портфеля определяется как:

    .

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

    In [120]: B = (10, np.array((11, 11)))

    In [121]: S = (10, np.array((20, 5)))

    In [122]: M = np.array((B[1], S[1])).T

    In [123]: M

    Out[123]: array([[11, 20],

                     [11,  5]])

    In [124]: M0 = np.array((B[0], S[0]))

    In [125]: R = M / M0 – 1

    In [126]: R

    Out[126]: array([[ 0.1, 1.  ],

                     [ 0.1, -0.5]])

    In [127]: P = np.array((0.5, 0.5))

    Матрица с будущими ценами финансовых активов.

    Вектор с ценами финансовых активов сегодня.

    Вычисление матрицы доходности в векторном виде.

    Результаты расчета.

    Определение вероятностной меры.

    На этой основе можно рассчитать ожидаемую доходность и волатильность портфеля через скалярное произведение:

    In [128]: np.dot(P, R)

    Out[128]: array([0.1 , 0.25])

    In [129]: s = 0.55

    In [130]: phi = (1-s, s)

    In [131]: mu = np.dot(phi, np.dot(P, R))

    In [132]: mu

    Out[132]: 0.18250000000000005

    In [133]: sigma = s * R[:, 1].std()

    In [134]: sigma

    Out[134]: 0.41250000000000003

    Ожидаемая доходность облигации и акции.

    Пример веса акции в портфеле (в десятичных долях).

    Полученный в результате портфель с нормализованным весом 1.

    Ожидаемая доходность портфеля с учетом распределения.

    Значение находится между безрисковой доходностью и доходностью акции.

    Волатильность портфеля: код Python здесь работает только при p = 0,5.

    Значение находится между волатильностью облигации, равной 0, и волатильностью акции, равной 0,75.

    Изменение веса акции в портфеле приводит к различным комбинациям «риск — доходность». На рис. 2.5 показаны ожидаемые доходность и волатильность портфеля для значений s от 0 до 1. Как видно из графика, ожидаемая доходность портфеля (от 0,1 до 0,25) и волатильность (от 0 до 0,75) линейно возрастают с увеличением веса акции в портфеле s:

    In [135]: values = np.linspace(0, 1, 25)

    In [136]: mu = [np.dot(((1-s), s), np.dot(P, R))

                    for s in values]

    In [137]: sigma = [s * R[:, 1].std() for s in values]

    In [138]: plt.figure(figsize=(10, 6))

              plt.plot(values, mu, lw = 3.0, label='$\mu_p$')

              plt.plot(values, sigma, '--', lw = 3.0, label='$\sigma_p$')

              plt.legend(loc=0)

              plt.xlabel('$s$');

    Создание объекта ndarray с 24 равномерно распределенными интервалами между 0 и 1.

    Вычисление ожидаемой доходности портфеля для каждого элемента values с последующим сохранением результатов в объекте list.

    Вычисление волатильности портфеля для каждого элемента values с последующим сохранением результатов в объекте list.

    Рис. 2.5. Ожидаемые доходность и волатильность портфеля с различным распределением

    Обратите внимание на то, что генерация списка sigma = [s * R[:, 1].std() for s in values] является сокращенным вариантом следующего кода11:

    sigma = list()

    for s in values:

        sigma.append(s * R[:, 1].std())

    Типичный график, который можно увидеть в контексте портфельной теории, — это график соотношения ожидаемой доходности и волатильности портфеля. Рисунок 2.6 показывает, что доход инвестора зависит от риска (волатильности), который он готов принять. В нашем случае зависимость линейная:

    In [139]: plt.figure(figsize=(10, 6))

              plt.plot(sigma, mu, lw = 3.0, label='risk-return')

              plt.legend(loc=0)

              plt.xlabel('$\sigma_p$')

              plt.ylabel('$\mu_p$');

    Рис. 2.6. Реальные комбинации ожидаемой доходности и волатильности портфеля

    Резюме

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

    Справочные материалы

    В этой главе были упомянуты следующие книги и статьи.

    • Cox J., Ross S. The Valuation of Options for Alternative Stochastic Processes // Journal of Financial Economics, 1976. — № 3. — Р. 145–166.
    • Delbaen F., Schachermayer W. The Mathematics of Arbitrage. — Berlin: Springer Verlag, 2006.
    • Guidolin M., Rinaldi F. Ambiguity in Asset Pricing and Portfolio Choice: A Review of the Literature // Theory and Decision, 2013. — № 74. — Р. 183–217. https://ssrn.com/abstract=1673494.
    • Harrison M., Kreps D.. Martingales and Arbitrage in Multiperiod Securities Markets // Journal of Economic Theory, 1979. — № 20. — Р. 381–408.
    • Harrison M., Pliska S. Martingales and Stochastic Integrals in the Theory of Continuous Trading // Stochastic Processes and their Applications, 1981. — № 11. — Р. 215–260.
    • Markowitz H. Portfolio Selection // Journal of Finance, 1952. — № 7 (1). — Р. 77–91.

    7 Подробно о фундаментальной теореме ценообразования финансовых активов можно узнать из оригинальных статей Харрисона и Крепса (1979) и Харрисона и Плиски (1981).

    8 Более подробное объяснение концепции экономики изложено в главе 5.

    9 u — от up («вверх»), d — от down («вниз»). — Примеч. пер.

    10 Формальное определение случайной величины приводится в главе 5.

    11 Подробнее о структурах данных и выражениях генерации — в документации Python, в разделе «Структуры данных» (https://oreil.ly/0dbCi).

    Подробнее о структурах данных и выражениях генерации — в документации Python, в разделе «Структуры данных» (https://oreil.ly/0dbCi).

    Основой финансовой модели является идея экономики. Экономика — это абстрактное понятие, включающее в себя отдельные элементы финансовой модели: активы (реальные и финансовые), агентов (люди и учреждения) или деньги. Как и в реальном мире, экономику нельзя увидеть или потрогать. Ее невозможно представить в какой-то одной определенной форме — обобщающий термин служит скорее для упрощения коммуникации8.

    11

    Подробно о фундаментальной теореме ценообразования финансовых активов можно узнать из оригинальных статей Харрисона и Крепса (1979) и Харрисона и Плиски (1981).

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

    Предположим, что через год экономика будет находиться в одном из двух состояний, u и d9, или, другими словами, в состоянии роста (хорошем) или спада (плохом). Тогда денежный поток проекта через год c1 можно выразить вектором:

    10

    Более подробное объяснение концепции экономики изложено в главе 5.

    u — от up («вверх»), d — от down («вниз»). — Примеч. пер.

    Формальное определение случайной величины приводится в главе 5.

    Глава 3. Экономика с тремя состояниями

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

    Стэнли Плиска (1997)

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

    Уильям Шарп (1964)

    В предыдущей главе мы рассмотрели простейшую модельную экономику, на которой, помимо всего прочего, смогли изучить понятие финансовой неопределенности. В этой главе в экономику с двумя торгуемыми финансовыми активами добавляется еще одно состояние. На основе статической экономики уже с тремя состояниями будут рассмотрены неполнота рынка и неопределенность мартингальной меры, а также представлены подходы к решению задачи, связанной с неполнотой рынка и ее последствиями для ценообразования условных требований: суперрепликация и аппроксимирующая репликация. В конце будет рассмотрена модель ценообразования капитальных активов (Capital Asset Pricing Model, CAPM), которая основывается на анализе портфеля среднего отклонения и добавляет параметры равновесия для выведения стоимости реплицируемых и нереплицируемых финансовых активов в пространстве средней волатильности.

    Далее представлены основные темы третьей главы.

    Финансы

    Математика

    Python

    Неопределенность

    Вероятностное пространство

    ndarray

    Финансовые активы

    Векторы, матрицы

    ndarray

    Достижимые условные требования

    Линейная оболочка векторов, базис векторного пространства

    ndarray

    Ценообразование по мартингалу, арбитраж

    Группы вероятностных мер, математическое ожидание

    ndarray, np.dot

    Суперрепликация

    Минимизация, ограничения

    scipy.optimize.minimize, dict, lambda

    Аппроксимирующая репликация

    Среднеквадратическая ошибка, метод наименьших квадратов (МНК)

    np.linalg.lstsq

    Линия рынка капитала

    Математическое ожидание, стандартное отклонение

    NumPy

    Модель ценообразования капитальных активов

    Корреляция, ковариация

    NumPy

    Предположения и расчеты, относящиеся к экономике с двумя состояниями (см. предыдущую главу), переносятся на экономику с тремя состояниями, рассматриваемую далее, если не указано иное.

    Неопределенность

    В экономике с тремя состояниями рассматриваются два момента времени: «сегодня», t = 0, и «через один год», t = 1. Пространство состояний имеет вид Ω = {u, m, d}, где {u, m, d} — это три различных возможных состояния экономики через год. Булеан пространства состояний задан как:

    .

    На булеане определена вероятностная мера P с условиями

    , ω Ω, а вероятностное пространство (Ω, ℘(Ω), P) представляет собой неопределенность в модельной экономике.

    Финансовые активы

    В модельной экономике торгуются два финансовых актива. Первый — это безрисковая облигация B = (B0, B1), где B0 = 10 и B1 = (11, 11, 11)T. Безрисковая процентная ставка i = 0,1.

    Второй актив — это рисковая акция

    , где S0 = 10 и:

    .

    Матрицу рыночных выплат

    обозначим как:

    .

    Достижимые условные требования

    Линейная оболочка торгуемых финансовых активов называется также множеством достижимых условных требований

    . Условное требование C1: Ω →
    0 считается достижимым, если выплата по нему может быть выражена линейной комбинацией векторов выплат по торгуемым активам, или, другими словами, существует портфель φ, который удовлетворяет условию
    . Следовательно:

    ,

    если нет ограничений касательно позиций портфеля, либо:

    ,

    если продажа без покрытия запрещена.

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

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

    Вычитание второго уравнения из первого дает s = 1/10. Вычитание третьего уравнения из первого дает s = 1/15, что, очевидно, противоречит первому решению. Таким образом, эта задача репликации не имеет решения.

    В Python множество достижимых условных требований может быть визуализировано в трех измерениях. Данный подход основан на составлении портфеля через моделирование Монте-Карло, в котором для простоты допускаются только положительные позиции портфеля в диапазоне от 0 до 1. На рис. 3.1 изображен график, где два вектора охватывают только двумерную область трехмерного пространства. Если бы рынок был полным, смоделированные векторы выплат заполнили бы куб (финансовые активы покрыли бы векторное пространство

    3), а не образовали в нем прямоугольную область (
    2). Моделирование неопределенности происходит по аналогии с кодом, представленным в предыдущей главе, но с некоторыми изменениями, необходимыми для работы с тремя возможными будущими состояниями экономики:

    In [1]: import numpy as np

            from numpy.random import default_rng

            np.set_printoptions(precision=5, suppress=True)

    In [2]: rng = default_rng(100)

    In [3]: B = (10, np.array((11, 11, 11)))

    In [4]: S = (10, np.array((20, 10, 5)))

    In [5]: n = 1000

    In [6]: b = rng.random(n)

    In [7]: b[:5]

    Out[7]: array([0.83498, 0.59655, 0.28886, 0.04295, 0.97365])

    In [8]: s = rng.random(n)

    In [9]: A = [b[i] * B[1] + s[i] * S[1] for i in range(n)]

    In [10]: A = np.array(A)

    In [11]: A[:3]

    Out[11]: array([[19.86232, 14.52356, 11.85418],

                    [26.35796, 16.46003, 11.51106],

                    [11.64939, 7.41344, 5.29547]])

    In [12]: from pylab import mpl, plt

             plt.style.use('seaborn')

             mpl.rcParams['savefig.dpi'] = 300

             mpl.rcParams['font.family'] = 'serif'

             from mpl_toolkits.mplot3d import Axes3D

    In [13]: fig = plt.figure(figsize=(10, 6))

             ax = fig.add_subplot(111, projection='3d')

             ax.scatter(A[:, 0], A[:, 1], A[:, 2], c='r', marker='.');

    Количество портфелей, которые необходимо смоделировать.

    Случайная позиция в облигации с несколькими примерами (все значения находятся в диапазоне от 0 до 1).

    Случайная позиция в акции.

    Генерация списка с расчетом векторов выплат по случайным портфелям.

    Импорт графического модуля matplotlib и задание основных параметров для него.

    Рис. 3.1. Трехмерная визуализация векторов выплат по случайным портфелям

    Импорт инструментов формирования трехмерного графика.

    Создание пустого холста.

    Добавление области для трехмерного объекта.

    Визуализация векторов выплат в виде множества отдельных красных точек.

    Неполнота рынка

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

    Ценообразование по мартингалу

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

    Мартингальные меры

    Любая вероятностная мера преобразует процесс дисконтированного ценообразования облигации в мартингал. А как насчет процесса ценообразования акции? Уравнением, определяющим мартингальную меру Q: ℘(Ω) →

    0, является:

    или

    ,

    где qωQ(ω), ω Ω. В численном виде и при условии qd = 1 − quqm это уравнение можно представить следующим образом:

    .

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

    и необязательное:

    ,

    а также обязательное:

    и необязательное:

    .

    Таким образом, можно заключить, что существует неограниченное коли­чество вероятностных мер, которые преобразуют процесс дисконтированного ценообразования акции в мартингал. При qqu множество всех мартингальных мер

    , согласующихся с рыночной моделью, имеет следующий вид:

    .

    Для примера подставим сюда q = 3/10, тогда:

    и

    ,

    как и требуется для процесса ценообразования акции.

    Следовательно, к предыдущему коду мы можем добавить следующее вычисление:

    In [14]: Q = np.array((0.3, 0.3, 0.4))

    In [15]: np.dot(Q, S[1])

    Out[15]: 11.0

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

    Мартингальные меры в условиях неполноты рынка

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

    Риск-нейтральное ценообразование

    К каким последствиям приводит неограниченное количество согласованных с рынком мартингальных мер при арбитражном ценообразовании условных требований? Во-первых, арбитражное ценообразование достижимых условных требова­ний

    выполняется так же, как в условиях полного рынка: стоимость реплицирующего портфеля равна цене реплицируемого условного требования, в противном случае возникают арбитражные возможности. Формально это можно выразить как C0 = V0(φ) при V1(φ) = C1.

    С недостижимыми условными требованиями

    все не так просто. Предположим, что у нас есть одна из ценных бумаг Эрроу — Дебре — γu. Как было показано ранее, она нереплицируема и поэтому принадлежит множеству
    . Ее мартингальная цена составляет:

    .

    Величину

    часто называют зависящей от состояния экономики ценой одной денежной единицы в состоянии ω Ω, и она является простой дисконтированной мартингальной вероятностью для данного состояния.

    В модельной экономике должно выполняться условие 1/10 q 2/5, поэтому мартингальная цена — цена, при которой невозможен арбитраж, — лежит в интервале:

    .

    Другими словами, в рассматриваемых нами условиях модельной экономики любая цена между 1/11 и 4/11 для ценной бумаги Эрроу — Дебре согласуется с отсутствием арбитража. Расчеты для других недостижимых условных требований будут иметь аналогичные результаты.

    Суперрепликация

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

    реплицирует условное требование C1, то:

    .

    Для недостижимого условного требования такое идеальное хеджирование недоступно, однако всегда можно составить портфель, суперреплицирующий выплаты по нему. Портфель φ суперреплицирует условное требование C1, если выплата по нему в каждом будущем состоянии экономики больше выплаты по условному требованию или равна ей — V1(φ) C1.

    Вернемся к ценной бумаге Эрроу — Дебре γu, которая является недостижимым условным требованием. Выплата по ней может быть суперреплицирована, например, портфелем, содержащим лишь безрисковую облигацию:

    .

    В результате мы получаем выплату:

    ,

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

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

    ,

    таким образом:

    или

    ,

    таким образом:

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

    In [16]: C1 = np.array((1, 0, 0))

    In [17]: 1 / B[1][0] * B[1] >= C1

    Out[17]: array([ True, True, True])

    In [18]: 1 / B[1][0] * B[0]

    Out[18]: 0.9090909090909092

    In [19]: def V(phi, t):

                 return phi[0] * B[t] + phi[1] * S[t]

    In [20]: phi = np.array((0.04, 0.03))

    In [21]: V(phi, 0)

    Out[21]: 0.7

    In [22]: V(phi, 1)

    Out[22]: array([1.04, 0.74, 0.59])

    Выплата по условному требованию (ценная бумага Эрроу — Дебре).

    Портфель, содержащий только облигацию, проверенный на наличие свойства суперрепликации.

    Затраты на создание данного портфеля.

    Функция для вычисления стоимости портфеля phi сегодня, t = 0, или через один год, t = 1.

    Другой вариант суперреплицирующего портфеля.

    Затраты на его создание (которые ниже, чем на портфель, содержащий только облигацию).

    И стоимость портфеля, суперреплицирующего ценную бумагу Эрроу — Дебре (то есть выплата по нему), через год.

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

    In [23]: from scipy.optimize import minimize

    In [24]: cons = ({'type': 'ineq', 'fun': lambda phi: V(phi, 1) - C1})

    In [25]: res = minimize(lambda phi: V(phi, 0),

                            (0.01, 0.01),

                            method='SLSQP',

                            constraints=cons)

    In [26]: res

    Out[26]:      fun: 0.3636363636310989

                  jac: array([10., 10.])

              message: 'Optimization terminated successfully'

                 nfev: 6

                  nit: 2

                 njev: 2

               status: 0

              success: True

                    x: array([-0.0303 ,  0.06667])

    In [27]: V(res['x'], 0)

    Out[27]: 0.3636363636310989

    In [28]: V(res['x'], 1)

    Out[28]: array([ 1.     ,  0.33333, -0.     ])

    Импорт функции minimize из модуля scipy.optimize.

    Определение ограничения в виде векторного неравенства на основе функции lambda: функция λ моделируется здесь как λ(φ) = V1(φ) − C1, для которой должно выполняться ограничение в виде неравенства λ(φ) 0.

    Оптимизируемая функция lambda.

    Исходное предположение оптимального решения (здесь играет не слишком важную роль).

    Метод минимизации, здесь — последовательный метод наименьших квадратов (Sequential Least Squares Programming, SLSQP).

    Определенные ранее ограничения для задачи по минимизации.

    Полный словарь с результатами минимизации с оптимальными параметрами x и минимальным значением функции fun.

    Значение оптимального суперреплицирующего портфеля сегодня.

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

    Аппроксимирующая репликация

    Суперрепликация предполагает несколько экстремальную ситуацию: выплата по суперреплицируемому условному требованию должна быть одинакова или превышена в любом заданном состоянии при любых обстоятельствах. Например, компания по страхованию жизни инвестирует таким образом, чтобы иметь возможность при любых обстоятельствах (что в реальном мире часто обозначает «с вероятностью 99,9 %») выполнить свои будущие финансовые и договорные обязательства (условные требования). Однако во многих случаях суперрепликация может оказаться экономически нецелесообразным или даже нежизнеспособным вариантом.

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

    Возможным вариантом целевой функции или функции погрешности является средняя квадратичная погрешность (mean squared error, MSE). Пусть V1(φ) — вектор стоимости портфеля репликации φ, тогда MSE для условного требования C1 с учетом портфеля φ составляет:

    .

    Данное уравнение определяет величину, которую необходимо минимизировать. Для достижимого условного требования MSE равна нулю. Сама задача в матричной форме имеет вид:

    .

    В линейной алгебре эта задача относится к обычной регрессии МНК. Пре­дыдущее уравнение является частным случаем задачи линейной регрессии МНК.

    Стандартным и эффективным подходом к решению задач такого рода в Python является использование функции np.linalg.lstsq из библиотеки NumPy:

    In [29]: M = np.array((B[1], S[1])).T

    In [30]: M

    Out[30]: array([[11, 20],

                    [11, 10],

                    [11,  5]])

    In [31]: reg = np.linalg.lstsq(M, C1, rcond=-1)

    In [32]: reg

             # (array,

             # array,

             # int,

             # array)

    Out[32]: (array([-0.04545,  0.07143]), array([0.07143]), 2, array([28.93836,

              7.11136]))

    In [33]: V(reg[0], 0)

    Out[33]: 0.2597402597402598

    In [34]: V(reg[0], 1)

    Out[34]: array([ 0.92857,  0.21429, -0.14286])

    In [35]: V(reg[0], 1) - C1

    Out[35]: array([-0.07143,  0.21429, -0.14286])

    In [36]: np.mean((V(reg[0], 1) - C1) ** 2)

    Out[36]: 0.02380952380952381

    Матрица будущих цен двух торгуемых финансовых активов.

    Процесс решения задачи линейной регрессии МНК путем минимизации MSE.

    Оптимальные позиции портфеля, то есть решение задачи.

    Значение MSE, полученное в результате процедуры оптимизации (минимальная средняя квадратичная погрешность репликации).

    Ранг матрицы M

    …И ее сингулярные значения.

    Стоимость аппроксимирующего портфеля, которая меньше стоимости портфеля, созданного с учетом минимальных затрат.

    Доходность аппроксимирующего портфеля.

    Вектор погрешностей репликации.

    MSE аппроксимирующей репликации.

    Аппроксимирующая репликация применима не во всех обстоятельствах, но инвестор или финансовый менеджер, обладающий свободой действий в процессе принятия решений, может выбрать именно ее, например, при слишком высокой стоимости суперрепликации.

    Линия рынка капитала

    Предположим, что речь идет о средней дисперсии или, скорее, средней волатильности. В дальнейшем под рисковой акцией мы будем иметь в виду рыночный портфель, который можно представить в виде широкого фондового индекса наподобие S&P 500.

    Как и раньше, агенты могут составлять портфели из облигации и рыночного портфеля. Ставка доходности облигации — безрисковая процентная ставка — составляет i = 0,1, а волатильность равна 0. Ожидаемая ставка доходности рыночного портфеля:

    .

    Его волатильность:

    .

    Быстрые вычисления в Python дают соответствующие числовые значения:

    In [37]: mu_S = 7 / 6 – 1

    In [38]: mu_S

    Out[38]: 0.16666666666666674

    In [39]: sigma_S = (S[1] / S[0]).std()

    In [40]: sigma_S

    Out[40]: 0.6236095644623235

    Ожидаемая доходность рыночного портфеля.

    Волатильность доходности рыночного портфеля12.

    Возможные средние значения для нормализованного портфеля, состоящего из облигации и рыночного портфеля без коротких продаж с общим весом 1, или 100 %, находятся в диапазоне от 0 до ~0,166. Что касается волатильности, возможны значения от 0 до ~0,623.

    С учетом доступности продаж без покрытия на рис. 3.2 показана линия рынка капитала (capital market line, CML), возникающая при различных составах портфеля. Поскольку разрешена продажа облигации без покрытия, возможны комбинации «риск — доходность» на верхней линии (с положительным наклоном), что в целом является той самой линией рынка капитала. Нижняя линия (с отрицательным наклоном) здесь неважна, поскольку портфели, являющиеся результатом коротких позиций в рыночном портфеле, имеют более низкие ожидаемые ставки доходности при том же риске, что и портфели с соответствующей длинной позицией в рыночном портфеле:

    In [41]: s = np.linspace(-2, 2, 25)

    In [42]: b = (1 - s)

    In [43]: i = 0.1

    In [44]: mu = b * i + s * mu_S

    In [45]: sigma = np.abs(s * sigma_S)

    In [46]: plt.figure(figsize=(10, 6))

             plt.plot(sigma, mu)

             plt.xlabel('$\sigma$')

             plt.ylabel('$\mu$');

    Позиции рыночного портфеля принимают значения от −200 до 200 %.

    Позиция портфеля облигации заполняет до 100 % общего веса портфеля.

    Безрисковая процентная ставка.

    Ожидаемые ставки доходности портфеля.

    Волатильность портфеля.

    Построение графика CML для коротких и длинных позиций в рыночном портфеле.

    Рис. 3.2. Линия рынка капитала (верхняя, возрастающая часть)

    Описать верхнюю, возрастающую часть линии рынка капитала можно с помощью уравнения:

    .

    Модель ценообразования капитальных активов

    В 1964 году У. Шарп разработал модель ценообразования капитальных активов (Capital Asset Pricing Model, CAPM) — модель равновесного ценообразования, которая соотносит ожидаемую ставку доходности произвольного финансового актива или портфеля и его волатильность с ожидаемой нормой доходности и волатильностью рыночного портфеля.

    Большое значение здесь имеет корреляция между ставками доходности финансового актива и рыночного портфеля. В дополнение к рыночному портфелю рассмотрим другой рисковый финансовый актив с процессом ценообразования T = (T0, T1). Корреляция ρ определяется как:

    ,

    где −1 ρST 1. При положительной корреляции два финансовых актива имеют тенденцию к движению в одном направлении, при отрицательной — в противоположных. В особом случае, когда положительная корреляция идеальна, то есть ρST = 1, два финансовых актива, например портфели, лежащие на CML, ставки доходности которых представляют собой ставки доходности рыночного портфеля, увеличенные на вес рыночного портфеля, всегда движутся в одном направлении. Неопределенность здесь возникает только из-за рыночного портфеля, поэтому от изменения его веса будет зависеть степень риска.

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

    .

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

    Ковариация между S1 и T1 определяется по формуле σST = ρST · σS · σT, вследствие чего:

    при

    .

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

    В CAPM линия рынка капитала заменяется линией рынка ценных бумаг (security market line, SML), которая строится в пространстве β-доходности с помощью следующего кода (график представлен на рис. 3.3):

    In [47]: beta = np.linspace(0, 2, 25)

    In [48]: mu = i + beta * (mu_S - i)

    In [49]: plt.figure(figsize=(10, 6))

             plt.plot(beta, mu, label='security market line')

             plt.xlabel('$\\beta$')

             plt.ylabel('$\mu$')

             plt.ylim(0, 0.25)

             plt.plot(1, mu_S, 'ro', label='market portfolio')

             plt.legend(loc=0);

    Генерация объекта ndarray со значениями beta.

    Расчет ожидаемой доходности mu в соответствии с CAPM.

    Построение графика комбинаций beta-mu.

    Настройка границ для оси Y.

    Построение графика со значениями β и ожидаемой доходности рыночного портфеля.

    Рис. 3.3. Линия рынка ценных бумаг

    Тем не менее остается вопрос: почему предыдущие уравнения, в частности формула CAPM, вообще верны? Чтобы ответить на него, рассмотрим портфель с весом 1, или 100 %, доля которого a инвестирована в финансовый актив T, а оставшаяся часть 1 − a — в рыночный портфель. Ожидаемая ставка доходности этого портфеля составляет:

    .

    Его волатильность, согласно Шарпу:

    .

    Незначительное изменение ожидаемой ставки доходности портфеля при незначительном изменении распределения финансового актива T определяется следующей частной производной:

    .

    Незначительное изменение волатильности портфеля при незначительном изменении распределения финансового актива T определяется следующей частной производной:

    .

    Основная идея CAPM как равновесной модели заключается в том, что финансовый актив T уже является частью рыночного портфеля. Поэтому долю a можно считать здесь только как избыточный спрос на финансовый актив, а в условиях равновесия, когда избыточный спрос на все финансовые активы равен нулю, доля a также равна нулю. Следовательно, в условиях равновесия частная производная для ожидаемой ставки доходности портфеля остается неизменной, в то время как для волатильности портфеля она значительно упрощается при вычислении в точке равновесия, где a = 0:

    .

    Таким образом, при рыночном равновесии соотношение между риском и доходностью имеет следующий вид:

    .

    Последняя мысль, необходимая для выведения формулы CAPM, заключается в том, что в условиях равновесия предыдущее выражение должно равняться наклону линии рынка капитала:

    .

    Как CAPM помогает в ценообразовании нереплицируемого финансового актива? С учетом вектора неопределенных цен через год финансового актива T1 неопределенные ставки доходности составляют:

    ,

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

    .

    На основе CAPM теперь можно определить цену риска как избыточную доходность рыночного портфеля на единицу дисперсии через:

    ,

    результатом чего является:

    .

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

    .

    Знаменатель здесь является коэффициентом дисконтирования с поправкой на риск.

    MVP, CAPM и полнота рынка

    И MVP, и CAPM опираются только на статистику высокого уровня: математическое ожидание, волатильность и ковариацию. При репликации условных требований, например, важную роль играет каждая отдельная выплата в каждом возможном будущем состоянии (с представленными эффектами, возникающими вследствие неполноты рынка). В MVP и CAPM (неявно) предполагается, что инвесторов волнует только совокупная статистика, а не каждое отдельное состояние.

    Но рассмотрим, например, два финансовых актива с одинаковой начальной стоимостью при равной вероятностной мере. Выплата 20 денежных единиц по первому активу происходит только в одном определенном состоянии, по второму — только в другом определенном состоянии. Оба финансовых актива имеют одинаковые характеристики «риск — доходность», однако агент может предпочесть один из них другому, несмотря на то что их статистические характеристики одинаковы. При выборе актива ориентация на его риск и доходность часто является удобным, но не всегда уместным упрощением.

    Резюме

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

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

    Модель ценообразования капитальных активов основана на аргументах равновесного ценообразования для выведения ожидаемых ставок доходности, а также цен на торгуемые финансовые активы с учетом их характеристик «риск — доходность» в пространстве средней волатильности. Центральную роль в ней играют корреляция и ковариация финансового актива с рыночным портфелем, который, как предполагается, содержит сам финансовый актив.

    Справочные материалы

    В этой главе были упомянуты следующие книги и статьи.

    • Pliska S. Introduction to Mathematical Finance. — Malden and Oxford: Black­well Publishers, 1997.
    • Sharpe W. Capital Asset Prices: A Theory of Market Equilibrium under Con­ditions of Risk // The Journal of Finance, 1964. — № 19 (3). — Р. 425–442.

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

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

    12

    Глава 4. Оптимальность и равновесие

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

    Даррелл Дюффе (1988)

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

    Гарри Марковиц (1959)

    Данная глава посвящена моделированию поведения и предпочтений агента и оптимизационных задач, с которыми он сталкивается. Здесь представлены некоторые фундаментальные элементы микроэкономической теории (см.: Вариан, 1992) и финансовой экономики (см.: Айхбергер и Харпер, 1997). В основе ее содержания лежит парадигма максимизации ожидаемой полезности, которая чаще всего используется при моделировании предпочтений агента в финансовой экономике. На базе этой парадигмы обсуждаются две центральные темы.

    Сначала поговорим о том, как агент выбирает оптимальный инвестиционный портфель с учетом своих предпочтений и первоначального капитала. При решении этой задачи, которая обычно называется выбором оптимального портфеля, мы не будем опираться на какое-либо упрощение, как при портфельной теории Марковица и модели ценообразования капитальных активов (CAPM), которые сводят проблему выбора инвестиционных портфелей к первому и второму момен­там распределения доходности финансовых активов, а также их ковариации.

    Если в двух предыдущих главах цены на финансовые активы были заданы априори, то здесь они будут выводиться из фундаментальных принципов, поскольку анализ ценообразования финансовых активов станет выполняться на основе задачи на оптимизацию так называемого репрезентативного агента и аргументов равновесия. Репрезентативный агент выступает здесь как совокупность неограниченно большого количества агентов, действующих на финансовых рынках независимо друг от друга. Условия существования такого репрезентативного агента хорошо известны (см. главу 6), однако здесь мы не будем их рассматривать, поскольку в целом финансовая теория принимает факт существования агента как данность.

    Со стороны Python вводится всего пару новых элементов. Основные инструменты для работы с финансами в дискретных моделях уже были представлены в предыдущих двух главах.

    Финансы

    Математика

    Python

    Предпочтения и полезность

    Функция полезности

    NumPy

    Максимизация полезности

    Целевая функция, бюджетное ограничение, теорема Лагранжа

    scipy.optimize.minimize

    Кривые безразличия, прямая бюджетного ограничения

    Функция

    NumPy, matplotlib

    Логарифмическая полезность

    Натуральный логарифм

    NumPy, matplotlib

    Аддитивная полезность относительно времени

    Функция полезности

    NumPy, scipy.optimize.minimize

    Аддитивная ожидаемая полезность относительно времени

    Вероятностная мера, теорема Лагранжа

    NumPy, scipy.optimize.minimize

    Оптимальный инвестиционный портфель

    Теорема Лагранжа, условия первого порядка

    NumPy, scipy.optimize.minimize

    Ценообразование в условиях равно­весия, репрезентативный агент

    Теорема Лагранжа, условия первого порядка

    NumPy, scipy.optimi­ze.minimize, SumPy

    Мартингальные меры в условиях неполного рынка

    Множество вероятностных мер

    SymPy, sy.Symbol, sy.solve

    Восполнение рынка условными требованиями

    Теорема Лагранжа, условия первого порядка

    NumPy, scipy.optimize.minimize

    Максимизация полезности

    Формально агентное моделирование осуществляется с помощью функции полезности, упорядочивающей варианты выбора, с которыми сталкивается агент, и являющейся представлением его предпочтений (см. главу 7). Рассмотрим статическую экономику без неопределенности из главы 2, а также предположим, что агент наделен некоторым первоначальным капиталом w

    >0. Агент может решить, какую часть своего капитала потратить сегодня (t = 0), а какую — сберечь для будущего потребления, открыв банковский депозит. Представим человека, перед которым встал вопрос: сколько откладывать на пенсию?

    Выяснить, какую пользу приносят агенту его деньги сегодня (c0) и через год (c1), можно с помощью соответствующей функции:

    .

    В качестве примера предположим, что u(c0, c1) = c0 · c1 говорит о том, что деньги сегодня и через год являются субститутами, хотя и не совершенными (если стоимость денег в любой момент времени равна нулю, то и полезность равна нулю). Каков оптимальный план накопления для агента? Формально задача на условный экстремум имеет вид:

    ,

    с ограничением:

    .

    Согласно теореме Лагранжа (см. главу 5), задача на условный экстремум может быть преобразована в задачу безусловного экстремума:

    .

    Необходимыми условиями оптимальности первого порядка являются:

    Из данных условий легко вывести оптимальный план экономии —

    .

    В Python такую задачу на оптимизацию, где, например, w = 10, можно смоделировать и решить в числовой форме следующим образом:

    In [1]: def u(c):

                return -c[0] * c[1]

    In [2]: w = 10

    In [3]: from scipy.optimize import minimize

    In [4]: cons = ({'type': 'eq', 'fun': lambda c: c[0] + c[1] - w})

    In [5]: opt = minimize(u, (1, 1), constraints=cons)

    In [6]: opt

    Out[6]:      fun: -24.999999999999996

                 jac: array([-5., -5.])

             message: 'Optimization terminated successfully'

                nfev: 6

                 nit: 2

                njev: 2

              status: 0

             success: True

                   x: array([5., 5.])

    In [7]: opt['x']

    Out[7]: array([5., 5.])

    In [8]: -opt['fun']

    Out[8]: 24.999999999999996

    Функция полезности с отрицательным знаком для достижения максимизации через минимизацию.

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

    Бюджетное ограничение в виде ограничения типа равенства для выполнения функции minimize.

    Экстремум с исходным предположением и бюджетным ограничением.

    Оптимальный план экономии.

    Максимальная полезность, получаемая по оптимальному плану.

    Кривые безразличия

    Решение задачи на оптимальность можно визуализировать с помощью кривых безразличия. Кривую безразличия образуют все комбинации c = (c0, c1), которые дают одинаковую полезность

    . В пространстве (c0, c1) ее можно описать с помощью уравнения:

    ,

    а прямую бюджетного ограничения

    .

    Графически задача на оптимизацию представлена на рис. 4.1. На нем оптимальный план обозначен точкой, в которой кривая безразличия для

    пересекается с прямой бюджетного ограничения.

    В Python данный график строится следующим образом:

    In [9]: def iu(u, c0):

                return u / c0

    In [10]: def c1(c0):

                return w - c0

    In [11]: import numpy as np

             np.set_printoptions(precision=5)

    In [12]: from pylab import mpl, plt

             plt.style.use('seaborn')

             mpl.rcParams['savefig.dpi'] = 300

             mpl.rcParams['font.family'] = 'serif'

    In [13]: c0 = np.linspace(1, w)

    In [14]: plt.figure(figsize=(10, 6))

             plt.plot(c0, c1(c0), label='budget constraint', lw=3.0)

             plt.plot(c0, iu(15, c0), '--', label='$u=15$')

             plt.plot(c0, iu(25, c0), label='$u=25$')

             plt.plot(c0, iu(35, c0), '-.', label='$u=35$')

             plt.plot(opt['x'][0], opt['x'][1], 'ro', label='$c=(5, 5)$')

             plt.legend(loc=0);

    Функция кривой безразличия.

    Функция линии бюджетного ограничения.

    Область, на которой строятся оба графика.

    Рис. 4.1. Задача на максимизацию полезности

    Условия функции полезности

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

    0
    , удовлетворяющей, как предполагается, трем условиям.

    1. u(x) — это дважды дифференцируемая функция.
    2. .
    3. .

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

    Логарифмическая полезность

    В этом разделе представлена функция, которая хорошо подходит для финансового анализа, основанного на максимизирующем полезность агенте, — натуральный логарифм u(x) = ln x. Она удовлетворяет трем условиям, приведенным в предыдущем подразделе, и регулярно используется в финансах для моделирования пользы, которую агент получает от денег (или потребления). При условии, что x

    >0, получается следующее.

    1. .
    2. .

    Python позволяет графически изобразить три рассмотренные нами функции посредством библиотеки NumPy в сочетании с векторными вычислениями. На рис. 4.2 показан график, сгенерированный следующим кодом:

    In [15]: x = np.linspace(0.5, 10, 50)

    In [16]: x[:5]

    Out[16]: array([0.5    , 0.69388, 0.88776, 1.08163, 1.27551])

    In [17]: u = np.log(x)

    In [18]: u1 = 1 / x

    In [19]: u2 = -1 / x ** 2

    In [20]: plt.figure(figsize=(10, 6))

             plt.plot(x, u, label='$u$')

             plt.plot(x, u1, '--', label='$du/dx$')

             plt.plot(x, u2, '-.', label='$d^2u/dx^2$')

             plt.legend(loc=0);

    Создание объекта ndarray с числами с плавающей запятой от 0,5 до 10 и равномерным интервалом для получения 50 значений.

    Вывод выборки из полученных чисел.

    Вычисление значений для функции полезности.

    И для ее первой производной, а также…

    …Для второй производной.

    Создание нового холста для построения графика и задание параметров размера.

    Нанесение на график функции полезности.

    Нанесение на график первой производной.

    Нанесение на график второй производной.

    Размещение условных обозначений в оптимальном месте (loc=0).

    Рис. 4.2. Функция натурального логарифма и две его производные

    Аддитивная полезность относительно времени

    С учетом натурального логарифма, использованного в качестве функции для моделирования полезности денег для агента, предпочтения агента относительно планов экономии c = (c0, c1) могут быть описаны как аддитивная функция полезности относительно времени следующего вида:

    .

    Предполагается, что κ

    0 принимает значения 0 < κ 1 и представляет собой временные предпочтения агента. Суть данной функции в том, что деньги и потребление сегодня ценятся выше, чем через год: например, 100 долларов сейчас предпочтительнее 100 долларов через год независимо от того, какая точная функция описывает полезность (при условии постоянства предпочтений с течением времени). Ее также можно рассматривать как неденежный коэффициент дисконтирования. Вдобавок на основе частных производных по отношению к c0 и c1 легко убедиться, что эта функция удовлетворяет трем условиям, описанным ранее: она является дважды дифференцируемой, вогнутой и возрастающей.

    При наличии у агента первоначального капитала w задача на условный экстремум имеет следующий вид:

    ,

    таким образом:

    ,

    или:

    .

    Необходимыми условиями оптимальности первого порядка в таком случае являются:

    результатом которых становится:

    .

    Оптимальный план экономии теперь отражает временные предпочтения в том, что потребление через год c1 — это κ · c0. Также верны равенства:

    и

    .

    Обязательным условием является бюджетное ограничение:

    .

    Следующий код решает задачу на оптимизацию в числовом виде при w = 10. Полученный оптимальный план отражает временные предпочтения агента:

    In [21]: import math

    In [22]: from scipy.optimize import minimize

    In [23]: kappa = 10 / 11

    In [24]: def U(c):

                 return -(math.log(c[0]) +  kappa * math.log(c[1]))

    In [25]: w = 10

    In [26]: cons = ({'type': 'eq', 'fun': lambda c: c[0] + c[1] - w})

    In [27]: opt = minimize(U, (1, 1), constraints=cons)

    In [28]: opt

    Out[28]:      fun: -3.0747286083026886

                  jac: array([-0.19091, -0.19091])

              message: 'Optimization terminated successfully'

                 nfev: 18

                  nit: 6

                 njev: 6

               status: 0

              success: True

                    x: array([5.23811, 4.76189])

    In [29]: opt['x']

    Out[29]: array([5.23811, 4.76189])

    In [30]: -opt['fun']

    Out[30]: 3.0747286083026886

    Функция полезности со знаком минус для достижения максимизации через минимизацию.

    Бюджетное ограничение в виде ограничения типа равенства для выполнения функции minimize.

    Оптимальный план экономии, отражающий временные предпочтения, при котором c0 больше c1 ровно на 10 %.

    Максимальная полезность, получаемая по оптимальному плану13.

    Ожидаемая полезность

    Перейдем к статической экономике с двумя состояниями и неопределенностью. Предположим, что у агента есть некоторый первоначальный капитал w

    >0, пользу от которого он получит только за счет денег, доступных через год. Полезность этих денег разнится в зависимости от того, какое из двух возможных состояний материализуется. Данная ситуация представляет собой задачу на чистую инвестицию, где весь имеющийся первоначальный капитал должен быть вложен в оптимальные торгуемые финансовые активы.

    Допустим, что торгуются два финансовых актива: безрисковая облигация с процессом ценообразования:

    и рисковая акция с процессом ценообразования:

    .

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

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

    .

    С вектором цен

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

    ,

    где

    — составленный агентом портфель, содержащий безрисковую облигацию и рисковую акцию. Данное бюджетное ограничение всегда будет обязательным условием из-за бесконечности спроса агента. Помимо этого, запрещены продажи без покрытия («короткие» продажи).

    Матрица рыночных выплат представлена как:

    .

    Сколько денег будет у агента в любом из состояний через год? Сумма определяется составленным им портфелем:

    ,

    который можно преобразовать в:

    или

    Полная задача принятия агентом решений касательно выбора оптимального портфеля может быть представлена в виде задачи условного экстремума:

    ;

    ;

    ,

    которую можно упростить до:

    ;

    .

    Согласно теореме Лагранжа эту задачу можно преобразовать в задачу безусловного экстремума:

    ,

    где агент выбирает b и s для максимизации ожидаемой полезности с учетом бюджетного ограничения.

    Теория ожидаемой полезности

    Спустя десятилетия после разработки и внедрения теория ожидаемой полезности (Expected Utility Theory, EUT) все еще остается доминирующей парадигмой принятия финансовых решений, несмотря на то что одно из ее основных допущений — агенты имеют полное представление о возможных будущих состояниях и вероятности их реализации — практически никогда не выполняется в реальности. Тем не менее для многих EUT является интеллектуально привлекательной теоремой с приятными результатами, которые часто легко понять и интерпретировать. Подробнее о проблемах данной парадигмы в финансах можно узнать у Хилпиша (2020, главы 3 и 4).

    Оптимальный инвестиционный портфель

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

    или

    и

    ,

    где

    , а также:

    .

    При логарифмической полезности двух торгуемых финансовых активов с процессами ценообразования B = (10, 11) и S = (10, (20, 5)T) и w = 10 получается, что b + s = 1, вследствие чего позиции портфеля представляют собой процентные значения.

    В Python функция minimize в модуле scipy.optimize подходит и для решения инвестиционной задачи агента:

    In [31]: B = (10, (11, 11))

    In [32]: S = (10, (20, 5))

    In [33]: M0 = np.array((B[0], S[0]))

    In [34]: M = np.array((B[1], S[1])).T

    In [35]: p = 0.5

    In [36]: P = np.array((p, 1-p))

    In [37]: def U(phi):

                 c1 = np.dot(M, phi)

                 return -np.dot(P, np.log(c1))

    In [38]: -U((1, 0))

    Out[38]: 2.3978952727983707

    In [39]: -U((0, 1))

    Out[39]: 2.3025850929940455

    In [40]: -U((0.5, 0.5))

    Out[40]: 2.410140782802518

    In [41]: w = 10

    In [42]: cons = ({'type': 'eq',

                      'fun': lambda phi: np.dot(M0, phi) – w})

    In [43]: opt = minimize(U, (1, 1), constraints=cons)

    In [44]: opt

    Out[44]:      fun: -2.4183062699261972

                  jac: array([-1. , -0.99999])

              message: 'Optimization terminated successfully'

                 nfev: 15

                  nit: 5

                 njev: 5

               status: 0

              success: True

                    x: array([0.69442, 0.30558])

    In [45]: opt['x']

    Out[45]: array([0.69442, 0.30558])

    In [46]: -opt['fun']

    Out[46]: 2.4183062699261972

    In [47]: -U(opt['x'])

    Out[47]: 2.4183062699261972

    In [48]: np.dot(M, opt['x'])

    Out[48]: array([13.75022,  9.16652])

    Процесс ценообразования облигации…

    …И акции.

    Вектор цен двух торгуемых финансовых активов.

    Матрица рыночных выплат по двум торгуемым финансовым активам.

    Физическая мера вероятности относительно экономики.

    Функция ожидаемой полезности вместе с логарифмической полезностью.

    Некоторые примерные значения для общего веса портфеля, равного единице, — диверсификация окупается.

    Бюджетное ограничение, основанное на скалярном произведении векторов цены и портфеля.

    Задача на максимизацию ожидаемой полезности в виде минимизации.

    Оптимальное распределение между облигацией и акцией.

    Оптимальное значение ожидаемой полезности.

    Зависящий от состояния экономики доход по оптимальному портфелю.

    Аддитивная ожидаемая полезность относительно времени

    Задачу принятия решений агентом можно сформулировать так, чтобы включить в нее полезность денег сегодня:

    .

    При первоначальном капитале w задача на оптимизацию без ограничений приобретает вид:

    .

    С учетом сделанных ранее предположений оптимальное решение выводится посредством следующего кода:

    In [49]: M0 = np.array((1, B[0], S[0]))

    In [50]: kappa = 10 / 11

    In [51]: def U(phi):

                 c0 = phi[0]

                 c1 = np.dot(M, phi[1:])

                 return –(np.log(c0) + kappa * np.dot(P, np.log(c1)))

    In [52]: opt = minimize(U, (1, 1, 1), constraints=cons)

    In [53]: opt

    Out[53]:      fun: -3.1799295980286093

                  jac: array([-0.19088, -1.90932, -1.90974])

              message: 'Optimization terminated successfully'

                 nfev: 32

                  nit: 8

                 njev: 8

               status: 0

              success: True

                    x: array([5.23899, 0.33087, 0.14523])

    In [54]: -opt['fun']

    Out[54]: 3.1799295980286093

    In [55]: opt['x'][0]

    Out[55]: 5.23898714830318

    In [56]: np.dot(M, opt['x'][1:])

    Out[56]: array([6.54422, 4.36571])

    Вектор цен, включающий единицу, на потребление сегодня.

    Фактор временных предпочтений.

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

    Это часть w, которую агент потребляет сегодня.

    Зависящий от состояния экономики доход по позиции облигации и акции.

    Ценообразование в условиях полного рынка

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

    2, а матрица рыночных выплат имеет вид:

    .

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

    .

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

    При инвестиционном портфеле φ = (φu, φd)T задача по максимизации ожидаемой полезности имеет вид:

    ,

    таким образом:

    или

    .

    Из-за особой матрицы рыночных выплат это выражение можно преобразовать следующим образом:

    ,

    таким образом:

    и

    .

    Задача безусловного экстремума имеет три условия первого порядка:

    Как данные условия оптимальности влияют на цены

    ? Первое условие касается относительной цены двух ценных бумаг Эрроу — Дебре:

    .

    Относительная цена полностью определяется вероятностями реализации каждого из двух состояний и предельной полезностью, получаемой от потребления. В условиях равновесия φu = φd = 1 относительная цена определяется только вероятностной мерой:

    .

    В результате добавления этого условия получается, что:

    .

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

    Например, приведение первоначального капитала к единице, w = 1, устанавливает такие цены:

    ,

    чтобы в итоге прийти к равновесным ценам:

    или вектору равновесных цен

    .

    Арбитражное ценообразование

    А что насчет арбитражных цен условных требований с учетом вектора равновесных цен

    ? На полных рынках каждое условное требование достижимо и цена любого их них
    задается как:

    .

    Это связано с тем, что портфель репликации — не что иное, как доход, зависящий от состояния экономики, φ = C1, в отдельном случае двух ценных бумаг Эрроу — Дебре. Поэтому цены таких ценных бумаг также считаются ценами, зависящими от состояния экономики, поскольку они представляют цену за одну единицу валюты (потребления) в определенном состоянии.

    Ценообразование по мартингалу

    Как выглядит уникальная мартингальная мера для текущей экономики? Мартингальная мера Q преобразует все процессы дисконтирования цен торгуемых финансовых активов в мартингалы. В матричной форме это свойство выглядит следующим образом:

    .

    А в более развернутом виде:

    Отсюда следует, что i = 0 и q = p. Физическая вероятностная мера сразу преобразует все вероятности в мартингалы, а цены двух ценных бумаг Эрроу — Дебре уравновешиваются таким образом, чтобы процессы дисконтирования цен являлись мартингалами.

    Цена каждого достижимого условного требования C1

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

    .

    Безрисковая процентная ставка

    Почему безрисковая процентная ставка в условиях равновесия равна нулю? Ответ довольно прост: потому что не существует безрискового финансового актива, который бы фиксировал другую процентную ставку. Рассмотрим безрисковый финансовый актив, приносящий единицу валюты в каждом состоянии, B1 = (1, 1)T. Арбитражная цена данного финансового актива составляет:

    и дает основания полагать, что безрисковая процентная ставка i = 0. Любая другая цена 0 < B0 < 1, подразумевающая положительную безрисковую процентную ставку, также будет предполагать возможность арбитража.

    Пример в числовом виде (часть 1)

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

    В частности, предположим максимизацию ожидаемой полезности на основе логарифмической полезности для репрезентативного агента. Процесс цено­образования для безрисковой облигации составляет:

    ,

    а для рисковой акции:

    .

    Матрица рыночных выплат имеет вид:

    .

    Ко всему прочему, дана физическая мера вероятности P = (p, (1 – p))T, где p = 1/3. Чистое предложение безрисковой облигации и рисковой акции составляет b = 1 и s = 1 соответственно. Агент располагает первоначальным капиталом w = 15.

    Задачей репрезентативного агента является:

    или

    .

    Три условия первого порядка:

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

    .

    Добавление бюджетного ограничения фиксирует не только относительную цену ζ, но и уровни абсолютных цен:

    .

    В Python эти расчеты преобразуются в простые векторные операции, выполняемые с помощью библиотеки NumPy:

    In [57]: p = 1 / 3

    In [58]: P = np.array((p, (1-p)))

    In [59]: B1 = np.array((11, 11))

    In [60]: S1 = np.array((20, 5))

    In [61]: zeta = np.dot(S1 / (B1 + S1), P) / np.dot(B1 / (B1 + S1), P)

    In [62]: zeta

    Out[62]: 0.7342657342657343

    In [63]: w = 15

    In [64]: B0 = w / (1 + zeta)

    In [65]: B0

    Out[65]: 8.649193548387098

    In [66]: S0 = zeta * B0

    In [67]: S0

    Out[67]: 6.350806451612904

    In [68]: B0 + S0

    Out[68]: 15.000000000000002

    In [69]: i = B1.mean() / B0 - 1

    In [70]: i

    Out[70]: 0.2717948717948717

    In [71]: mu = np.dot(S1, P) / S0 – 1

    In [72]: mu

    Out[72]: 0.5746031746031743

    Вероятностная мера.

    Ценовой коэффициент ζ (дзета) с учетом условий оптимальности.

    Первоначальный капитал.

    Уровень равновесной цены безрисковой облигации с учетом коэффициента цен ζ и первоначального капитала w.

    Уровень равновесной цены рисковой акции.

    Бюджетное ограничение как обязательное условие.

    Равновесная процентная ставка с учетом уровня цены безрисковой облигации.

    Равновесная ожидаемая ставка доходности рисковой акции.

    В этом примере равновесное ценообразование не приводит к «мартингализации» процессов дисконтирования цен при физической вероятностной мере. Однако вывести здесь мартингальную меру не составит труда — для этого понадобится библиотека SymPy для символьных вычислений в Python:

    In [73]: import sympy as sy

    In [74]: q = sy.Symbol('q')

    In [75]: eq = (q * 20 + (1 - q) * 5) / (1 + i) - S0

    In [76]: eq

    Out[76]: 11.7943548387097*q - 2.41935483870968

    In [77]: q = sy.solve(eq)[0]

    In [78]: q

    Out[78]: 0.205128205128205

    In [79]: Q = np.array((q, 1 - q))

    In [80]: np.dot(B1, Q) / (1 + i)

    Out[80]: 8.64919354838710

    In [81]: np.dot(S1, Q) / (1 + i)

    Out[81]: 6.35080645161290

    Импорт библиотеки символьных вычислений SymPy.

    Определение символа q.

    Формулировка уравнения для q с учетом условия мартингала.

    Упрощение уравнения.

    Решение уравнения в числовой форме.

    Полученная в результате решения мартингальная мера.

    Оба процесса дисконтирования цен являются мартингалами Q.

    Ценообразование в условиях неполного рынка

    Как работает ценообразование относительно репрезентативного агента на неполных рынках? К счастью, точно так же, как и на полных рынках.

    Рассмотрим экономику с двумя датами и тремя состояниями, в которой торгуются безрисковая облигация с процессом ценообразования:

    и рисковая акция с процессом ценообразования:

    .

    Физической вероятностной мерой является P = (p, p, p)T, где p = 1/3. Все остальные условия не меняются.

    Формально задача репрезентативного агента на оптимизацию не меняется:

    .

    Расчет относительной цены тоже остается прежним:

    .

    В Python необходимо скорректировать лишь векторы будущих цен финансовых активов и вектор, представляющий вероятностную меру:

    In [82]: p = 1 / 3

    In [83]: P = np.array((p, p, p))

    In [84]: B1 = np.array((11, 11, 11))

    In [85]: S1 = np.array((20, 10, 5))

    In [86]: zeta = np.dot(S1 / (B1 + S1), P) / np.dot(B1 / (B1 + S1), P)

    In [87]: zeta

    Out[87]: 0.9155274934101636

    In [88]: w = 15

    In [89]: B0 = w / (1 + zeta)

    In [90]: B0

    Out[90]: 7.8307411674347165

    In [91]: S0 = zeta * B0

    In [92]: S0

    Out[92]: 7.169258832565284

    In [93]: B0 + S0

    Out[93]: 15.0

    In [94]: i = B1.mean() / B0 – 1

    In [95]: i

    Out[95]: 0.40472016183411985

    In [96]: mu = np.dot(S1, P) / S0 – 1

    In [97]: mu

    Out[97]: 0.6273183796451287

    Вероятностная мера.

    Ценовой коэффициент ζ с учетом условий оптимальности.

    Первоначальный капитал.

    Уровень равновесной цены безрисковой облигации с учетом коэффициента цен ζ и первоначального капитала w.

    Уровень равновесной цены рисковой акции.

    Бюджетное ограничение как обязательное условие.

    Равновесная процентная ставка с учетом уровня цены безрисковой облигации.

    Равновесная ожидаемая ставка доходности рисковой акции.

    Ценообразование относительно репрезентативного агента

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

    Мартингальные меры

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

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

    In [98]: qu = sy.Symbol('qu')

             qm = sy.Symbol('qm')

    In [99]: eq = (qu * 20 + qm * 10 + (1 - qu - qm) * 5) / (1 + i) - S0

    In [100]: eq

    Out[100]: 3.55942780337942*qm + 10.6782834101383*qu - 3.60983102918587

    In [101]: Q = sy.solve(eq, set=True)

    In [102]: Q

    Out[102]: ([qm], {(1.01416048550236 - 3.00000000000001*qu,)})

    Определение символов qu и qm.

    Формулировка уравнения для qu и qm с учетом условия мартингала.

    Упрощение уравнения.

    Решение уравнения в числовой форме с выводом множества результатов (без учета условия 0 qu, qd 1).

    Соотношение между qu и qm как результат решения, указывающий на бесконечно большое количество решений.

    Мартингальная мера в условиях неполного рынка

    Ценообразование по мартингалу — это удобный и простой подход к оценке условных требований на полных рынках. На неполных рынках, как правило, существует бесконечно большое количество мартингальных мер, согласованных с рынком. На практике данную задачу часто решают, опираясь на публично наблюдаемую рыночную стоимость ликвидных условных требований, например обычных европейских пут- или колл-опционов. Эти цены используются для калибровки параметров модели или непосредственно мартингальной меры, чтобы достичь согласованности с рынком. Более подробная информация о калибровке модели представлена в работе Хилпиша 2015 года.

    Ценообразование в условиях равновесия

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

    3.

    Рассмотрим матрицу рыночных выплат по первым двум ценным бумагам Эрроу — Дебре, каждая из которых доступна при чистом предложении, равном единице:

    .

    Этот рынок явно неполный, поскольку две ценные бумаги не покрывают пространство

    3. Введение условного требования с чистым предложением, равным единице, которое приносит одну единицу валюты в состоянии d (то есть условное требование, которое приносит ровно столько, сколько приносила бы третья ценная бумага Эрроу — Дебре), восполняет рынок, что демонстрирует следующая матрица выплат:

    .

    Сейчас три вектора выплат формируют стандартный базис

    3.

    Формально задача репрезентативного агента на оптимизацию не отличается от представленной ранее:

    ,

    таким образом:

    .

    Здесь

    — вектор цен, зависящих от состояния экономики, а φ = (1, 1, 1)T — рыночный портфель.

    Согласно теореме Лагранжа задача безусловного экстремума в развернутом виде такова:

    Она имеет четыре условия первого порядка:

    В результате получаем следующие относительные цены:

    через которые устанавливается и третья относительная цена. При логарифмической полезности и первоначальном капитале w = 1 мы приходим к такому уравнению:

    Вектором равновесных цен является

    , что соответствует вектору вероятностной меры, а это значит, что все процессы дисконтирования цен являются мартингалами при физической вероятностной мере.

    Пример в числовом виде (часть 2)

    Вернемся к предыдущему числовому примеру: предположим максимизацию ожидаемой полезности на основе логарифмической полезности для репрезентативного агента. Процесс ценообразования для безрисковой облигации составляет:

    ,

    а для рисковой акции:

    .

    Матрица рыночных выплат имеет вид:

    .

    Ко всему прочему, дана физическая мера вероятности P = (p, p, p)T, где p = 1/3. Чистое предложение безрисковой облигации и рисковой акции составляет b = 1 и s = 1 соответственно. Агент располагает первоначальным капиталом w = 15.

    Введем условное требование с выплатой С1 = (5, 0, 0)T и чистым предложением c = 1. В результате задача репрезентативного агента имеет вид:

    или

    .

    Четырьмя условиями первого порядка для этой задачи являются:

    Устанавливаем также относительные цены для трех финансовых активов:

    Добавление бюджетного ограничения фиксирует не только относительные цены ζ1 и ζ2, но и уровни абсолютных цен:

    .

    Переходим к Python и немного изменяем код для полного рынка:

    In [103]: p = 1 / 3

    In [104]: P = np.array((p, p, p))

    In [105]: B1 = np.array((11, 11, 11))

    In [106]: S1 = np.array((20, 10, 5))

    In [107]: C1 = np.array((5, 0, 0))

    In [108]: zeta_1 = (np.dot(S1 / (B1 + S1 + C1), P) /

                        np.dot(B1 / (B1 + S1 + C1), P))

    In [109]: zeta_1

    Out[109]: 0.8862001308044474

    In [110]: zeta_2 = (np.dot(C1 / (B1 + S1 + C1), P) /

                        np.dot(B1 / (B1 + S1 + C1), P))

    In [111]: zeta_2

    Out[111]: 0.09156311314584695

    In [112]: w = 15

    In [113]: B0 = w / (1 + zeta_1 + zeta_2)

    In [114]: B0

    Out[114]: 7.584325396825396

    In [115]: S0 = zeta_1 * B0

    In [116]: S0

    Out[116]: 6.721230158730158

    In [117]: C0 = zeta_2 * B0

    In [118]: C0

    Out[118]: 0.6944444444444443

    In [119]: B0 + S0 + C0

    Out[119]: 14.999999999999998

    In [120]: i = B1.mean() / B0 – 1

    In [121]: I

    Out[121]: 0.45035971223021587

    In [122]: muS = np.dot(S1, P) / S0 – 1

    In [123]: muS

    Out[123]: 0.7357933579335794

    In [124]: muC = np.dot(C1, P) / C0 – 1

    In [125]: muC

    Out[125]: 1.4000000000000004

    Вероятностная мера.

    Векторы выплат.

    Первая относительная цена.

    Вторая относительная цена.

    Первоначальный капитал…

    …И получаемая цена безрисковой облигации.

    Равновесная цена рисковой акции.

    Равновесная цена условного требования.

    Бюджетное ограничение как обязательное условие.

    Безрисковая процентная ставка.

    Равновесная ожидаемая ставка доходности рисковой акции.

    Равновесная ожидаемая ставка доходности условного требования.

    О том, что введение условного требования в качестве третьего торгуемого финансового актива восполняет рынок, можно судить по тому, что теперь существует уникальная мартингальная мера:

    In [126]: M = np.array((B1, S1, C1)).T

    In [127]: M

    Out[127]: array([[11, 20, 5],

                     [11, 10, 0],

                     [11,  5, 0]])

    In [128]: M0 = np.array((B0, S0, C0))

    In [129]: Q = np.linalg.solve(M.T / (1 + i), M0)

    In [130]: Q

    Out[130]: array([0.20144, 0.34532, 0.45324])

    In [131]: sum(Q)

    Out[131]: 1.0

    In [132]: np.allclose(np.dot(M.T, Q), M0 * (1 + i))

    Out[132]: True

    Новая матрица рыночных выплат, включающая в себя условное требование.

    Вектор цен трех финансовых активов, включая условное требование.

    Решение относительно вектора Q, представляющего мартингальную меру Q (обратите внимание на использование оператора транспонирования .T).

    Вектор результата решения, сумма компонентов которого равна 1.

    Итоговая проверка того, что все процессы дисконтирования цен действительно являются мартингалами.

    Резюме

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

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

    Справочные материалы

    В этой главе были упомянуты следующие книги.

    • Duffie D. Security Markets — Stochastic Models. — San Diego: Academic Press, 1988.
    • Eichberger J., Harper I. Financial Economics. — N.Y.: Oxford University Press, 1997.
    • Hilpisch Y. Artificial Intelligence in Finance. — Sebastopol: O’Reilly, 2020.
    • Hilpisch Y. Derivatives Analytics with Python. — Wiley Finance, 2015.
    • Markowitz H. Portfolio Selection — Efficient Diversification of Investments. — New York: John Wiley & Sons, 1959.
    • Milne F. Finance Theory and Asset Pricing. — N.Y.: Oxford University Press, 1995.
    • Sundaram R. A First Course in Optimization Theory. — Cambridge: Cambridge University Press, 1996.
    • Varian H. Microeconomic Analysis. 3rd ed. — New York and London: W.W. Nor­ton & Company, 1992.

    13 Полезность необходимо понимать только через призму ординалов, то есть через приведение различных планов в определенный порядок. Сравнение этой числовой величины с оптимальной, выведенной ранее, не имеет никакого смысла, поскольку сами функции полезности различны.

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

    13

    Глава 5. Статическая экономика

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

    Харрисон и Крепс (1979)

    Аргументы безарбитражности связаны с мартингальной теорией так называемой фундаментальной теоремой ценообразования финансовых активов.

    Дельбаен и Шахермайер (2006)

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

    В этой главе используются понятия линейной алгебры и теории вероятностей. Данные темы подробно освещены в книгах Алескерова и др., Якода и Проттера соответственно. Плавное введение в общую статичную экономику и ее анализ можно найти в книге Мильне. Учебник Плиски (1997) — это хорошее, понятное и полное введение в данную тему. Учебник Дюффе (1988) — более сложный и подробный, он во всей полноте представляет все необходимые элементы линейной алгебры и теории вероятностей для работы с финансами.

    Здесь будут рассмотрены общие дискретные вероятностные пространства, финансовые активы и условные требования, полнота рынка, две фундаментальные теоремы ценообразования финансовых активов, репликация и арбитражное ценообразование, модели ценообразования опционов Блэка — Шоулза — Мертона (1973) и Мертона (1976), а также ценообразование через репрезентативного агента с добавлением ценных бумаг Эрроу — Дебре.

    Финансы

    Математика

    Python

    Неопределенность

    Пространство состояний, алгебра, вероятностная мера, вероятностное пространство

    NumPy, ndarray, rng.normal

    Финансовые активы, условные требования

    Случайная величина, математическое ожидание

    rng, mean(), np.dot

    Матрица рыночных выплат

    Матрица

    ndarray, mean(), std()

    Репликация, арбитражное ценообразование

    Решение системы линейных уравнений, скалярное произведение

    np.maximum, np.linalg.solve, np.dot

    Полнота рынка

    Ранг, линейная оболочка, векторное пространство

    ndarray, np.dot, np.linalg.matrix_rank

    Мартингальная мера

    Вероятностная мера

    ndarray, scipy.optimize.minimize

    Модель Блэка — Шоулза — Мертона

    Геометрическое броуновское движение, нормальное распределение, моделирование Монте-Карло, репликация

    rng.standard_normal, np.linalg.lstsq

    Модель Мертона, логарифмически нормальный скачок

    Скачкообразная диффузия, распределение Пуассона

    rng.poisson, np.linalg.lstsq

    Основная цель этой главы — обобщение. Несмотря на то что почти все представленные здесь концепции и расчеты были введены в предыдущих главах, расширение пространства состояний требует использования дополнительных формул. Тем не менее код Python останется таким же лаконичным, как и раньше. Преимущества такого обобщения очевидны: нереально моделировать возможную будущую цену акции, скажем, Apple на основании только двух или трех возможных состояний. Гораздо объективнее предположить, что цена акции может принимать какое-то значение из возможных 100, 500 или более значений, — это важный шаг при переходе к более реалистичной финансовой модели.

    Неопределенность

    Рассмотрим экономику с общим дискретным пространством состояний Ω с конечным числом элементов |Ω| < ∞. Алгебра

    в Ω — это семейство множеств, для которых справедливы следующие утверждения.

    1. .
    2. .
    3. .

    обозначает дополнение множества E. Алгеброй называется модель наблюдения за событиями, происходящими в экономике. Булеан ℘(Ω) является самой большой алгеброй, а множество
    — самой маленькой алгеброй в пространстве Ω. В данном контексте одно состояние экономики ω Ω можно интерпретировать как атомарное событие.

    Вероятность соотносит действительное число 0 pωP({ω}) 1 с состоянием ω Ω или действительное число 0 P(

    ) 1 с событием
    . Если известны вероятности реализации всех состояний, то
    .

    Вероятностная мера

    имеет следующие свойства.

    1. .
    2. для непересекающихся множеств Ei
      .
    3. P(Ω) = 1.

    Вместе три элемента

    образуют вероятностное пространство, которое в модельной экономике формально представляет неопределенность.

    Случайные величины

    В вероятностном пространстве

    случайная величина является
    -измеримой функцией:

    .

    -измеримость подразумевает, что для каждого множества
    {[a, b]: a, b
    , a < b}, существует:

    .

    Если

    ≡ ℘(Ω), то математическое ожидание случайной величины определяется через:

    ,

    если нет, то через:

    .

    Примеры в числовом виде

    Приведу конкретный пример. Предположим, что существует пространство состояний (элементарных событий) Ω = {ω1, ω2, ω3, ω4}, а также задана алгебра с множеством

    , которое удовлетворяет трем свойствам алгебры в пространстве Ω. Вероятностная мера определяется как P({ω1, ω2}) = P({ω3, ω4}) = 1/2, где P является вероятностной мерой на множестве
    в приведенных ранее условиях.

    Рассмотрим теперь функцию T, в которой T1) = 1, T2) = 2, T3) = 3 и T4) = 4. Данная функция не является определенной на вероятностном пространстве случайной величиной, поскольку алгебра

    не различает, например, ω1 и ω2 из-за их принадлежности к множеству {ω1, ω2}. Здесь можно сказать, что алгебра недостаточно «гранулирована».

    Взглянем на другую функцию, S, в которой S1) = 20, S2) = 20, S3) = 5 и S4) = 5. Она является случайной величиной, определенной на вероятностном пространстве, с математическим ожиданием:

    .

    Тем не менее, как правило, предполагается, что

    ≡ ℘(Ω), при этом P определена так, что функция (случайная величина), например T, также является
    -измеримой с правильно определенным математическим ожиданием.

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

    In [1]: import numpy as np

            from numpy.random import default_rng

            np.set_printoptions(precision=5, suppress=True)

    In [2]: rng = default_rng(100)

    In [3]: I = 1000

    In [4]: S = rng.normal(loc=100, scale=20, size=I)

    In [5]: S[:14]

    Out[5]: array([ 76.84901, 105.79512, 115.61708, 110.87947,  80.77235, 121.42017,

                   114.02911, 114.09947, 114.90125, 122.08694, 144.85945,  87.77014,

                   100.94422, 135.08469])

    In [6]: S.mean()

    Out[6]: 100.88376804485935

    Установление начального значения для генератора случайных чисел NumPy для сходимости результатов.

    Установление количества состояний в пространстве состояний (для последующего моделирования).

    Вывод нормально распределенных псевдослучайных величин I со средним значением loc и стандартным отклонением scale.

    Вычисление математического ожидания (средней величины) при условии равной вероятности каждого моделируемого значения (состояния).

    Разумеется, можно выбрать любую другую вероятностную меру:

    In [7]: P = rng.random(I)

    In [8]: P[:10]

    Out[8]: array([0.34914, 0.33408, 0.41319, 0.06102, 0.6339 , 0.51285, 0.51177,

                   0.92149, 0.72853, 0.58985])

    In [9]: P /= P.sum()

    In [10]: P.sum()

    Out[10]: 1.0

    In [11]: P[:10]

    Out[11]: array([0.00072, 0.00069, 0.00085, 0.00013, 0.00131, 0.00106,

                    0.00106, 0.0019 , 0.0015 , 0.00122])

    In [12]: np.dot(P, S)

    Out[12]: 100.71981640185018

    Вывод равномерно распределенных случайных чисел от 0 до 1.

    Приведение суммы значений в объекте ndarray к единице.

    Полученный вес в соответствии со случайной вероятностной мерой.

    Математическое ожидание как скалярное произведение вектора вероятностей и вектора случайной величины.

    Математические методы

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

    Финансовые активы

    Рассмотрим экономику с двумя датами t 0, 1, «сегодня» и «через год» (или любой другой период времени в будущем). Предположим, что задано вероятностное пространство {Ω,

    ≡ ℘(Ω), P}, которое представляет собой неопределенность относительно будущего в модельной экономике с возможными будущими состояниями |Ω| ≡ I. В данном случае Ω = {ω1, ω2… ωI}.

    Торгуемый финансовый актив представлен процессом ценообразования S = (S0, S1), где цена сегодня составляет S0

    >0, а цена через год S1: Ω →
    0 является случайной
    -измеримой величиной. Формально вектор будущих цен торгуемого финансового актива — это вектор с элементами I:

    .

    Если торгуется несколько финансовых активов, скажем, K > 1, то они представлены несколькими процессами ценообразования,

    . Матрица рыночных выплат состоит из векторов будущих цен торгуемых финансовых активов:

    .

    Обозначим множество торгуемых финансовых активов через

    . Таким образом, статичную модельную экономику можно представить в таком общем виде:

    .

    Как правило, здесь подразумевается, что

    ≡ ℘(Ω).

    Предположим, что в экономике существует пять возможных будущих состояний Ω = {ω1… ω5} с равной вероятностью материализации ∀ω Ω: P(ω) = 1/5 и торгуются пять финансовых активов. На языке Python данную ситуацию можно представить следующим кодом:

    In [13]: M = np.array((

                 (11, 25,  0,  0, 25),

                 (11, 20, 30, 15, 25),

                 (11, 10,  0, 20, 10),

                 (11,  5, 30, 15,  0),

                 (11,  0,  0,  0,  0)

            ))

    In [14]: M0 = np.array(5 * [10.])

    In [15]: M0

    Out[15]: array([10., 10., 10., 10., 10.])

    In [16]: M.mean(axis=0)

    Out[16]: array([11., 12., 12., 10., 12.])

    In [17]: mu = M.mean(axis=0) / M0 – 1

    In [18]: mu

    Out[18]: array([0.1, 0.2, 0.2, 0. , 0.2])

    In [19]: (M / M0 - 1)

    Out[19]: array([[ 0.1,  1.5, -1. , -1. ,  1.5],

                    [ 0.1,  1. ,  2. ,  0.5,  1.5],

                    [ 0.1,  0. , -1. ,  1. ,  0. ],

                    [ 0.1, -0.5,  2. ,  0.5, -1. ],

                    [ 0.1, -1. , -1. , -1. , -1. ]])

    In [20]: sigma = (M / M0 - 1).std(axis=0)

    In [21]: sigma

    Out[21]: array([0.     , 0.92736, 1.46969, 0.83666, 1.1225 ])

    Предполагаемая матрица рыночных выплат, столбцы которой представляют собой векторы будущих неопределенных цен на торгуемые финансовые активы.

    Вектор текущих цен пяти активов, для каждого из которых установлена цена 10.

    Расчет ожидаемой (или средней) будущей цены для каждого торгуемого финансового актива.

    Расчет ожидаемой (или средней) ставки доходности.

    Расчет и вывод матрицы ставок доходности.

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

    Условные требования

    В модельной экономике

    условное требование характеризуется процессом ценообразования C = (C0, C1), где C1 — это
    -измеримая случайная величина.

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

    , где K
    0 — цена исполнения опциона. Поскольку выплата по опциону производна от другого актива, мы говорим о производных финансовых инструментах, или, сокращенно, деривативах.

    Если условное требование может быть реплицировано портфелем φ

    K торгуемых финансовых активов
    :

    ,

    то его арбитражная цена равна:

    ,

    где

    является вектором текущих цен торгуемых финансовых активов.

    Продолжим код из предыдущего раздела. Репликация условных требований на основе линейной алгебры имеет следующий вид:

    In [22]: K = 15

    In [23]: M[:, 1]

    Out[23]: array([25, 20, 10,  5,  0])

    In [24]: C1 = np.maximum(M[:, 1] - K, 0)

    In [25]: C1

    Out[25]: array([10,  5,  0,  0,  0])

    In [26]: phi = np.linalg.solve(M, C1)

    In [27]: phi

    Out[27]: array([ 0.,  0.5,  0.01667, -0.2, -0.1])

    In [28]: np.allclose(C1, np.dot(M, phi))

    Out[28]: True

    In [29]: C0 = np.dot(M0, phi)

    In [30]: C0

    Out[30]: 2.1666666666666665

    Цена исполнения европейского колл-опциона и вектор выплат по соответствующему финансовому активу.

    Выписка колл-опциона на второй торгуемый финансовый актив с будущей выплатой

    .

    Решение задачи репликации с учетом матрицы рыночных выплат.

    Проверка того, что реплицирующий портфель действительно воспроизводит будущие выплаты по европейскому колл-опциону.

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

    Полнота рынка

    Полнота рынка в статичной модельной экономике может быть проанализирована на основе ранга матрицы рыночных выплат

    , определяемой торгуемыми финансовыми активами
    . Ранг матрицы равен числу линейно независимых векторов-столбцов (см.: Алескеров и др., 2011, раздел 2.7). Рассмотрим векторы-столбцы, представляющие векторы будущих цен торгуемых финансовых активов. Они линейно независимы, если:

    имеет одно решение, а именно изотропный вектор φ = (0, 0… 0)T

    K.

    В то же время линейная оболочка матрицы рыночных выплат

    задается всеми линейными комбинациями векторов-столбцов:

    .

    Модельная экономика

    является полной, если множество достижимых услов­ных требований удовлетворяет условию
    =
    I. К тому же по определению это множество равно линейной оболочке торгуемых финансовых активов
    ≡ span(
    ). Таким образом, модельная экономика
    является полной при

    .

    При каких обстоятельствах полнота рынка возможна? Она возможна, если ранг матрицы равен числу возможных будущих состояний или больше него:

    .

    Другими словами, векторы-столбцы

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

    1. Функция сложения, сопоставляющая два вектора, v1, v2
      , с другим элементом векторного пространства, (v1 + v2)
      .
    2. Функция скалярного умножения, сопоставляющая скаляр α
      и вектор v
      с другим элементом векторного пространства (α · v)
      .
    3. Специальный элемент — нулевой, или нейтральный, — 0
      с условием v + 0 = v.

    Таким образом, например, не остается сомнений, что множества

    ,
    5, или
    I, I
    >0, являются векторными пространствами.

    В соответствии с изложенным ранее модельная экономика считается неполной, если:

    .

    Для большей конкретизации рассмотрим пространство состояний с тремя возможными будущими состояниями Ω = {ω1, ω2, ω3}. Все случайные переменные, таким образом, являются векторами в пространстве

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

    .

    Подтвердить линейную зависимость финансовых активов 2 и 3 не составляет труда:

    .

    Для сравнения посмотрим на другую матрицу рыночных выплат с другими тремя торгуемыми финансовыми активами. Она имеет ранг 3, то есть отображает полноту рынка. В таком случае также говорят о полном ранге матрицы:

    .

    Далее предположим вероятностное пространство, в котором пространство состояний состоит из пяти элементов, Ω = {ω1… ω5}. Векторы будущих неопределенных цен и выплат по пяти торгуемым финансовым активам

    и, соответственно, всех условных требований теперь являются элементами векторного пространства
    5. Следующий код анализирует репликацию условных требований на основе такой модельной экономики
    . Он начинается с допущения о том, что все пять ценных бумаг Эрроу — Дебре участвуют в торговле:

    In [31]: M = np.eye(5)

    In [32]: M

    Out[32]: array([[1., 0., 0., 0., 0.],

                    [0., 1., 0., 0., 0.],

                    [0., 0., 1., 0., 0.],

                    [0., 0., 0., 1., 0.],

                    [0., 0., 0., 0., 1.]])

    In [33]: np.linalg.linalg.matrix_rank(M)

    Out[33]: 5

    In [34]: C1 = np.arange(10, 0, -2)

    In [35]: C1

    Out[35]: array([10,  8,  6,  4,  2])

    In [36]: np.linalg.solve(M, C1)

    Out[36]: array([10.,  8.,  6.,  4.,  2.])

    Создание двумерного объекта ndarray — матрицы тождества, которую можно интерпретировать как матрицу рыночных выплат, полученную в результате торговли пятью ценными бумагами Эрроу — Дебре. Она образует так называемый канонический базис векторного пространства

    5.

    Вычисление ранга матрицы.

    Выплата по условному требованию, которая должна быть реплицирована торгуемыми финансовыми активами.

    Решение задачи репликации (реализации).

    Далее идет генерация рандомизированной матрицы рыночных выплат с полным рангом:

    In [37]: rng = default_rng(100)

    In [38]: M = rng.integers(1, 10, (5, 5))

    In [39]: M

    Out[39]: array([[7, 8, 2, 6, 1],

                    [3, 4, 1, 6, 9],

                    [9, 6, 4, 8, 9],

                    [9, 1, 7, 7, 2],

                    [5, 9, 7, 3, 3]])

    In [40]: np.linalg.matrix_rank(M)

    Out[40]: 5

    In [41]: np.linalg.matrix_rank(M.T)

    Out[41]: 5

    In [42]: phi = np.linalg.solve(M, C1)

    In [43]: phi

    Out[43]: array([-1.16988, 0.52471, -0.3861 , 2.56409, -0.62085])

    In [44]: np.dot(M, phi)

    Out[44]: array([10., 8., 6., 4., 2.])

    Установление начального значения для генератора случайных чисел NumPy для сходимости результатов.

    Создание рандомизированной матрицы рыночных выплат (объекта ndarray с формой (5, 5), заполненного случайными целыми числами от 1 до 10).

    Матрица имеет полный ранг: векторы-столбцы и векторы-строки линейно независимы.

    Ненулевое решение задачи репликации с рандомизированным базисом векторного пространства

    5.

    Проверка решения на достижение абсолютной репликации.

    Фундаментальные теоремы ценообразования финансовых активов

    Рассмотрим общую статичную модельную экономику

    = ({Ω,
    , P},
    ) с возможными состояниями I и торгуемыми финансовыми активами K. Предположим, что безрисковая краткосрочная процентная ставка предоставления и получения займов в экономике r
    014.

    Арбитражная возможность возникает тогда, когда цена портфеля φ

    K торгуемых финансовых активов
    равна нулю:

    ,

    а ожидаемая выплата по нему — больше нуля:

    .

    Обозначим множество всех арбитражных возможностей через:

    .

    Мартингальная мера Q для модельной экономики преобразует процессы дисконтирования цен в мартингалы и поэтому удовлетворяет следующему условию:

    .

    Таким образом, можно сформулировать первую фундаментальную теорему ценообразования финансовых активов (см. главу 2), согласно которой мартингальная мера существует только при отсутствии арбитражных возможностей. Данная теорема была рассмотрена и доказана Стэнли Плиской (1997, раздел 1.3).

    Первая фундаментальная теорема ценообразования финансовых активов. Эквивалентны следующие утверждения.

    1. Мартингальная мера Q существует.
    2. Экономика является безарбитражной,
      = ∅.

    Формула выведения мартингальной меры совпадает с решением задачи репликации для условного требования C = (C0, C1):

    .

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

    ,

    где

    и

    .

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

    In [45]: import scipy.optimize as sco

    In [46]: M = np.array((

                 (11, 25,  0,  0, 25),

                 (11, 20, 30, 15, 25),

                 (11, 10,  0, 20, 10),

                 (11,  5, 30, 15,  0),

                 (11,  0,  0,  0,  0)

              ))

    In [47]: np.linalg.matrix_rank(M)

    Out[47]: 5

    In [48]: M0 = np.ones(5) * 10

    In [49]: M0

    Out[49]: array([10., 10., 10., 10., 10.])

    In [50]: r = 0.1

    In [51]: def E(Q):

                 return np.sum((np.dot(M.T, Q) - M0 * (1 + r)) ** 2)

    In [52]: E(np.array(5 * [0.2]))

    Out[52]: 4.0

    In [53]: cons = ({'type': 'eq', 'fun': lambda Q: Q.sum() - 1})

    In [54]: bnds = (5 * [(0, 1)])

    In [55]: bnds

    Out[55]: [(0, 1), (0, 1), (0, 1), (0, 1), (0, 1)]

    In [56]: res = sco.minimize(E, 5 * [1],

                                method='SLSQP',

                                constraints=cons,

                                bounds=bnds)

    In [57]: Q = res['x']

    In [58]: Q

    Out[58]: array([0.14667, 0.18333, 0.275 , 0.18333, 0.21167])

    In [59]: np.dot(M.T, Q) / (1 + r)

    Out[59]: array([10.     , 9.99998,  9.99999, 10.00001,  9.99998])

    In [60]: np.allclose(M0, np.dot(M.T, Q) / (1 + r))

    Out[60]: True

    Импорт модуля optimize из scipy.

    Определение матрицы рыночных выплат.

    Проверка полноты ранга матрицы.

    Определение вектора цен для торгуемых финансовых активов…

    …И вывод значений — все они равны 10.

    Установление постоянной краткосрочной ставки.

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

    Ограничение, согласно которому сумма единичных вероятностей равна единице.

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

    Процедура оптимизации, которая минимизирует функцию E

    …Определяет используемый метод…

    …Устанавливает ограничения, которые должны соблюдаться…

    …И устанавливает пределы для параметров.

    Вектор с результатами — мартингальная мера.

    Согласно определению мартингальной меры, процессы дисконтирования цен являются мартингалами.

    Вторая фундаментальная теорема о ценообразовании финансовых активов также действует в отношении обобщенной статичной модельной экономики

    . Она также была рассмотрена и доказана Стэнли Плиской (1997, раздел 1.5).

    Вторая фундаментальная теорема ценообразования финансовых активов. Эквивалентны следующие утверждения.

    1. Мартингальная мера Q уникальна.
    2. Модель рынка является полной,
      .

      Фундаментальные теоремы

      Поиски приемлемых способов представления ценообразования опционов привели к созданию прорывных моделей Блэка и Шоулза (1973) и Мертона (1973), образовавших в совокупности модель Блэка — Шоулза — Мертона. Эти модели довольно специфичны, поскольку предполагают геометрическое броуновское движение в качестве модели процесса цено­образования одного рискового актива. Исследования конца 1970-х — начала 1980-х годов, проведенные Харрисоном совместно с Крепсом (1979) и Плиской (1981), послужили основой для представления ценообразования условных требований. Центральную роль в них играют мартингальные меры и семимартингальные процессы. Класс семимартингальных процессов довольно велик и включает в себя как ранние модели (например, геометрическое броуновское движение), так и многие более сложные финансовые модели, появившиеся и исследованные гораздо позже (диффузия со скачками или процессы стохастической волатильности). Это одна из причин, почему представленные теоремы называют фундаментальными, — они применимы к большому количеству интересных и важных финансовых моделей.

    Модель ценообразования опционов Блэка — Шоулза — Мертона

    Основой для модели ценообразования опционов Блэка — Шоулза — Мертона послужила непрерывная модель экономики, обычно представляемая стохастическими дифференциальными уравнениями (СДУ) с подходящими граничными условиями. СДУ, которые описывают развитие единственного рискового актива (например, акции или фондового индекса), используются также для описания геометрического броуновского движения. Помимо рискового актива, в модельной экономике торгуется еще один безрисковый актив, по которому уплачивается непрерывная безрисковая краткосрочная ставка.

    В статичной модели с двумя релевантными моментами времени, скажем t = 0 и t = T > 0, будущую, неопределенную стоимость рискового актива ST можно вычислить через:

    ,

    где S0

    >0 — это цена рискового актива сегодня, r
    0 — постоянная безрисковая краткосрочная ставка, σ
    >0 — постоянный коэффициент волатильности, а z — стандартная нормально распределенная случайная величина (см.: Якод и Проттер, 2004, глава 16).

    В дискретных условиях, чтобы получить в предыдущем уравнении числовые значения I для ST, можно взять, например, стандартные нормально распределенные псевдослучайные величины zi, i = 1, 2... I:

    .

    Такая процедура обычно называется моделированием методом Монте-Карло. Для упрощения обозначений в дальнейшем ST будет означать вектор смоделированных будущих цен акции:

    .

    Таким образом, модельная экономика выглядит следующим образом. Существует общее вероятностное пространство {Ω,

    ≡ ℘(Ω), P} с возможными будущими состояниями экономики I. Предполагается, что каждое состояние одинаково вероятно, то есть:

    .

    Множество торгуемых финансовых активов

    состоит из безрискового актива — облигации с процессом ценообразования B = (B0, B0 · erT), рискового актива — акции (по которой выплачиваются дивиденды) с процессом ценообразования S = (S0, ST) и определенного ранее ST. Все вместе они образуют экономическую модель Блэка — Шоулза — Мертона:

    .

    Предположим, что в качестве условного требования на акцию выписан европейский колл-опцион. Выплата по нему составляет:

    с ценой исполнения K

    0. Стоимость (используется оценка методом Монте-Карло) колл-опциона здесь дается в виде ожидаемой (средней) дисконтированной выплаты:

    .

    Представленная модельная экономика и подход к ценообразованию по методу Монте-Карло легко реализуются на языке Python. На рис. 5.1 показано частотное распределение смоделированных цен акции со средним значением и стандартным отклонением вокруг него:

    In [61]: import math

    In [62]: S0 = 100

             r = 0.05

             sigma = 0.2

             T = 1.0

             I = 10000

    In [63]: rng = default_rng(100)

    In [64]: ST = S0 * np.exp((r - sigma ** 2 / 2) * T +

                  sigma * math.sqrt(T) * rng.standard_normal(I))

    In [65]: ST[:8].round(1)

    Out[65]: array([ 81.7, 109.2, 120.5, 114.9,  85. , 127.7, 118.6, 118.6])

    In [66]: ST.mean()

    Out[66]: 105.6675325917807

    In [67]: S0 * math.exp(r * T)

    Out[67]: 105.12710963760242

    In [68]: from pylab import mpl, plt

             plt.style.use('seaborn')

             mpl.rcParams['savefig.dpi'] = 300

             mpl.rcParams['font.family'] = 'serif'

    In [69]: plt.figure(figsize=(10, 6))

             plt.hist(ST, bins=35, label='frequency');

             plt.axvline(ST.mean(), color='r', label='mean')

             plt.axvline(ST.mean() + ST.std(), color='y', label='sd up')

             plt.axvline(ST.mean() - ST.std(), color='y', label='sd down')

             plt.legend(loc=0);

    Начальная цена акции.

    Постоянная краткосрочная ставка.

    Коэффициент волатильности.

    Период времени в долях года.

    Количество состояний и количество моделирований.

    Установление начального значения для сходимости результатов.

    Основная строка кода — реализация моделирования методом Монте-Карло с помощью NumPy в векторном режиме через пошаговое моделирование значений I.

    Среднее значение, полученное из смоделированного множества цен акции.

    Теоретически ожидаемая цена акции.

    Вывод результатов моделирования в виде гистограммы и добавление некоторых основных статистических данных.

    Рис. 5.1. Частотное распределение смоделированных цен акции по Блэку — Шоулзу — Мертону

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

    In [70]: K = 105

    In [71]: CT = np.maximum(ST - K, 0)

    In [72]: CT[:8].round(1)

    Out[72]: array([ 0. ,  4.2, 15.5,  9.9,  0. , 22.7, 13.6, 13.6])

    In [73]: C0 = math.exp(-r * T) * CT.mean()

    In [74]: C0

    Out[74]: 8.288763195530931

    Цена исполнения опциона.

    Вектор выплат по опциону.

    Оценка стоимости опциона методом Монте-Карло.

    Полнота модельной экономики в системе Блэка — Шоулза — Мертона

    Рассмотрим модельную экономику Блэка — Шоулза — Мертона

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

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

    В приведенном ранее расчете арбитражной цены через моделирование методом Монте-Карло используется тот факт, что модельная экономика

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

    Функция np.linalg.solve из библиотеки NumPy, использовавшаяся до сих пор для решения репликационных задач, требует квадратной матрицы (рыночных выплат). В экономике Блэка — Шоулза — Мертона, где есть только два торгуемых финансовых актива, а возможных будущих состояний гораздо больше, данный элемент отсутствует. Однако задачу репликации в таком случае можно решить способом наименьших квадратов — np.linalg.lstsq:

    In [75]: B0 = 100

    In [76]: M0 = np.array((B0, S0))

    In [77]: BT = B0 * np.ones(len(ST)) * math.exp(r * T)

    In [78]: BT[:4]

    Out[78]: array([105.12711, 105.12711, 105.12711, 105.12711])

    In [79]: M = np.array((BT, ST)).T

    In [80]: M

    Out[80]: array([[105.12711,  81.74955],

                    [105.12711, 109.19348],

                    [105.12711, 120.4628 ],

                    ...,

                    [105.12711,  71.10624],

                    [105.12711, 105.32038],

                    [105.12711, 134.77647]])

    In [81]: phi = np.linalg.lstsq(M, CT, rcond=None)[0]

    In [82]: phi

    Out[82]: array([-0.51089,  0.59075])

    In [83]: np.mean((np.dot(M, phi) - CT))

    Out[83]: 1.1798206855928583e-14

    In [84]: np.dot(M0, phi)

    Out[84]: 7.9850808951857335

    Произвольно установленная стоимость облигации.

    Вектор цен сегодня для двух торгуемых финансовых активов.

    Вектор будущей цены облигации с учетом начальной цены и краткосрочной ставки.

    Полученная в результате матрица рыночных выплат с рангом 2 (сопоставленная с 10 000 будущих состояний).

    Решение задачи репликации способом наименьших квадратов. Для репликации колл-опциона облигация должна быть продана, а акция куплена.

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

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

    Модель ценообразования опционов со скачкообразной диффузией Мертона

    В этом разделе представлена еще одна важная экономическая модель, которая основывается на идеях Мертона и отличается от модели ценообразования акции Блэка — Шоулза — Мертона наличием скачков. Случайные скачки являются причиной неполноты модели экономики

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

    В реальных финансовых временных рядах скачки имеют определенные закономерности. Они могут быть вызваны обвалом фондового рынка, или другими редкими событиями, или чрезвычайными происшествиями. Модель Мертона подробно моделирует такие редкие события и их влияние на стоимость финансовых активов. Как правило, модели без скачков плохо подходят для объяснения определенных показателей и явлений, регулярно наблюдающихся в финансовых временных рядах. К тому же модель способна формировать как положительные, так и отрицательные скачки. На практике отрицательный скачок (большое падение) можно наблюдать в отношении фондовых индексов, а положительные скачки (пики) — в отношении индексов волатильности.

    Также экономика со скачкообразной диффузией Мертона

    отличается от экономики Блэка — Шоулза — Мертона
    будущей ценой акций в момент времени T, которую можно смоделировать посредством следующей формулы:

    ,

    где

    — это стандартные нормально распределенные величины, а yi — распределенная по закону Пуассона случайная величина с интенсивностью λ (см.: Якод и Проттер, 2004, глава 4). Скачки, в свою очередь, имеют логарифмически нормальное распределение с математическим ожиданием μ и стандартным отклонением δ (см.: Якод и Проттер, 2004, глава 7). Ожидаемый размер скачка составляет:

    .

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

    In [85]: M0 = np.array((100, 100))

    In [86]: r = 0.05

             sigma = 0.2

             lmbda = 0.3

             mu = -0.3

             delta = 0.1

             rj = lmbda * (math.exp(mu + delta ** 2 / 2) - 1)

             T = 1.0

             I = 10000

    In [87]: BT = M0[0] * np.ones(I) * math.exp(r * T)

    In [88]: z = rng.standard_normal((2, I))

             z -= z.mean()

             z /= z.std()

             y = rng.poisson(lmbda, I)

    In [89]: ST = S0 * (

                np.exp((r - rj - sigma ** 2 / 2) * T +

                       sigma * math.sqrt(T) * z[0]) +

                (np.exp(mu + delta * z[1]) - 1) * y

            )

    In [90]: ST.mean() * math.exp(-r * T)

    Out[90]: 100.53765025420363

    In [91]: plt.figure(figsize=(10, 6))

             plt.hist(ST, bins=35, label='frequency');

             plt.axvline(ST.mean(), color='r', label='mean')

             plt.axvline(ST.mean() + ST.std(), color='y', label='sd up')

             plt.axvline(ST.mean() - ST.std(), color='y', label='sd down')

             plt.legend(loc=0);

    Вектор начальных цен для двух торгуемых финансовых активов — облигации и акции.

    Первое множество стандартных нормально распределенных случайных величин.

    Второе множество стандартных нормально распределенных случайных величин.

    Множество распределенных по закону Пуассона случайных величин с интенсивностью lambda.

    Моделирование цен акции в момент времени T с учетом трех множеств случайных величин.

    Вычисление средней дисконтированной стоимости акции на основе смоделированных цен.

    Рис. 5.2. Частотное распределение смоделированных цен акции по Мертону

    Исключить отрицательные значения в моделировании методом Монте-Карло можно с помощью функции максимума (рис. 5.3):

    In [92]: ST = np.maximum(S0 * (

                 np.exp((r - rj - sigma ** 2 / 2) * T +

                        sigma * math.sqrt(T) * z[0]) +

                 (np.exp(mu + delta * z[1]) - 1) * y

            ), 0)

    In [93]: plt.figure(figsize=(10, 6))

             plt.hist(ST, bins=35, label='frequency')

             plt.axvline(ST.mean(), color='r', label='mean')

             plt.axvline(ST.mean() + ST.std(), color='y', label='sd up')

             plt.axvline(ST.mean() - ST.std(), color='y', label='sd down')

             plt.legend(loc=0);

    Функция максимума…

    …Исключает отрицательные значения цены акции.

    Рис. 5.3. Смоделированные (округленные) цены акции по Мертону

    Заключительным этапом является установление цены европейского колл-опциона посредством оценки методом Монте-Карло и аппроксимирующей репликации:

    In [94]: K = 105

    In [95]: CT = np.maximum(ST - K, 0)

    In [96]: C0 = math.exp(-r * T)  * np.mean(CT)

    In [97]: C0

    Out[97]: 10.306374338651601

    In [98]: M = np.array((BT, ST)).T

    In [99]: phi = np.linalg.lstsq(M, CT, rcond=-1)[0]

    In [100]: phi

    Out[100]: array([-0.41827,  0.51847])

    In [101]: np.mean(np.dot(M, phi) - CT)

    Out[101]: 1.1823431123048067e-15

    In [102]: np.dot(M0, phi)

    Out[102]: 10.020157308565008

    Оценка европейского колл-опциона методом Монте-Карло.

    Аппроксимирующий портфель.

    Погрешность репликации в оптимальном портфеле.

    Арбитражная цена по оптимальному портфелю.

    Неполнота модели из-за наличия скачков

    Если модель Блэка — Шоулза — Мертона является полной в узком смысле, то наличие скачков из модели скачкообразной диффузии Мертона делает ее неполной в широком смысле. Даже введение дополнительных финансовых активов не сможет ее восполнить, так как скачки могут принимать бесконечное число значений и, следовательно, для восполнения модели потребуется бесконечное количество финансовых активов.

    Ценообразование через репрезентативного агента

    Предположим, что в обобщенной статичной экономике

    действует репрезентативный агент, максимизирующий ожидаемую полезность. Его первоначальный капитал составляет w
    >0, а предпочтения представлены функцией полезности
    . Формально задача агента такая же, как и в главе 4:

    .

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

    Более того, если предположить, что полный набор ценных бумаг Эрроу — Дебре с чистым предложением единицы за каждую — это K = I, то матрица рыночных выплат имеет вид:

    .

    Согласно теореме Лагранжа задача безусловного экстремума выражается формулой:

    .

    Отсюда следует, что условиями первого порядка для всех позиций портфеля φi, i = 1, 2… I, где i — окупающаяся в состоянии ωi ценная бумага Эрроу — Дебре, являются:

    ,

    где

    — это стоимость ценной бумаги Эрроу — Дебре, погашающейся в состоянии ωi. Соотношение цен всех ценных бумаг Эрроу — Дебре определяется вероятностями реализации соответствующих состояний выплат:

    .

    Таким образом, при w = 1 можно вывести абсолютные цены:

    .

    Другими словами, стоимость ценной бумаги Эрроу — Дебре, погашающейся в состоянии ωi, равна вероятности Pi) материализации этого состояния.

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

    Резюме

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

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

    Тем не менее в отношении моделирования в финансовом пространстве статичные экономики ограничены. Так, в них не учитывается досрочное исполнение опционов, как бывает, например, в работе с американскими опционами. Данное упущение будет восполнено увеличением релевантных моментов времени, что станет следующим шагом к динамическим экономикам, представленным в следующей главе.

    Справочные материалы

    В этой главе были упомянуты следующие статьи.

    • Black F., Scholes M. The Pricing of Options and Corporate Liabilities // Journal of Political Economy, 1973. — № 81 (3). — Р. 638–659.
    • Harrison M., Kreps D. Martingales and Arbitrage in Multiperiod Securities Markets // Journal of Economic Theory, 1979. — № (20). — Р. 381–408.
    • Harrison M., Pliska S. Martingales and Stochastic Integrals in the Theory of Continuous Trading // Stochastic Processes and their Applications, 1981. — № (11). — Р. 215–260.
    • Merton R. Option Pricing when the Underlying Stock Returns are Discon­tinuous // Journal of Financial Economics, 1976. — № 3 (3). — Р. 125–144.
    • Merton R. Theory of Rational Option Pricing // Bell Journal of Economics and Management Science, 1973. — № (4). — Р. 141–183.

    В этой главе были упомянуты следующие книги.

    • Aleskerov F, Ersel Hasan, Piontkovski D. Linear Algebra for Economists. — Heidel­berg: Springer, 2011.
    • Delbaen F., Schachermayer W. The Mathematics of Arbitrage. — Berlin: Springer Verlag, 2006.
    • Duffie D. Security Markets — Stochastic Models. — San Diego: Academic Press, 1988.
    • Jacod J., Protter P. Probability Essentials. — Berlin and Heidelberg: Springer, 2004.
    • Milne F. Finance Theory and Asset Pricing. — N.Y.: Oxford University Press, 1995.
    • Pliska S. Introduction to Mathematical Finance. — Malden and Oxford: Blackwell Publishers, 1997.

    14 Мы заменили обозначение процентной ставки с i на r, чтобы подчеркнуть ее краткосрочность.

    Мы заменили обозначение процентной ставки с i на r, чтобы подчеркнуть ее краткосрочность.

    14

    Глава 6. Динамическая экономика

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

    Стэнли Плиска (1997)

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

    Даррел Дюффе (1986)

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

    Формулы, необходимые для правильного моделирования динамических экономик, сложнее тех, с которыми вы познакомились ранее. В этой главе не будет их подробного разбора, зато мы рассмотрим две наиболее важные динамические модельные экономики, основанные на динамике дискретного времени: модель биномиального ценообразования опционов Кокса — Росса — Рубинштейна (1979) и модель ценообразования опционов Блэка — Шоулза — Мертона в ее дискретной версии моделирования методом Монте-Карло. Под дискретным временем понимается увеличение количества релевантных дат от двух до большего, но все еще конечного числа, скажем до 5 или 50.

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

    В этой главе будут затронуты такие темы, как стохастические процессы, ценообразование опционов на динамично полных рынках, биномиальное ценообразование опционов, динамическое моделирование Блэка — Шоулза — Мертона, досрочное исполнение и ценообразование американских опционов, а также ценообразование опционов методом наименьших квадратов Монте-Карло.

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

    Финансы

    Математика

    Python

    Неопределенность, древовидное решение

    Стохастический процесс, биномиальное дерево

    NumPy, ndarray

    Неопределенность, решение на основе моделирования

    Стохастический процесс, моделирование методом Монте-Карло

    NumPy, ndarray, rng.standard_normal

    Ценообразование европейского опциона

    Внутренняя стоимость, обратная индукция, риск-нейтральное математическое ожидание

    NumPy, ndarray, np.maximum

    Ценообразование американского опциона

    Внутренняя стоимость, продленная стоимость, регрессия МНК, обратная индукция, риск-нейтральное математическое ожидание

    NumPy, ndarray, np.polyval, np.polyfit, np.where

    Основной целью данной главы также является обобщение. Однако если в главе 5 обобщается пространство состояний, то здесь — дискретное множество релевантных моментов времени, в которые появляется новая информация и происходят события, связанные с экономикой. Несмотря на то что такое обобщение требует введения дополнительных формул, здесь они даны в минимальном количестве, поскольку глава не пытается представить общую структуру динамичных экономик с дискретным временем, а фокусируется только на двух конкретных моделях.

    Биномиальное ценообразование опционов

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

    В модели Кокса — Росса — Рубинштейна существует два торгуемых финансовых актива: рисковый (акция) и безрисковый (облигация). Модельная экономика рассматривается на конечном множестве дат

    ≡ {t0 = 0, t1, t2tM = T} с элементами M + 1, M > 1.

    При условии, что в начале стоимость акции равна

    , в следующем моменте времени ее цена
    может принять только два значения:

    где u означает повышение цены, а d — ее понижение15.

    Для упрощения предположим равномерное распределение временной сетки с M временных интервалов, длина каждого из которых составляет Δt = T / M. Тогда конечное множество дат можно записать в виде

    ≡ {t0 = 0, t1 = Δt, t2 = 2ΔtT}. Кроме того, определим, что:

    Таким образом мы получаем свойство u · d = 1, которое создает так называемое рекомбинирующее биномиальное дерево. σ

    >0 представляет собой постоянный коэффициент волатильности.

    Предположим, что постоянная краткосрочная безрисковая процентная ставка задана через r

    0. При условии, что цена облигации равна
    , в следующем временном периоде она составит:

    или для некоторых значений t

    \T

    .

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

    >0, 0 < q < 1. Из свойства мартингала для цены акции следует:

    Здесь видно, что мартингальная мера фиксирована в каждом узле и, следовательно, на всем дереве.

    Основы биномиальной модели ценообразования опционов легко реализуются кодом Python:16

    In [1]: import math

            import numpy as np

    In [2]: S0 = 36.

            K = 40.

            r = 0.06

            T = 1.0

            sigma = 0.2

    In [3]: m = 4

            dt = T / m

            df = math.exp(-r * dt)

            up = math.exp(sigma * math.sqrt(dt))

            down = 1 / up

    In [4]: q = (1 / df - down) / (up - down)

    Начальная стоимость акции.

    Цена исполнения оцениваемого опциона.

    Постоянная безрисковая краткосрочная процентная ставка.

    Горизонт расчета и срок погашения опциона.

    Постоянный коэффициент волатильности.

    Количество временных интервалов.

    Длина каждого временного интервала.

    Коэффициент дисконтирования в установленном временном интервале.

    Повышающий и понижающий коэффициенты.

    Мартингальная вероятность повышения цены.

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

    Моделирование и оценка посредством циклов Python

    Несмотря на то что в этом разделе идет речь о циклах Python, основной задействованной в реализации структурой данных является объект NumPy ndarray:

    In [5]: S = np.zeros((m + 1, m + 1))

            S

    Out[5]: array([[0., 0., 0., 0., 0.],

                   [0., 0., 0., 0., 0.],

                   [0., 0., 0., 0., 0.],

                   [0., 0., 0., 0., 0.],

                   [0., 0., 0., 0., 0.]])

    In [6]: S[0, 0] = S0

            S

    Out[6]: array([[36.,  0.,  0.,  0.,  0.],

                   [ 0.,  0.,  0.,  0.,  0.],

                   [ 0.,  0.,  0.,  0.,  0.],

                   [ 0.,  0.,  0.,  0.,  0.],

                   [ 0.,  0.,  0.,  0.,  0.]])

    In [7]: z = 1

            for t in range(1, m + 1):

                for i in range(0, z):

                    S[i, t] = S[i, t - 1] * up

                    S[i + 1 ,t] = S[i, t - 1] * down

                z += 1

    In [8]: np.set_printoptions(formatter=

                    {'float_kind': lambda x: '%7.3f' % x})

    In [9]: S

    Out[9]: array([[ 36.000,  39.786,  43.970,  48.595,  53.706],

                   [  0.000,  32.574,  36.000,  39.786,  43.970],

                   [  0.000,   0.000,  29.474,  32.574,  36.000],

                   [  0.000,   0.000,   0.000,  26.669,  29.474],

                   [  0.000,   0.000,   0.000,   0.000,  24.132]])

    Начало работы с объектом ndarray.

    Установление начальной цены акции в левом верхнем углу матрицы.

    Установление счетчика z на значение 1.

    Переход от 1 к m+1, то есть проход по всем временным шагам после 0.

    Проход по узлам, релевантным для заданного временного шага.

    Расчет верхнего и нижнего значений с последующим их помещением в объект ndarray.

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

    Полученное в результате предыдущих действий рекомбинирующее биномиальное дерево.

    Ценообразование европейского опциона

    Оценка европейского опциона на основе доступного процесса ценообразования акции происходит путем расчета внутренней стоимости опциона при наступлении срока его погашения и применения обратной индукции. То есть необходимо начинать с конца, двигаться шаг за шагом от будущего к настоящему времени и в каждом узле раз за разом применять парадигму риск-нейтрального ценообразования, как было представлено на примере простой статичной экономики с двумя состояниями (см. главу 2).

    Следующий код представляет выплату по европейскому пут-опциону:

    In [10]: h = np.zeros_like(S)

    In [11]: z = 1

             for t in range(0, m + 1):

                 for i in range(0, z):

                     h[i, t] = max(K - S[i, t], 0)

                 z += 1

    In [12]: h

    Out[12]: array([[  4.000,  0.214,  0.000,  0.000,  0.000],

                    [  0.000,  7.426,  4.000,  0.214,  0.000],

                    [  0.000,  0.000, 10.526,  7.426,  4.000],

                    [  0.000,  0.000,  0.000, 13.331, 10.526],

                    [  0.000,  0.000,  0.000,  0.000, 15.868]])

    In [13]: V = np.zeros_like(S)

             V[:, -1] = h[:, -1]

             V

    Out[13]: array([[  0.000,  0.000,  0.000,  0.000,  0.000],

                    [  0.000,  0.000,  0.000,  0.000,  0.000],

                    [  0.000,  0.000,  0.000,  0.000,  4.000],

                    [  0.000,  0.000,  0.000,  0.000, 10.526],

                    [  0.000,  0.000,  0.000,  0.000, 15.868]])

    In [14]: m

    Out[14]: 4

    In [15]: # Ценообразование европейского опциона

             z = 0

             for t in range(m - 1, -1, -1):

                 for i in range(0, m - z):

                     V[i, t] = df * (q * V[i, t + 1] +

                                 (1-q) * V[i + 1, t + 1])

                 z += 1

    In [16]: V

    Out[16]: array([[  3.977,  2.190,  0.784,  0.000,  0.000],

                    [  0.000,  6.299,  3.985,  1.771,  0.000],

                    [  0.000,  0.000,  9.344,  6.830,  4.000],

                    [  0.000,  0.000,  0.000, 12.735, 10.526],

                    [  0.000,  0.000,  0.000,  0.000, 15.868]])

    In [17]: V[0, 0]

    Out[17]: 3.9771456941187893

    Объект ndarray для внутренней стоимости.

    Расчет внутренней стоимости для релевантных узлов.

    Оценка по узлам с использованием риск-нейтрального ценообразования.

    Полученное в результате предыдущих действий биномиальное дерево приведенной стоимости.

    Приведенная стоимость европейского пут-опциона сегодня.

    Ценообразование американского опциона

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

    ,

    где ht — внутренняя стоимость опциона в момент времени t, а

    — его продленная стоимость.

    Для того чтобы предыдущий код успешно реализовал ценообразование американского опциона, нужно добавить к нему всего одну строку:

    In [18]: # Ценообразование американского опциона

             z = 0

             for t in range(m - 1, -1, -1):

                 for i in range(0, m-z):

                     V[i, t] = df * (q * V[i, t + 1] +

                               (1 - q) * V[i + 1, t + 1])

                     V[i, t] = max(h[i, t], V[i, t])

                 z += 1

    In [19]: V

    Out[19]: array([[  4.540,  2.307,  0.784,  0.000,  0.000],

                    [  0.000,  7.426,  4.249,  1.771,  0.000],

                    [  0.000,  0.000, 10.526,  7.426,  4.000],

                    [  0.000,  0.000,  0.000, 13.331, 10.526],

                    [  0.000,  0.000,  0.000,  0.000, 15.868]])

    In [20]: V[0, 0]

    Out[20]: 4.539560595224299

    Данная строка проверяет решение о досрочном исполнении и определяет внутреннюю стоимость в качестве стоимости американского опциона, если она выше продленной стоимости.

    Полученное в результате этих действий биномиальное дерево для приведенной стоимости американского пут-опциона.

    Приведенная стоимость американского пут-опциона сегодня, которая значительно выше, чем его стоимость при наступлении срока погашения.

    Моделирование и оценка посредством векторизованного кода

    Следующая реализация алгоритма планомерно использует возможности векторизации библиотеки NumPy. Некоторые строки кода выполняют только поясняющую функцию и для самого алгоритма не нужны:

    In [21]: u = np.arange(m + 1)

             u

    Out[21]: array([0, 1, 2, 3, 4])

    In [22]: u ** 2

    Out[22]: array([ 0, 1, 4, 9, 16])

    In [23]: 2 ** u

    Out[23]: array([ 1, 2, 4, 8, 16])

    In [24]: u = np.resize(u, (m + 1, m + 1))

             u

    Out[24]: array([[0, 1, 2, 3, 4],

                    [0, 1, 2, 3, 4],

                    [0, 1, 2, 3, 4],

                    [0, 1, 2, 3, 4],

                    [0, 1, 2, 3, 4]])

    In [25]: d = u.T

             d

    Out[25]: array([[0, 0, 0, 0, 0],

                    [1, 1, 1, 1, 1],

                    [2, 2, 2, 2, 2],

                    [3, 3, 3, 3, 3],

                    [4, 4, 4, 4, 4]])

    In [26]: (u - 2 * d)

    Out[26]: array([[ 0, 1, 2, 3, 4],

                    [-2, -1, 0, 1, 2],

                    [-4, -3, -2, -1, 0],

                    [-6, -5, -4, -3, -2],

                    [-8, -7, -6, -5, -4]])

    Создание объекта ndarray для количества повышения цены от 0 до m.

    Расчет квадратов через векторную операцию.

    Расчет чисел, кратных 2, с использованием объекта u в качестве векторной экспоненты.

    Изменение размера объекта u с одного измерения на два. Количество повышения цены теперь хранится в каждом ряду.

    Транспозиция объекта u для получения двумерного объекта ndarray d. В каждом столбце находится количество повышений цен.

    Комбинация объектов u и d для получения чистого количества повышений и понижений цен. Например, +2 означает «повышение больше на 2 пункта, чем понижение», а 1 — «понижение больше на один пункт, чем повышение»17.

    При наличии матрицы, содержащей чистое количество изменений цен в биномиальном дереве, моделирование процесса ценообразования сводится к одной строке кода:

    In [27]: S = S0 * np.exp(sigma * math.sqrt(dt) * (u - 2 * d))

             S

    Out[27]: array([[ 36.000,  39.786,  43.970,  48.595,  53.706],

                    [ 29.474,  32.574,  36.000,  39.786,  43.970],

                    [ 24.132,  26.669,  29.474,  32.574,  36.000],

                    [ 19.757,  21.835,  24.132,  26.669,  29.474],

                    [ 16.176,  17.877,  19.757,  21.835,  24.132]])

    Векторное моделирование процесса ценообразования акции (биномиальное дерево).

    Рассматриваются только те числа, которые расположены на диагонали матрицы и выше ее.

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

    In [28]: h = np.maximum(K - S, 0)

             h

    Out[28]: array([[  4.000,  0.214,  0.000,  0.000,  0.000],

                    [ 10.526,  7.426,  4.000,  0.214,  0.000],

                    [ 15.868, 13.331, 10.526,  7.426,  4.000],

                    [ 20.243, 18.165, 15.868, 13.331, 10.526],

                    [ 23.824, 22.123, 20.243, 18.165, 15.868]])

    In [29]: V = h.copy()

    In [30]: # Ценообразование европейского опциона

             for t in range(m - 1, -1, -1):

                 V[0:-1, t] = df * (q * V[:-1, t + 1] +

                                (1-q) * V[1:, t + 1])

    In [31]: V[0, 0]

    Out[31]: 3.977145694118792

    In [32]: # Ценообразование американского опциона

             for t in range(m - 1, -1, -1):

                 V[0:-1, t] = df * (q * V[:-1, t + 1] +

                                (1-q) * V[1:, t + 1])

                 V[:, t] = np.maximum(h[:, t], V[:, t])

    In [33]: V

    Out[33]: array([[  4.540,  2.307,  0.784,  0.000,  0.000],

                    [ 10.526,  7.426,  4.249,  1.771,  0.000],

                    [ 15.868, 13.331, 10.526,  7.426,  4.000],

                    [ 20.243, 18.165, 15.868, 13.331, 10.526],

                    [ 23.824, 22.123, 20.243, 18.165, 15.868]])

    In [34]: V[0, 0]

    Out[34]: 4.5395605952243

    Полностью векторизованный расчет внутренней стоимости пут-опциона.

    Рассматриваются только те числа, которые расположены на диагонали матрицы и выше ее.

    Создание копии объекта h.

    Частично векторизованный алгоритм оценки стоимости европейского пут-опциона.

    Приведенная стоимость европейского пут-опциона.

    Частично векторизованный алгоритм оценки стоимости американского пут-опциона.

    Приведенная стоимость американского пут-опциона.

    Европейские и американские опционы

    Прелесть рекомбинирующей биномиальной модели ценообразования опционов, разработанной Коксом, Россом и Рубинштейном, заключается не только в ее простоте, но и в высокоточных результатах, которые она дает при оценке как европейских, так и американских опционов. В пределе, бесконечно уменьшая временные интервалы, она сходится к модели Блэка — Шоулза — Мертона, что является еще одним ее преимуществом.

    Сравнение скорости работы

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

    In [35]: m = 500

             dt = T / m

             df = math.exp(-r * dt)

             up = math.exp(sigma * math.sqrt(dt))

             down = 1 / up

             q = (1 / df - down) / (up - down)

             q

    Out[35]: 0.5044724639230862

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

    Функция binomial_looping() объединяет все элементы циклической реализации алгоритма моделирования и оценки американского пут-опциона:

    In [36]: def binomial_looping():

                 # Моделирование цен акции в виде биномиального дерева

                 S = np.zeros((m + 1, m + 1))

                 S[0, 0] = S0

                 z = 1

                 for t in range(1, m + 1):

                     for i in range(0, z):

                         S[i, t] = S[i, t - 1] * up

                         S[i + 1 ,t] = S[i, t - 1] * down

                     z += 1

                 # Расчет внутренней стоимости

                 h = np.zeros_like(S)

                 z = 1

                 for t in range(0, m + 1):

                     for i in range(0, z):

                         h[i, t] = max(K - S[i, t], 0)

                     z += 1

                 # Ценообразование американского опциона

                 V = np.zeros_like(S)

                 V[:, -1] = h[:, -1]

                 z = 0

                 for t in range(m - 1, -1, -1):

                     for i in range(0, m - z):

                         V[i, t] = df * (q * V[i, t + 1] +

                                   (1 - q) * V[i + 1, t + 1])

                         V[i, t] = max(h[i, t], V[i, t])

                     z += 1

                 return V[0, 0]

    Как правило, выполнение кода занимает не более 200 мс:

    In [37]: %time binomial_looping()

             CPU times: user 190 ms, sys: 4.69 ms, total: 194 ms

             Wall time: 190 ms

    Out[37]: 4.486374777505983

    In [38]: %timeit binomial_looping()

             173 ms ± 2.48 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

    Функция binomial_vectorization() объединяет все элементы векторной реализации алгоритма моделирования и оценки американского пут-опциона:

    In [39]: def binomial_vectorization():

                 u = np.arange(m + 1)

                 u = np.resize(u, (m + 1, m + 1))

                 d = u.T

                 # Моделирование цен акции

                 S = S0 * np.exp(sigma * math.sqrt(dt) * (u - 2 * d))

                 # Расчет внутренней стоимости

                 h = np.maximum(K - S, 0)

                 # Ценообразование американского опциона

                 V = h.copy()

                 for t in range(m-1, -1, -1):

                     V[0:-1, t] = df * (q * V[:-1, t + 1] +

                                    (1-q) * V[1:, t + 1])

                     V[:, t] = np.maximum(h[:, t], V[:, t])

                 return V[0, 0]

    Векторная реализация примерно в 40 раз быстрее циклической, что явно говорит в пользу первой с точки зрения производительности:

    In [40]: %time binomial_vectorization()

             CPU times: user 4.67 ms, sys: 2.39 ms, total: 7.07 ms

             Wall time: 8.73 ms

    Out[40]: 4.486374777506075

    In [41]: %timeit binomial_vectorization()

             4.7 ms ± 252 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)

    Инфраструктура и производительность

    Представленная здесь абсолютная скорость зависит как от используемого оборудования, так и от конфигурации программного обеспечения. Например, можно применять NumPy в сочетании с библиотекой Math Kernel Library (MKL) от Intel. Такая сборка значительно ускоряет выполнение числовых операций на системах, работающих на базе процессоров Intel. В свою очередь, относительная скорость и коэффициент ускорения должны быть примерно одинаковыми вне зависимости от используемой инфраструктуры.

    Модель ценообразования опционов Блэка — Шоулза — Мертона

    В данном разделе представлена динамическая модель ценообразования опционов Блэка — Шоулза — Мертона, статическую версию которой мы рассматривали в предыдущей главе.

    Динамика в экономику Блэка — Шоулза — Мертона вводится через стохастическое дифференциальное уравнение:

    ,

    где St

    >0 — цена акции в момент времени t, r
    0 — постоянная краткосрочная ставка, σ
    >0 — постоянный коэффициент волатильности, а Zt — арифметическое броуновское движение18.

    Моделирование ценовой траектории акций методом Монте-Карло

    Предположим, что имеется конечное множество релевантных моментов времени ℑ ≡ {t0 = 0, t1, t2tM = T} с элементами M + 1, M > 1 и зафиксированной длиной интервала Δt. Стоимость акции St, 0 < t T, с учетом предыдущей цены на нее St Δt может быть смоделирована через дифференциальное уравнение:

    ,

    где z — стандартная нормально распределенная случайная величина. Такое уравнение называется дискретизацией Эйлера. Она известна своей точностью, поскольку обеспечивает сходимость дискретного процесса к непрерывному процессу для значения Δt, которое, в свою очередь, сходится к 0.

    Реализация динамического моделирования методом Монте-Карло на языке Python не составит труда при наличии базовых знаний о статическом моделировании из главы 5. На рис. 6.1 показаны десять смоделированных ценовых траекторий акции:

    In [43]: S0 = 36.

             K = 40.

             r = 0.06

             T = 1.0

             sigma = 0.2

    In [44]: M = 100

             I = 50000

    In [45]: dt = T / M

             dt

    Out[45]: 0.01

    In [46]: df = math.exp(-r * dt)

             df

    Out[46]: 0.9994001799640054

    In [47]: from numpy.random import default_rng

             rng = default_rng(100)

    In [48]: rn = rng.standard_normal((M + 1, I))

             rn

    Out[48]: array([[ -1.160,  0.290,  0.780, ...,  1.890,  0.050, -0.760],

                    [  0.460, -1.400,  0.140, ..., -1.350,  0.150, -0.530],

                    [  0.200, -0.040, -0.730, ...,  2.140,  0.170, -0.340],

                    ...,

                    [ -0.220, -1.310,  0.730, ..., -0.820, -0.600, -0.400],

                    [ -2.130, -1.240,  0.580, ...,  0.960,  0.890,  0.780],

                    [  2.130, -0.410,  0.710, ...,  1.190,  0.100, -0.520]])

    In [49]: S = np.zeros_like(rn)

             S[0] = S0

             S

    Out[49]: array([[ 36.000, 36.000, 36.000, ..., 36.000, 36.000, 36.000],

                    [  0.000,  0.000,  0.000, ...,  0.000,  0.000,  0.000],

                    [  0.000,  0.000,  0.000, ...,  0.000,  0.000,  0.000],

                    ...,

                    [  0.000,  0.000,  0.000, ...,  0.000,  0.000,  0.000],

                    [  0.000,  0.000,  0.000, ...,  0.000,  0.000,  0.000],

                    [  0.000,  0.000,  0.000, ...,  0.000,  0.000,  0.000]])

    In [50]: for t in range(1, M + 1):

             S[t] = S[t - 1] * np.exp((r - sigma ** 2 / 2) * dt +

             sigma * math.sqrt(dt) * rn[t])

    In [51]: S

    Out[51]: array([[ 36.000,  36.000,  36.000, ...,  36.000,  36.000,  36.000],

                    [ 36.349,  35.023,  36.114, ...,  35.056,  36.119,  35.633],

                    [ 36.508,  35.009,  35.602, ...,  36.601,  36.259,  35.402],

                    ...,

                    [ 42.689,  39.760,  40.681, ...,  37.516,  47.893,  42.846],

                    [ 40.921,  38.804,  41.175, ...,  38.260,  48.769,  43.534],

                    [ 42.716,  38.499,  41.782, ...,  39.200,  48.884,  43.103]])

    In [52]: from pylab import mpl, plt

             plt.style.use('seaborn')

             mpl.rcParams['font.family'] = 'serif'

             mpl.rcParams['savefig.dpi'] = 300

    In [53]: plt.figure(figsize=(10, 6))

             plt.plot(S[:, :10]);

    Рис. 6.1. Смоделированные ценовые траектории акции по Блэку — Шоулзу — Мертону

    Финансовые параметры остаются прежними.

    Параметры моделирования методом Монте-Карло (ценовые траектории, временные шаги, длина временного интервала, коэффициент дисконтирования в одном временном интервале).

    Генерация двумерного объекта ndarray со стандартными нормально распределенными случайными величинами соответствующего размера.

    Создание еще одного двумерного объекта ndarray той же формы и установление начальных значений для ценовой траектории отдельной акции.

    Моделирование ценовых траекторий отдельной акции на основе ее начальной стоимости, матрицы случайных чисел и дифференциального уравнения для геометрического броуновского движения.

    Построение графика первых десяти смоделированных траекторий

    Как и в случае со статической моделью, стоимость акции на конец периода можно представить в виде гистограммы (рис. 6.2):

    Рис. 6.2. Частотное распределение смоделированных цен акции в конце периода по Блэку — Шоулзу — Мертону

    In [54]: ST = S[-1]

             plt.figure(figsize=(10, 6))

             plt.hist(ST, bins=35, color='b', label='frequency');

             plt.axvline(ST.mean(), color='r', label='mean')

             plt.axvline(ST.mean() + ST.std(), ls='--', color='y', label='sd up')

             plt.axvline(ST.mean() - ST.std(), ls='-.', color='y', label='sd down')

             plt.legend(loc=0);

    In [55]: S0 * math.exp(r * T)

    Out[55]: 38.22611567563295

    In [56]: ST.mean()

    Out[56]: 38.25248936738523

    Математическое ожидание для St.

    Усреднение по всем смоделированным значениям ST.

    Оценка европейского пут-опциона методом Монте-Карло

    Стоимость европейского пут-опциона методом Монте-Карло можно оценить через:

    ,

    где I — количество смоделированных ценовых траекторий. Таким образом, ценообразование европейского пут-опциона сводится к нескольким строкам кода, реализующим моделирование ценовых траекторий акции. На рис. 6.3 показана гистограмма смоделированной внутренней стоимости опциона при наступлении срока погашения:

    In [57]: h = np.maximum(K - ST, 0)

             h

    Out[57]: array([ 0.000, 1.501, 0.000, ..., 0.800, 0.000, 0.000])

    In [58]: plt.figure(figsize=(10, 6))

             plt.hist(h, color='b', bins=35);

    In [59]: math.exp(-r * T) * h.mean()

    Out[59]: 3.818117261795047

    Векторный расчет внутренней стоимости.

    Построение графика частотного распределения внутренней стоимости опциона при наступлении срока погашения, на котором изображены характерные для него крайне асимметричные выплаты19.

    Расчет среднего значения по всей внутренней стоимости и дисконтирование среднего значения к настоящему моменту.

    Рис. 6.3. Частотное распределение смоделированной внутренней стоимости акции при наступлении срока погашения европейского пут-опциона

    Оценка американского пут-опциона методом Монте-Карло

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

    Вот как реализуется метод наименьших квадратов Монте-Карло для оценки американских опционов на языке Python:

    In [60]: h = np.maximum(K - S, 0)

    In [61]: # Оценка методом наименьших квадратов Монте-Карло

             V = h[-1]

             for t in range(M - 1, 0, -1):

                 reg = np.polyfit(S[t], df * V, deg=5)

                 C = np.polyval(reg, S[t])

                 V = np.where(h[t] > C, h[t], df * V)

    In [62]: df * V.mean()

    Out[62]: 4.454837750511421

    Расчет внутренней стоимости опциона на всей его ценовой траектории, выраженной объектом ndarray.

    Приравнивание начальных смоделированных цен американского опциона к его внутренней стоимости при наступлении срока погашения.

    Алгоритм работает также на основе обратной индукции, начиная с T − Δt и заканчивая Δt.

    Основной этап алгоритма, в котором устанавливается (приблизительно определяется) продленная стоимость на основе регрессии МНК текущей смоделированной стоимости опциона относительно уровней цен на акцию.

    Если внутренняя стоимость выше предполагаемой (приблизительной) продленной стоимости, опцион исполняем, в противном случае — нет.

    Приведенная стоимость рассчитывается как среднее значение вектора цены американского опциона в момент времени t = Δt, полученное на основе алгоритма наименьших квадратов Монте-Карло и дисконтированное для последнего временного интервала к настоящему времени t = 0.

    Досрочное исполнение опциона и моделирование методом Монте-Карло

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

    Резюме

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

    Вторая модель представляет собой динамическую версию непрерывной модели ценообразования опционов Блэка — Шоулза — Мертона, разработанной по методу Монте-Карло. Динамическое моделирование методом Монте-Карло может быть реализовано численно эффективным образом посредством использования библиотеки NumPy. Даже требовательный к вычислительным ресурсам и включающий в себя трудоемкую регрессию метод наименьших квадратов Монте-Карло, разработанный Лонгстаффом и Шварцем (2001), работает довольно быстро, если реализован на основе методов векторизации.

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

    Справочные материалы

    В этой главе были упомянуты следующие статьи.

    • Black F., Scholes M. The Pricing of Options and Corporate Liabilities // Journal of Political Economy, 1973. — № 81 (3). — Р. 638–659.
    • Cox J., Ross S., Rubinstein M. Option Pricing: A Simplified Approach // Journal of Financial Economics, 1979. — № 7 (3). — Р. 229–263.
    • Duffie D. Stochastic Equilibria: Existence, Spanning Number and the No Expected Gains from Financial Trade Hypothesis // Econometrica, 1986. — № 54 (5). — Р. 1161–1183.
    • Longstaff F., Schwartz E. Valuing American Options by Simulation: A Simple Least Squares Approach // Review of Financial Studies, 2001. — № 14 (1). — Р. 113–147.
    • Merton R. Theory of Rational Option Pricing // Bell Journal of Economics and Management Science, 1973. — № 4. — Р. 141–183.

    В этой главе были упомянуты следующие книги.

    • Duffie D. Security Markets —Stochastic Models. — San Diego: Academic Press, 1988.
    • Glasserman P. Monte Carlo Methods in Financial Engineering. — N.Y.: Springer Verlag, 2004.
    • Hilpisch Y. Derivatives Analytics with Python. — Wiley Finance, 2015.
    • Hilpisch Y. Python for Finance. 2nd ed. — Sebastopol: O’Reilly, 2018.
    • Pliska S. Introduction to Mathematical Finance. — Malden and Oxford: Blackwell Publishers, 1997.

    15 u — upward movement, d — downward movement. — Примеч. пер.

    16 Используемые в этой главе параметры взяты из работы Лонгстаффа и Шварца (2001, табл. 1).

    17 Здесь стоит обратить внимание на то, что имеют значение только те числа, которые расположены на диагонали матрицы и выше ее. Числа, находящиеся ниже диагонали, можно игнорировать. Они являются результатом специфических векторных операций, реализованных на объекте ndarray.

    18 См.: Glasserman, Monte Carlo Methods in Financial Engineering (2004, глава 3) и «Python для финансовых расчетов» (2018, глава 12).

    19 Здесь, как это часто бывает на практике, существует много случаев, когда опцион истекает, не принося прибыли, то есть с выплатой, равной нулю.

    16
    15

    u — upward movement, d — downward movement. — Примеч. пер.

    Используемые в этой главе параметры взяты из работы Лонгстаффа и Шварца (2001, табл. 1).

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

    См.: Glasserman, Monte Carlo Methods in Financial Engineering (2004, глава 3) и «Python для финансовых расчетов» (2018, глава 12).

    18

    Здесь, как это часто бывает на практике, существует много случаев, когда опцион истекает, не принося прибыли, то есть с выплатой, равной нулю.

    17
    19