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

Вступление

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

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

Акции, входящие в диверсифицированный портфель, не выбираются случайным образом, а вместо этого выполняются определенные шаги или подходы. В этой статье мы собираемся следовать статистическому подходу, который использует корреляционную матрицу для выбора правильных акций для диверсифицированного портфеля. До этого, что такое корреляция? Корреляция - это не что иное, как величина связи, существующей между двумя или более переменными. Корреляцию можно разделить на три типа: положительная корреляция, когда отношение между двумя или более переменными больше нуля (›0), отрицательная корреляция, когда отношение меньше нуля (‹ 0), и отсутствие корреляции, когда показание равно ноль (= 0).

Конечная цель этой статьи - найти две лучшие акции среди FAANG (аббревиатура Facebook, Amazon, Apple, Netflix, Google), которые можно держать в диверсифицированном портфеле, который обеспечивает меньший риск при постепенном постоянном доходе. С учетом сказанного давайте запрограммируем подход на Python.

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

Реализация на Python

Кодирование можно разделить на следующие этапы:

1. Importing packages
2. Extracting Stock Data from Twelve Data
3. Calculating Returns
4. Creating and Analyzing the Correlation Matrix
5. Backtesting
6. Volatility Comparison

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

Шаг 1. Импорт пакетов

Импорт необходимых пакетов в среду Python - шаг, который нельзя пропустить. Основными пакетами будут Pandas для работы с данными, NumPy для работы с массивами и для сложных функций, Matplotlib и Seaborn для построения графиков и запросы на выполнение вызовов API. Вторичными пакетами будут Math для математических функций и Termcolor для настройки шрифтов (необязательно).

Реализация Python:

# IMPORTING PACKAGES

import pandas as pd
import requests
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from math import floor
from termcolor import colored as cl

from matplotlib import style
from matplotlib import rcParams

style.use('fivethirtyeight')
rcParams['figure.figsize'] = (20, 10)

Теперь, когда мы импортировали все необходимые пакеты в нашу среду Python. Давайте возьмем исторические данные FAANG (сокращение от Facebook, Amazon, Apple, Netflix, Google) с конечной точкой API Twelve Data.

Шаг 2: извлечение данных о запасах из двенадцати данных

На этом этапе мы собираемся получить исторические данные о запасах FAANG, используя конечную точку API, предоставленную twelvedata.com. Перед этим заметка на twelvedata.com: Twelve Data - один из ведущих поставщиков рыночных данных, имеющий огромное количество конечных точек API для всех типов рыночных данных. Очень легко взаимодействовать с API, предоставляемыми Twelve Data, и у него одна из лучших документации. Кроме того, убедитесь, что у вас есть учетная запись на twelvedata.com, только тогда вы сможете получить доступ к своему ключу API (жизненно важный элемент для извлечения данных с помощью API).

Реализация Python:

# EXTRACTING STOCKS DATA

def get_historical_data(symbol, start_date, end_date):
    api_key = 'YOUR API KEY'
    api_url = f'https://api.twelvedata.com/time_series?symbol={symbol}&interval=1day&outputsize=5000&apikey={api_key}'
    raw_df = requests.get(api_url).json()
    df = pd.DataFrame(raw_df['values']).iloc[::-1].set_index('datetime').astype(float)
    df = df[df.index >= start_date]
    df = df[df.index <= end_date]
    df.index = pd.to_datetime(df.index)
    return df

fb = get_historical_data('FB', '2020-01-01', '2021-01-01')
amzn = get_historical_data('AMZN', '2020-01-01', '2021-01-01')
aapl = get_historical_data('AAPL', '2020-01-01', '2021-01-01')
nflx = get_historical_data('NFLX', '2020-01-01', '2021-01-01')
googl = get_historical_data('GOOGL', '2020-01-01', '2021-01-01')

