From noreply at r-forge.r-project.org Tue Oct 24 07:52:21 2017 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Tue, 24 Oct 2017 07:52:21 +0200 (CEST) Subject: [Ifrogs-commits] r12 - in pkg: . R data inst/tests man vignettes Message-ID: <20171024055221.E55431891C2@r-forge.r-project.org> Author: anupa Date: 2017-10-24 07:52:21 +0200 (Tue, 24 Oct 2017) New Revision: 12 Added: pkg/R/ic.R pkg/data/ic_CINEMAX.RData pkg/data/lob.RData pkg/inst/tests/data_ic.Rdata pkg/inst/tests/test_ic.R pkg/man/create_snapshot.Rd pkg/man/execute_order.Rd pkg/man/ic.Rd pkg/man/ic_CINEMAX.Rd pkg/man/lob.Rd pkg/vignettes/ic.Rnw Modified: pkg/DESCRIPTION pkg/NAMESPACE Log: Added the IC related files: R code, test file and files in vignettes and man. Accordingly, modified the Namespace to export IC functions Modified: pkg/DESCRIPTION =================================================================== --- pkg/DESCRIPTION 2015-01-14 10:05:41 UTC (rev 11) +++ pkg/DESCRIPTION 2017-10-24 05:52:21 UTC (rev 12) @@ -1,15 +1,24 @@ Package: ifrogs Title: Finance routines developed by the IGIDR Finance Research Group. -Version: 1.1 -Depends: urca, vars, boot, xtable, fOptions, testthat -Author: Finance Research Group +Version: 0.1-3 +Depends: + R (>= 2.10), + urca, + vars, + fOptions, + boot +Imports: + xtable, + testthat +Author: Finance Research Group Maintainer: Chirag Anand Description: Finance routines developed at IGIDR Finance Research Group. -URL: http://r-forge.r-project.org/projects/ifrogs/ -BugReports: https://r-forge.r-project.org/tracker/?group_id=1561 +URL: http://ifrogs.r-forge.r-project.org +BugReports: https://r-forge.r-project.org/tracker/?group_id=xxx License: GPL (>= 2) -Date: 2013-06-26 +Date: 2013-01-03 Type: Package ByteCompile: TRUE LazyLoad: TRUE BuildVignettes: TRUE +RoxygenNote: 6.0.1.9000 Modified: pkg/NAMESPACE =================================================================== --- pkg/NAMESPACE 2015-01-14 10:05:41 UTC (rev 11) +++ pkg/NAMESPACE 2017-10-24 05:52:21 UTC (rev 12) @@ -1 +1 @@ -export(pdshare, dtd, prep_maturity, weighted_iv, vix_ci, vix_pt, vxo) +export(pdshare, dtd, prep_maturity, weighted_iv, vix_ci, vix_pt, vxo, ic, create_snapshot, execute_order) Added: pkg/R/ic.R =================================================================== --- pkg/R/ic.R (rev 0) +++ pkg/R/ic.R 2017-10-24 05:52:21 UTC (rev 12) @@ -0,0 +1,257 @@ +##' Execute a market order using limit order book data. +##' +##' @title Execute market order and return execution details. +##' @param lob.p A vector of limit order book snapshot (at a +##' timestamp) of prices. +##' @param lob.q A vector of limit order book snapshot (at a +##' timestamp) of quantities at the quoted price. +##' +##' @param Q The execution quantity desired. +##' @return A numeric vector containing: +##' \itemize{ +##' \item q: quantity executed +##' \item p: price at which the order was fully/ partially executed +##' \item partial: whether it was a partial execution (0 or 1) +##' } +##' @author Chirag Anand +##' @examples +##' +##' ## Execution with lob.p and lob.q defined in the working +##' ## environment. +##' +##' lob.q <- matrix( nrow = 1, ncol = 4, +##' dimnames = list(c(), +##' c("bsq1", "bsq2", +##' "bsq3", "bsq4"))) +##' lob.q[1, ] <- c(60, 70, 100, 50) ## best sell quantity info +##' +##' lob.p <- matrix( nrow = 1, ncol = 4 , +##' dimnames = list(c(), +##' c("bsp1", "bsp2", +##' "bsp3", "bsp4"))) +##' lob.p[1, ] <- c(101, 102, 103, 103) ## best sell price info +##' str(lob.p) +##' str(lob.q) +##' +##' ans <- execute_order( lob.p, lob.q, Q = 200) +##' +##' print(ans) +##' +##' ## Demonstration of IC functions using the market by price data +##' ## of CINEMAX from the ic_CINEMAX dataset. +##' try(data( package = "ifrogs", "ic_CINEMAX")) +##' mbp <- cbind(as.data.frame(CINEMAX[1]), +##' as.data.frame(CINEMAX[2]), +##' as.data.frame(CINEMAX[3]), +##' as.data.frame(CINEMAX[4])) +##' +##' bbqSnap <- create_snapshot( mbp, type = "bbq") +##' head(bbqSnap) +##' lob.q <- bbqSnap[75, ] ##take any random timestamp +##' head(lob.q) +##' +##' bbpSnap <- create_snapshot( mbp, type = "bbp") +##' head(bbqSnap) +##' lob.p <- bbpSnap[75, ] ## take any random timestamp +##' str(lob.p) +##' str(lob.q) +##' ans <- execute_order( lob.p, lob.q, Q = 1500) +##' print(ans) + + + +execute_order <- function(lob.p, lob.q, Q) { + + stopifnot(Q > 0, length(lob.p) > 0, + length(lob.p) == length(lob.q)) + + cum.lob.q <- c(0, cumsum(lob.q)) + feasible <- tail(cum.lob.q, 1) # Is a full execution infeasible? + if (Q > feasible) { + execution_price <- c(feasible, + tail(cumsum(lob.p * lob.q), 1) / feasible, + TRUE) + names(execution_price) <- c( "q", "p", "partial") + return(execution_price) + } else { + howdeep <- findInterval(Q, cum.lob.q) + 1 # How deep do we need to + # plumb into the book? + cum.lob.q <- cum.lob.q[1:(howdeep + 1)] + + cum.proceeds <- c(0, cumsum(lob.p[1:howdeep] + * lob.q[1:howdeep])) + + p <- approx(cum.lob.q, cum.proceeds, + xout = Q)$y / Q + execution_price <- c(q = Q, p = p, partial = FALSE) + return(execution_price) + } +} + +##' Extract the list of best prices and quantities for a given mbp. +##' @title Prepare data for computing impact cost. +##' @param mbp A 'data.frame' containing market by price data. +##' Rownames of the data frame should contain the timestamp +##' corresponding to the given row. +##' @param type a character scalar: 'bsp' for sell side price, +##' 'bbp' for buy side price, 'bbq' for buy side quantity and +##' 'bsq' for sell side quantity. +##' +##' @return A 'matrix' containing prices/quantities for the buy +##' side/sell side with timestamps as rownames. Example: For type +##' = 'bsp', the fields 'bsp1' and 'bsp2' contain the list of +##' 1st and 2nd best sell prices from the LOB at every timestamp. +##' +##' @author Chirag Anand +##' @examples +##' +##' ## Demonstration of IC functions using the market by +##' ## price data of CINEMAX from the ic_CINEMAX dataset. +##' +##' try(data( package = "ifrogs", "ic_CINEMAX")) +##' mbp <- cbind(as.data.frame(CINEMAX[1]), +##' as.data.frame(CINEMAX[2]), +##' as.data.frame(CINEMAX[3]), +##' as.data.frame(CINEMAX[4])) +##' str(mbp) +##' +##' ## create_snapshot for the best buy quantity. +##' bbqSnap <- create_snapshot( mbp, type = "bbq") +##' head(bbqSnap) +##' +##' ## create_snapshot for best sell price +##' bspSnap <- create_snapshot( mbp, type = "bsp") +##' head(bspSnap) +##' +create_snapshot <- function(mbp, type) { + cols <- grep(type, colnames(mbp), value = TRUE) + element_snapshots <- mbp[, cols] + element_snapshots <- as.matrix(element_snapshots) + return(element_snapshots) +} + +##' Function to compute impact cost for a security for a day. +##' @title Function to compute impact cost. +##' +##' +##' @param mbp a data.frame, containing best price/quantity +##' pairs for buy and sell side with time stamps as row names. +##' Units: +##' \itemize{ +##' \item Price (bbp/bsp): Some currency (INR, USD, etc.) +##' \item Quantities (bbq/bsq): Number of shares +##' } +##' +##' +##' +##' @param Q an 'integer' vector containing the quantities +##' for which to compute the Impact Cost. +##' @param d Date +##' @param partial a 'logical' scalar, telling whether to do +##' partial executions +##' +##' @return A 'list' of matrices containing buy and sell IC. +##' 'names' of the list are the Q values used. Each matrix will +##' contain rows having +##' \itemize{ +##' \item buyIC percentage: numeric +##' \item sellIC percentage: numeric +##' } +##' +##' The function returns \sQuote{NA} values if \dQuote{partial} is +##' \sQuote{FALSE}, or, if there were no orders (empty book) at a +##' particular time.For the buy and sell ic measures the +##' corresponding row name for that entry is its timestamp. +##' +##' +##' @author Chirag Anand +##' @examples +##' ## Demonstration of IC functions using the market by price data +##' ## of CINEMAX from the ic_CINEMAX dataset. +##' try(data(package="ifrogs", "ic_CINEMAX")) +##' mbp <- cbind(as.data.frame(CINEMAX[1]), +##' as.data.frame(CINEMAX[2]), +##' as.data.frame(CINEMAX[3]), +##' as.data.frame(CINEMAX[4])) +##' print(mbp) +##' +##' ans1 <- ic( mbp, Q = 600, d, partial = FALSE) +##' head(ans1) +##' +##' ans2 <- ic( mbp, Q = 600, d, partial = TRUE) +##' head(ans2) +ic <- function(mbp, Q, d, partial = FALSE) { + if (is.null(nrow(mbp)) | nrow(mbp) == 0) { + warning(d, + "No data points available.", + call. = FALSE, + immediate. = TRUE) + return(NULL) + } + + buyQty <- create_snapshot(mbp, "bbq") + buyPrice <- create_snapshot(mbp, "bbp") + sellQty <- create_snapshot(mbp, "bsq") + sellPrice <- create_snapshot(mbp, "bsp") + + p.mid <- (buyPrice[, 1] + sellPrice[, 1]) / 2 + + ## estimation of sell and buy IC + IC.Q <- lapply(Q, function(qty) { + + buy.execution <- lapply(1:nrow(sellQty), function(i) { + lob.q <- na.omit(as.vector(sellQty[i, ], + mode = "integer")) + + lob.p <- na.omit(as.vector(sellPrice[i, ], + mode = "numeric")) + + if (length(lob.q) == 0 || length(lob.p) == 0) { + return(NA) + } + execute_order(lob.q = lob.q, lob.p = lob.p, Q = qty) + }) + + sell.execution <- lapply(1:nrow(buyQty), function(i) { + + lob.q <- na.omit(as.vector(buyQty[i, ], + mode = "integer")) + + lob.p <- na.omit(as.vector(buyPrice[i, ], + mode = "numeric")) + + if (length(lob.q) == 0 || length(lob.p) == 0) { + return(NA) + } + execute_order(lob.q = lob.q, lob.p = lob.p, Q = qty) + }) + + if (all(is.na(sell.execution)) | all(is.na(buy.execution))) { + + warning("No execution possible.", + call. = FALSE, + immediate. = TRUE) + + return(NULL) + } + + buy.execution <- do.call(rbind, buy.execution) + sell.execution <- do.call(rbind, sell.execution) + rownames(buy.execution) <- rownames(buyQty) + rownames(sell.execution) <- rownames(buyQty) + + if (partial == FALSE) { # make partial execution prices NA + buy.execution[buy.execution[, "partial"] == 1, "p"] <- NA + sell.execution[sell.execution[, "partial"] == 1, "p"] <- NA + } + + buyIC <- ((buy.execution[, "p"] - p.mid) / p.mid) * 100 + sellIC <- ((sell.execution[, "p"] - p.mid) / p.mid) * 100 + IC <- cbind(sellIC, buyIC, deparse.level = 1) # don't lose the labels + + return(IC) + }) + + names(IC.Q) <- Q + return(IC.Q) +} \ No newline at end of file Added: pkg/data/ic_CINEMAX.RData =================================================================== (Binary files differ) Property changes on: pkg/data/ic_CINEMAX.RData ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: pkg/data/lob.RData =================================================================== (Binary files differ) Property changes on: pkg/data/lob.RData ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: pkg/inst/tests/data_ic.Rdata =================================================================== (Binary files differ) Property changes on: pkg/inst/tests/data_ic.Rdata ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: pkg/inst/tests/test_ic.R =================================================================== --- pkg/inst/tests/test_ic.R (rev 0) +++ pkg/inst/tests/test_ic.R 2017-10-24 05:52:21 UTC (rev 12) @@ -0,0 +1,123 @@ +## load the CINEMAX ic data from the ic_CINEMAX dataset. + require("testthat") + try(data(package="ifrogs","ic_CINEMAX")) + + mbp <- cbind(as.data.frame(CINEMAX[1]), + as.data.frame(CINEMAX[2]), + as.data.frame(CINEMAX[3]), + as.data.frame(CINEMAX[4])) + + +library("testthat") +context("ic") + + +test_that("test_execute_order for Q = 1500 (partial execution of order)", { + load(system.file("tests", "data_ic.Rdata", package = "ifrogs")) + + bbqSnap <- create_snapshot(mbp,type="bbq") + lob.q <-bbqSnap[75,] ##take any random timestamp + bbpSnap <- create_snapshot(mbp,type="bbp") + lob.p <-bbpSnap[75,] ##take any random timestamp + names(lob.p) <- NULL + names(lob.q) <- NULL + + + # to test execute_orders + test_execute_order_tmp <- execute_order(lob.p, lob.q, + Q = 1500) + + cat("\nTesting execute_order for Q=1500 (partial execution)") + expect_identical(test_execute_order_tmp, + execute_order_result$partial_order_execution) + +}) + + +test_that("test_execute_order for Q=900 (full execution)", { + load(system.file("tests", "data_ic.Rdata", package = "ifrogs")) + + bbqSnap <- create_snapshot(mbp,type="bbq") + lob.q <-bbqSnap[75,] ##take any random timestamp + bbpSnap <- create_snapshot(mbp,type="bbp") + lob.p <-bbpSnap[75,] ##take any random timestamp + names(lob.p) <- NULL + names(lob.q) <- NULL + + + # to test execute_orders + test_execute_order_tmp <- execute_order(lob.p, lob.q, + Q = 900) + + cat("\nTesting execute_order for Q=900 (full execution)") + expect_identical(test_execute_order_tmp, + execute_order_result$full_order_execution) + +}) + + +test_that("test_execute_order for Q=1108 (boundary case)", { + load(system.file("tests", "data_ic.Rdata", package = "ifrogs")) + + bbqSnap <- create_snapshot(mbp,type="bbq") + lob.q <-bbqSnap[75,] ##take any random timestamp + bbpSnap <- create_snapshot(mbp,type="bbp") + lob.p <-bbpSnap[75,] ##take any random timestamp + names(lob.p) <- NULL + names(lob.q) <- NULL + + # to test execute_orders + + test_execute_order_tmp <- execute_order(lob.p, lob.q, + Q = 1108) + cat("\nTesting execute_order for Q=1108 (Boundary Value)") + expect_identical(test_execute_order_tmp, + execute_order_result$boundary_case) + + +}) + + +test_that("test_create_snapshot", { + load(system.file("tests", "data_ic.Rdata", package = "ifrogs")) + + # to test create_snapshot + test_create_snapshot_bsp_tmp <- create_snapshot(mbp, type = "bsp") + + + cat("\nTesting create_snapshot for type = 'bsp' ") + expect_identical(test_create_snapshot_bsp_tmp, + create_snapshot_bsp_result) + + test_create_snapshot_bsq_tmp <- create_snapshot(mbp, type = "bsq") + + cat("\nTesting create_snapshot for type = 'bsq' ") + expect_identical(test_create_snapshot_bsq_tmp, + create_snapshot_bsq_result) + + +}) + +test_that("test_ic", { + load(system.file("tests", "data_ic.Rdata", package = "ifrogs")) + + # to test function ic + test_ic_partial_false_tmp <- ic( mbp, + Q = 600 , + partial = FALSE ) + + + cat("\nTesting ic for partial = false ") + expect_identical(test_ic_partial_false_tmp, + test_ic_partial_false_result) + + test_ic_partial_true_tmp <- ic( mbp, + Q = 600 , + partial = TRUE ) + + cat("\nTesting ic for partial = true ") + expect_identical(test_ic_partial_true_tmp, + test_ic_partial_true_result) + + +}) \ No newline at end of file Added: pkg/man/create_snapshot.Rd =================================================================== --- pkg/man/create_snapshot.Rd (rev 0) +++ pkg/man/create_snapshot.Rd 2017-10-24 05:52:21 UTC (rev 12) @@ -0,0 +1,49 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/ic.R +\name{create_snapshot} +\alias{create_snapshot} +\title{Prepare data for computing impact cost.} +\usage{ +create_snapshot(mbp, type) +} +\arguments{ +\item{mbp}{A 'data.frame' containing market by price data. +Rownames of the data frame should contain the timestamp +corresponding to the given row.} + +\item{type}{a character scalar: 'bsp' for sell side price, +'bbp' for buy side price, 'bbq' for buy side quantity and +'bsq' for sell side quantity.} +} +\value{ +A 'matrix' containing prices/quantities for the buy +side/sell side with timestamps as rownames. Example: For type += 'bsp', the fields 'bsp1' and 'bsp2' contain the list of +1st and 2nd best sell prices from the LOB at every timestamp. + + @author Chirag Anand +} +\description{ +Extract the list of best prices and quantities for a given mbp. +} +\examples{ + +## Demonstration of IC functions using the market by +## price data of CINEMAX from the ic_CINEMAX dataset. + +try(data( package = "ifrogs", "ic_CINEMAX")) +mbp <- cbind(as.data.frame(CINEMAX[1]), + as.data.frame(CINEMAX[2]), + as.data.frame(CINEMAX[3]), + as.data.frame(CINEMAX[4])) +str(mbp) + +## create_snapshot for the best buy quantity. +bbqSnap <- create_snapshot( mbp, type = "bbq") +head(bbqSnap) + +## create_snapshot for best sell price +bspSnap <- create_snapshot( mbp, type = "bsp") +head(bspSnap) + +} Added: pkg/man/execute_order.Rd =================================================================== --- pkg/man/execute_order.Rd (rev 0) +++ pkg/man/execute_order.Rd 2017-10-24 05:52:21 UTC (rev 12) @@ -0,0 +1,75 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/ic.R +\name{execute_order} +\alias{execute_order} +\title{Execute market order and return execution details.} +\usage{ +execute_order(lob.p, lob.q, Q) +} +\arguments{ +\item{lob.p}{A vector of limit order book snapshot (at a +timestamp) of prices.} + +\item{lob.q}{A vector of limit order book snapshot (at a +timestamp) of quantities at the quoted price.} + +\item{Q}{The execution quantity desired.} +} +\value{ +A numeric vector containing: + \itemize{ + \item q: quantity executed + \item p: price at which the order was fully/ partially executed + \item partial: whether it was a partial execution (0 or 1) +} +} +\description{ +Execute a market order using limit order book data. +} +\examples{ + +## Execution with lob.p and lob.q defined in the working +## environment. + +lob.q <- matrix( nrow = 1, ncol = 4, + dimnames = list(c(), + c("bsq1", "bsq2", + "bsq3", "bsq4"))) +lob.q[1, ] <- c(60, 70, 100, 50) ## best sell quantity info + +lob.p <- matrix( nrow = 1, ncol = 4 , + dimnames = list(c(), + c("bsp1", "bsp2", + "bsp3", "bsp4"))) +lob.p[1, ] <- c(101, 102, 103, 103) ## best sell price info +str(lob.p) +str(lob.q) + +ans <- execute_order( lob.p, lob.q, Q = 200) + +print(ans) + +## Demonstration of IC functions using the market by price data +## of CINEMAX from the ic_CINEMAX dataset. +try(data( package = "ifrogs", "ic_CINEMAX")) +mbp <- cbind(as.data.frame(CINEMAX[1]), + as.data.frame(CINEMAX[2]), + as.data.frame(CINEMAX[3]), + as.data.frame(CINEMAX[4])) + +bbqSnap <- create_snapshot( mbp, type = "bbq") +head(bbqSnap) +lob.q <- bbqSnap[75, ] ##take any random timestamp +head(lob.q) + +bbpSnap <- create_snapshot( mbp, type = "bbp") +head(bbqSnap) +lob.p <- bbpSnap[75, ] ## take any random timestamp +str(lob.p) +str(lob.q) +ans <- execute_order( lob.p, lob.q, Q = 1500) +print(ans) +} +\author{ +Chirag Anand +} Added: pkg/man/ic.Rd =================================================================== --- pkg/man/ic.Rd (rev 0) +++ pkg/man/ic.Rd 2017-10-24 05:52:21 UTC (rev 12) @@ -0,0 +1,61 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/ic.R +\name{ic} +\alias{ic} +\title{Function to compute impact cost.} +\usage{ +ic(mbp, Q, d, partial = FALSE) +} +\arguments{ +\item{mbp}{a data.frame, containing best price/quantity +pairs for buy and sell side with time stamps as row names. +Units: +\itemize{ +\item Price (bbp/bsp): Some currency (INR, USD, etc.) +\item Quantities (bbq/bsq): Number of shares +}} + +\item{Q}{an 'integer' vector containing the quantities +for which to compute the Impact Cost.} + +\item{d}{Date} + +\item{partial}{a 'logical' scalar, telling whether to do +partial executions} +} +\value{ +A 'list' of matrices containing buy and sell IC. +'names' of the list are the Q values used. Each matrix will +contain rows having +\itemize{ +\item buyIC percentage: numeric +\item sellIC percentage: numeric +} + +The function returns \sQuote{NA} values if \dQuote{partial} is + \sQuote{FALSE}, or, if there were no orders (empty book) at a +particular time.For the buy and sell ic measures the +corresponding row name for that entry is its timestamp. +} +\description{ +Function to compute impact cost for a security for a day. +} +\examples{ +## Demonstration of IC functions using the market by price data +## of CINEMAX from the ic_CINEMAX dataset. +try(data(package="ifrogs", "ic_CINEMAX")) +mbp <- cbind(as.data.frame(CINEMAX[1]), + as.data.frame(CINEMAX[2]), + as.data.frame(CINEMAX[3]), + as.data.frame(CINEMAX[4])) +print(mbp) + +ans1 <- ic( mbp, Q = 600, d, partial = FALSE) +head(ans1) + +ans2 <- ic( mbp, Q = 600, d, partial = TRUE) +head(ans2) +} +\author{ +Chirag Anand +} Added: pkg/man/ic_CINEMAX.Rd =================================================================== --- pkg/man/ic_CINEMAX.Rd (rev 0) +++ pkg/man/ic_CINEMAX.Rd 2017-10-24 05:52:21 UTC (rev 12) @@ -0,0 +1,21 @@ +\name{ic_CINEMAX} +\docType{data} +\alias{CINEMAX} +\title{Limit order book data of Cinemax India Ltd. for 29th October, + 2013} +\description{Twenty deep limit order book data consisting of the best + buy and sell side prices and quantities for Cinemax India Ltd. (a + company listed on the National Stock Exchange, India) for 29th + October, 2013. The dataset is a list of four dataframe: buyQty, + buyPrice, sellQty and sellPrice. + + - buyQty: twenty levels of best buy quantities available for the day + - buyPrice: twenty levels of best sell prices available for the day + - sellQty: twenty levels of best sell quantities available for the day + - sellPrice: twenty levels of best sell prices available for the day +} + +\usage{data(ic_CINEMAX)} + +\format{list (4)} +\keyword{limit order book} Added: pkg/man/lob.Rd =================================================================== --- pkg/man/lob.Rd (rev 0) +++ pkg/man/lob.Rd 2017-10-24 05:52:21 UTC (rev 12) @@ -0,0 +1,18 @@ +\name{lob} +\docType{data} +\alias{lob} +\title{A snapshot of the RELIANCE spot limit order book at 11AM on 1st January, +2009.} +\description{ + The data is a snapshot of the limit order book for a stock + RELIANCE trading on the National Stock Exchange of India on 1st + January 2009. The snapshot has been taken at 11AM. The data consists + of pairs of limit order price-limit order quantity present in the + limit order book at the time. + + The snaphot pertains to the ask side of the limit order book and + hence, the limit prices are arranged in increasing order of price priority. +} +\usage{data(lob)} +\format{data.frame (8561 x 2)} +\keyword{datasets} Added: pkg/vignettes/ic.Rnw =================================================================== --- pkg/vignettes/ic.Rnw (rev 0) +++ pkg/vignettes/ic.Rnw 2017-10-24 05:52:21 UTC (rev 12) @@ -0,0 +1,251 @@ +\documentclass[nojss]{jss} +\usepackage{amssymb} +\usepackage{amsmath} +\usepackage{thumbpdf} +\usepackage{color} +\usepackage{float} +\floatstyle{ruled} +\restylefloat{table} + +\newcommand{\floatintro}[1]{ + \vspace*{0.1in} + {\footnotesize #1 } \vspace*{0.1in} +} + +\newcommand{\alert}[1]{\textcolo{red}{#1}} + +%\VignetteIndexEntry{ic} +\author{ + Ajay Shah \\ + National Institute of Public Finance \& Policy, New Delhi +} + +\title{ Impact Cost: Implementation in \proglang{R} } + +\Plaintitle{Impact Cost Implementation in R} +\Shorttitle{Impact Cost Implementation} + +\Abstract{ + This paper describes the implementation of the function \code{ic} in + the package \pkg{ifrogs}. The function estimates the impact cost of + trading a given quantity of a security on both the buy side and sell + side of the limit order book. Impact cost is a measure of liquidity, + indicating the cost of transaction in a stock for a specific + quantity at a given point in time. +} + +\Keywords{ + Impact cost, Limit order book, Liquidity +} + +\Address{ + Ajay Shah\\ + National Institute of Public Finance and Policy\\ + Special Institutional Area\\ + New Delhi 110067, India\\ + E-mail: \email{ajayshah at mayin.org}\\ +} + +\begin{document} + +\section{Introduction} +\label{s:intro} + +Liquidity means transaction costs, a highly liquid market is one where +large orders can be executed without incurring a high transaction +cost. Liquidity is valuable to market participants, yet is notoriously +hard to define. The consensus in the literature is that liquidity +cannot be represented by a single variable. Most empirical studies use +several alternative measures, such as quoted and effective bid-ask +spreads and depth at the best bid and offer quotations, to obtain a +robust picture of a market's liquidity. + +Such measures have a limitation of being able to capture the liquidity +available within the best quotes or limit prices only. They are unable +to provide a measure of liquidity when the transaction size is greater +than the depth available at the best quotes in the limit order book. + +An ex-ante measure of liquidity which aggregates the status of the +limit order book at any moment in time for a specific transaction size +into one number is called \code{Impact cost}. Impact cost is defined as +the percentage mark-up of the average weighted execution price of +instantaneously buying or selling of a security using a market order +of quantity $Q$ over mid-quote price of the security. It measures the +percentage degradation that is experienced with respect to the +mid-quote price of the security for buying or selling. It is different +for buy and sell orders and varies with different transaction size. + +The function \code{ic} from package \pkg{ifrogs} is the first +implementation of impact cost estimation in \proglang{R}. + +The paper is organised as follows: Section 1 briefly +discusses the steps involved in estimation of impact cost. Section +2 describes the implementation of the function in +\proglang{R}. Section 3 illustrates the function with an +example. Section 4 shows the computational efficiency +of the function. + +\section{Estimation of Impact Cost} +\label{s:estimation} + +Electronic limit order books have become an important means of trading +equities, derivatives and bonds. A distinguishable feature of this +format is that a high proportion of available liquidity is committed +(displayed) rather than implicit or hidden. + +If a market order of quantity $Q$ is placed, it would either get +executed at the best limit prices else the market order would have to +walk through the various limit prices in the book. If the execution +takes place at the best price the transaction cost incurred would be +equal to one half of the bid-ask spread. But when the order gets +executed further away from the best prices, the transaction cost +increases and is captured by the impact cost. + +As a benchmark for our analysis, we use a hypothetical perfectly +liquid capital market. Every investor is assumed to be a price taker, +facing perfectly elastic demand and supply of shares at the same +market-clearing price. We propose to evaluate the liquidity of an +actual market according to its proximity to this hypothetical +perfectly liquid market: the closer the resemblance, the more liquid +is the actual market. + +The hypothetical perfect liquid market would allow the security to be +traded in unlimited quantities at the mid point of the best bid and +ask prices. We call this as the mid-quote price. + +Thus, the mid-quote can be computed as: + +\begin{equation} + p_{mid} = \frac{p_{1}^{bid} + p_{1}^{ask}}{2} +\end{equation} + +where $p_{1}^{bid}$ and $p_{1}^{ask}$ represent the best prices offers +on the bid and the ask side of the book. The best bid is defined as +the maximum price associated with any buy limit order, and the best +ask is defined as the minimum price associated with any sell limit +order. + +The average weighted price of execution for the market order of size +$Q$ is given by: + +\begin{equation} + p_{t} (Q) = \frac{1}{Q} [ (Q - \sum_{i=1}^{s} Q_{it})*p_{s +1,t} + + \sum_{i=1}^{s} p_{it}*Q_{it} ] +\end{equation} + +Here, $p_{t}$ (Q) is the average weighted execution price of the +quantity $Q$ at time $t$. $p_{it}$ and $Q_{it}$ are the price and +quantity of the $i^{th}$ limit order away from the best prices that +would be fully consumed by the market order at time $t$ for $ i = 1,2, +\hdots, s$. $Q$ is the size of the market order. $p_{s+1,t}$ is the +price of the $(s+1)^{th}$ limit order which would be partially +executed against the market order. The average weighted execution +price can be calculated for both a buy and a sell market order. + +The impact cost is the percentage degradation that is experienced with +respect to the ideal price (mid-quote price) for a buy or a sell +market order. Mathematically, the impact cost can be written as: + +\begin{equation} + ic_{t} (Q) = \frac{\lvert p_{t} (Q) - p_{mid} \rvert} {p_{mid}} * 100 +\end{equation} + +The impact cost thus measured is in percentage terms and can also be +expressed in basis points by further multiplication of the estimate by +100. The measure can be computed for both the bid as well as the ask +side of the limit order book. + +\section{R implementation} +\label{s:rimplement} + +The function \code{ic} implements the above estimation of impact +cost. It requires limit order prices (\code{buyPrice} \& \code{sellPrice}) +and the corresponding quantities (\code{buyQty} \& \code{sellQty}) on +the buy and sell side of the order book and the size of the market order +(\code{Q}) . The function can also handle partial execution of market +orders if the \code{partialExecution} flag is \code{TRUE} and the +market order \code{Q} exceeds the quantity available in the book for +execution. + +The function is given as: +<>= +library(ifrogs) +str(ic) +@ + +In the above arguments 'mbp' should be a data frame which has the buy +and sell side price and quantity information based on which the impact +cost has to be calculated.Once the arguments are specified, the function +compares the depth of the book and the quantity \code{Q} requested. In +case it is not feasible to fully execute the market order, it returns +\code{NA} or the average weighted price and the impact cost for the +quantity feasible for execution based on the value of +\code{partialExecution}. If it is feasible to fully execute the +market, the function calculates the average weighted price of execution +and the impact cost for the market order \code{Q}. + +The function returns a list having the percentage of impact cost incurred +for both the buy and sell side, corresponding to all timestamps in the +mbp file. The name of the list is the Quantity \code{Q} for which the impact +cost has been computed. + +\section{Example} +\label{s:example} +We illustrate the function with an example data of a company, +Cinemax India Ltd., listed on the National Stock Exchange, India. The +data, \code{CINEMAX} is a twenty deep limit order book data +consisting of the best buy and sell side prices and quantities for +Cinemax India Ltd. on 29$^{th}$ October, 2013. The dataset is a list of +four dataframe: buyQty, buyPrice, sellQty and sellPrice. +%buyQty and sellQty consist of the best quantities on the buy and sell side +%respectively for the topmost twenty levels. Similarly, buyPrice and +%sellPrice consist of the best prices on the buy and sell side +%respectively for the topmost twenty levels. + +<< echo = TRUE >>= +data("ic_CINEMAX") +str(CINEMAX, list.len = 5) +@ + +One can estimate the impact cost for selling and buying shares of a +given quantity for the stock on a particular day using the function: + +The data from the cinemax data set is first converted into a format +as required for the ic function which takes mbp file for the required +security for the given date as an argument. +<>= +mbp <- cbind(as.data.frame(CINEMAX[1]), + as.data.frame(CINEMAX[2]), + as.data.frame(CINEMAX[3]), + as.data.frame(CINEMAX[4])) + +result_ic <- ic(mbp, Q = 600 , partial=TRUE) + + + +computeTime <- system.time(ic(mbp, Q = 600, partial=FALSE)) +head(result_ic[[1]],10) +@ + +\code{sellIC} and \code{buyIC} contain the impact cost for selling and +buying 600 shares of Cinemax India Ltd. for 29$^{th}$ October, +2013. + + +\section{Computational efficiency} +\label{s:efficiency} +In this section, we discuss the efficiency of the code in terms of +computational time taken to generate the `Impact Cost' for twenty deep +limit order book of 476 records. The innermost code for calculating +the average weighted price is vectorised, thus making the whole +function far more efficient than other implementations. The +\code{computeTime} variable in the above code computes the time taken +for estimating IC using this data. The time taken is: + +<>= +computeTime +@ + +The above computation is done on a 64-bit Linux machine with R-3.2.3. + +\end{document} From noreply at r-forge.r-project.org Tue Oct 24 12:19:06 2017 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Tue, 24 Oct 2017 12:19:06 +0200 (CEST) Subject: [Ifrogs-commits] r13 - pkg Message-ID: <20171024101906.4D8321877CD@r-forge.r-project.org> Author: anupa Date: 2017-10-24 12:19:05 +0200 (Tue, 24 Oct 2017) New Revision: 13 Modified: pkg/NAMESPACE Log: Made changes to the Namespace file Modified: pkg/NAMESPACE =================================================================== --- pkg/NAMESPACE 2017-10-24 05:52:21 UTC (rev 12) +++ pkg/NAMESPACE 2017-10-24 10:19:05 UTC (rev 13) @@ -1 +1,2 @@ export(pdshare, dtd, prep_maturity, weighted_iv, vix_ci, vix_pt, vxo, ic, create_snapshot, execute_order) +import(urca, vars, fOptions, boot, xtable, testthat) From noreply at r-forge.r-project.org Tue Oct 24 13:27:54 2017 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Tue, 24 Oct 2017 13:27:54 +0200 (CEST) Subject: [Ifrogs-commits] r14 - pkg Message-ID: <20171024112754.18C06188C49@r-forge.r-project.org> Author: anupa Date: 2017-10-24 13:27:53 +0200 (Tue, 24 Oct 2017) New Revision: 14 Modified: pkg/NAMESPACE Log: Made changes to the Namespace file Modified: pkg/NAMESPACE =================================================================== --- pkg/NAMESPACE 2017-10-24 10:19:05 UTC (rev 13) +++ pkg/NAMESPACE 2017-10-24 11:27:53 UTC (rev 14) @@ -1,2 +1,4 @@ export(pdshare, dtd, prep_maturity, weighted_iv, vix_ci, vix_pt, vxo, ic, create_snapshot, execute_order) import(urca, vars, fOptions, boot, xtable, testthat) +importFrom("stats", "approx", "complete.cases", "embed", "lm.fit", "na.omit", "optim", "pnorm") +importFrom("utils", "tail") From noreply at r-forge.r-project.org Thu Oct 26 09:28:42 2017 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Thu, 26 Oct 2017 09:28:42 +0200 (CEST) Subject: [Ifrogs-commits] r15 - pkg Message-ID: <20171026072842.65DAE1801E7@r-forge.r-project.org> Author: anupa Date: 2017-10-26 09:28:41 +0200 (Thu, 26 Oct 2017) New Revision: 15 Modified: pkg/DESCRIPTION Log: Modified the title in the description file Modified: pkg/DESCRIPTION =================================================================== --- pkg/DESCRIPTION 2017-10-24 11:27:53 UTC (rev 14) +++ pkg/DESCRIPTION 2017-10-26 07:28:41 UTC (rev 15) @@ -1,5 +1,5 @@ Package: ifrogs -Title: Finance routines developed by the IGIDR Finance Research Group. +Title: Finance routines developed by the IGIDR Finance Research Group Version: 0.1-3 Depends: R (>= 2.10), From noreply at r-forge.r-project.org Tue Oct 31 07:07:12 2017 From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org) Date: Tue, 31 Oct 2017 07:07:12 +0100 (CET) Subject: [Ifrogs-commits] r16 - pkg Message-ID: <20171031060712.778BE1891F3@r-forge.r-project.org> Author: anupa Date: 2017-10-31 07:07:10 +0100 (Tue, 31 Oct 2017) New Revision: 16 Modified: pkg/DESCRIPTION Log: In the description file, changed the date and the title Modified: pkg/DESCRIPTION =================================================================== --- pkg/DESCRIPTION 2017-10-26 07:28:41 UTC (rev 15) +++ pkg/DESCRIPTION 2017-10-31 06:07:10 UTC (rev 16) @@ -1,5 +1,5 @@ Package: ifrogs -Title: Finance routines developed by the IGIDR Finance Research Group +Title: Finance Routines Developed by the IGIDR Finance Research Group Version: 0.1-3 Depends: R (>= 2.10), @@ -16,7 +16,7 @@ URL: http://ifrogs.r-forge.r-project.org BugReports: https://r-forge.r-project.org/tracker/?group_id=xxx License: GPL (>= 2) -Date: 2013-01-03 +Date: 2017-10-31 Type: Package ByteCompile: TRUE LazyLoad: TRUE