長い投稿で申し訳ありませんが、それを減らす方法はわかりません。Guy Yollin のこのチュートリアル
から、blotter / quanstrat パッケージの使用を開始しました。Yollinさんのコードをそのまま使っても、同じような結果になる心配はありません。
library(blotter)
currency("USD")
initDate <- "2000-01-01"
startDate <- "2000-01-02"
endDate <- "2016-07-01"
initEq <- 1e6
私が行っている唯一の変更は、Githubで Systematic Investor によって提供されたわずかに変更された関数を使用して、.csv にローカルに保存されたデータを使用することです。
これが関数です。
getSymbols.sit <- function(
Symbols,
env = .GlobalEnv,
auto.assign = TRUE,
stock.folder = 'Google Drive/Software/TechnicalAnalysis/StockData',
stock.date.format = '%Y-%m-%d',
...)
{
require(quantmod)
for(i in 1:length(Symbols)) {
s = Symbols[i]
temp = list()
temp[[ s ]] = list(src='csv', format=stock.date.format, dir=stock.folder)
setSymbolLookup(temp)
temp = quantmod::getSymbols(s, env = env, auto.assign = auto.assign)
if (!auto.assign) {
cat(s, format(range(index(temp)), '%d-%b-%Y'), '\n', sep='\t')
return(temp)
}
if(!is.null(env[[ s ]]))
cat(i, 'out of', length(Symbols), 'Reading', s, format(range(index(env[[ s ]])), '%d-%b-%Y'), '\n', sep='\t')
else
cat(i, 'out of', length(Symbols), 'Missing', s, '\n', sep='\t')
}
}
それからそれを呼び出します。
getSymbols.sit("SPY", source = "yahoo", from=startDate, to=endDate, adjust=T)
これまでのところ、すべてが機能しているようです。現在、Faber の 10 か月 SMA に基づくバック テストの構築を続けています。
stock("SPY", currency = "USD", multiplier = 1)
SPY=to.monthly(SPY, indexAt = 'endof', drop.time = FALSE)
SPY$SMA10m <- SMA(Cl(SPY), n=10)
portfolio.st <- "portf.faber"
account.st <- "acct.faber"
initPortf(portfolio.st, "SPY", initDate = initDate)
initAcct(account.st, portfolios = portfolio.st, initDate = initDate, initEq = initEq)
今、戦略を作成して実行しています。
for(i in 1:nrow(SPY))
{
#set up all the values for the specific date and update them in the loop
actualDate <- time(SPY)[i]
equity = getEndEq(Account = account.st, Date = actualDate)
closePrice <- as.numeric(Cl(SPY[i]))
posn <- getPosQty(Portfolio = portfolio.st, Symbol = "SPY", Date = actualDate)
unitSize = as.numeric(trunc(equity/closePrice))
ma <- as.numeric(SPY$SMA10m[i])
#Take market decision
if( !is.na(ma) ) { #we have to wait to have our first 10sma
if( posn == 0 ) { #if no position then we go long
if( closePrice > ma ) {
addTxn(Portfolio = portfolio.st, Symbol = "SPY", TxnDate = actualDate,
TxnQty = unitSize, TxnPrice = closePrice, TxnFees = 0) }
} else {
if( closePrice < ma ) { #sell share and go cash if closing price < 10sma
addTxn(Portfolio = portfolio.st, Symbol = "SPY", TxnDate = actualDate,
TxnQty = -posn, TxnPrice = closePrice, TxnFees = 0)
} else {
if( i == nrow(SPY) ) #last recorded price, we close the system
addTxn(Portfolio = portfolio.st, Symbol = "SPY", TxnDate = actualDate,
TxnQty = -posn, TxnPrice = closePrice, TxnFees = 0)
}
}
}
updatePortf(portfolio.st, Dates = actualDate)
updateAcct(name = account.st, Dates = actualDate)
updateEndEq(Account = account.st, actualDate)
}
スクリプトはエラーなく実行されますが、気になる点が 3 つあります。
- 使用時の警告
getSymbols.sit()
。そして、私はそれについて何をすべきかわかりません。これが警告です。
1 out of 1 Reading SPY 03-Jan-2000 19-Jul-2016 Warning message: In if (as.character(sc[[1]]) != calling.fun) return() : the condition has length > 1 and only the first element will be used
- 最後の 3 つの更新機能を実行したときの警告。
There were 50 or more warnings (use warnings() to see the first 50) 1: In updatePortf(portfolio.st, Dates = actualDate) : Incompatible methods ("Ops.POSIXt", "Ops.Date") for ">="
- checkBlotterUpdate (チュートリアルで指定) 関数を使用すると、エラーが発生します。
checkBlotterUpdate(portfolio.st, account.st) [1] "portfolio P&L doesn't match sum of symbols P&L" [1] FALSE
したがって、これらの警告について心配する必要があるようですが、問題を解決する方法がわかりません。
だけですべてを実行するとgetSymbols("SPY")
、問題はありません。しかし、ローカルに保存されたデータを使用してバックテストできるようにしたいと考えています。私はアフリカのザンビアに住んでいますが、インターネット / 電源は常に信頼できるとは限りません。ヒントをお寄せいただきありがとうございます。