Analysis Patterns 1.0 Help

10. Производные контракты

Чтобы полностью понять эту главу, вам нужно сначала прочитать разделы 9.1 и 9.2. Производные финансовые сделки [3] играют все более заметную роль в торговле. Производная сделка (дериватив) — это сделка, стоимость которой зависит от стоимости другой ценной бумаги. Более простые формы деривативов существуют уже довольно давно. Например, опционы на акции впервые стали торговаться на организованной бирже в 1973 году. С тех пор появляются все более экзотические варианты деривативов. Они ценны для инвесторов, поскольку снижают риск, возникающий при изменении цен. Однако при отсутствии должного контроля деривативы могут быть опасны. Недавно в нескольких известных случаях организации потеряли огромные суммы денег на плохо управляемых деривативах.

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

Мы начнем с представления простых производных: форвардных контрактов (10.1) и опционов (10.2). Форвардные контракты вводят понятие тенор (срок действия контракта), что приводит к обсуждению того, почему вычисления дат сложнее, чем сложение дней. Опционы представляют собой несколько неудобных областей моделирования: определение трейдером понятий «колл» (право покупки) и «пут» (право продажи), а также связь между опционом и базовым контрактом.

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

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

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

Ключевые понятия

Форвардный контракт, срок действия, опцион, продукт.

10.1 Форвардные контракты

Контракты, рассмотренные в разделе 9.1, являются простыми и связаны с немедленными сделками. На большинстве рынков существует целый ряд более сложных сделок. Самый простой из них — форвардный контракт. По обычному контракту, который часто называют спот-контрактом, поставка осуществляется как можно ближе к дате заключения контракта. Обычно поставка осуществляется в течение нескольких дней. Форвардные контракты — это соглашения о совершении сделки через некоторое время в будущем. Например, компания должна получить танкер с нефтью через два месяца. За эту нефть компания должна будет заплатить несколько миллионов долларов. Однако если компания немецкая, то ее обычное финансирование осуществляется в марках. Если в ближайшие два месяца курс доллара к марке значительно изменится, компания может оказаться вынужденной заплатить больше марок, чем ожидала, что может стать серьезной проблемой. Конечно, компания выиграет и от благоприятного изменения обменного курса, но неопределенность для нее нежелательна. Чтобы снять эту неопределенность, компания могла бы купить несколько миллионов долларов по форвардному контракту на обменный курс, заплатив оговоренную сумму марок сейчас за поставку долларов через два месяца. Цена предлагается банком, осуществляющим сделку, на основе рыночных представлений о том, куда может пойти курс доллара к марке в ближайшие пару месяцев. О такой сделке говорят: тенор в два месяца (в отличие от спотовой).

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

10.1.png

Сроки погашения зависят от разницы между датами торговли и поставки.

Рисунок 10.1 Контракт, который может поддерживать форвардные контракты.

Пример: Компания Aroma Coffee Makers соглашается 1 января 1997 года купить 5000 тонн кофе Brazilian у Brazil Coffee Exports. Поставка назначена на 20 октября 1997 года, а цена установлена на уровне сегодняшней.

Пример: Я покупаю авиабилет для путешествия через три месяца, заплатив за него цену, указанную на данный момент.

Важным моментом при обсуждении форвардных контрактов является срок действия контракта. Срок действия контракта — это период между датой заключения сделки и датой поставки, в нашем примере — два месяца. Цены на рынке обычно котируются с учетом конкретного срока действия, и срок действия является важной частью рассмотрения контракта. Однако срок действия контракта — это не просто продолжительность периода между датами заключения и поставки. Если наш двухмесячный контракт торгуется 4 мая, то дата поставки не будет 4 июля, просто потому, что 4 июля в США — праздник. Праздники оказывают большое влияние на то, как рассчитываются эти даты. Если предположить, что 4 июля не выпадает на выходные, то двухмесячный контракт, заключенный 4 мая, будет поставлен 5 июля. Обратите внимание, что если бы по какой-то причине в Германии 5 июля был выходной, то дата поставки была бы сдвинута еще на один день. Срок действия контракта по-прежнему составляет два месяца, хотя дата его поставки совпадает с датой поставки по контракту с датой два месяца и один день. Обратите внимание, что такое поведение требуется и для спот-контрактов: сделка, заключенная в четверг, будет поставлена в понедельник (если это не праздничный день), даже если спот принимается за два дня. Таким образом, на рисунке 10.1 указаны дата заключения сделки, дата поставки и срок исполнения.

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

