量子化中的每月重新平衡

时间:2015-06-11 09:21:22

标签: r quantstrat

(我知道这是一个冗长而混乱的问题,但我真的希望有人可以帮助我,因为我已经在这个假设很简单的东西上工作了大约两个星期......)

两个问题

1)在quantstrat中,我找到了可用于重新平衡投资组合的函数 rulePctEquity 。当我读到这个函数里面的代码时,我发现这个函数主要是关于一个新的 addPosLimit 。我是否知道理解 add.rule(qs.strategy,'rulePctEquity',...)作为设置检查其他规则的频率以及进入的最大位置的工具是否正确?换句话说,如果它是战略中的唯一规则,是否意味着不会进行交易?

2)在显示我的代码之前,我的测试策略摘要如下。在每个月的开始,投资组合将卖出它拥有的所有股票,并在那时买入前三个(排名)选定的股票。等重用于测试。

但是,我的测试结果与我认为它应该显示的非常不同。为了节省时间,我认为问题来自第4节。指示买入,卖空,卖出和买入的功能

library(quantstrat)
library(lattice)
quotes.file <- "testfile.csv"  #Need editing

quotes.file2 <- "testfile2.csv"  #Need editing

    #
    # 1. Instrument: read csv file into xts object
    #
    code  <- read.csv(quotes.file2,head=TRUE)
    data2 <- read.csv(quotes.file, head=TRUE)
    code=apply(code,1,"toString")
    matsplitter<-function(M, r, c) {
        rg <- (row(M)-1)%/%r+1
        cg <- (col(M)-1)%/%c+1
        rci <- (rg-1)*max(cg) + cg
        N <- prod(dim(M))/r/c
        cv <- unlist(lapply(1:N, function(x) M[rci==x]))
        dim(cv)<-c(r,c,N)
        cv
    } 

    data=matsplitter(data2[,-1],nrow(data2),4)
    colnames(data)=c("close","pe","pe_avg","pe_sd")
    dates <- as.Date(data2$Date,"%d/%m/%Y")
    C=list()
    i=1
    for (i in 1:(dim(data)[3])){
        C[[i]] <- xts(x=data[,,i], order.by=dates)
    }


    #
    # 2. Support Functions
    #
    osFixedDollar <- function(timestamp,orderqty, portfolio, symbol, ruletype, ...)
    {
      ClosePrice <- as.numeric((mktdata[timestamp,"close"]))
      orderqty <- round(tradeSize/ClosePrice,-2)
      return(orderqty)
    }


    pause <- function() {
      cat ("Press [enter] to continue")
      line <- readline()
    }

    Zscore <- function(x0,y0,z0) {
      x <- as.numeric(x0)
      y <- as.numeric(y0)
      z <- as.numeric(z0)
      res <- (x-y)/z
      res
    }

    for (i in 1:(dim(data)[3])){
        C[[i]]$Zscore <-Zscore(C[[i]]$pe,C[[i]]$pe_avg,C[[i]]$pe_sd)
    }

    for (j in  1:(nrow(data))){
        temp=0
        for (i in 1:(dim(data)[3])){    
            temp=c(temp,C[[i]][j,"Zscore"])
        }
        temp=temp[-1]
        temp=as.numeric(temp)
        temp2=rank(temp)
        for (i in 1:(dim(data)[3])){
            C[[i]]$ranking[j]=temp2[i]
        }   
    }

    for (i in 1:(dim(data)[3])){
        assign(code[i],C[[i]])
    }

    #
    # 3. Initializations
    #

    # Currency:
    currency("HKD")

    # Instrument:
    big.point.value <- 1
    for (i in 1:(dim(data)[3])){
        stock(code[i], currency="HKD", multiplier=big.point.value)
    }

    # Strategy, portfolio and account names:
    qs.strategy <- "PE.on.HKex"
    qs.portfolio <- "Equities"
    qs.account <- "My.account"

    # Remove previous strategy, portfolio and account:
    suppressWarnings(rm(list = c(paste("account", qs.account, sep='.'), paste("portfolio", qs.portfolio, sep='.')), pos=.blotter))
    suppressWarnings(rm(list = c(qs.strategy, paste("order_book", qs.portfolio, sep='.')), pos=.strategy))
    rm.strat(qs.strategy) # remove strategy etc. if this is a re-run

    # Portfolio:
    initDate <- '2015-01-01'
    initPortf(qs.portfolio, code, initDate=initDate, currency='HKD')

    # Account:
    initEq <- 100000
    initAcct(qs.account, portfolios=qs.portfolio, initDate=initDate, currency='HKD', initEq=initEq)

    # Orders:
    initOrders(portfolio=qs.portfolio, initDate=initDate)

    # Strategy:
    strategy(qs.strategy, store=TRUE)

    #
    # 4. Functions indicating buy, sell short, sell and buy to cover
    #

    nb.bars.with.no.trade <- 0
    topchoice=3

    buy.function <- function(x) {
      N <- nrow(x) 
      buy.signals <- numeric(N)
      # buy.signals[1:nb.bars.with.no.trade]<- 0
      for (i in (nb.bars.with.no.trade+1):N) {
        if ( (x[i]<=topchoice)
             && (index(x)[i] < index(get(code[1]))[nrow(data)]) # trick to avoid an open trade at the end
             ) {
          buy.signals[i] <- 1
        } else {
          buy.signals[i] <- 0
        }
      }

      xts(x=buy.signals, order.by=index(x))
    }

    sell.function <- function(x) {
      N <- nrow(x)
      sell.signals <- numeric(N)
      #sell.signals[1:nb.bars.with.no.trade]<- 0
      for (i in (nb.bars.with.no.trade+1):N) {
        #if ( (x[i]<=topchoice) && (index(x)[i] < index(get(code[1]))[nrow(data)])){
        #   sell.signals[i] <- 0}
        #else{ 
        sell.signals[i] <-1
        #}
      }

      xts(x=sell.signals, order.by=index(x))
    }


    #
    # 5. Indicators for buy, sell short, sell and buy to cover
    #

    add.indicator(strategy = qs.strategy,
                  name = "buy.function",
                  arguments = list(x = quote(mktdata[,"ranking"])),
                  label="Buy")

    add.indicator(strategy = qs.strategy,
                  name = "sell.function",
                  arguments = list(x = quote(mktdata[,"ranking"])),
                  label="Sell")

    #
    # 6. Signals for buy, sell short, sell and buy to cover
    #

    add.signal(qs.strategy,
               name="sigFormula",
               arguments = list(formula="X1.Buy == 1"),
               label="Buy",
               cross=FALSE)

    add.signal(qs.strategy,
               name="sigFormula",
               arguments = list(formula="X1.Sell == 1"),
               label="Sell",
               cross=FALSE)

    # 
    # 7. Rules for buy, sell short, sell and buy to cover
    # 

    nb.contracts <- 2
    round.trip.commission.for.one.contract <- 6
    round.trip.commission.for.total.contracts <- round.trip.commission.for.one.contract * nb.contracts

    add.rule(qs.strategy, 'rulePctEquity',
            arguments=list(rebalance_on='months',
                           trade.percent=1/topchoice,
                           refprice=quote(last(mktdata[,"price"][paste('::',curIndex,sep='')])),
                           digits=0
            ),
            type='rebalance',
            label='rebalance')

    add.rule(qs.strategy,
             name='ruleSignal',
             arguments = list(sigcol="Sell", 
                              sigval=TRUE,
                              orderqty='all',
                              ordertype='market',
                              orderside='long',
                              pricemethod='market',
                              replace=FALSE,TxnFees=-0),
             type='exit',
             label="LongExit")

    add.rule(qs.strategy,
             name='ruleSignal',
             arguments = list(sigcol="Buy",
                              sigval=TRUE,
                              orderqty=1000000000,
                              ordertype='market',
                              orderside='long',
                              replace=FALSE,pricemethod='market',TxnFees=-0,osFUN='osMaxPos'),     
             type='enter',
             label="LongEntry")





    posval<-initEq/topchoice
    for(symbol in code){
        pos<-round((posval/first(get(symbol)[,1])[,1]),0)
        addPosLimit(qs.portfolio,symbol,initDate, maxpos=pos,minpos=-pos)
    }




    #
    # 8. Apply Strategy to Porfolio
    #
    tradeSize <- initEq/topchoice




    applyStrategy.rebalancing(strategy = qs.strategy,
                  portfolios = qs.portfolio)

    updatePortf(qs.portfolio, Symbols=code, Dates=paste('::',as.Date(Sys.time()),sep=''))
    updateAcct(qs.account)
    updateEndEq(qs.account)

