Блог им. Zmey56

Оптимизации портфеля с помощью Python и PyPortfolioOpt

    • 11 мая 2021, 21:57
    • |
    • Aleks
  • Еще
Портфельная теория Марковица

Портфельная теория Марковица(далее ПТМ) (Modern portfolio theory) — разработанная Гарри Марковицем методика формирования инвестиционного портфеля, направленная на оптимальный выбор активов, исходя из требуемого соотношения доходность/риск. Сформулированные им в 1950-х годах идеи составляют основу современной портфельной теории.

Основные положения портфельной теории были сформулированы Гарри Марковицем при подготовке им докторской диссертации в 1950—1951 годах.

Рождением же портфельной теории Марковица считается опубликованная в «Финансовом журнале» в 1952 году статья «Выбор портфеля». В ней он впервые предложил математическую модель формирования оптимального портфеля и привёл методы построения портфелей при определённых условиях. Основная заслуга Марковица состояла в предложении вероятностной формализации понятий «доходность» и «риск», что позволило перевести задачу выбора оптимального портфеля на формальный математический язык. Надо отметить, что в годы создания теории Марковиц работал в RAND Corp., вместе с одним из основателей линейной и нелинейной оптимизации — Джорджем Данцигом и сам участвовал в решении указанных задач. Поэтому собственная теория, после необходимой формализации, хорошо ложилась в указанное русло.

Марковиц постоянно занимается усовершенствованием своей теории и в 1959 году выпускает первую посвящённую ей монографию «Выбор портфеля: эффективная диверсификация инвестиций».

В 1990 году, когда Марковицу вручают Нобелевскую премию, выходит книга «Средне-дисперсионный анализ при выборе портфеля и рынка капитала» ссылка.

Основа модели

1. Ожидаемая доходность портфеля(Portfolio Expected Return)

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

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

Оптимизации портфеля с помощью Python и PyPortfolioOpt

2.Дисперсия портфеля (Portfolio Variance)

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

 Оптимизации портфеля с помощью Python и PyPortfolioOpt

3.Коэффициент Шарпа (Sharpe Ratio)

Коэффициент Шарпа измеряет доходность инвестиций по отношению к безрисковой ставке (казначейской ставке) и степени риска. В целом, более высокое значение коэффициента Шарпа указывает на лучшие и более прибыльные инвестиции. Таким образом, если сравнивать два портфеля с одинаковыми рисками, то при прочих равных условиях было бы лучше инвестировать в портфель с более высоким коэффициентом Шарпа.

Оптимизации портфеля с помощью Python и PyPortfolioOpt

4. Эффективная граница (The Efficient Frontier)



Определение и рисунок из Википедии:

Граница эффективности (англ. Efficient frontier) в портфельной теории Марковица — инвестиционный портфель, оптимизированный в отношении риска и доходности. Формально границей эффективности является набор портфелей, удовлетворяющих такому условию, что не существует другого портфеля с более высокой ожидаемой доходностью, но с таким же стандартным отклонением доходности. Понятие границы эффективности было впервые сформулировано Гарри Марковицем в 1952 году в модели Марковица.

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

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

Оптимизации портфеля с помощью Python и PyPortfolioOpt

Оптимизация портфеля на Python

1. Импорт необходимых библиотек

Как обычно в начале импортируем все необходимые библиотеки для дальнейшей работы:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import pandas_datareader as web
from matplotlib.ticker import FuncFormatter
Непосредственно для анализа и оптимизации портфеля существует библиотека PyPortfolioOpt. Так как она не входит в стандартный набор, то ее необходимо установить. 
!pip install PyPortfolioOpt
Импортируем функции для дальнейшей работы:
from pypfopt.efficient_frontier import EfficientFrontier 
from pypfopt import risk_models 
from pypfopt import expected_returns
from pypfopt.cla import CLA
import pypfopt.plotting as pplt
from matplotlib.ticker import FuncFormatter

2. Получение данных по акциям из интернета

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

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

!pip install yfinance --upgrade --no-cache-dir
import yfinance as yf
tickers = ['LKOH.ME','GMKN.ME', 'DSKY.ME', 'NKNC.ME', 'MTSS.ME', 'IRAO.ME', 'SBER.ME', 'AFLT.ME']
df_stocks= yf.download(tickers, start='2018-01-01', end='2020-12-31')['Adj Close']
df_stocks.head()
Оптимизации портфеля с помощью Python и PyPortfolioOpt
Дальше необходимо проверить есть ли среди полученных значений NaN. В случае их наличия они будут мешать дальнейшему исследованию. Для того, чтобы это решить, необходимо рассмотреть или иную акцию, или заменить их для примера средней ценой между днем до и после значения NaN.
nullin_df = pd.DataFrame(df_stocks,columns=tickers)
print(nullin_df.isnull().sum())
Оптимизации портфеля с помощью Python и PyPortfolioOpt

3. Расчеты

Перейдем к расчетам по оптимизации портфеля и начнем с определения ожидаемой доходности и дисперсии портфеля. Далее сохраним значения весов портфеля с максимальным коэффициентом Шарпа и минимальной дисперсией.

