2012-11-04 49 views
2

希望某人能夠提供給定日期的函數,它將返回紐約證券交易所每月的交易日。計算紐約證券交易所每月交易日的函數

如果考慮到假期是一個獎金,如果不是我不太擔心。

在此先感謝!

+2

這*是*一個有效的(如果措辭很奇怪)的問題(我碰巧是下面答案中使用的接口包的作者)。 –

回答

4

有幾個軟件包可以處理繁瑣的日曆問題,這很麻煩。從timeDate引用:

「這對於工作日,週末和節假日實現函數並不是微不足道的,從算法的角度來說並不困難,但實現日曆本身的規則可能變得單調乏味,例如復活節的日期。「

不過,如果我正確理解你的問題,這樣的事情應該工作(雖然你可能要想想你想,如果myDate結果本身不是交易日......此刻它給人的交易日的之前的交易日)。

library(RQuantLib) 

tradingDayOfMonth <- function(myDate, calendar = "UnitedStates/NYSE") { 
    FirstOfMonth <- as.Date(paste(year(myDate), month(myDate), "01", sep="/")) 
    businessDaysBetween(calendar, from = FirstOfMonth, to = myDate, 
         includeFirst = 1, includeLast = 1) 
} 

tradingDayOfMonth(as.Date("2012/11/05")) 
# [1] 3 
5

我有一個個人包一個函數調用TradingDates使用假期從timeDate包 日曆返回的所有交易日的日期,在指定年度(S)。我在該帖子結尾處包含了 該功能的代碼以及功能 PrevTradingDateNextTradingDate,這些都是功能的動機。

一旦你找到了這個代碼,很容易做出一個函數,返回 ,這個函數在給定日期的月份的交易日。目前,輸入日期 必須是(單一)交易日期,但可以根據您的偏好根據 輕鬆更改。對於上述要求

TradingDayOfMonth <- function(Date, FUN=holidayNYSE, ...) { 
    if (length(Date) > 1) stop('not vectorized; Date should be length 1') 
    Date <- as.Date(Date, ...) 
    tdy <- TradingDates(format(Date, "%Y"), FUN=FUN) #trading dates in year 
    if (!Date %in% tdy) stop("Date is not a Trading Date") 
    tdm <- tdy[format(tdy, "%m") %in% format(Date, "%m")] # trading dates in the same month as "Date" 
    which(tdm == Date) 
} 

R> PrevTradingDate() 
[1] "2012-11-02" 
R> NextTradingDate() 
[1] "2012-11-05" 
R> TradingDayOfMonth(PrevTradingDate()) 
[1] 2 
R> TradingDayOfMonth(NextTradingDate()) 
[1] 3 
R> TradingDayOfMonth('2012-11-15') 
[1] 11 

代碼工作:

#' Get Trading Dates for one or more years 
#' 
#' Get a vector of dates of non-holiday weekdays. 
#' 
#' This uses holiday calendar functions (\code{holidayNYSE} by default) 
#' from the \emph{timeDate} package. If \emph{timeDate} is not loaded, it 
#' will be temporarily loaded, then unloaded \code{on.exit}. 
#' 
#' @param year vector of 4 digit years or something that is coercible to 
#' a vector 4 digit years via \code{as.numeric} 
#' @param FUN a function that takes a \code{year} argument and returns a vector 
#' that can be coerced to a \code{Date}. \code{holidayNYSE} by default. Most 
#' likely, this will be one of: \sQuote{holidayLONDON}, \sQuote{holidayNERC}, 
#' \sQuote{holidayNYSE}, \sQuote{holidayTSX}, \sQuote{holidayZURICH} 
#' @return a vector of all dates in \code{years} that are weekdays and not 
#' holidays. 
#' @author GSee 
#' @examples 
#' \dontrun{ 
#' TradingDates(2012) 
#' TradingDates(2010:2011) 
#' } 
#' @export 
TradingDates <- function(year=format(Sys.Date(), "%Y"), FUN=holidayNYSE) { 
    # the next few lines should be removed when this code is added to a package 
    # that Imports timeDate 
    if (!"package:timeDate" %in% search()) { 
    suppressPackageStartupMessages({ 
     if (!require(timeDate)) { 
     stop("timeDate must be installed to use this function.") 
     } 
    }) 
    on.exit(detach(package:timeDate, unload=TRUE)) 
    } 
    ## End of code that should be removed when this is added to a package 
    year <- as.numeric(year) 
    fun <- match.fun(FUN) 
    do.call('c', lapply(year, function(y) { 
    holidays <- as.Date(fun(year=y)) 
    all.days <- seq.Date(as.Date(paste(y, '01-01', sep='-')), 
         as.Date(paste(y, '12-31', sep='-')), by='days') 
    nohol <- all.days[!all.days %in% holidays] 
    nohol[!format(nohol, '%w') %in% c("6", "0")] #neither holiday nor weekend 
    })) 
} 


