一旦我在 Quantstrat R 中建仓,就停止添加更多仓位

Jor*_*ong 1 r quantmod quantstrat

我正在研究基本 RSI 交易信号。当股票低于 20 RSI 时买入 100 股,当股票高于 80 RSI 时平仓。

发生的情况是,一旦股票跌破 20,我就买入 100 股,如果股票再次跌破 20,而 RSI 没有首先达到 80,我最终会再买入 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)
Run Code Online (Sandbox Code Playgroud)

Jar*_*rks 5

您可以做的一件事是考虑编写自己的订单大小函数。add.rule这将作为参数 -传递给 quastrat in osFUN

像这样的东西:

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)
    }
Run Code Online (Sandbox Code Playgroud)

如果您已经有仓位,则返回 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)
}
Run Code Online (Sandbox Code Playgroud)