2015-08-13 5 views
1
stratMACROSS <- add.indicator(strategy = stratMACROSS, name = "SMA", 
           arguments = list(x=quote(Cl(mktdata)), n=50), 
           label= "ma50") 

stratMACROSS <- add.indicator(strategy = stratMACROSS, name = "SMA", 
           arguments = list(x=quote(Cl(mktdata)[,1]), n=200), 
           label= "ma200") 

stratMACROSS <- add.signal(strategy = stratMACROSS, name="sigCrossover", 
          arguments = list(columns=c("ma50","ma200"), 
              relationship="gte"), 
          label="ma50.gt.ma200") 

stratMACROSS <- add.signal(strategy = stratMACROSS, name="sigCrossover",  
          arguments = list(column=c("ma50","ma200"), 
              relationship="lt"), 
          label="ma50.lt.ma200") 

stratMACROSS <- add.rule(strategy = stratMACROSS, name='ruleSignal', 
         arguments = list(sigcol="ma50.gt.ma200", sigval=TRUE, 
              orderqty=100, ordertype='market', 
              orderside='long'), 
         type='enter') 

stratMACROSS <- add.rule(strategy = stratMACROSS, name='ruleSignal', 
         arguments = list(sigcol="ma50.lt.ma200", sigval=TRUE, 
              orderqty='all', ordertype='market', 
              orderside='long'), 
         type='exit') 

Приведенный выше объем покупки при перемещении среднего (MV) 50 крестов выше MV200 и продается, когда MV50 пересекает ниже MV200. В этом коде я хотел бы добавить еще два условия:Как добавить несколько условий в квант?

Buy 
(MV 50 Crosses above MV200) and (close price is above MV50 and MV200) 

Sell 
(MV 200 Crosses above MV50) and (close price is below MV50 and MV200) 

Как это сделать?

ответ

0

Возможно, вы можете изучить сигналы и посмотреть, можете ли вы их комбинировать. Таким образом, я хотел бы создать сигнал, когда цена закрытия выше maV50 & MV200 и маркировать этот сигнал как clgtmv50mv200 и другого сигнал mv50.gt.ma200

compt.str <- 'clgtmv50mv200 == 1 & mv50.gt.ma200 == 1' 

тогда я передам, что в формуле часть add.signal function with cross = True и обозначить это как ваш новый сигнал

0

Я написал улучшенную функцию сравнения на основе sigComparison. Это не красиво, также я не тестировал функцию смещения. Протестировано - это спецификация сравнений 'и', 'или', 'xor', и с помощью сравнения первого и второго уровня можно использовать до четырех столбцов для получения столбца результата True/False.

#'sigCOMP 
#'@description signal comparison operators incl and, or, xor for quantstrat signals. 
#'@param label name of the output signal 
#'@param data the market data 
#'@param columns the signal columns to intersect, if a second level comparison is used, the comparison result must reside in the first column only (compare one 2nd level with a True/False Column) or in both, marked by Keyword '2nd' 
#'@param relationship operators gte, gt, lte, lt, eq, and, or, xor TODO:NOT 
#'@param secondComparison vector of columns to intersect, if yes, then also set the relationship comparison 
#'@param relationshipSecondComparison operators gte, gt, lte, lt, eq 
#'@param offset1 optional 
#'@param offset2 optional 
#'@return a new signal column that intersects the provided columns 
#'@export 


