рекомендации

суббота, 23 ноября 2019 г.

Сравнительный анализ рынка ценных бумаг с помощью Quandl и tidyverse


Создание набора данных

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

Доступны как бесплатные, так и премиумные данные. Зарегистрированные пользователи имеют ограничение в 300 запросов за 10 секунд, 2000 запросов за 10 минут и 50 000 запросов в день. Пользователи с премиум-аккаунтами имеют ограничение 5000 запросов за 10 минут и 720 000 запросов в день.

Мы будем использовать этот онлайн-репозиторий для получения наших данных с помощью пакета «Quandl» непосредственно из консоли R. Пакет Quandl напрямую взаимодействует с API Quandl, предлагая данные в нескольких форматах, которые можно использовать в R, загружать zip-архив со всеми данными из базы данных Quandl, и предоставляет возможность поиска.

Для получения дополнительной информации о пакете Quandl, пожалуйста, посетите эту страницу.

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

В нашем анализе мы выбрали следующие банки

    ICICI
    BOB
    CANARA
    AXIS
    SBI
    PNB

Мы выбрали эти банки, так как они находятся в ценовом диапазоне от 200 до 500 рупий. Мы будем использовать следующий код для скачивания данных в консоль R.
Quandl(Code=“NSE/—”,collapse=“—”,start_date=“—-”,type=“…”)
Параметры, которые мы используем, следующие:

     code - код набора данных в Quandl, указан в виде строки или массива строк.
     collapse - формат данных, т.е. дневные, месячные, недельные, годовые.
     start_date -  желаемая дата начальной точки.
   type - тип возвращаемых данных, указанный как строка. Может быть «raw», «ts», «zoo», «xts» или «timeSeries»

Библиотеки, которые нам понадобятся в процессе работы:

library(Quandl)
library(tidyverse)
library(ggplot2)
library(tidyquant)
library(timetk)
library(forcats)
library(stringr)
library(gganimate)
library(plyr)
library(stringr)
library(gridExtra)
Теперь мы загрузим данные, добавим столбец «Stock» для идентификатора тикера, а затем вставим соответствующее название тикера в загруженный набор данных. Затем мы объединим все данные о тикерах в один фрейм данных для анализа.


## SЗадаем Quandl Free Account и API Key
Quandl.api_key("<Your-API-Key>")

## скачиваем набор данных
ICICI = Quandl("NSE/ICICIBANK",collapse="daily",start_date="2016-09-01",type="raw")
PNB= Quandl("NSE/PNB",collapse="daily",start_date="2016-09-01",type="raw")
Axis=Quandl("NSE/AXISBANK",collapse="daily",start_date="2016-09-01",type="raw")
Canara=Quandl("NSE/CANBK",collapse="daily",start_date="2016-09-01",type="raw")
BOB=Quandl("NSE/BANKBARODA",collapse="daily",start_date="2016-09-01",type="raw")
SBI=Quandl("NSE/SBIN",collapse="daily",start_date="2016-09-01",type="raw")

## добавляем еще один столбец ("Stock") с помощью команды cbind

ICICI=cbind(ICICI,Stock="")
PNB=cbind(PNB,Stock="")
Axis=cbind(Axis,Stock="")
SBI=cbind(SBI,Stock="")
Canara=cbind(Canara,Stock="")
BOB=cbind(BOB,Stock="")

## Вставляем имя тикера в столбец stock

ICICI$Stock=paste(ICICI$Stock,"ICICI",sep="")
PNB$Stock=paste(PNB$Stock,"PNB",sep="")
Axis$Stock=paste(Axis$Stock,"Axis",sep="")
SBI$Stock=paste(SBI$Stock,"SBI",sep="")
Canara$Stock=paste(Canara$Stock,"Canara",sep="")
BOB$Stock=paste(BOB$Stock,"BOB",sep="")

## объединяем в один набор данных

Master_Data=rbind(ICICI,PNB,Axis,SBI,Canara,BOB)

Визуализация месячных цен

Давайте посмотрим на месячную и дневную цену акций, используя пакет ggplot. Для этого нам нужно сгруппировать dataframe по акциям.


## Визуализация в ggplot2 ("Comparative Visulisation of Close Price listed on NSE")

## конвертируем даты в символы, чтобы разбить столбец даты на столбцы "Y" "m" "dd""
Master_Data$Date=as.character(Master_Data$Date)

## разрезаем дату

list = strsplit(Master_Data$Date,"-")

## конвертируем list в dataframe
library(plyr)
Master_Date1 = ldply(list)
colnames(Master_Date1) = c("Year","Month","Day")

## объединяем столбец с основным dataframe
Master_Data = cbind(Master_Data,Master_Date1)
names(Master_Data)

## Меняем масштаб для "Traded Quantity"