10.2.png

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

Рисунок 10.2 Вычисление даты на бирже.

Пример: Компании необходимо произвести выплату сотруднику в течение пяти рабочих дней с 30 июня 1997 года. Если это американская компания, то до 8 июля (пропуская выходные и 4 июля); для британской компании это 7 июля.

10.2 Options

Для нашей немецкой нефтяной компании форвардный контракт — ценный инструмент, позволяющий снизить риск изменения обменного курса, в результате которого ей придется платить за нефть больше. Однако компания рискует понести убытки, если курс изменится не в ее пользу. Финансовым директорам, по сути, приходится делать ставки на изменение обменного курса. Если они считают, что курс вырастет, они должны покупать на спотовом рынке; если они считают, что он снизится, они должны покупать форвардные контракты. Опционы снижают этот риск. Опцион дает покупателю право купить доллары по заранее оговоренному курсу, если он того пожелает. Таким образом, если марка упадет, нефтяная компания может исполнить свой опцион и купить доллары по заранее оговоренной цене; если доллар вырастет, она может проигнорировать свой опцион (пусть он истечет) и купить на спотовом рынке. Банк берет с нефтяной компании премию за продажу опциона, так что теперь банк управляет риском. Поскольку банк обслуживает множество подобных сделок, он может компенсировать риски различных сделок друг против друга. На рисунках 10.3 и 10.4 описано поведение опциона.

10.3.png

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

Рисунок 10.3 Диаграмма событий для процесса использования опции.

10.4.png

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

Рисунок 10.4 Диаграмма состояний Харела, иллюстрирующая поведение опциона.

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

Таким образом, мы можем рассматривать опцион как подтип контракта, как показано на рис. 10.5. Ключевой особенностью структуры опциона является полиморфная операция стоимость(сценарий). Стоимость спот-контракта легко понять, поскольку она является простым результатом применения спот-курса обмена в предусмотренном сценарии к сумме контракта. Стоимость опционов, мягко говоря, сложнее. Наиболее распространенной методикой является анализ Блэка-Шоулза (Black-Scholes) [3]. Объяснение этого метода выходит за рамки данной книги, разве что отметим, что для того, кто вызывает эту операцию, она является единой. Сложности математики могут быть надежно спрятаны внутри операции.

10.5.png

Термины «колл» и «пут» выведены от терминов «лонг» и «шорт».

Рисунок 10.5 Структура опциона.

10.2.1 Лонги, шорты, коллы и путы: Представление сложного словаря

Вопрос о лонгах и шортах действительно нуждается в обсуждении. В разделе 9.1 мы объяснили, что контракт может быть на покупку (long) или на продажу (short). Однако для опционов существует четыре варианта. Мы можем продать опцион на продажу денег, продать опцион на покупку денег, купить опцион на продажу денег или купить опцион на покупку денег. Выбор длинный/короткий по-прежнему существует в контракте, но он дополняется еще одним выбором длинный/короткий в опционе. В словарном запасе трейдера есть термины «колл» и «пут». Колл — это опцион на покупку (то есть длинный контракт), а пут — опцион на продажу (короткий контракт). Естественно, мы можем купить или продать колл (право покупки), а также купить или продать пут (право продажи). Пересказ этого языка несколько сложен, а также запутан.

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

Один из способов взглянуть на это — сказать, что мы можем заменить длинное/короткое описание контракта на колл/пут. Но это не совсем работает, потому что мы не используем термины «колл» и «пут» для контрактов, которые не являются опционами.

