R/risk_of_price_change.R

#' Compute risk of price change
#'
#' This function compute possible minimum and maximum prices of stock in given period of time.
#' Function simulate a 10^4 of random trajectories for stock marked prices of chosen asset, take
#' maximums and minimums from each  trajectory and return quantiles from this vectors.
#' Moreover  function on its own is providing data from google finance. Stochastic process which is used in function
#' to modeling future prices is a Black Scholes model. Simulation values are aproximations of process: \cr
#' \eqn{dX_t = a * X_t dt + sigma * X_t dW_t} , \cr
#' where W is a standard Wiener process. \cr
#' Function has additional assumption that "a" is equal to 0, because in risk management it is a more secure approach.
#'
#' @param symbol Symbol of a stock exchange data.
#' @param days Number of days for which simulation is to be performed.
#' @param significance_level Chosen significance level. Commonly it is set on 0.05.
#' @param price_type Type of price : "close" or "open".
#' @return A frame contains actual_price, predicted max_possible_price and min_possible_price values for given period of future time.
#' @examples
#' risk_of_price_change("YHOO",100,0.05)
#' risk_of_price_change("GOOG",100,0.05,"open")
#' @export
risk_of_price_change <- function(symbol, days, significance_level, price_type = "close"){

  assertthat::assert_that(is.character(symbol))
  assertthat::assert_that(days%%1 == 0 & days >= 1, msg="Number of days must be integer value and greater then 0")
  assertthat::assert_that(price_type == "close" | price_type == "open")
  assertthat::assert_that(is.numeric(significance_level))
  assertthat::assert_that(significance_level > 0 & significance_level < 0.1,
                          msg="significance_level must be value from range (0,0.1)")

  simulations <- 10^4
  driftless <- TRUE
  # basic parameters
  t <- days/365
  dt <- 1/365
  seq1 <- seq(0, t, by = dt)
  N <- length(seq1)
  m <- simulations

  # get data from google finance
  options(warn = -1)
  data <- quantmod::getSymbols (symbol, src = "google", env = NULL)
  options(warn = 1)

  # # test that the columns are in set order
  assertthat::assert_that(grepl("Open", colnames(data)[1]))
  assertthat::assert_that(grepl("Close", colnames(data)[4]))

  if (price_type=="close"){data_col <- 4}
  if (price_type=="open"){data_col <- 1}

  # simple parameters estimation from data
  differences <- diff(data[, data_col])
  drift <- if(driftless==F){
                            mean(differences, na.rm = T)
           }else{drift <- 0}
  risk <- 2 # it is only assumption used because this model is builded under real world measure and Black Scholes is constructed under (martingale) risk neutral measure
  volatility <- sd(as.numeric(differences), na.rm = T)/mean(data[,data_col],na.rm = T) * risk


  # simulation using Black Scholes model for stock prices.
  Y <- matrix(rep(0, N * m), ncol = N, nrow = m)
  dB.matrix <- matrix(rep(0, (N - 1) * m), ncol = (N - 1), nrow = m)

  for(j in 1:m){
    X <- c()
    X[1] <- as.numeric(data[nrow(data), data_col])
    dB <- sqrt(dt) * rnorm(N - 1, mean = 0, sd = 1)
    dB.matrix[j, ] <- dB
    for(i in 1:(N - 1)){
      X[i + 1] <- X[i] + X[i] * drift * dt + X[i] * volatility * dB[i]
    }
    Y[j, ] <- X
  }
  # count simulated minimum and maximum prices of stock in given period of time
  max_prices_in_period <- apply(Y, 1, max)
  min_prices_in_period <- apply(Y, 1, min)

  max_possible_price<- quantile(max_prices_in_period,  probs = 1 - significance_level)
  min_possible_price<- quantile(min_prices_in_period,  probs = significance_level)

  return(data.frame(actual_price = X[1] , max_possible_price = max_possible_price, min_possible_price = min_possible_price))
}
mrepsilon/PawelKawskiPackage documentation built on May 21, 2019, 2:22 p.m.