#' Get Date of previous (next) trading day 
#' 
#' Get the Date of the previous (next) trading day. 
#' 
#' For \code{PrevTradingDate}, \code{n} is the number of days to go back. So, 
#' if \code{n} is 2 and today is a a Monday, it would return the date of the 
#' prior Thursday because that would be 2 trading days ago. 
#' \code{n} works analogously in \code{NextTradingDate}. 
#' 
#' The maximum value that \code{n} can be is the total number of days in the 
#' year prior to \code{Date} plus the total number of years in the current 
#' year of \code{Date}. So, on the last day of the year, the max value of 
#' \code{n} will usually be \code{504} (because most years have 252 trading 
#' days). One the first day of the year, the max value of \code{n} will usually 
#' be \code{252}. 
#' 
#' @param n number of days to go back. 1 is the previous trading day; 2 is the 
#' trading day before that, etc. \code{n} should be less than 365, but see 
#' details 
#' @param Date a \code{Date} or something that can be coerced to a \code{Date} 
#' @return \code{PrevTradingDate} returns the date of the previous trading day 
#' up to, but not including, \code{Date}. \code{NextTradingDate} returns the 
#' date of the next trading day. 
#' @author GSee 
#' @seealso \code{\link{TradingDates}} 
#' @examples 
#' \dontrun{ 
#' PrevTradingDate() 
#' PrevTradingDate('2012-01-03') 
#' NextTradingDate() 
#' NextTradingDate('2012-12-24') 
#' } 
#' @export 
#' @rdname PrevTradingDate 
PrevTradingDate <- function(Date=Sys.Date(), n=1) { 
    stopifnot(require(xts)) #remove this line when this is added to a package that Imports xts (needed for first/last) 
    D <- as.Date(Date) 
    y <- as.numeric(format(D, "%Y")) 
    trading.days <- TradingDates(y) 
    out <- trading.days[trading.days < Date] 
    if (length(out) >= n) { 
    first(last(out, n)) 
    } else { 
    prev.year.td <- TradingDates(y - 1) 
    max.n <- length(out) + length(prev.year.td) 
    if (n > max.n) stop("'n' is too large. Try something less than 252.") 
    new.n <- n - length(out) # we need this many trading days from previous year 
    # if it's the 1st trading day of the year, return the last trading date of 
    # previous year 
    first(last(TradingDates(y - 1), new.n)) 
    } 
} 

#' @export 
#' @rdname PrevTradingDate 
NextTradingDate <- function(Date=Sys.Date(), n=1) { 
    stopifnot(require(xts)) #remove this line when this is added to a package that Imports xts (needed for first/last) 
    D <- as.Date(Date) 
    y <- as.numeric(format(D, "%Y")) 
    trading.days <- TradingDates(y) 
    out <- trading.days[trading.days > Date] 
    if (length(out) >= n) { 
    last(first(out, n)) 
    } else { 
    next.year.td <- TradingDates(y + 1) 
    max.n <- length(out) + length(next.year.td) 
    new.n <- n - length(out) # how many trading days we need from next year 
    if (n > max.n) stop("'n' is too large. Try something less than 252.") 
    # if it's the last trading day of the year, return the first trading date of 
    # next year 
    last(first(TradingDates(y + 1), new.n)) 
    } 
} 
0

由於交易只記錄天的時候市場是開放的:

TradeDates <- function() { 
    # KO is one of the oldest publicly traded companies 
    getSymbols("KO", from = as.Date("1973-01-02"), to = Sys.Date()) 
    TradeDays <- index(KO) 
    rm(KO) 
    TradeDates 
} 

TradingDays <- function(TradeDates, year = 2001, month = 5) { 
    Date2Month <- function(date) as.numeric(substring(as.Date(date),6,7)) 
    Date2Year <- function(date) as.numeric(substring(as.Date(date),1,4)) 
    TradeDates[which(Date2Month(TradeDates) == month & Date2Year(TradeDates) == year)] 
} 

TradingDays(TradeDates, year = 2001, month = 5) 

# [1] "2001-02-01" "2001-02-02" "2001-02-05" "2001-02-06" "2001-02-07" "2001-02-08" 
# [7] "2001-02-09" "2001-02-12" "2001-02-13" "2001-02-14" "2001-02-15" "2001-02-16" 
# [13] "2001-02-20" "2001-02-21" "2001-02-22" "2001-02-23" "2001-02-26" "2001-02-27" 
# [19] "2001-02-28"