Другой вариант — использовать термины long и short только для опционов, чтобы обозначить состояние опциона, а не контракта. Таким образом, первый пример выше будет коротким коллом, а второй — длинным путом (нет, ничего не перепутано). Это может иметь смысл для трейдера, но может запутать любое программное обеспечение. При оценке риска важна позиция суммы контракта, а в приведенных выше примерах оба контракта короткие. Следовательно, нам нужно уметь задавать направление контракта (которое определяет позицию), направление опциона и колл/пут. Итак, два примера: (короткий контракт, короткий опцион, колл) и (короткий контракт, длинный опцион, пут). Очевидно, что один из них может быть получен из двух других. На диаграмме показано, что колл/пут является производным. Вывод — это напоминание о том, что одно из них является производным, а не указание исполнителю на то, что на самом деле хранится или вычисляется в реализации.

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

Пример: 1 июня 1997 года я получил опцион на покупку 200 акций Aroma Coffee Makers 1 января 1999 года по цене $5 за акцию. Это опцион с датой сделки 1 июня 1997 года, инструментом — акциями Aroma Coffee Makers, количеством 200, датами поставки и истечения 1 января 1999 года, премией 0 долларов и ценой 5 долларов. 1 акция будет приобретена, поэтому контракт длинный (по отношению ко мне), и опцион тоже длинный (поскольку я его держу); таким образом, это колл.

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

Другой проблемой является взаимодействие между датой поставки и датой истечения срока действия. Для опциона дата поставки может быть вычислена, если известна дата истечения срока действия (дата поставки = дата истечения + спот). Обратное, однако, не верно (из-за вмешательства праздников). Это означает, что для опционов дата поставки является вычисляемым сопоставлением. Важным моментом здесь является то, что интерфейс не меняется — по-прежнему существует аксессор для даты доставки, однако информация сохранена. Есть два способа для описания этой ситуации. Первый — мы можем отметить (обычно в глоссарии), что для опционов атрибут даты доставки переопределяется и вычисляется из даты истечения срока действия в соответствии с формулой. Второй — описать формулу как ограничение на тип опциона. Оба варианта вполне разумны, и выбор — дело вкуса. Какой код и структуру данных использовать, зависит только от исполнителя.

10.2.2 Подтипировать или нет — вот в чем вопрос

Структура, показанная на рис. 10.5 — не единственный способ работы с опционами; другой вариант показан на рис. 10.6. Разница между этими двумя структурами заключается в том, как опциональность добавляется в контракт. На рисунке 10.5 мы добавляем ее путем подтипизации. В этой схеме опцион — это разновидность контракта с дополнительными свойствами и некоторым вариантом поведения. На рис. 10.6 мы можем сказать, что у опциона есть базовый контракт, который трейдеры часто называют базой опциона. Здесь есть по крайней мере некоторое понятие сдерживания, особенно в том, что мы вряд ли попросили бы контракт оценить себя, если бы он был базовым для опциона. Аналогично, дата поставки будет зависеть от даты истечения опциона.

10.6.png

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

Рисунок 10.6 Отдельный объектный подход к опционам и контрактам.

Выбор между этими двумя конструкциями непрост. Обе обладают элегантными качествами. Модель на рис. 10.6 разделяет понятия опциона и контракта с определенным понятием базового контракта. Недостатком этой схемы является то, что один контракт представлен двумя объектами. Проще изменить рисунок 10.6 для работы с составными опционами (опционами, в которых базовый контракт является опционом). При таком небольшом выборе между ними мы можем легко запутаться. Прототипирование иногда может прояснить ситуацию, но не всегда. Когда появляются альтернативы, подобные этой, хорошей идеей будет использовать более простой подход, а затем, при необходимости, перейти к более сложному. В данном случае, однако, можно поспорить, какой подход проще. Когда ситуация настолько близка, я доверяю инстинктам экспертов домена, спрашивая их о том, что кажется лучше. Мы продолжим использовать рисунок 10.5 в качестве основы для дальнейшего обсуждения.

10.3 Продукт

Сделки с деривативами долгое время считались несколько рискованными, в основном из-за сложной математики, необходимой для оценки риска. Уравнение Блэка-Шоулза (Black-Scholes) [3], которое служит строительным блоком для большей части процесса оценки, представляет собой дифференциальное уравнение второго порядка. Даже имея инженерное образование, эти звери все равно вызывают у меня дрожь.

