一旦我在Quantstrat R

时间:2019-06-16 04:52:51

标签: r quantmod quantstrat

我正在研究基本的RSI交易信号。当股价低于20 RSI时购买100股股票,而当股价高于80 RSI时关闭头寸。

发生的事情是,一旦股价跌至20以下,我便买入100股,如果股价再次跌破20而又没有先达到80 RSI,我最终又买入100股(共200股)。

一旦我有职位,我就不想添加。谢谢。

rm.strat(portfolio.st)
rm.strat(strategy.st)
rm.strat(account.st)

#setup
Sys.setenv(TZ = "UTC")
stock.str = "AAPL"
currency('USD')
stock("AAPL", currency= "USD", multiplier = 1)

initDate = "2010-01-01"
startDate = "2011-01-01"
to = Sys.Date()
initEq = 100000

portfolio.st = account.st = strategy.st = 'rsi'

getSymbols("AAPL", from = initDate)

initPortf(portfolio.st, symbols = stock.str,
          initDate = initDate)
initAcct(account.st,
         portfolio.st,
         initDate = initDate, initEq = initEq)
initOrders(portfolio.st, initDate = initDate)
strategy(strategy.st, store = T)

add.indicator(strategy.st, 
              name = "RSI",
              arguments = list(
                    price = quote(Cl(mktdata)),
                    n = 14,
                    maType = "EMA"
              ),
              label = "rsi14")
add.signal(strategy.st,
           name = "sigThreshold",
           arguments = list(
                 column = "rsi14",
                 threshold = 20,
                 cross = T,
                 relationship = "lt"

           ),
           label = "crossBelow")
add.signal(strategy.st,
           name = "sigThreshold",
           arguments = list(
                 column = "rsi14",
                 threshold = 80,
                 cross = T,
                 relationship = "gt"
           ),
           label = "crossAbove")

add.rule(strategy.st,
         name = "ruleSignal",
         arguments = list(
               sigcol = "crossBelow",
               sigval = T,
               orderqty = 100,
               ordertype = "market",
               orderside = "long"

         ),
         type = "enter",
         label = "enter")
add.rule(strategy.st,
         name = "ruleSignal",
         arguments = list(
               sigcol = "crossAbove",
               sigval = T, 
               orderqty = "all",
               ordertype = "market",
               orderside = "long"),
         type = "exit",
         label = "exit"
         )
out = applyStrategy(strategy.st,
                    portfolio.st)

1 个答案:

答案 0 :(得分:1)

您可以做的一件事是考虑编写您自己的订单调整功能。将此作为参数add.rule传递到osFUN中的quanstrat。

类似这样的东西:

my_sizing_fun <- function(data, timestamp, symbol, portfolio, ...) {


    equity <- getEndEq(strategy.st, Date = timestamp) 

    # Get current Position and return 0 if we already have a position
    pos <- getPosQty(portfolio, symbol, timestamp) 
    if(pos != 0) {
      return(0)
    } else {

    return(100)
    }

如果已有职位,它将返回0,否则返回100。您可以在订单大小调整功能内做一些非常复杂的事情,以帮助增强策略。

现在,只需在osFUN=my_sizing_fun内添加add.rule作为自变量,然后删除orderqty,就应该一切就绪。

当您开始尝试做空或处理您当前的资产价值时,以下是一个有用的示例:

### Order Size Function ### 
## Calculates Order Size as a percent risk of account equity - currently does not account for multiple symbols or a max trade size like we may implement in real life
## Takes in arguments passed from 'RuleSignal'
## riskPct is the percentage of account equity to risk per trade
## Returns the order quantity as a numeric value
## to do - round order qty to lot sizes
osATR <- function(data, orderside, timestamp, symbol, portfolio, riskPct, ...) {

  # Update Accounts and get the Ending Equity
  updatePortf(strategy.st)
  updateAcct(strategy.st)
  updateEndEq(strategy.st)

  equity <- getEndEq(strategy.st, Date = timestamp) 

  # Get current Position and return 0 if we already have a position
  pos <- getPosQty(portfolio, symbol, timestamp) 
  if(pos != 0) {
    return(0)
  }


  # Calculate Order Quantity
  qty <- # Add your logic here
  qty <-  as.numeric(trunc(qty)) # return a numeric and round the qty

  # Long / Short Check & Set
  if(orderside == "short") {
    qty <- -qty
  } 

  # Make sure not to end up with net positions on the wrong side
  if (orderside == 'long' && qty < 0 | orderside == 'short' && qty > 0) {
    stop("orderqty is of the wrong sign")
  }

  return(qty)
}