R:量化如何为投资组合中的完整股权进行交易



我仍然在玩Guy Yollins定量的例子。在这个例子中,当SPY越过其10日均线时,他买入1000股。既然我们定义了初始净值,是否有可能总是以整个投资组合金额购买,而不仅仅是 900 股?"全部"对进入不起作用,只是出口。

if (!exists('.blotter')) .blotter <- new.env()
if (!exists('.strategy')) .strategy <- new.env()
if (!exists('.instrument')) .instrument <- new.env()
currency("USD")
stock("SPY",currency="USD",multiplier=1)
ls(envir=FinancialInstrument:::.instrument)

initDate <- '1997-12-31'
startDate <- '1998-01-01'
endDate <- '2013-07-31'
initEq <- 1e6
Sys.setenv(TZ="UTC")
getSymbols('SPY', from=startDate, to=endDate, adjust=T)
SPY=to.monthly(SPY, indexAt='endof')
SPY$SMA10m <- SMA(Cl(SPY), 10)
# inz portfolio, account
qs.strategy <- "qsFaber"
rm.strat(qs.strategy) # remove strategy etc. if this is a re-run
initPortf(qs.strategy,'SPY', initDate=initDate)
initAcct(qs.strategy,portfolios=qs.strategy, initDate=initDate, initEq=initEq)

initOrders(portfolio=qs.strategy,initDate=initDate)
# instantiate a new strategy object
strategy(qs.strategy,store=TRUE)
add.indicator(strategy = qs.strategy, name = "SMA",
              arguments = list(x = quote(Cl(mktdata)), n=10), label="SMA10")
add.signal(qs.strategy,name="sigCrossover",
           arguments = list(columns=c("Close","SMA10"),relationship="gt"),
           label="Cl.gt.SMA")
add.signal(qs.strategy,name="sigCrossover",
           arguments = list(columns=c("Close","SMA10"),relationship="lt"),
           label="Cl.lt.SMA")
add.rule(qs.strategy, name='ruleSignal',
         arguments = list(sigcol="Cl.gt.SMA", sigval=TRUE, orderqty=900,
                          ordertype='market', orderside='long', pricemethod='market'),
         type='enter', path.dep=TRUE)
add.rule(qs.strategy, name='ruleSignal',
         arguments = list(sigcol="Cl.lt.SMA", sigval=TRUE, orderqty='all',
                          ordertype='market', orderside='long', pricemethod='market'),
         type='exit', path.dep=TRUE)

out <- applyStrategy(strategy=qs.strategy , portfolios=qs.strategy)
updatePortf(qs.strategy)
updateAcct(qs.strategy)
updateEndEq(qs.strategy)
myTheme<-chart_theme()
myTheme$col$dn.col<-'lightblue'
myTheme$col$dn.border <- 'lightgray'
myTheme$col$up.border <- 'lightgray'
# plot performance
chart.Posn(qs.strategy, Symbol = 'SPY', Dates = '1998::',theme=myTheme)
plot(add_SMA(n=10,col=4, on=1, lwd=2))

您不能在入场时使用orderqty="all",因为"all"是指当前仓位大小(即,当您想退出整个仓位时)。

可以购买等于可用投资组合总净值的金额,但您必须定义自定义订单大小调整功能。 并且该功能必须标记账簿(使用updatePortf)以确定可用权益的数量。

这是一个实现你想要的玩具示例。

您需要引入订单大小调整功能。

查看函数ruleSignal的参数(例如 formals(ruleSignal)?ruleSignal)。

您将看到有一个参数osFUN,您可以在其中编写自定义函数来确定如何订购大小。

您可以在add.rule中修改相应的参数以引入订单规模(在入场交易中)。

osFUN_all_eq <- 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)
    # 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(equity / ClosePrice))
    UnitSize <- osMaxPos(data, timestamp, UnitSize, ordertype, orderside, portfolio, symbol, ruletype, digits=0)
    UnitSize
}