Самым ярким примером подводных камней торговли деривативами является крах британского Barings Bank. По имеющимся данным, основной причиной краха стала торговля особым видом деривативов, называемым стрэддл (straddle) — пример комбинированного опциона. Комбинированные опционы можно рассматривать как составную часть других опционов. Представляется уместным обсудить этот раздел на примере стрэддлов.

Концепция стрэддла на самом деле очень проста. У вас есть пакет акций стоимостью около 70 миллионов долларов, и вас беспокоит любое значительное изменение его стоимости в течение следующих трех месяцев. Либо повышение, либо понижение приведет к проблемам. Чтобы избежать этой проблемы, вы можете купить колл и пут, оба с ценой 70 миллионов долларов и сроком истечения через три месяца. Предположим, что премия по каждому из них составляет 2,5 миллиона долларов. Если цена вырастет, вы исполните колл и получите стоимость пакета по новой цене, за вычетом 70 миллионов долларов и общей премии в 5 миллионов долларов. Таким образом, если стоимость акций вырастет выше 75 миллионов долларов, вы будете довольны. Аналогично, если стоимость упадет ниже 65 миллионов долларов, вы будете счастливы. Худшее, что может произойти, — это то, что цена останется неизменной, и в этом случае вы потеряете премию в размере 5 миллионов долларов. Привлекательность стрэддла обусловлена фиксированным риском, который покрывает очень широкий диапазон движения. Естественно, очень волатильный инструмент может привести к более высокой премии за стрэддл, но если вы пытаетесь снизить свой риск в условиях нестабильности, это может быть очень полезным продуктом.

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

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

10.7.png

Стрэддл — это комбинация колла и пута.

Рисунок 10.7 Моделирование стрэддлов как подтипов опционов.

Использование подтипа подтверждает, что стрэддл является разновидностью опциона и имеет такое же поведение, как и его супертип. Однако это вызывает вопросы. Некоторое поведение может быть безопасно унаследовано, например, способность оценивать себя и дату сделки. Премию можно представить как сумму премий опционов-компонентов. Но как насчет цены? Для стрэддла все компоненты имеют одинаковую цену, поэтому мы можем считать, что это цена стрэддла. Однако другой распространенной комбинацией является спрэд (разница цены покупки и продажи). Как уже говорилось, спрэд — это два опциона, но оба опциона одного направления (то есть два колла или два пута) по разным ценам. Что в данном случае является ценой? Возвращаясь к стрэддлу, что это — колл или пут?

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

10.8.png

Рисунок 10.8 Разделение подтипов на комбинированные и обычные.

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

Это приводит нас к модели, показанной на рис. 10.9. Здесь взгляд продавца явно отделен от взгляда риск-менеджера. Риск-менеджер видит контракты, которые продавец собирает в продукт. Теперь стрэддл — это особый вид продукта. Это позволяет нам пересмотреть поведение контракта и перенести поведение, связанное с продажами, в продукт, оставив рисковую сторону вещей в контракте. Это касается и частей продукта, которые, как правило, не имеют отношения к управлению рисками (если только речь не идет о риске для конкретной части). Поскольку у контрактов должен быть продукт (из-за обязательных связей), контракт все равно может найти свои части, сотрудничая со своим продуктом (но см. обсуждение в разделе 10.3.1).

10.9.png

Продукт отражает перспективу продаж. При анализе рисков игнорируется то, как контракты объединяются в продукты.

Рисунок 10.9 Знакомство с продуктом.

Рассматривая вопрос о том, стоит ли вводить подтип, мы должны задать два вопроса. Первый — действительно ли все признаки супертипа наследуются подтипом. Непосредственное подтипирование, как показано на рис. 10.7, должно быть рассмотрено с учетом всех особенностей супертипа, включая особенности супертипов этого супертипа. Об этом легко забыть и пойти по опасному пути. Такой анализ приведет к рефакторингу иерархии обобщений, и этот рефакторинг может оказаться нетривиальным. Второй вопрос, который мы должны задать — действительно ли доменный эксперт считает, что подтипизация имеет место? В нашем примере доменный эксперт сопротивлялся подтипизации, предпочитая модель рис. 10.9. Позже стиль рис. 10.8 снова появился, но пока не показался достаточно убедительным, чтобы изменить модель (и фреймворк, который ее реализует).

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

