Базовые показатели актива

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

Расчёт всех основных показалетей портфеля производится на основе месячных закрывающих значений от начального месяца с индексом 0 до месяца с индексом для актива. Индекс 0 взят для того, чтобы далее вычислить показатели, зависящие от пар закрывающих значений, и поэтому имеющие длину на 1 меньше. Например, для индекса S&P за 13 месяцев с января 2016 года такими значениями будут:

> import yapo
> snp = yapo.portfolio_asset(name='SNP', start_period='2016-01', end_period='2017-1')
> close = snp.close()
> close
array([48.71263823, 49.19708287, 56.35994283, 61.22169078, 59.04168992,
       63.13509861, 62.9684921 , 62.5826665 , 65.81357015, 64.53918416,
       64.34312478, 63.29153355, 71.32996825])

13 значений – минимальное необходимое количество для корректного вычисления риска, приведённого к годовому значению.

Доходность

Доходность (Rate of Return) – это относительный прирост каждого закрывающего значения к предыдущему:

Для внутреннего представления временных рядов мы используем np.array, в котором нет встроенной операции, которая бы вычисляла относительный прирост, как например pct_change() в Pandas. Поэтому мы вычисляем так:

> import numpy as np
> ror = np.diff(close) / close[:-1]
> ror
array([ 0.00994495,  0.14559522,  0.08626247, -0.03560831,  0.06933082,
       -0.00263889, -0.00612728,  0.05162617, -0.01936357, -0.00303783,
       -0.01634349,  0.12700648])

Обратим внимание на два важных момента:

  1. деление применяется поэлементно для векторов
  2. в результате вычислений получилось 12 значений, а не 13. Выдумывать несуществующие значения, чтобы длина вектора close была равна длине вектора ror – чревато ошибками

Накопленная доходность

Накопленная доходность (Accumulated Rate of Return) – это кумулятивное произведение доходностей от начальной до текущей:

Вектор aror вычисляется так:

> aror = (ror + 1.).cumprod() - 1.
> aror
array([0.00994495, 0.1569881 , 0.25679275, 0.21204049, 0.29607225,
       0.29265206, 0.28473162, 0.3510574 , 0.32489609, 0.32087128,
       0.29928363, 0.46430107])

Риск

Мы различаем два типа риска: месячный и приведённый к году из помесячных данных. Месячный риск равен стандартному отклонению месячных значений доходности:

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

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

Соответствующие значения вычисляются так:

> risk_monthly = ror.std()
> risk_monthly
0.0581122245021435
> ror_mean = (1. + ror).mean()
> risk_yearly = np.sqrt(risk_monthly**2 + ror_mean**2)**12 - ror_mean**24)
> risk_yearly
0.29298344643386953

Среднегодовая доходность

Среднегодовая доходность (Compound Annual Growth Rate) – это усреднённая (в смысле геометрической прогрессии) доходность на выбранном периоде:

Обратим внимание на то, что – не обязательно целое число.

Вычислим значение CAGR для всего периода:

> years_total = aror.size / 12
> cagr = (aror[-1] + 1.) ** (1 / years_total) - 1.
> cagr
0.4643010692240086

Инфляция

За инфляцию примем изменение показателя индекса потребительских цен (CPI Rate).

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

Вычисление:

> inflation = snp.inflation() # US inflation for period from 2016-02 to 2017-1
> inflation
array([ 0.000823,  0.004306,  0.004741,  0.004046,  0.003284, -0.001618,
        0.000918,  0.002404,  0.001247, -0.001555,  0.000327,  0.005828])
> inflation_arithmetic_mean = inflation.mean()
> inflation_arithmetic_mean
0.0020625833333333334
> inflation_accumulated = (inflation + 1.).cumprod() - 1.
> inflation_accumulated
array([0.000823  , 0.00513254, 0.00989788, 0.01398392, 0.01731385,
       0.01566783, 0.01660022, 0.01904412, 0.02031487, 0.01872828,
       0.01906141, 0.0250005 ])
> years_total = inflation.size / 12
> inflation_geometric_mean = (inflation_accumulated + 1.)**(1 / years_total) - 1.
> inflation_geometric_mean
0.025000495851904336

Реальные значения

Реальные значения , , – значения, скорректированные на коэффициент удешевления денег – инфляции. Формулы для вычисления реальных значений:

Вычисляются значения так:

> ror_real = (ror + 1.) / (inflation + 1.) - 1.
> ror_real
array([ 0.00911445,  0.14068343,  0.0811368 , -0.03949451,  0.06583063,
       -0.00102254, -0.00703882,  0.04910413, -0.02058491, -0.00148514,
       -0.01666504,  0.12047634])
> aror_real = (aror + 1.) / (inflation_accumulated + 1.) - 1.
array([0.00911445, 0.15108013, 0.24447509, 0.19532515, 0.27401416,
       0.27271143, 0.26375304, 0.32580853, 0.29851689, 0.29658841,
       0.27498071, 0.42858572])
> cagr_real = (cagr + 1.) / (inflation_accumulated[-1] + 1.)**(1/years_total) - 1.
> cagr_real
0.42858571790932665

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