sigCOMP <- function (label, data = mktdata, columns, relationship = c("gte", "gt", "lte", "lt", "eq", "and", "or", "xor"), relationshipSecondComparison = c("gte", "gt", "lte", "lt", "eq"), secondComparison, res_not, offset1 = 0, offset2 = 0) 
{ 
    ret_sig = NULL 
    compcols <- NULL 

    if(!missing(columns)){ 
    if (relationship == "op") { 
     if (columns[1] %in% c("Close", "Cl", "close")) 
     stop("Close not supported with relationship=='op'") 
     switch(columns[1], Low = , low = , bid = { 
     relationship = "lt" 
     }, Hi = , High = , high = , ask = { 
     relationship = "gt" 
     }) 
    } #whatever that is 

    colNums <- NULL 
    for(sec in 1:length(columns)){ 
     if (columns[sec]=='2nd'){ 
     colNums <- c(colNums,0) 
     } 
     else{ 
     colNums <- c(colNums, match.names(columns[sec], colnames(data))) 
     } 
    } 

    opr <- switch(relationship[1], 
        gt = , `>` = ">", 
        gte = , gteq = , ge = , `>=` = ">=", 
        lt = , `<` = "<", 
        lte = , lteq = , le = , `<=` = "<=", 
        eq = , `==` = , `=` = "==", 
        and = "&", 
        or = "|", 
        xor = "xor" 
        # todo: NOT 
    ) 

    } #perform preparation actions if 1|2 columns exist or else stop 
    else { 

     stop("only works if two comparison columns are provided. for true/false evaluations you can add e.g. 2nd 2nd or <Signal>, 2nd ") 


    } 


    if (!missing(secondComparison)) 
    { 
     ret_sig2nd <- NULL 
     opr2nd <- c(1:length(secondComparison)) 

     if (length(secondComparison) != length(relationshipSecondComparison)){ 
      stop("make sure to have a comparison operator for each second level comparison you would like to perform") 
     } 
     else { 

      for (j in 1:length(relationshipSecondComparison)) { 
       # run through pairs of columns and relationship checks and return these in a dataframe ret_sig2nd 
       # the return column of the appropriate pair will have the name col1 op col2 e.g. close gt nFast 

       colNums2nd <- c(0,0) 
       comp2ndPartners <- unlist(secondComparison[j]) 
       relationship2 <- unlist(relationshipSecondComparison)[j] 
       colNums2nd[1] <- match.names(comp2ndPartners[1], colnames(data)) 
       colNums2nd[2] <- match.names(comp2ndPartners[2], colnames(data)) 
       opr2nd[j] <- switch(relationship2, 
            gt = , `>` = ">", 
            gte = , gteq = , ge = , `>=` = ">=", 
            lt = , `<` = "<", 
            lte = , lteq = , le = , `<=` = "<=", 
            eq = , `==` = , `=` = "==", 
            and = "&", 
            or = "|", 
            xor = "xor" 
            # todo: NOT 
      ) 
       ret_append <- do.call(opr2nd[j], list(data[, colNums2nd[1]] + offset1, 
              data[, colNums2nd[2]] + offset2)) 

       colnames(ret_append) <- paste0(comp2ndPartners[1]," ",relationship2[j]," ",comp2ndPartners[2]) 
       ret_sig2nd <- cbind(ret_sig2nd,ret_append) 
       rm(ret_append) 
      } 

      compcols <- ret_sig2nd 
     } # end of 2nd Comp = 2nd Relationship validity block 

     if(ncol(compcols)==1){ # check the case if only one second level comparison exists 
     transfer2ndToFirst <- compcols #assumption is, the second level comparison took place with the first column of the first level 
     # if one second level comparison is provided, execute transfer object with second column of first level 
     compcols <- transfer2ndToFirst[, 1] #offset already included in second level comparison 
     compcols <- cbind(compcols, data[, colNums[2]] + offset2) 

     } # provide the transfer object to be used in the first level comparison if only one second level comparison exists 
    } 
    else { # check the case if no second level comparison exists 

     # if no second level comparison is provided, only execute first level 
     compcols <- data[, colNums[1]] + offset1 
     compcols <- cbind(compcols, data[, colNums[2]] + offset2) 
    } # if no second level exists, execute comparison for first level only 

    # for all cases, perform the first level comparison with the columns stored in compcols - offset has to be applied before storing to compcols 
    ret_sig <- do.call(opr, list(compcols[, 1] , 
           compcols[, 2])) 

    colnames(ret_sig) <- label 
    return(ret_sig) 
} 

# ### TESTS 
# # To compare just two (first level) colums 
# rm(testOnlyFirst) 
# testOnlyFirst<- sigCOMP(
# columns=c("nSlow","nFast"), 
# relationship=c("gt"), 
# label='GT' 
#) 
# 
# 
# #To compare a signal or another T/F value with a second level comparison 
# rm(testOneSecond) 
# testOneSecond<- sigCOMP(
# columns=c("2nd","exitLong"), 
# relationship=c("and"), 
# secondComparison =list(c("Close", "nFast")), 
# relationshipSecondComparison = list(c("gt")), 
# label='andGT' 
#) 
# 
# 
# rm(test2Second) 
# test2Second<- sigCOMP(
# columns=c("2nd", "2nd"), 
# relationship=c("or"), 
# secondComparison =list(c("Close", "nFast"), c("Close", "nSlow")), 
# relationshipSecondComparison = list(c("gt"), c("gt")), 
# label='orGT' 
#) 
# 
# rm(test2SecondOr) 
# test2SecondOr<- sigCOMP(
# columns=c("2nd", "2nd"), 
# relationship=c("or"), 
# secondComparison =list(c("Close", "nFast"), c("Close", "nSlow")), 
# relationshipSecondComparison = list(c("gt"), c("gt")), 
# label='orGT' 
#) 
# 
# rm(test2SecondXor) 
# test2SecondXor<- sigCOMP(
# columns=c("2nd", "2nd"), 
# relationship=c("xor"), 
# secondComparison =list(c("Close", "nFast"), c("Close", "nSlow")), 
# relationshipSecondComparison = list(c("gt"), c("gt")), 
# label='orGT' 
#) 
+0

Чтобы тесты работают правильно, убедитесь, чтобы иметь mktdata dataframe в вашей среде, включая индикатор столбцов из SMA (т.е. nFast, nSlow) и сигнальной колонки «exitLong», например, от RSI или адаптировать тестовые окна к именам столбцов. – til