10.10.png

Это хороший пример иерархии, основанной на ограничениях. Контракты, связанные с продуктом, называются «ногами» продукта.

Рисунок 10.10 Общий вид составного продукта.

Пример: Клиент владеет крупным пакетом акций Aroma Coffee Makers и обеспокоен движением цены акций в течение следующих 6 месяцев, прежде чем он сможет их продать. Он может купить стрэддл по текущей цене $5. Для трейдера этот продукт разбивается на два отдельных варианта.

Пример: Я хочу купить 7000 акций компании Aroma Coffee Makers. Трейдер не может найти ни одного желающего продать именно это количество. Он может найти одну сторону, которая продаст 2000 акций, и другую, которая продаст 5000 акций. У меня есть один продукт с трейдером на покупку 7000 акций. Продукт состоит из двух контрактов на каждую сделку.

10.3.1 Должен ли продукт всегда присутствовать?

Одно из последствий модели на рис. 10.9 заключается в том, что не составные контракты представлены одним контрактом и одним продуктом. Продукт мало что добавляет к картине (кроме разделения ответственности между отделом продаж и отделом управления рисками).

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

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

10.4 Машины состояний подтипов

Хотя многие распространенные деривативы могут быть представлены как комбинации опционов, это не всегда так. Барьерный опцион может либо появиться, либо исчезнуть, когда цена инструмента, котируемого на каком-либо согласованном рынке (например, на странице Reuters), достигнет определенного предела. Таким образом, можно купить опцион на покупку (колл) 10 миллионов иен по цене 90 JPY/USD, который будет исполнен при цене 85 JPY/USD. Этот опцион ведет себя иначе, чем стандартный. По сути, опцион не может быть исполнен (knock-in), если курс не упадет ниже 85 JPY/USD до даты истечения. Если курс упадет ниже этого барьера, то опцион будет исполнен и останется в силе, что бы ни случилось с ценой в период между этой датой и датой истечения срока действия опциона. Если цена так и не опустится ниже барьерного уровня, покупатель никогда не сможет исполнить опцион. (Барьеры могут быть и «knock-out», в этом случае опцион может быть исполнен только в том случае, если обменный курс не преодолеет барьер).

Такое поведение с knock-out можно выразить модификацией диаграммы состояний барьера, фактически заменив ее диаграммой, показанной на рис. 10.11. Диаграмма событий для ее использования показана на рис. 10.12.

10.11.png

Рисунок 10.11 Диаграмма состояний Харела для вызова нок-ин.

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

10.12.png

Рисунок 10.12 Диаграмма событий процесса использования опции knock-in.

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

10.4.1 Обеспечение соответствия диаграмм состояния

Диаграмма состояния сама по себе представляет интересную задачу. Мы можем заменить диаграмму состояний, показанную на рис. 10.4, диаграммой на рис. 10.11, обеспечивающей различное поведение подтипа барьера. Однако при этом возникает вопрос: можно ли так делать? В большинстве методик подчеркивается важность возможности замены подтипа на супертип. Это отражается на диаграммах объектов, позволяя нам только добавлять ассоциации, но не удалять их. Во многих учебниках не упоминается, какие правила управляют диаграммами состояний с подтипами. Шлаер и Меллор (Shlaer and Mellor) [6] указывают, что машины состояний можно размещать только либо в супертипе, либо в подтипе. Однако если у всех подтипов есть общая часть, то она может быть помещена в супертип для облегчения сопровождения. Рамбо [5] указывает, что подтипы могут (обычно) добавлять только ортогональные машины состояний.

Лучше всего о том, как работают подтипы и состояния, рассказано в работе Кука и Дэниелса (Cook and Daniels) [1], которые посвятили подтипам и машинам состояний целую главу. Они подчеркивают принципы проектирования по контракту [4], которые можно кратко сформулировать так: машина состояний супертипа может быть расширена двумя способами: либо добавлением ортогональной машины состояний, либо взятием состояния супертипа и разбиением его на подсостояния. Переходы супертипа могут быть изменены только путем перенаправления их на подсостояния состояния их супертипа.

