Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Васильев Ю. - Python для data science (Библиотека программиста) - 2023.pdf
Скачиваний:
7
Добавлен:
07.04.2024
Размер:
7.21 Mб
Скачать

Общие методы анализа временных рядов      211

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

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

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

_mysql_connector.MySQLInterfaceError: Access denied for user 'root'@'localhost' (using password: YES)

NameError: name 'cursor' is not defined

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

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

Общие методы анализа временных рядов

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

212      Глава 10. Анализ данных временных рядов

Как вы видели в главах 3 и 5, биржевые данные можно получить через Pythonскрипт с помощью библиотеки yfinance. Вот, например, данные для тикера TSLA (Tesla, Inc.) за пять последних биржевых дней:

import yfinance as yf ticker = 'TSLA'

tkr = yf.Ticker(ticker)

df = tkr.history(period='5d')

Результат представлен в формате pandas DataFrame и выглядит примерно следующим образом (у вас фактические даты и возвращаемые данные будут отличаться):

 

Open

High

Low

Close

Volume

Dividends

Stock Splits

Date

 

 

 

 

 

 

 

2022-01-10

1000.00

1059.09

980.00

1058.11

30605000

0

0

2022-01-11

1053.67

1075.84

1038.81

1064.40

22021100

0

0

2022-01-12

1078.84

1114.83

1072.58

1106.21

27913000

0

0

2022-01-13

1109.06

1115.59

1026.54

1031.56

32403300

0

0

2022-01-14

1019.88

1052.00

1013.38

1049.60

24246600

0

0

 

 

 

 

 

 

 

 

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

Скорее всего, для анализа вам не понадобятся все эти столбцы. На самом деле сейчас вам нужен лишь столбец Close. Выведем его на экран в виде pandas Series:

print(df['Close'])

Серия будет выглядеть следующим образом:

Date

2022-01-10 1058.11

2022-01-11 1064.40

2022-01-12 1106.21

2022-01-13 1031.56

2022-01-14 1049.60

Общие методы анализа временных рядов      213

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

Вычисление процентных изменений

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

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

Когда временной ряд реализован в виде pandas Series или DataFrame, можно использовать метод shift() для сдвига точек данных во времени на нужное количество периодов. Вспомните пример с тикером TSLA. Вам, возможно, будет интересно, насколько изменилась цена закрытия за два дня. В этом случае необходимо использовать shift(2), чтобы сдвинуть цену закрытия, которая была зафиксирована двумя днями ранее, вперед до цены закрытия на данный день. Чтобы понять, как работает сдвиг, сдвиньте столбец Close на два дня вперед, сохраните результат как серию 2DaysShift и объедините ее с исходным столбцом Close:

print(pd.concat([df['Close'], df['Close'].shift(2)], axis=1, keys= ['Close', '2DaysShift']))

Вы получите следующий вывод:

Date

Close

2DaysShift

 

 

2022-01-10 1058.11

NaN

2022-01-11 1064.40

NaN

2022-01-12

1106.21

1058.11

2022-01-13

1031.56

1064.40

2022-01-14

1049.60

1106.21

 

 

 

214      Глава 10. Анализ данных временных рядов

Как видите, значения в колонке Close находят отражение в колонке 2DaysShift, но со смещением в два дня. Первые два значения в колонке 2DaysShift пустые (NaN), потому что цен за дни, предшествующие первым двум значениям временного ряда, у нас нет.

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

(df['Close'] - df['Close'].shift(2))/ df['Close'].shift(2)

Однако в финансовом анализе принято делить новое значение на старое и брать натуральный логарифм получившегося значения. Этот расчет обеспечивает почти точное приближение процентного изменения, когда оно находится в диапазоне от +/–5 до +/–20%. Во фрагменте кода ниже мы рассчитываем двухдневную разницу в процентах, используя натуральный логарифм, и сохраняем результат в виде нового столбца 2daysRise в датафрейме df:

import numpy as np

df['2daysRise'] = np.log(df['Close'] / df['Close'].shift(2))

Мы получаем цену закрытия в текущий день и делим ее на цену закрытия двумя биржевыми днями ранее, используя shift(2). Затем используем функцию NumPy log(), чтобы вычислить натуральный логарифм полученного значения. Теперь выводим на экран колонки Close и 2daysRise:

print(df[['Close','2daysRise']])

Полученный временной ряд:

 

Close

2daysRise

Date

 

 

2022-01-10 1058.11

NaN

2022-01-11 1064.40

NaN

2022-01-12

1106.21

0.044455

2022-01-13

1031.56 -0.031339

2022-01-14

1049.60

-0.052530

 

 

 

Колонка 2daysRise показывает процентное изменение цены акции по сравнению с ее стоимостью двумя днями ранее. И снова первые два значения