Master_Data$`Total Trade Quantity` = Master_Data$`Total Trade Quantity`/100000

## Конвертируем Date в as.Date()

Master_Data$Date = as.Date(Master_Data$Date)

## Визуализация с Bubble Plot
P = ggplot(Master_Data,aes(factor(Stock),Close,color=Stock,frame=Month)) +
  geom_jitter(aes(size = Close, colour=Stock, alpha=.02)) +
  ylim(0,1000)+
  labs(title = "Bank Stock Monthly Prices", x = "Banks", y= "Close Price") +
  theme(panel.border = element_blank(),
        panel.grid.major = element_line(colour = "grey61", size = 0.5, linetype = "dotted"),
        panel.grid.minor = element_blank(),
        axis.line=element_line(colour="black"),
        plot.title = element_text(hjust = 0.5,size=18,colour="indianred4"))+
  theme(legend.position="none")

P1 = gganimate(P,'Price_Range.gif',ani.width=600,ani.height=400,interval=1)

## Группировка по акциям

Master_Data = Master_Data%>%
  tibble::as.tibble()%>%
  group_by(Stock)

## Визуализация для дневных цен

Master_Data %>%
  ggplot(aes(x = Date, y = Close, color = Stock)) +
  geom_point() +
  labs(title = "Daily Close Price", x = "Month",y="Close Price") +
  facet_wrap(~ Stock, ncol = 3, scale = "free_y") +
  scale_fill_tq(fill="green4",theme="light") +
  theme_tq() +
  theme(panel.border = element_blank(),
        panel.grid.major = element_line(colour = "grey61", size = 0.5, linetype = "dotted"),
        panel.grid.minor = element_blank(),
        axis.line=element_line(colour="black"),
        plot.title = element_text(hjust = 0.5,size=18,colour="indianred4"))+
  theme(legend.position="none")



Обнаружение взаимосвязи между объемом и ценой закрытия

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

## Traded Quantity vs Price

z = Master_Data %>%
  ggplot(aes(x = `Total Trade Quantity`, y = Close, color = Stock,frame=Month)) +
  geom_smooth(method='loess') +
  xlim(0,400)+
  labs(title = "Monthly Traded Quantity vs Price", x = "Traded Quantity (Lacs)",y="Close Price") +
  facet_wrap(~ Stock, ncol = 3, scale = "free_y") +
  scale_fill_tq(fill="green4",theme="light") +
  theme_tq() +
  theme(panel.border = element_blank(), 
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        plot.title = element_text(hjust = 0.5,size=18,colour="indianred4"),
        axis.line = element_line(colour = "black"))+
  theme(legend.position="none")

z1 = gganimate(z,'Quantity_Price.gif',ani.width=600,ani.height=400,interval=0.7)


У нас есть представление о тренде цены акций, но из месячных цен это не очень ясно. Стоимость акций Axis Bank в сентябре увеличилась и осталась на уровне 750 рупий в течение месяца. в то время как все другие банки были постоянны и не показывали значительную волатильность.

Нахождение распределения плотности отклонения наибольшей цены от цены открытия

Теперь мы посмотрим на распределение плотности отклонения High Price от Open Price, чтобы понять, насколько цена отклоняется в любом направлении на еженедельной основе. Это дает нам представление о ценовом диапазоне для любых акций при внутридневной торговле.

Мы будем использовать функцию transmute_tq() из пакета tidyquant для расчета недельных цен. Пожалуйста, кликните здесь, чтобы получить больше информации.

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


## Отклонение от High и Low Price
Master_Data_High = Master_Data%>%mutate(Dev_High=High-Open)
Master_Data_Low = Master_Data%>%mutate(Dev_Low=Open-Low)

## Вычисление недельного среднего для high Price

Master_Data_High_Week = Master_Data_High %>%
  tq_transmute(
    select     = Dev_High,
    mutate_fun = apply.weekly, 
    FUN        = mean,
    na.rm      = TRUE,
    col_rename = "Dev_High_Mean"
  )

## Вычисление недельного среднего для Low Price
Master_Data_Low_Week = Master_Data_Low%>%
    tq_transmute(
        select  = Dev_Low,
        mutate_fun = apply.weekly,
        FUN = mean,
        na.rm = TRUE,
        col_rename = "Dev_Low_Mean"
    )

## Визуализация плотности распределения для High Price

High = Master_Data_High_Week%>%ggplot(aes(x=Dev_High_Mean,color=Stock))+
  geom_dotplot(binwidth=0.50,aes(fill=Stock))+
  xlim(0,10)+
  scale_fill_manual(values=c("#999999", "#E69F00","#CC9933","#99FF00","#CC3399","#FF9933"))+
  labs(title="Distribution of High Price Deviation from Open Price",x="Weekly Mean Deviation")+
  facet_wrap(~Stock,ncol=3,scale="free_y")+
  scale_color_tq(values=c("#999999"))+
  theme_tq()+
  theme(panel.border = element_blank(),
        panel.grid.major = element_line(colour = "grey61", size = 0.5, linetype = "dotted"),
        panel.grid.minor = element_blank(),
        axis.line=element_line(colour="black"),
        plot.title = element_text(hjust = 0.5,size=16,colour="indianred4"))+
  theme(legend.position="none")

