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

Stop Adding More Positions Once I have A Position On In Quantstrat R

我正在研究基本的 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)

您可以做的一件事是考虑编写您自己的订单大小函数。这将作为参数传递给 add.rule 中的 quanstrat - 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)
    }

这将 return 如果您已经有职位,则为 0,否则为 100。您可以在定单大小函数中做一些非常复杂的事情来帮助增强您的策略。

现在只需在 add.rule 中添加 osFUN=my_sizing_fun 作为参数并删除 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)
}