Начинающие (да и не только) инвесторы часто задаются вопросом о том, как отобрать для себя идеальное соотношение активов входящих в портфель. Часто (или не очень, но знаю про двух точно) у некоторых брокеров эту функцию выполняет торговый робот. Но заложенные в них алгоритмы не раскрываются.
В этом посте будет рассмотрено то, как оптимизировать портфель при помощи Python и симуляции Монте Карло. Под оптимизацией портфеля понимается такое соотношение весов, которое будет удовлетворять одному из условий:
Для расчета возьмем девять акций, которые рекомендовал торговый робот одного из брокеров на начало января 2020 года и так же он устанавливал по ним оптимальные веса в портфеле: 'ATVI','BA','CNP','CMA', 'STZ','GPN','MPC','NEM' и 'PKI'. Для анализа будет взяты данные по акциям за последние три года.
#Загружаем библиотеки import pandas as pd import yfinance as yf import numpy as np import matplotlib.pyplot as plt # Получаем данные по акциям ticker = ['ATVI','BA','CNP','CMA', 'STZ','GPN','MPC','NEM', 'PKI'] stock = yf.download(ticker,'2017-01-01', '2019-01-31')
После всех вычислений, приведенных в этой и этой публикациях, можно углубиться в статистический анализ и рассмотреть метод наименьших квадратов. Для этой цели используется библиотека statsmodels, которая позволяет пользователям исследовать данные, оценивать статистические модели и выполнять статистические тесты. За основу были взяты эта статья и эта статья. Само описание используемой функции на английском доступно по следующей ссылке.
Сначала немного теории:
О линейной регрессии
Линейная регрессия используется в качестве прогнозирующей модели, когда предполагается линейная зависимость между зависимой переменной (переменная, которую мы пытаемся предсказать) и независимой переменной (переменная и/или переменные, используемые для предсказания).
# Выделяю скорректированную цену закрытия adj_close_px = sber['Adj Close'] # Вычисляю скользящую среднию moving_avg = adj_close_px.rolling(window=40).mean() # Вывожу результат print(moving_avg[-10:])

# Вычисление короткой скользящей средней sber['40'] = adj_close_px.rolling(window=40).mean() # Вычисление длинной скользящей средней sber['252'] = adj_close_px.rolling(window=252).mean() # Построение полученных значений sber[['Adj Close', '40', '252']].plot(figsize=(20,20)) plt.show()
'Min10',
'Cl/High',
'Vol20',
'tLow%',
'Cl/Low',
'tHigh%-tLow%',
'ATRP(14)',
'DIMinus(14)',
'RSI(Close.20)',
'MomentumPct(Close.14)',
'MFI(20)',
'KST(Close.10.10.15.10.20.10.30.15)',
'TRIX(Close.10)',
'Cl/w_High',
'DSS(10. 20. 5)
| Год | Колл | % сделка |
| 2011 | 611 | 0,1 |
| 2012 | 440 | 0,34 |
| 2013 | 305 | 0,42 |
| 2014 | 420 | 1,17 |
| 2015 | 263 | 0,85 |
| 2016 | 248 | 0,74 |
| 2017 | 261 | 0,41 |
| 2018 | 46 | 0,34 |
| Mean: | 323 |
Из тестов которые я привел в прошлых постах, следует что для задач с ограниченной выборкой и моим виденьем рынка, следует использовать GB, как наиболее эффективный инструмент, далее близко идет RF, а а где то далеко позади, глотая пыль плетется нейросеть. Также следует необходимость чистки от левых фичей. В чем вообще вопрос?! Лишние фичи это возможность инструментам ML найти черную кошку даже если ее там нет, особенно феерически это показала нейросеть, которая при относительно небольшом числе примеров откровенно творит (от слова тварь). Давайте попробуем зациклить чистку фичей и сделаем это системно. Системно это в частности избежать заглядывание в будущее а танцев с бубнами. Мои данные это около 50 тысяч дневок для наиболее ликвидных российских фишек с 2010 по апрель 2018 года (2008 год безудержного падения, 2009 год безудержного роста, поэтому все что до 2010 года оставил за бортом, как заведомо простые для извлечения профита годы), заглянуть на них в будущее это в частности использовать для прогноза движения цен в 2011 году данные о ценности фичей за все года. Мы так делать не будем. Мы представим что переместились в начале 2011 года и имеем только данные за 2010 год. Для прогноза 2011 года используем данные о ценности фичей на тесте за 2010 год. Как используем? Да просто — из более чем трех десятков фичей используем только 5, 10, 20 наиболее информативных. Для прогноза 2012 года используем данные о ценности фичей на основе теста 2010-2011 годов итд. (Код разбухает, становится все менее читаемым, впору задумываться о ООП). После получения прогнозов, для удобство переведу их в столь любимое для трейдеров виде: профит на сделку, и сравню их с результатами если бы каждый раз использовались все доступные фичи. А их 34 штуки. Чистка фичей это будет во первых.
Во вторых попробую улучшить результат за счет скалерновской VotingClassifier, которая будет выводить нечто среднее из прогнозов RF и XGB.
Приступим с первого пункта.