library(quantstrat)
currency("USD")
stock("SPY",currency="USD",multiplier=1)

initDate <- '1997-12-31'
startDate <- '1998-01-01'
endDate <- '2013-07-31'
initEq <- 1e6
Sys.setenv(TZ="UTC")
getSymbols('SPY', from=startDate, to=endDate, adjust=T)
SPY=to.monthly(SPY, indexAt='endof')
SPY$SMA10m <- SMA(Cl(SPY), 10)

qs.strategy <- "qsFaber"
rm.strat(qs.strategy) # remove strategy etc. if this is a re-run
initPortf(qs.strategy,'SPY', initDate=initDate)
initAcct(qs.strategy,portfolios=qs.strategy, initDate=initDate, initEq=initEq)

initOrders(portfolio=qs.strategy,initDate=initDate)
# instantiate a new strategy object
strategy(qs.strategy,store=TRUE)

# Specify the max quantity you could hold in the SPY instrument.  Here we simply assume 1e5 units. You could reduce this number to limit the exposure
max_qty_traded <- 1e5
addPosLimit(qs.strategy, "SPY", timestamp = startDate, maxpos = max_qty_traded)
add.indicator(strategy = qs.strategy, name = "SMA",
              arguments = list(x = quote(Cl(mktdata)), n=10), label="SMA10")
add.signal(qs.strategy,name="sigCrossover",
           arguments = list(columns=c("Close","SMA10"),relationship="gt"),
           label="Cl.gt.SMA")
add.signal(qs.strategy,name="sigCrossover",
           arguments = list(columns=c("Close","SMA10"),relationship="lt"),
           label="Cl.lt.SMA")
add.rule(qs.strategy, name='ruleSignal',
         arguments = list(sigcol="Cl.gt.SMA",
                          sigval=TRUE,
                          orderqty = 1, # the acutal orderqty size becomes redundant when supplying a function to the argument `osFUN`
                          osFUN = osFUN_all_eq,
                          ordertype='market', orderside='long', pricemethod='market'),
         type='enter', path.dep=TRUE)

add.rule(qs.strategy, name='ruleSignal',
         arguments = list(sigcol="Cl.lt.SMA",
                          sigval=TRUE,
                          orderqty='all', # flatten all open long positions
                          ordertype='market',
                          orderside='long',
                          pricemethod='market'),
                          type='exit',
         path.dep=TRUE)

# supply initEq parameter and its value, which pass through to `osFUN`
out <- applyStrategy(strategy=qs.strategy , portfolios=qs.strategy, initEq=initEq)
updatePortf(qs.strategy)
updateAcct(qs.strategy)
updateEndEq(qs.strategy)
myTheme<-chart_theme()
myTheme$col$dn.col<-'lightblue'
myTheme$col$dn.border <- 'lightgray'
myTheme$col$up.border <- 'lightgray'
# plot performance
chart.Posn(qs.strategy, Symbol = 'SPY', Dates = '1998::',theme=myTheme)
plot(add_SMA(n=10,col=4, on=1, lwd=2))

在订单大小调整函数中,您应该考虑一些事项:

1) 如果您已经有未平仓头寸,您是否要允许在特定一侧"堆叠"/金字塔化头寸? 例如,如果您只想拥有一个仓位,而您不会进一步贡献,则可以在 osFUN 中包含 getPosQty(qs.strategy, "SPY", timestamp),如果当前持仓不是 0,则返回 0。

2) 您想要最大交易规模吗? 这可以使用addPosLimit()处理,如上面的此示例所示。

我知道这个问题很久以前就发布了,但请查看软件包"IKTrading"和订单大小函数"osMaxDollar"。 这是一篇关于该主题的博客文章;当您使用此订单大小功能时,您可以设置每笔交易的美元价值和总头寸。

https://quantstrattrader.wordpress.com/2014/08/29/comparing-atr-order-sizing-to-max-dollar-order-sizing/

最新更新