Применяя эти рекомендации к моделям состояния опционов, мы видим ряд проблем. Первая заключается в трактовке события начала срока действия опциона. На рисунке 10.4 (диаграмма опциона) оно вызывает переход из состояния «куплен» в состояние «исполняется», но на рисунке 10.11 (диаграмма барьера) переход происходит из нового состояния «разрешен к исполнению». Аналогичная проблема возникает и с событием окончания срока действия: на рисунке 10.4 оно вызывает переход только из состояния, пригодного (разрешенного) для исполнения, а на рисунке 10.11 — из любого состояния.

Первая проблема возникает при рассмотрении следующей ситуации. Что должен делать объект, если он получает событие, при нахождении в состоянии когда с событием ничего не можем сделать. Объект может либо молча проигнорировать событие, либо выдать ошибку. Для того чтобы определить, как поступать в этом случае, следует выработать некоторую общую политику; например, Кук и Дэниелс советуют [1] явно перечислять события, в которых заинтересован объект. Любые события, которые обычно молча игнорировались бы, перечисляются как допустимые. Это решает вопрос о том, что произойдет, если диаграмма с рис. 10.11 (барьер) получит событие начала срока истечения, находясь в начале закупки. Если начало срока истечения является разрешенным событием, оно просто проигнорирует его.

Однако это все еще не полностью соответствует супертипу. На рис. 10.11 показано, что при получении события начала даты истечения купленный опцион меняется на исполняемый. Если рассматривать это в терминах контракта, то изменение на купленный является частью постусловия начала даты истечения. Мы не можем ослабить это постусловие в подтипе, только усилить его. Чтобы иметь колл с knock-down в качестве подтипа опциона, мы должны заменить обе диаграммы состояний на те, что показаны на рисунках 10.13 и 10.14.

10.13.png

Рисунок 10.13 Модифицированная диаграмма состояний для опции, позволяющей Куку и Дэниелсу соответствовать вызовам knock-in

10.14.png

Рисунок 10.14 Модифицированная диаграмма состояний для вызовов knock-in для поддержки соответствия рисунку 10.13.

Чтобы обеспечить соответствие, эти диаграммы отражают два изменения. Первое — это обобщение приобретенного и реализуемого в активное состояние. Отсюда мы можем перенаправить событие окончания срока действия. Второе изменение заключается в добавлении можноЛиИсполнить в качестве защиты для события начала срока действия. Эта операция — способ сказать, что начало срока истечения не всегда приводит к состоянию, пригодному для исполнения. Для обычных опционов можноЛиИсполнить всегда истинна. Подтипы опциона могут переопределять его для другого поведения. На рис. 10.14 показано, как это переопределение происходит для барьеров knock-in. Мы вводим подстатусы «куплено», чтобы указать, был ли барьер достигнут или нет. Затем мы разделили источник перехода «начало срока исполнения» и ослабили защиту, чтобы показать незащищенный переход. Так как мы разрешили начало срока исполнения для супертипа, барьер может игнорировать начало срока исполнения, когда его не достигают.

10.4.2 Проблемы с использованием соответствия

Пройдя через это упражнение по достижению соответствия, мы должны остановиться и задать себе несколько вопросов об этом процессе. По моему мнению, рисунки 10.4 и 10.11 представляют собой более простые и понятные выражения поведения, чем рисунки 10.13 и 10.14. Таким образом, хотя мы и приобрели соответствие (по крайней мере, в соответствии с определением Кука и Дэниелса), мы потеряли понятность. Кроме того, моделирование вызова «knock-in» заставило нас изменить диаграмму супертипов. Она и так была хороша — но нам понадобилась другая диаграмма состояний на основе новых состояний подтипа. Это означает, что новый подтип может заставить нас изменить диаграммы состояний супертипов снова, если только мы не окажемся достаточно умны, чтобы создать удивительно гибкую диаграмму состояний супертипа. К сожалению, я не думаю, что я настолько умен, поэтому подтипизация будет сопряжена с трудностями.