Пояснение к коду: Первое, что мы сделали, - это определили функцию с именем 'get_historical_data', которая принимает символ акции ('symbol'), дату начала ('start_date') и дату окончания (' end_date ') исторических данных в качестве параметров. Внутри функции мы определяем ключ API и URL-адрес и сохраняем их в соответствующей переменной. Затем мы извлекаем исторические данные в формате JSON с помощью функции «get» и сохраняем их в переменной «raw_df». После выполнения некоторых процессов очистки и форматирования необработанных данных JSON мы возвращаем их в виде чистого фрейма данных Pandas. Наконец, мы вызываем созданную функцию, чтобы извлечь исторические данные FAANG с начала 2020 года и сохранить их в соответствующих переменных («fb», «amzn», «aapl», «nflx», «googl»).

Шаг 3: Расчет прибыли

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

Реализация Python:

# CALCULATING RETURNS

fb_rets, fb_rets.name = fb['close'] / fb['close'].iloc[0], 'fb'
amzn_rets, amzn_rets.name = amzn['close'] / amzn['close'].iloc[0], 'amzn'
aapl_rets, aapl_rets.name = aapl['close'] / aapl['close'].iloc[0], 'aapl'
nflx_rets, nflx_rets.name = nflx['close'] / nflx['close'].iloc[0], 'nflx'
googl_rets, googl_rets.name = googl['close'] / googl['close'].iloc[0], 'googl'

plt.plot(fb_rets, label = 'FB')
plt.plot(amzn_rets, label = 'AMZN')
plt.plot(aapl_rets, label = 'AAPL')
plt.plot(nflx_rets, label = 'NFLX')
plt.plot(googl_rets, label = 'GOOGL', color = 'purple')
plt.legend(fontsize = 16)
plt.title('FAANG CUMULATIVE RETURNS')
plt.show()

Вывод:

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

Шаг 4: Создание и анализ корреляционной матрицы

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

Реализация Python:

# CREATING THE CORRELATION MATRIX

rets = [fb_rets, amzn_rets, aapl_rets, nflx_rets, googl_rets]
rets_df = pd.DataFrame(rets).T.dropna()
rets_corr = rets_df.corr()

plt.style.use('default')
sns.heatmap(rets_corr, annot = True, linewidths = 0.5)
plt.show()

Вывод:

Пояснение к коду. Сначала мы создаем переменную с именем «rets» для хранения всех вычисленных ранее результатов, а на следующем этапе мы создаем из нее фрейм данных. Чтобы вычислить корреляцию между акциями, мы используем функцию «corr», предоставляемую пакетом Pandas, и сохранили матрицу в переменной «rets_corr». Корреляционная матрица не имеет смысла, если она не построена в виде тепловой карты.

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

Теперь давайте проанализируем тепловую карту, которая отображает корреляцию между акциями. Мы могли видеть некоторые значения внутри графика, которые представляют собой не что иное, как оценку корреляции. Корреляция между Google и Facebook составляет 0,91, что соответствует прочным отношениям. Это означает, что если акции Google упадут на 10%, Facebook также упадет примерно на 8% (поскольку корреляция не на 100%), и наоборот. Точно так же мы могли видеть, что корреляция между Google и Netflix составляет 0,69, что представляет собой более слабую связь (по сравнению с другими), колебания цен которых будут противоречить друг другу (не сильно, но немного, поскольку они не имеют отрицательной корреляции).

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

Шаг 5: Тестирование на истории

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

Реализация Python:

# BACKTESTING

investment_value = 100000
N = 2
nflx_allocation = investment_value / N
googl_allocation = investment_value / N

nflx_stocks = floor(nflx_allocation / nflx['close'][0])
googl_stocks = floor(googl_allocation / googl['close'][0])

nflx_investment_rets = nflx_rets * nflx_stocks
googl_investment_rets = googl_rets * googl_stocks
total_rets = round(sum(((nflx_investment_rets + googl_investment_rets) / 2).dropna()), 3)
total_rets_pct = round((total_rets / investment_value) * 100, 3)

print(cl(f'Profit gained from the investment : {total_rets} USD', attrs = ['bold']))
print(cl(f'Profit percentage of our investment : {total_rets_pct}%', attrs = ['bold']))

Вывод:

Profit gained from the investment : 30428.957 USD
Profit percentage of our investment : 30.429%

