问题
I'm new to R and I'm trying to figure out how to get quantstrat to work with a custom ordersize function. The idea is to always invest all available equity in Bitcoin so that it will be comparable to a B&H strategy. I have provided reproducible code. At first it seems to be working fine but the problem arises when I look at my orderbook. Maybe their is some mismatch between Closing prices but quantstrat doesn't order the amount of Bitcoin in accordance with the available equity. E.g. (from= "2016-12-31" to= "2018-01-01") At "2017-01-30" quantstrat first buys USD 10000 worth of bitcoin at 920.730042 with the orderqty being 10.8609467963901. At "2017-03-20" it sells the initial investment at 1047.51001 thereby the avaible equity should now be (10.8609467963901 x 1047.51001)= 11376.9504873 and I would expect that quantstrat should order (11376.9504873 / 1129.869995)= 10.0692562309 BTC when it buys again at "2017-04-04" when BTCUSD = 1129.869995. Instead 10.3482135951968 BTC is ordered. Could someone please point me in the right direction?
Order.Qty Order.Price Order.Type Order.Side
2017-01-30 "10.8609467963901" "920.730042" "market" "long" NA
2017-03-20 "all" "1047.51001" "market" "long" NA
2017-04-04 "10.3482135951968" "1129.869995" "market" "long" NA
2017-06-27 "all" "2577.73999" "market" "long" NA
2017-07-23 "9.36005714412325" "2763.42041" "market" "long" NA
2017-09-12 "all" "3870.289551" "market" "long" NA
2017-09-28 "7.68025279952473" "4172.790527" "market" "long" NA
2017-12-27 "all" "15416.633789" "market" "long" NA
library("quantstrat")
init.portf <- "2016-12-31"
.from <- init.portf
.to <-"2018-01-01"
Sys.setenv(TZ="UTC")
initEq <- 10000
getSymbols("BTCUSD=X", src = "yahoo", from= .from, to= .to)
BTCUSD <- `BTCUSD=X`
currency(c("USD", "BTC"))
exchange_rate("BTCUSD", currency = "USD")
trend1.strat <- "TrendStrat1"
rm.strat(trend1.strat)
strategy(name=trend1.strat,store=TRUE)
add.indicator(strategy=trend1.strat,name="SMA",
arguments=list(x=quote(Cl(mktdata)),n=5),label="FastSMA")
add.indicator(strategy=trend1.strat,name="SMA",
arguments=list(x=quote(Cl(mktdata)),n=20),label="SlowSMA")
add.signal(strategy=trend1.strat,name="sigCrossover",
arguments=list(columns=c("FastSMA","SlowSMA"),
relationship="gt"),label="BuySignal")
add.signal(strategy=trend1.strat,name="sigCrossover",
arguments=list(columns=c("FastSMA","SlowSMA"),
relationship="lt"),label="SellSignal")
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))
trading_pl <- sum(.getPortfolio(portfolio)$summary$Net.Trading.PL)
equity <- initEq + trading_pl
ClosePrice <- getPrice(data, prefer = "Close")[datePos]
UnitSize <- as.numeric((equity / ClosePrice))
UnitSize
}
add.rule(strategy=trend1.strat,name='ruleSignal',
arguments=list(sigcol="BuySignal",sigval=TRUE,ordertype='market',
orderside='long', osFUN = osInvestAll, prefer =
"Close"),type='enter',label="EnterRule",enabled=T)
add.rule(strategy=trend1.strat,name='ruleSignal',
arguments=list(sigcol="SellSignal",sigval=TRUE,orderqty='all',
ordertype='market',orderside='long', prefer
="Close"),type='exit',label="ExitRule",enabled=T)
trend1.portf <- "TrendPort1"
rm.strat(trend1.portf)
initPortf(name=trend1.portf,symbols="BTCUSD",initDate=init.portf)
initAcct(name=trend1.strat,portfolios=trend1.portf,
initDate=init.portf,initEq= initEq)
initOrders(portfolio=trend1.portf,initDate=init.portf)
applyStrategy(strategy=trend1.strat,portfolios=trend1.portf, initEq =
initEq)
updatePortf(Portfolio=trend1.portf)
updateAcct(name=trend1.strat)
updateEndEq(Account=trend1.strat)
trend1.book <- getOrderBook(portfolio=trend1.portf)
trend1.book
回答1:
Fixed this problem by adjusting the ordersize function:
osInvestAll <- function (data, timestamp, orderqty, ordertype,
orderside, equity, portfolio, symbol, ruletype, ..., initEq) {
datePos <- format(timestamp,"%Y-%m-%d %H:%M:%OS")
datePos <- strptime(c(datePos), format = "%Y-%m-%d %H:%M:%OS", tz =
"UTC") + 86400 #for daily data
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((equity / ClosePrice))
UnitSize1 <- round(UnitSize, digits = 8)
UnitSize1
}
来源:https://stackoverflow.com/questions/49994856/quantstrat-ordersize-function