#Годовая доходность
mu = expected_returns.mean_historical_return(df_stocks) 
#Дисперсия портфеля
Sigma = risk_models.sample_cov(df_stocks)
#Годовая доходность
mu = expected_returns.mean_historical_return(df_stocks) 
#Дисперсия портфеля
Sigma = risk_models.sample_cov(df_stocks)
#Максимальный коэффициент Шарпа
ef = EfficientFrontier(mu, Sigma, weight_bounds=(0,1)) #weight bounds in negative allows shorting of stocks
sharpe_pfolio=ef.max_sharpe() #May use add objective to ensure minimum zero weighting to individual stocks
sharpe_pwt=ef.clean_weights()
print(sharpe_pwt)
OrderedDict([('AFLT.ME', 0.0), ('DSKY.ME', 0.22606), ('GMKN.ME', 0.48796), ('IRAO.ME', 0.0), ('LKOH.ME', 0.0), ('MTSS.ME', 0.02953), ('NKNC.ME', 0.25645), ('SBER.ME', 0.0)])

Необходимо обратить внимание, что если изменить weight_bounds=(0,1) на weight_bounds=(-1,1), то в портфеле будут учитываться и короткие позиции по акциям.

Дальше посмотрим общие характеристики по портфелю.

ef.portfolio_performance(verbose=True)

Expected annual return: 37.1%
Annual volatility: 20.7%
Sharpe Ratio: 1.70
(0.37123023494063007, 0.20717177784552962, 1.695357536597058)

Теперь посмотрим портфель с минимальной волатильностью:

ef1 = EfficientFrontier(mu, Sigma, weight_bounds=(0,1)) 
minvol=ef1.min_volatility()
minvol_pwt=ef1.clean_weights()
print(minvol_pwt)

OrderedDict([('AFLT.ME', 0.02876), ('DSKY.ME', 0.24503), ('GMKN.ME', 0.10403), ('IRAO.ME', 0.0938), ('LKOH.ME', 0.01168), ('MTSS.ME', 0.41967), ('NKNC.ME', 0.09704), ('SBER.ME', 0.0)])

ef1.portfolio_performance(verbose=True, risk_free_rate = 0.27)
Expected annual return: 24.0%Annual volatility: 16.9%Sharpe Ratio: -0.18(0.239915644698749, 0.16885732511472468, -0.17816434839774456)

4. Построение графика эффективных границ

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

Анализ произведем для суммы в 100 000 рублей.

cl_obj = CLA(mu, Sigma)
ax = pplt.plot_efficient_frontier(cl_obj, showfig = False)
ax.xaxis.set_major_formatter(FuncFormatter(lambda x, _: '{:.0%}'.format(x)))
ax.yaxis.set_major_formatter(FuncFormatter(lambda y, _: '{:.0%}'.format(y)))
Первым этапом посчитаем портфель с минимальной волатильностью:
latest_prices = get_latest_prices(df_stocks)
allocation_minv, rem_minv = DiscreteAllocation(minvol_pwt, latest_prices, total_portfolio_value=100000).lp_portfolio() 
print(allocation_minv)
print("Осталось денежных средств после построения портфеля с минимальной волатильностью составляет {:.2f} рублей".format(rem_minv))
print()
{'AFLT.ME': 41, 'DSKY.ME': 181, 'IRAO.ME': 1765, 'LKOH.ME': 1, 'MTSS.ME': 127, 'NKNC.ME': 107}Осталось денежных средств после построения портфеля с минимальной волатильностью составляет 6152.03 рублей

Вторым шагом портфель с максимальным коэффициентом Шарпа:

latest_prices1 = get_latest_prices(df_stocks)
allocation_shp, rem_shp = DiscreteAllocation(sharpe_pwt, latest_prices1, total_portfolio_value=100000).lp_portfolio() 
print(allocation_shp)
print("Осталось денежных средств после построения портфеля с максимальным коэффициентом Шарпа {:.2f} рублей".format(rem_shp))
{'DSKY.ME': 167, 'GMKN.ME': 2, 'MTSS.ME': 9, 'NKNC.ME': 283} Leftover Fund value in$ after building Max Sharpe ratio portfolio is $1319.05 Осталось денежных средств после построения портфеля с максимальным коэффициентом Шарпа 1319.05 рублей

В результате нам предлагается купить для оптимального портфеля 167 акций Детского мира, 2 акции Норильского никеля, 9 акций МТС и 283 акцию Нижнекамскнефтехим. В результате у нас еще останется 1319 рублей.

Еще раз напоминаю, что все вышеприведённое не является инвестиционной рекомендацией, а только поводом к размышлению.
 
★14
5 комментариев
И что все цепляются за теорию Марковица, какой в ней смысл если рынки падают все вместе… какая бы диверсификация не была, все равно все упадет… только в теории все хорошо..

Скажу по большому секрету:
1. Необходимо обогонять индекс полной доходности
2. Самое главные параметры эквити это доходность и волатильность
3.Необходимо понимание о справедливой стоимости индекса относительно макропоказателей


Все остальное — книжки по рискам, теориям западным, cfa это попытка всех загнать в неправильные рамки работы на финансовых рынках, чтобы инвестирование не было эффективным… Но это никому не докажешь… белые воротнички не ищут сложных путей, а действуют как им пишут в книгах, да еще и на английском языке
avatar
Пьяный ищет не там, где потерял, а там, где светло.
Впрочем, про портфели тоже самое можно сказать. Этим Марковицем уже плешь проели, а толку никакого. Ни от эффективных границ, ни от всего остального. Прошлые доходности не гарантируют будущих. Ладно, Марковиц этого не знал. Но целый комитет раздатчиков премий… тоже не догадался?  
avatar
Больше питонячих скриптов в жизнь трейдера!
Так где скачать бук?
avatar
Gravizapa, бук по адресу лежит. Можно как в колабе сразу открыть, так и на гитах
avatar

теги блога Aleks

....все тэги



UPDONW
Новый дизайн