Position calibration

I currently have my backtest installed so that it invests 25% of my current capital. The problem is that when my capital starts to grow, the strategy begins to take huge deals.

How can I tell him to invest Equiuty * 0.25, but only to the limit, for example, 1000 contracts?

Below are the relevant parts of my code.

Thanks for any help. This has been frustrating me for several weeks now.

osInvestAll <- function (data, timestamp, orderqty, ordertype, orderside, equity, portfolio, symbol, ruletype, ..., orderprice, MaxPosn) { datePos <- format(timestamp,"%Y-%m-%d") updatePortf(Portfolio=portfolio,Symbol=symbol,Dates=datePos) updateAcct(portfolio,Dates=datePos) updateEndEq(portfolio,Dates=datePos) Posn <- getPosQty(portfolio,Symbol=symbol,Date=datePos) equity <- getEndEq(portfolio,datePos) ClosePrice <- getPrice(get(symbol))[datePos] UnitSize <- as.numeric(trunc(0.25*equity/ClosePrice)) osMaxPos <-function(data, timestamp, orderqty, ordertype, orderside, portfolio, symbol, ruletype, ...) addPosLimit(portfolio = portfolioname,symbol = symbollist,maxpos = 100, minpos = -100,timestamp = as.POSIXct(init.date)) if (Posn == 0) { osInvestAll <- UnitSize } else {osInvestAll <- 0 } 

This is how I have my rule at the moment, but I get the error "unitize not found"

 add.rule(strategyname,name='ruleSignal', arguments = list(sigcol="longentry", sigval=TRUE, replace=FALSE, prefer='open', orderside='long', ordertype='market', orderqty=unitsize, orderset='ocolong', osFUN = "osMaxPos", maxSize='PosLimit' ), type='enter', label='LE' ) 

My original rule (when it worked, but held huge positions) before trying to change it.

 add.rule(strategyname,name='ruleSignal', arguments = list(sigcol="longentry", sigval=TRUE, replace=FALSE, prefer='open', orderside='long', ordertype='market', orderqty=1, orderset='ocolong', osFUN = "osInvestAll", maxSize='PosLimit' ), type='enter', label='LE' ) 
+5
source share
1 answer

Here is a reproducible example that I think does what you are looking for?

A strategy simply enters a long position if RSI SPY falls below 60, and exits the entire long position if RSI crosses above 70. The maximum number of units that a long position can be is 1000 units.

Your code in osInvestAll contains the wrong / redundant code that I missed. This is a pure minimum order size function that (I think) does what you want.

In addition, just a tip: you do not need to call updateAcct and updateEndEq for each long record in order to exchange the current equity for the symbol in question, since this will add unnecessary additional computational time in large simulations.

 osInvestAll <- function (data, timestamp, orderqty, ordertype, orderside, equity, portfolio, symbol, ruletype, ..., initEq) { datePos <- format(timestamp,"%Y-%m-%d") updatePortf(Portfolio=portfolio,Symbol=symbol,Dates=paste0(start(data), "/", datePos)) # After updating portfolio profit, we can extract the Net.Trading.PL earned up to datePos. trading_pl <- sum(.getPortfolio(portfolio)$summary$Net.Trading.PL) # The total equity in the strategy for this symbol (and this symbol only in isolation always, as this is how quantstrat by default works with applyStrategy) equity <- initEq + trading_pl ClosePrice <- getPrice(data, prefer = "Close")[datePos] UnitSize <- as.numeric(trunc(0.25 * equity / ClosePrice)) UnitSize <- osMaxPos(data, timestamp, UnitSize, ordertype, orderside, portfolio, symbol, ruletype, digits=0) UnitSize } library(quantstrat) suppressWarnings(rm("order_book.RSI",pos=.strategy)) suppressWarnings(rm("account.RSI","portfolio.RSI",pos=.blotter)) suppressWarnings(rm("account.st","portfolio.st","stock.str","stratRSI","startDate","initEq",'start_t','end_t')) strategy.st <- "RSI" stratRSI <- strategy(strategy.st, store = TRUE) add.indicator(strategy = strategy.st, name = "RSI", arguments = list(price = quote(getPrice(mktdata))), label="RSI") add.signal(strategy = strategy.st, name="sigThreshold",arguments = list(threshold=70, column="RSI",relationship="gt", cross=TRUE),label="RSI.gt.70") add.signal(strategy = strategy.st, name="sigThreshold",arguments = list(threshold=60, column="RSI",relationship="lt",cross=TRUE),label="RSI.lt.60") add.rule(strategy = strategy.st, name='ruleSignal', arguments = list(sigcol="RSI.lt.60", sigval=TRUE, orderqty= 100, TxnFees=0, ordertype='market', orderside='long', pricemethod='market', replace=FALSE, osFUN=osInvestAll), type='enter', path.dep=TRUE) add.rule(strategy = strategy.st, name='ruleSignal', arguments = list(sigcol="RSI.gt.70", sigval=TRUE, orderqty='all', TxnFees=0, ordertype='market', orderside='long', pricemethod='market', replace=FALSE), type='exit', path.dep=TRUE) currency("USD") symbols = c("SPY") stock.str = symbols startDate <- "1987-01-01" getSymbols(stock.str,from=startDate, to= Sys.Date()) #getSymbols(stock.str,from=startDate, to= Sys.Date()) for(symbol in symbols){ stock(symbol, currency="USD",multiplier=1) } SPY <- SPY["2015/"] startDate='1999-12-31' initEq=100000 port.st<-'RSI' initPortf(port.st, symbols=symbols) initAcct(port.st, portfolios=port.st, initEq=initEq) initOrders(portfolio=port.st) # Must add maxpos: for(symbol in symbols){ addPosLimit(port.st, symbol, timestamp = startDate, maxpos = 1000) } applyStrategy(strategy=strategy.st, portfolios=port.st, initEq = initEq) # > applyStrategy(strategy=strategy.st, portfolios=port.st, initEq = initEq) # [1] "2015-03-01 19:00:00 SPY 118 @ 211.990005" # [1] "2015-03-03 19:00:00 SPY 118 @ 210.229996" # [1] "2015-05-25 20:00:00 SPY 117 @ 210.699997" # [1] "2015-10-21 20:00:00 SPY 119 @ 205.210007" # [1] "2015-11-09 19:00:00 SPY 119 @ 208.559998" # [1] "2015-12-02 19:00:00 SPY 119 @ 205.610001" # [1] "2016-03-08 19:00:00 SPY 116 @ 199.380005" # [1] "2016-04-05 20:00:00 SPY 119 @ 206.419998" # [1] "2016-04-07 20:00:00 SPY 55 @ 204.5" # [1] "2016-11-27 19:00:00 SPY -1000 @ 220.479996" # [1] "2016-12-01 19:00:00 SPY 129 @ 219.679993" # [1] "2016-12-07 19:00:00 SPY -129 @ 225.149994" # [1] "2016-12-28 19:00:00 SPY 127 @ 224.350006" # [1] "2017-01-09 19:00:00 SPY 126 @ 226.460007" # [1] "2017-01-12 19:00:00 SPY 126 @ 227.050003" # [1] "2017-01-17 19:00:00 SPY 126 @ 226.75" # [1] "2017-01-30 19:00:00 SPY 126 @ 227.529999" # [1] "2017-02-13 19:00:00 SPY -631 @ 233.699997" # [1] "2017-03-14 20:00:00 SPY 125 @ 238.949997" # [1] "2017-03-19 20:00:00 SPY 124 @ 236.770004" # [1] "2017-04-30 20:00:00 SPY 124 @ 238.679993" # [1] "2017-05-14 20:00:00 SPY 124 @ 240.300003" # [1] "2017-05-17 20:00:00 SPY 124 @ 236.770004" # [1] "2017-06-04 20:00:00 SPY -621 @ 243.990005" # [1] "2017-06-18 20:00:00 SPY 125 @ 244.660004" # [1] "2017-06-20 20:00:00 SPY 125 @ 242.949997" # [1] "2017-08-10 20:00:00 SPY 125 @ 244.119995" # [1] "2017-09-05 20:00:00 SPY 124 @ 246.899994" # [1] "2017-09-21 20:00:00 SPY 124 @ 249.440002" updatePortf(Portfolio=port.st,Dates=paste('::',as.Date(Sys.time()),sep='')) tradeStats(port.st, "SPY") # Portfolio Symbol Num.Txns Num.Trades Net.Trading.PL Avg.Trade.PL Med.Trade.PL Largest.Winner Largest.Loser Gross.Profits Gross.Losses Std.Dev.Trade.PL Std.Err.Trade.PL Percent.Positive Percent.Negative Profit.Factor # SPY RSI SPY 29 4 24581.97 5548.314 4063.635 13360.36 0 22193.25 0 5460.273 2730.136 100 0 NA # Avg.Win.Trade Med.Win.Trade Avg.Losing.Trade Med.Losing.Trade Avg.Daily.PL Med.Daily.PL Std.Dev.Daily.PL Std.Err.Daily.PL Ann.Sharpe Max.Drawdown Profit.To.Max.Draw Avg.WinLoss.Ratio Med.WinLoss.Ratio Max.Equity Min.Equity # SPY 5548.314 4063.635 NaN NA 5548.314 4063.635 5460.273 2730.136 16.13047 -19148.87 1.28373 NA NA 24946.23 -18349.48 # End.Equity # SPY 24581.97 

In the conclusion, you can see that in the strategy there are no more than 1000 units (long). And each transaction is 25% of current capital when a long signal is triggered.

+2
source

Source: https://habr.com/ru/post/1264730/


All Articles