Одно из решений этих трудностей — перестроить иерархию обобщений, чтобы не беспокоиться о соответствии. Мы предположили, что колл с knock-down (т.е. барьер не достигнут) будет подтипом опциона, каждый из которых имеет свою собственную таблицу состояний, как показано на рис. 10.15. Другой подход заключается в том, чтобы рассматривать опцион как абстрактный тип без собственной диаграммы состояния и создать обычный подтип опциона для хранения машины состояния с рисунка 10.4, как показано на рисунке 10.16. Это избавляет от необходимости беспокоиться о соответствующих диаграммах состояний, позволяет использовать более естественные диаграммы состояний, но вводит отдельный тип. Это также более соответствует рекомендациям Рамбо, Шлаера и Меллора, которые не обсуждают соответствие между моделями состояний.

10.15.png

Это естественный подход, но как связаны модели состояний?

Рисунок 10.15 Knock-in (с достижением барьера) колл как подтип опциона.

10.16.png

Это может облегчить работу с моделями состояний, но это не так естественно. Оригинальная диаграмма приемлема. Главное, чтобы начало истечения срока действия

Рисунок 10.16 Создание обычного типа опции.

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

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

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

10.5 Параллельные иерархии приложения и доменов

Столкнувшись с портфелем различных контрактов, трейдер может захотеть просмотреть список контрактов вместе с важной информацией о них. В таком списке каждый контракт будет показан в отдельной строке. Информация, отображаемая в строке, будет зависеть от вида контракта. Колонки могут быть: длинный/короткий, дата сделки, цена исполнения, колл/пут (только для опционов), дата истечения (только для опционов), барьерный уровень (только для барьеров), knock-in или knock-out (только для барьеров).

В этой схеме некоторые столбцы таблицы имеют значение только для определенных подтипов опциона. Это добавляет проблеме определенную сложность. Чего мы не можем сделать, так это предположить, что некий класс строки обозревателя (элемент просмотра) запрашивает у каждого контракта каждый релевантный атрибут. Такой подход не сработает, потому что элемент просмотра не сможет запросить у «неопциона» дату истечения срока действия, поскольку у «неопциона» ее по определению нет.

Первым этапом создания дизайна решения является использование многоуровневой структуры, рассмотренной в главе 12. При ее использовании типы портфолио, обозреватель и элемент просмотра представляют собой фасады приложений (прим. в данном случае «фасад» следует понимать как «визуальное представление»), работающие, как показано на рис. 10.17. Объектом обозревателя портфеля является портфель, объектом элемента просмотра — контракт. Ни портфель, ни контракт ничего не знают об обозревателе портфеля или элементе просмотра, поскольку последние типы находятся внутри слоя приложения о котором доменный слой не знает (см. рис. 12.6).

10.17.png

Рисунок 10.17 Обозреватель портфеля и его связь с доменной моделью. Обозреватель портфеля и элемент просмотра являются фасадами приложения.

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

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

10.5.1 Проверка типов в фасаде приложения

В этой стратегии за решение проблемы отвечает элемент просмотра. Перед каждым запросом к контракту выполняется проверка типа контракта, чтобы убедиться, что запрос может быть выполнен безопасно, как показано на рис. 10.18. В C++ это происходит в виде проверки типа, затем следует преобразование типа к подтипу (downcast), после чего выполняется запрос.

10.18.png

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

Рисунок 10.18 Взаимодействие для проверки типа в строке браузера.

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

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

10.5.2 Предоставление супертипу охватывающего интерфейса

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

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

10.5.3 Использование атрибута времени выполнения

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

Базовая модель для контрактов показана на рис. 10.19, или даже лучше взять рис. 10.20, где используется отображение с ключом (см. раздел 15.2). Все контракты имеют несколько условий, и каждый из них получает тип условия. В этом примере каждый атрибут контракта и его подтипы (цена исполнения, колл, барьерный уровень и так далее) будут типами условий контракта. Если у контракта запрашивают условие, он отвечает объектом значения, если такой условие существует. Таким образом, запрос даты истечения «неопциона» не является ошибкой.

