Прекратите добавлять больше позиций, как только у меня будет позиция в Quantstrat R - PullRequest
0 голосов
/ 16 июня 2019

Я работаю над базовым торговым сигналом RSI. Купите 100 акций, когда акции опустятся ниже 20 RSI, и закройте позицию, когда акции поднимутся выше 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 Ответ

1 голос
/ 21 июня 2019

Одна вещь, которую вы можете сделать, - это написать собственную функцию определения размера заказа. Это передается в quanstrat в add.rule в качестве параметра - 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)
    }

Возвращает 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)
}
...