Пояснение к коду. Во-первых, мы создаем переменную с именем «investment_value» для хранения общего капитала, который мы хотели бы инвестировать, который составляет сто тысяч долларов. Затем мы равномерно распределяем капитал по каждой из двух акций, и портфель с равным распределением капитала известен как портфель с равным весом. Иногда инвесторы присваивают уникальный вес каждой акции в портфеле по некоторым факторам, но это выходит за рамки данной статьи. После этого мы создаем две новые переменные «nflx_stocks» и «googl_stocks» для хранения количества акций, которые мы могли бы купить на наш капитал. Затем следует расчет возврата инвестиций. Во-первых, мы вычисляем доходность каждой акции, умножая количество акций, которые мы купили, на доходность акций, которые мы рассчитали ранее.

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

Шаг 6: Сравнение волатильности

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

Реализация Python:

# VOLATILITY CALCULATION
    
rets_df['Portfolio'] = (rets_df[['googl', 'nflx']].sum(axis = 1)) / 2
daily_pct_change = rets_df.pct_change()
volatility = round(np.log(daily_pct_change + 1).std() * np.sqrt(252), 5)

companies = ['FACEBOOK', 'APPLE', 'AMAZON', 'NFLX', 'GOOGL', 'PORTFOLIO']
for i in range(len(volatility)):
    if i == 5:
        print(cl(f'{companies[i]} VOLATILITY : {volatility[i]}', attrs = ['bold'], color = 'green'))
    else:
        print(cl(f'{companies[i]} VOLATILITY : {volatility[i]}', attrs = ['bold']))

Вывод:

FACEBOOK VOLATILITY : 0.46539
APPLE VOLATILITY : 0.38944
AMAZON VOLATILITY : 0.47043
NFLX VOLATILITY : 0.46069
GOOGL VOLATILITY : 0.3881
PORTFOLIO VOLATILITY : 0.37843

Пояснение к коду. Во-первых, мы создаем новый столбец «Портфель» во фрейме данных «rets_df» (который мы использовали ранее) для хранения доходов нашего диверсифицированного портфеля. Затем мы используем функцию «pct_change», предоставляемую пакетом Pandas, для вычисления процентного изменения между текущим и предыдущим показаниями доходности каждой акции в «rets_df» и сохраняем их в переменной «daily_pct_change». Затем идет расчет волатильности. Прежде чем обсуждать код, нужно запомнить одну формулу, которая является формулой для расчета годовой волатильности:

VOLATILITY = LOG [ ( STD OF PCT CHANGE + 1 ) * SQRT OF 252 ]
where,
STD OF PCT CHANGE = Standard Deviation of Daily Percentage Change
SQRT OF 252 = Square Root of 252

Мы подставляем приведенную выше формулу в наш код для расчета волатильности каждой акции и сохраняем их в переменной «volatility». Из представленных результатов мы могли видеть, что нашему диверсифицированному портфелю удалось достичь наименьшей волатильности по сравнению с другими акциями FAANG. Замечательно!

Последние мысли!

После долгого процесса программирования мы успешно создали диверсифицированный портфель, который снижает риск до минимума и приносит прибыль. Я также сравнил эффективность нашего портфеля с показателями SPY ETF (ETF, специально разработанного для отслеживания движения рыночного индекса S&P 500), и, похоже, мы отклонили его с небольшой разницей. А теперь поговорим об улучшениях.

Первый аспект, который можно улучшить, - это использование большого количества запасов. В этой статье мы приняли во внимание только пять акций и выбрали две из них, которые менее коррелированы, чем остальные. Но концепция диверсификации портфеля лучше всего работает при хранении огромного количества некоррелированных акций. Например, мы можем принять во внимание все акции, входящие в рыночный индекс S&P 500, и выбрать сильно некоррелированные акции. Делая это, мы можем достичь двух важных вещей.

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

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

Сказав это, вы подошли к концу статьи. Если вы забыли выполнить какую-либо часть кода, не волнуйтесь. В конце я предоставил полный исходный код. Надеюсь, вы узнали что-то новое и полезное из этой статьи.

