2012-08-18 2 views
2

Я позволил сказать XTS объект (данные) со следующими значениями ...Применить функцию к XTS объекта

  SPY.Adjusted  SMA 
2012-08-02  136.64 137.115 
2012-08-03  139.35 137.995 
2012-08-06  139.62 139.485 
2012-08-07  140.32 139.970 
2012-08-08  140.49 140.405 
2012-08-09  140.61 140.550 
2012-08-10  140.84 140.725 

Я пытаюсь использовать применить функцию, чтобы добавить к нему сигналы, если соблюдены некоторые условия ... в этом случае, когда close> SMA. Моя функция:

signal<-function(x,y,z) 
    { 
    z$signals<-ifelse(x>y,1,0) 
    } 

и я стараюсь ...

apply(data,1,FUN=signal(data$SPY.Adjusted,data$SMA,data)) 

с возвращаемой ошибки:

Error in match.fun(FUN) : 'signal(data$SPY.Adjusted, data$SMA, data)' 
    is not a function, character or symbol 

Что, возможно, пойдет не так? Я передал ему функцию, которая доходит до переданных им данных, чтобы создать новый столбец, если выполнено определенное условие.

ответ

4

Когда вы назовете это применимым с помощью MARGIN=1, это как передача каждой строки до FUN. Ваша функция уже векторизована, поэтому вам не нужно использовать apply. Однако ваша функция ничего не возвращает. Попробуйте это:

library(quantmod) 
getSymbols("SPY", src='yahoo', from='2010-01-01', to='2012-01-01') 
dat <- cbind(Ad(SPY), SMA=SMA(Ad(SPY))) 
signal<-function(x,y,z) 
{ 
    z$signals<-ifelse(x>y,1,0) 
    z 
} 

tail(signal(dat[, 1], dat[, 2], dat)) 
#   SPY.Adjusted  SMA signals 
#2011-12-22  124.08 121.693  1 
#2011-12-23  125.19 121.805  1 
#2011-12-27  125.29 122.108  1 
#2011-12-28  123.64 122.361  1 
#2011-12-29  124.92 122.871  1 
#2011-12-30  124.31 123.276  1 

На самом деле, я стараюсь избегать ifelse в подобных ситуациях, потому что это медленнее, чем делать это

signal<-function(x,y,z) 
{ 
    z$signals <- 0 
    z$signals[x > y] <- 1 
    z 
} 
+0

спасибо так много. – user1234440

2

@answer адреса GSEE в ваш фактический вопрос, но я считаю, что это будет намного более прямой:

dat$signal = (dat[,1] > dat[,2]) + 0 

часть (dat[,1] > dat[,2]) создает вектор TRUE и FALSE, который, когда вы добавляете к нему «0», преобразует его в 0 для FALSE и 1 для TRUE.

(dat, в этом примере, является таким же, как @ GSEE-х dat.)

Конечно, вы можете использовать это, чтобы также соответствовать более чем одно условие:

set.seed(1) 
dat$SAMPLE = sample(as.vector(c(dat$SPY.Adjusted, dat$SMA)), nrow(dat)) 
dat$signal = (dat$SPY.Adjusted > dat$SMA & dat$SPY.Adjusted > dat$SAMPLE) + 0 
tail(dat, 15) 
#   SPY.Adjusted  SMA SAMPLE signal 
# 2011-12-09  124.07 122.421 125.990  0 
# 2011-12-12  122.26 122.864 124.260  0 
# 2011-12-13  121.11 123.159 128.350  0 
# 2011-12-14  119.82 122.839 114.966  0 
# 2011-12-15  120.26 122.565 128.490  0 
# 2011-12-16  120.44 122.320 126.486  0 
# 2011-12-19  119.15 121.812 128.598  0 
# 2011-12-20  122.75 121.660 127.605  0 
# 2011-12-21  122.99 121.485 119.150  1 
# 2011-12-22  124.08 121.693 116.030  1 
# 2011-12-23  125.19 121.805 104.870  1 
# 2011-12-27  125.29 122.108 116.460  1 
# 2011-12-28  123.64 122.361 126.127  0 
# 2011-12-29  124.92 122.871 119.750  1 
# 2011-12-30  124.31 123.276 104.110  1 
+0

Могу ли я установить несколько условностей в фигурные скобки? например, если у меня есть два индикатора, которые мне понадобятся ... dat $ signal = (a> b и a> c) + 0 – user1234440

+0

@Tom, см. мой обновленный ответ. – A5C1D2H2I1M1N2O1R2T1

Смежные вопросы