[1] "2015-01-02 00:00:00 HK3 3052 @ 10.92020872"
[1] "2015-01-02 00:00:00 HK3 -3052 @ 10.92020872"
[1] "2015-01-02 00:00:00 HK6 1325 @ 25.16659456"
[1] "2015-01-02 00:00:00 HK6 -1325 @ 25.16659456"
[1] "2015-01-02 00:00:00 HK7 1189 @ 28.02736734"
[1] "2015-01-02 00:00:00 HK7 -1189 @ 28.02736734"
[1] "2015-02-01 00:00:00 HK3 33000 @ 11.05592774"
[1] "2015-02-01 00:00:00 HK3 -33000 @ 11.05592774"
[1] "2015-02-01 00:00:00 HK4 33000 @ 16.49518325"
[1] "2015-02-01 00:00:00 HK6 33000 @ 26.05446399"
[1] "2015-02-01 00:00:00 HK6 -33000 @ 26.05446399"
[1] "2015-03-01 00:00:00 HK3 33000 @ 11.90615998"
[1] "2015-03-01 00:00:00 HK3 -33000 @ 11.90615998"
[1] "2015-03-01 00:00:00 HK4 -33000 @ 16.04816942"
[1] "2015-03-01 00:00:00 HK4 33000 @ 16.04816942"
[1] "2015-03-01 00:00:00 HK6 33000 @ 22.68828416"
[1] "2015-03-01 00:00:00 HK6 -33000 @ 22.68828416"
[1] "2015-04-01 00:00:00 HK4 -33000 @ 16.54012275"
[1] "2015-04-01 00:00:00 HK4 -4868 @ 16.54012275"
[1] "2015-04-01 00:00:00 HK4 4868 @ 16.54012275"
[1] "2015-04-01 00:00:00 HK4 23264 @ 16.54012275"
[1] "2015-04-01 00:00:00 HK6 28132 @ 22.04928995"
[1] "2015-04-01 00:00:00 HK6 -28132 @ 22.04928995"
[1] "2015-04-01 00:00:00 HK8 28132 @ 31.03327848"
[1] "2015-05-01 00:00:00 HK4 -23264 @ 14.2995661"
[1] "2015-05-01 00:00:00 HK4 10225 @ 14.2995661"
[1] "2015-05-01 00:00:00 HK4 -10225 @ 14.2995661"
[1] "2015-05-01 00:00:00 HK4 23264 @ 14.2995661"
[1] "2015-05-01 00:00:00 HK6 33489 @ 24.21335116"
[1] "2015-05-01 00:00:00 HK6 -33489 @ 24.21335116"
[1] "2015-05-01 00:00:00 HK8 -28132 @ 32.12345799"
[1] "2015-05-01 00:00:00 HK8 5357 @ 32.12345799"
[1] "2015-05-01 00:00:00 HK8 -5357 @ 32.12345799"
[1] "2015-05-01 00:00:00 HK8 28132 @ 32.12345799"

两个问题:

1)在开始购买之前,如何让投资组合出售所有持股? (投资组合正在做相反的事情)

2)我不明白为什么数量在第二个月或第二个月好的时候变得如此之大。

(3052 * 10.92 + 1325 * 25.03 + 1189 * 28.03 =〜100000 = InitEq

0 个答案:

没有答案
相关问题