Exploring Open Interest for Futures Contracts with R
In this article we will explore in greater depth the Open Interest variable of the futures contracts price data and see in which months of the year this variable tends to increase for a particular contract. For this purpose, we have gathered contracts futures data from CSI 500 Shanghai Index.
Our task will be to load all CSV files from a specific folder in R environment, read each file as a data frame and returns a list structure where each item is the contract code and the values of the list are the Open Interest values on each trading day. We will call this function openInterest and the directory parameter is the folder that stores all the csv files with the individual contract information.
With this structure we can obtain the min, max and mean Open Interest by contract for a specific year.
Download the below data and store all the csv files in one folder in your computer.
1openInterest <- function(directory){
2 data <- c(list.files(directory))
3 files <- paste(directory,data,sep="/")
4 contractsNumber <- length(files)
5 OI <- list()
6 # Loop over all contracts in the directory folder
7 for (contract in 1:contractsNumber){
8 openInterest <- c()
9 contractData <- read.csv(files[contract])
10 # Retrieve the open Interest column that is in the 9 position
11 openInterest <- contractData[,9]
12 OI[[contract]] <- openInterest
13 }
14 names(OI) <- gsub('.csv','',list.files(directory))
15 return(OI)
16}
17
18OI <- openInterest("C:/Users/Nicolas/Documents/Shanghai CSI")
19
20# The contracts have different periods. Using the sapply command with the OI list
21# we can view the number of trading days for each contract.
22
23contracts_Length <- sapply(OI,length)
24
25# contracts_Length has the following values:
26
1# Remove the first Open Interest value in all contracts which is zero. We want to #know the min value of Open Interest for each contract, but should remove 0 that is #when the contract starts. This function will keep only values from each item of the #OI list that are different from zero.
2
3newOIList <- lapply(OI, function(i) Filter(function(x) any(x != 0), i))
4
5# Calculate mean, max and min for each item of the newOIList. This would return
6# all maxs,means and mins Open Interest values for each particular contract.
7
8mean<- sapply(newOIList,mean,na.rm=TRUE)
9max <- sapply(newOIList,max,na.rm=TRUE)
10min <- sapply(newOIList,min,na.rm=TRUE)
11
12# Make a data frame with cbind command that combine the three lists by columns
13
14OI_metrics <- data.frame(cbind(max,min,mean))
15
16# Create a column with the contracts code and reset the index by assign NULL to r
17# rownames.
18
19OI_metrics$Contract <- row.names(OI_metrics)
20rownames(OI_metrics) <- NULL
21
22#OI_metrics is a dataframe with wide format with the following values:
23
24 max min means Contract
251 20457 228 11054 CFFEX-ICF2018
262 17308 165 7451 CFFEX-ICG2018
273 23228 95 5825 CFFEX-ICH2018
284 20545 67 11786 CFFEX-ICJ2018
295 19696 81 8848 CFFEX-ICK2018
306 28363 162 7798 CFFEX-ICM2018
317 26187 232 14225 CFFEX-ICN2018
328 34943 116 11126 CFFEX-ICU2018
339 43776 131 14167 CFFEX-ICZ2018
34
35
36# Next step is to transform the data from wide to long in order to make a grouped
37# barplot and show the metrics values by contract. The OI_metrics has a wide format #now, because each contract is in a unique row. In order to make a barplot we need #to change the format to long format. The gather command from dplyr package #transform the shape of the data from wide to long. The purpose of this is to get #tidy data for their analysis.
38
39long_OI_metrics <- gather(OI_metrics, metric, value ,c('max','min','mean'))
40
41# Use order command with Contract column to sort the dataframe by contract name
42
43OI_metricsByContracts <- long_OI_metrics[order(long_OI_metrics$Contract),]
44
45# The OI_metricsByContracts is a dataframe with long format that allow us to create a barplot by year.
46
47 Contract metric value
481 CFFEX-ICF2018 max 20457
4910 CFFEX-ICF2018 min 228
5019 CFFEX-ICF2018 means 11054
512 CFFEX-ICG2018 max 17308
5211 CFFEX-ICG2018 min 165
5320 CFFEX-ICG2018 means 7451
543 CFFEX-ICH2018 max 23228
5512 CFFEX-ICH2018 min 95
5621 CFFEX-ICH2018 means 5825
574 CFFEX-ICJ2018 max 20545
5813 CFFEX-ICJ2018 min 67
5922 CFFEX-ICJ2018 means 11786
605 CFFEX-ICK2018 max 19696
6114 CFFEX-ICK2018 min 81
6223 CFFEX-ICK2018 means 8848
636 CFFEX-ICM2018 max 28363
6415 CFFEX-ICM2018 min 162
6524 CFFEX-ICM2018 means 7798
667 CFFEX-ICN2018 max 26187
6716 CFFEX-ICN2018 min 232
6825 CFFEX-ICN2018 means 14225
698 CFFEX-ICU2018 max 34943
7017 CFFEX-ICU2018 min 116
7126 CFFEX-ICU2018 means 11126
729 CFFEX-ICZ2018 max 43776
7318 CFFEX-ICZ2018 min 131
7427 CFFEX-ICZ2018 means 14167
75
76# Finally we will use the ggplot2 package to plot the min, max and mean values of the gold mini future contract on 2017 from Indian Exchange
77
78ggplot(OI_metricsByContract,aes(x=Contract,y=value,fill=metric)) +
79 geom_bar(stat="identity",position="dodge")+
80 xlab("Gold Mini Future Contracts 2017")+ylab("Open Interest") +
81 theme(axis.text.x = element_text(angle = 45, hjust = 1)) +ggtitle("CSI SHANGAI Futures Open Interest")
82
CSI 500 Shanghai Futures Open Interest Metrics
From the barplot above, we can observe that the highest Open Interest is in the CFFEX-ICZ2018 contract that is the Dec 2018 contract. Secondly, the CFFEX-ICU2018 future contract which is from Nov 2018 is the second highest traded contract in 2018. The contracts at the beginning of the year such as Jan, Feb, Mar, Apr and May have less trading activity than contracts at the end of the year.
Unlock Premium Content
Upgrade your account to access the full article, downloads, and exercises.
You'll get access to:
- Access complete tutorials and examples
- Download source code and resources
- Follow along with practical exercises
- Get in-depth explanations