## Визуализация плотности распределения для Low PriceLow = Master_Data_Low_Week%>%ggplot(aes(x=Dev_Low_Mean,color=Stock))+
  geom_dotplot(binwidth=0.50,aes(fill=Stock))+
  xlim(0,10)+
  scale_fill_manual(values=c("#999999", "#E69F00","#CC9933","#99FF00","#CC3399","#FF9933"))+
  labs(title="Distribution of Weekly Low Price Deviation from Open Price",x="Weekly Mean Deviation")+
  facet_wrap(~Stock,ncol=3,scale="free_y")+
  scale_color_tq(values=c("#999999"))+
  theme_tq()+
  theme(panel.border = element_blank(),
        panel.grid.major = element_line(colour = "grey61", size = 0.5, linetype = "dotted"),
        panel.grid.minor = element_blank(),
        axis.line=element_line(colour="black"),
        plot.title = element_text(hjust = 0.5,size=16,colour="indianred4"))+
  theme(legend.position="none")
## Размещение графиков
grid.arrange(High,Low,ncol = 2, nrow = 1)


Наблюдение автокорреляционных лагов

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

Здесь «k» обозначается как лаг. Мы рассмотрим лаг в 180 дней и посмотрим, как поведут себя акции.

Пошаговые вычисления:

1) Определить период лага k.
2) Создать столбцы для периодов лага.
3) Сгруппировать данные по акциям, создав новый фрейм данных для лагов.
4) Применить lag.xts, используя функцию tq_mutate() на новом фрейме данных.
5) Применить автокорреляцию.


k = 1:180
col_names = paste0("lag_", k)

## Выбираем только столбцы "Date" и "Close" из  data frame.

Master_Data_lags = Master_Data%>%
tibble::as_tibble() %>%
group_by(Stock)

Master_Data_lags = Master_Data_lags%>%select(Date,Close)
# Применяем функцию lag.xts используя tq_mutate

Master_Data_lags = Master_Data_lags%>%
tq_mutate(
select = Close,
mutate_fun = lag.xts,
k=1:180,
col_rename=col_names
)

# Рассчитываем автокорреляцию и 95% интервалы

Master_Data_AutoCorrelations = Master_Data_lags %>%
gather(key = "lag", value = "lag_value", -c(Stock,Date, Close)) %>%
mutate(lag = str_sub(lag, start = 5) %>% as.numeric) %>%
group_by(Stock, lag) %>%
summarize(
cor = cor(x = Close, y = lag_value, use = "pairwise.complete.obs"),
cutoff_upper = 2/(n())^0.5,
cutoff_lower = -2/(n())^0.5
)

## Визуализация автокорреляции: ACF Plot

Master_Data_AutoCorrelations %>%
ggplot(aes(x = lag, y = cor, color = Stock, group = Stock)) +

# добавляем горизонтальную линию y=0
geom_hline(yintercept = 0) +

# строим автокорреляции
geom_point(size = 2) +
geom_segment(aes(xend = lag, yend = 0), size = 1) +

# добавляем доверительные интервалы
geom_line(aes(y = cutoff_upper), color = "blue", linetype = 2) +
geom_line(aes(y = cutoff_lower), color = "blue", linetype = 2) +

# Добавляем границы
facet_wrap(~ Stock, ncol = 3) +

# Aesthetics
expand_limits(y = c(-1, 1)) +
scale_color_tq() +
theme_tq() +
labs(
title = paste0("Tidyverse ACF Plot: Lags ", rlang::expr_text(k)),
x = "Lags"
) +
theme(
legend.position = "none",
axis.text.x = element_text(angle = 45, hjust = 1),
panel.grid.major = element_line(colour = "grey61", size = 0.5, linetype = "dotted"),
plot.title = element_text(hjust = 0.5,size=18,colour="indianred4")
)


Из графика ACF видно, что недельного или месячного паттерна не существует.

Итоги

Эта статья содержит описательный анализ акций с точки зрения ежедневных/недельных колебаний цен. Она также включает анализ отклонений от максимальных и минимальных цен. Внимание также уделяется взаимосвязи между ежедневным объемом и ценой закрытия и проверкой взаимосвязей. 
В следующей статье я намерен сосредоточиться на прогнозной аналитике для прогнозирования цен на акции. Так что следите за обновлениями!

Комментариев нет:

Отправить комментарий