Полный код:

# IMPORTING PACKAGES

import pandas as pd
import requests
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from math import floor
from termcolor import colored as cl

from matplotlib import style
from matplotlib import rcParams

style.use('fivethirtyeight')
rcParams['figure.figsize'] = (20, 10)

# EXTRACTING STOCKS DATA

def get_historical_data(symbol, start_date, end_date):
    api_key = 'YOUR API KEY'
    api_url = f'https://api.twelvedata.com/time_series?symbol={symbol}&interval=1day&outputsize=5000&apikey={api_key}'
    raw_df = requests.get(api_url).json()
    df = pd.DataFrame(raw_df['values']).iloc[::-1].set_index('datetime').astype(float)
    df = df[df.index >= start_date]
    df = df[df.index <= end_date]
    df.index = pd.to_datetime(df.index)
    return df

fb = get_historical_data('FB', '2020-01-01', '2021-01-01')
amzn = get_historical_data('AMZN', '2020-01-01', '2021-01-01')
aapl = get_historical_data('AAPL', '2020-01-01', '2021-01-01')
nflx = get_historical_data('NFLX', '2020-01-01', '2021-01-01')
googl = get_historical_data('GOOGL', '2020-01-01', '2021-01-01')

# CALCULATING RETURNS

fb_rets, fb_rets.name = fb['close'] / fb['close'].iloc[0], 'fb'
amzn_rets, amzn_rets.name = amzn['close'] / amzn['close'].iloc[0], 'amzn'
aapl_rets, aapl_rets.name = aapl['close'] / aapl['close'].iloc[0], 'aapl'
nflx_rets, nflx_rets.name = nflx['close'] / nflx['close'].iloc[0], 'nflx'
googl_rets, googl_rets.name = googl['close'] / googl['close'].iloc[0], 'googl'

plt.plot(fb_rets, label = 'FB')
plt.plot(amzn_rets, label = 'AMZN')
plt.plot(aapl_rets, label = 'AAPL')
plt.plot(nflx_rets, label = 'NFLX')
plt.plot(googl_rets, label = 'GOOGL', color = 'purple')
plt.legend(fontsize = 16)
plt.title('FAANG CUMULATIVE RETURNS')
plt.show()

# CREATING THE CORRELATION MATRIX

rets = [fb_rets, amzn_rets, aapl_rets, nflx_rets, googl_rets]
rets_df = pd.DataFrame(rets).T.dropna()
rets_corr = rets_df.corr()

plt.style.use('default')
sns.heatmap(rets_corr, annot = True, linewidths = 0.5)
plt.show()

# BACKTESTING

investment_value = 100000
N = 2
nflx_allocation = investment_value / N
googl_allocation = investment_value / N

nflx_stocks = floor(nflx_allocation / nflx['close'][0])
googl_stocks = floor(googl_allocation / googl['close'][0])

nflx_investment_rets = nflx_rets * nflx_stocks
googl_investment_rets = googl_rets * googl_stocks
total_rets = round(sum(((nflx_investment_rets + googl_investment_rets) / 2).dropna()), 3)
total_rets_pct = round((total_rets / investment_value) * 100, 3)

print(cl(f'Profit gained from the investment : {total_rets} USD', attrs = ['bold']))
print(cl(f'Profit percentage of our investment : {total_rets_pct}%', attrs = ['bold']))

 # VOLATILITY CALCULATION
    
rets_df['Portfolio'] = (rets_df[['googl', 'nflx']].sum(axis = 1)) / 2
daily_pct_change = rets_df.pct_change()
volatility = round(np.log(daily_pct_change + 1).std() * np.sqrt(252), 5)

companies = ['FACEBOOK', 'APPLE', 'AMAZON', 'NFLX', 'GOOGL', 'PORTFOLIO']
for i in range(len(volatility)):
    if i == 5:
        print(cl(f'{companies[i]} VOLATILITY : {volatility[i]}', attrs = ['bold'], color = 'green'))
    else:
        print(cl(f'{companies[i]} VOLATILITY : {volatility[i]}', attrs = ['bold']))