10.19.png

Такой способ запроса свойства определенного только в опции не будет приводить к ошибке.

Рисунок 10.19 Атрибут времени выполнения для контракта.

10.20.png

Рисунок 10.20 Рисунок 10.19 Использование сопоставления с ключом.

Конечно, эта модель допускает случайное присвоение «неопциону» даты истечения. Это можно предотвратить несколькими способами. Первый — использовать уровень знаний (см. раздел 2.5), как показано на рис. 10.21. Другой способ — рассматривать тип условия как производный интерфейс. При этом предоставляются как атрибуты модели (те, что касаются контракта и его подтипов), так и интерфейс типа условия. Обновления предоставляются только через атрибуты модели.

10.21.png

Это позволит предотвратить неправильное размещение условий в контрактах, но проверить это можно только во время выполнения.

Рисунок 10.21 Использование уровня знаний для контроля размещения условий в контрактах.

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

10.5.4 Создание фасада приложения, видимого для доменной модели

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

10.22.png

Элемент просмотра должен быть виден контракту, что нарушает обычные правила видимости между слоями домена и приложения.

Рисунок 10.22 Взаимодействие для контрактов, создающий элементы просмотра.

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

Самый большой недостаток заключается в нарушении правил видимости между слоями приложения и домена, которые обсуждаются в главе 12. Этого можно избежать, поместив элемента просмотра в собственный пакет/библиотеку, как показано на рис. 10.23. Таким образом, зависимость от доменной модели ограничивается только типом элемента просмотра. Видимость можно еще больше уменьшить, разделив тип элемента просмотра на два. Презентация для обозревателя и контракты используют совершенно разные интерфейсы для элемента просмотра. Он может иметь свое собственное визуальное представление в UI пакете обозревателя. Тот в свою очередь имеет простое взаимодействие с элементом просмотра. В этом случае можно убрать видимость из представления обозревателя в пакет элемента просмотра.

10.23.png

Пакет элемента просмотра — это особый случай между слоями приложения и домена.

Рисунок 10.23 Видимость пакета элемента просмотра (на основе рисунка 12.6).

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

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

10.5.5 Использование обработки исключений

Конечно, все вышеперечисленные идеи основаны на том, что спрашивать у небарьерного опциона о его барьерном уровне — это плохо. Однако в правильном окружении это не такая уж и проблема. Если запрос объекта приводит к ошибке времени выполнения и эта ошибка проявляется в виде исключения, то элемента просмотра может просто перехватить исключение и обработать его как nil. Элемента просмотра должен проверить, что исключение действительно является результатом того, что приёмник не понял запрос, а не какой-то другой, более тревожной ошибкой. Это также предполагает, что можно отправить сообщение объекту, для которого у приёмника нет интерфейса. Именно здесь отсутствие безопасности типов становится преимуществом, в сочетании с функциями обработки исключений, присутствующими в новых реализациях. Smalltalk всегда можно использовать подобным образом, поскольку он не типизирован. В C++ безопасность типов можно обойти, используя приведение к дочерним типам (downcast).

Ссылки

  1. Cook, S. and J. Daniels. Designing Object Systems: Object-Oriented Modelling with Syntropy. Hemel Hempstead, UK: Prentice-Hall International, 1994.

  2. Gamma, E., R. Helm, R. lohnson and J. Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Reading, MA: Addison-Wesley, 1995.

  3. Hull, J.C. Options, Futures, and Other Derivative Securities (Second Edition). London: Prentice-Hall International, 1993.

  4. Meyer, B. “Applying ‘Design by Contract,’” IEEE Computer, 25, 10 (1992), pp. 40–51.

  5. Rumbaugh, J., M. Blaha, W. Premerlani, F. Eddy, and W. Lorensen. Object-Oriented Modeling and Design. Englewood Cliffs, NJ: Prentice-Hall, 1991.

  6. Shlaer, S. and S. J. Mellor. Object Life Cycles: Modeling the World in States. Englewood Cliffs, NJ: Prentice-Hall, 1991.

Last modified: 16 January 2025