заобикаляне за изтегляне на данни в R, като се вземат предвид договори за мини опции

Вкарвам вериги от опции с функция в quantmod, наречена getOptionsChain. Сега, когато има договори за мини опции, предлагани за акции като GOOG, AAPL и т.н., това създава грешка в моя код. Изтривам числата след символа и сега минидоговорите се прехвърлят през всички данни с GOOG7. Някакви идеи?

library(quantmod)
underlying <- 'GOOG'
# set what your volatility forcast or assumption is
volforcast <- .25
# Get symbols current price
yqf <- "Last Trade (Price Only)"
underlying.price <- getQuote(underlying,what=yahooQF(yqf))$Last

OC <- getOptionChain(underlying, NULL)
#check data
head(OC)
lputs <- lapply(OC, FUN = function(x) x$puts)
head(lputs) #check for NA values, yahoo returns all NA values sometimes
puts <- do.call('rbind', lputs )
#check data
head(puts,150)

symbols <- as.vector(unlist(lapply(lputs, rownames)))
expiries <- unlist(lapply(symbols, function(x) {
  regmatches(x=x, regexpr('[0-9]{6}', x)) } ))
puts$maturity <- as.numeric((as.Date(expiries, "%y%m%d") - Sys.Date())/365)
GetIV <- function(type, value,
              underlying, strike,dividendYield, riskFreeRate, maturity, volatility,
              timeSteps=150, gridPoints=151) {


  AmericanOptionImpliedVolatility(type, value,
                                  underlying, strike,dividendYield, riskFreeRate, maturity,  volatility, timeSteps=150, gridPoints=151)$impliedVol
}
#this is the part that throws the error due to NA values in puts$maturity
puts$IV <- mapply(GetIV, value = puts$Ask, strike = puts$Strike, maturity = puts$maturity,
                  MoreArgs= list(type='put', underlying= underlying.price,
                  dividendYield=0, riskFreeRate = 0.01,  
                  volatility = volforcast), SIMPLIFY=TRUE)
#this is the error Error: Date's serial number (-2147442285) outside allowed range [367-109574],      i.e. [January 1st, 1901-December 31st, 2199]

Искам да избегна добавянето на редовете, където puts$maturity е NA.


person cdcaveman    schedule 30.03.2013    source източник
comment
трябва поне да ни покажеш каква е грешката. Съобщение за грешка? Грешен отговор? Компютърът се запалва?   -  person Spacedman    schedule 30.03.2013
comment
Тъй като знаете годината и месеца на изтичане от names(OC), можете да промените регулярния израз [0-9]{6}, който е твърде общ, на нещо по-прецизно, като например 1304[0-9]{2}.   -  person Vincent Zoonekynd    schedule 30.03.2013
comment
1304 първи? ако поставите опашка (puts,10), ще видите GOOG150117P01260000, което изтича на 17 януари 2015 г.. не разбирам reg израза, който сте посочили .. но мисля, че приемате, че 1304 е постоянен.. това са годината и денят .. това е GOOG7130420P00780000 с GOOG7, представляващ минидоговорите с GOOG7, който хвърля Na   -  person cdcaveman    schedule 30.03.2013


Отговори (2)


За кратък филтър, който премахва „GOOG7“ или всеки основен защитен символ, последван от „7“, опитайте следното:

symbols <- grep(paste("^",underlying,"[0-6,8-9]", sep="", collapse = NULL), 
                symbols, value = TRUE)
person Erastotle    schedule 30.03.2013
comment
Може също така да потърси GOOG7 и invert, за да запази само тези, които не са GOOG7: grep(paste("^", underlying, "7", sep=""), symbols, value=TRUE, invert=TRUE). Този код трябва да работи, докато не бъдат изброени опции, изтичащи през 2070 г. - person GSee; 30.03.2013
comment
Друг начин да получите всичко, което няма 7 след тикера: grep(paste("^",underlying,"[^7]", sep=""), symbols, value = TRUE). Вътре в скоби ([]), ^ означава не - person GSee; 30.03.2013

Искате само редове, където puts$maturity не е NA? Това би постигнало тази цел:

puts <- puts[!is.na(puts$maturity), ]

Другата опция, като @VincentZoonekynd предложено е да се използва по-добър регулярен израз.

Например, това търси символи, които започват с главни букви, последвани от 6 цифри, последвани от "C" или "P", последвани от 8 цифри и нищо друго. Няма да улавя символи, които имат 7 цифри след тикера.

symbols <- c("GOOG7130420P00695000", "GOOG130426P00720000")
grep("^[A-Z]+\\d{6}[CP]\\d{8}$", symbols, value=TRUE)
#[1] "GOOG130426P00720000"

^[A-Z]+: започва с (^) която и да е главна буква ([A-Z]), един или повече пъти (+)
\\d{6} : последвано от 6 ({6}) цифри (\\d)
[CP] : последвано от буквата "C" или "P"
\\d{8}$: завършващ с 8 ({8}) цифри (\\d) без нищо след тях ($)


Според желанията в коментарите, ето един начин да премахнете редовете, които не искате, преди да направите нещо друго. Той просто пресъздава обекта само с нещата, които ви интересуват.

OC <- lapply(OC, function(x) {
  list(calls=x$calls[grep("[A-Z]\\d{6}[CP]\\d{8}$", rownames(x$calls)), ],  
       puts=x$puts[grep("[A-Z]\\d{6}[CP]\\d{8}$", rownames(x$puts)), ],
       symbol=x$symbol)
})
person GSee    schedule 30.03.2013
comment
въпреки че това е добре.. има други зависимости в кода, които го карат да се счупи все още.. в идеалния случай списъкът „OC“ трябва да има поднабор на GOOG7.. - person cdcaveman; 30.03.2013
comment
Съжалявам, @cdcaveman, мислех, че е ясно. Опитайте това lputs <- lapply(OC, FUN = function(x) x$puts[grep("[A-Z]\\d{6}[CP]\\d{8}$", rownames(x$puts)), ]). Ако това не работи, ще проработя вашия код и ще актуализирам отговора. - person GSee; 30.03.2013
comment
наистина смятам, че е най-добре да подмножа данните в променливата „OC“ веднага.. това е списък от списъци.. не съм сигурен как да направя това.. сигурен съм, че мога да приложа този grep като аргумент към някаква функция, която връща променените списъци - person cdcaveman; 30.03.2013
comment
интересно.. разбрах, че работи с lputs <- lapply(OC, FUN = function(x) x$puts[grep("[A-Z]\\d{6}[CP]\\d{8}$", rownames(x$puts)), ]) - person cdcaveman; 31.03.2013