All,
I have tried to implement a traditional (80/20) stochastic oscillator
overbought-oversold (OBOS) strategy in quantstrat.
The script runs, however it may actually be wrong!
I'd like to get this working correctly.
Amarjit
#
# Stochastic Oscillator
#
#
# 3 types of Stochastics
#
# (1) nfastk (Stochastic nfastk (%K)) is calculated as:
#
# %K = (Current Close - Lowest Low)/(Highest High - Lowest Low)
#
# where,
# Current Close is the most recent close,
# Lowest Low is the lowest low over the last n-periods,
# Highest High is highest high over the last n-periods
#
#
# (2) nfastD (Stochastic nfastD (%D)) is a m-period moving average of
Stochastic nfastk (%K) )
# (3) nslowD (Stochastic nslowD) is a p-period moving average of Stochastic
nfastD (%D) )
#
#
# Stochastics generate signals via:
#
# (a) Crossover
# (b) Over-Bought Over-Sold (OBOS)
#
#
# (b) OBOS
#
# Traditionally:
# --------------
#
# Use 80% as the OVERBOUGHT threshold and 20% as the OVERSOLD threshold
#
# Buy Long when indicator crosses ABOVE 20%
# Sell Short when indicator crosses BELOW 80%
#
# In otherwords, this strategy implements:
# (i) EnterLONG when indicator >20%
# (ii) Exit2SHORT when indicator >=80%
# (iii) EnterSHORT when indicator <80%
# (iv) Exit2LONG when indicator <= 20%
#
# I have used nslowD as the indicator.
#
#
###############################################################################################
library(quantstrat)
suppressWarnings(rm("order_book.stoch",pos=.strategy))
suppressWarnings(rm("account.stoch","portfolio.stoch",pos=.blotter))
suppressWarnings(rm("account.st","portfolio.st","stock.str","stratstoch","initDate",
"initEq",'start_t','end_t'))
###############################################################################################
#
# INITILIASATION
#
#
# Initialize currency
# Initialize instruments
# Load historic data
# Set parameters
#correct for TZ issues if they crop up
oldtz<-Sys.getenv('TZ')
if(oldtz=='') {
Sys.setenv(TZ="GMT")
}
Sys.timezone()
currency("USD")
symbols = c("GOOG")
#establish trade-able instruments
for(symbol in symbols){
stock(symbol, currency="USD",multiplier=1)
getSymbols(symbol, from="2010-01-01", to="2013-12-31")
}
#view data
class(GOOG)
head(GOOG)
tail(GOOG)
#Set initial values
initDate='2009-12-31'
initEq=10000
#
# parameters
#
nFastK = 20
nFastD = 3
nSlowD = 5
maType="SMA"
.qty=1000
.txn=0
###############################################################################################
#
# INITILIASATION
#
#
# Initialize Portfolio
# Initialize Account
# Initialize Orders
#
# Initialize a strategy object
port.st <- 'stoch'
acct.st <- 'stoch'
initPortf(port.st, symbols=symbols, initDate=initDate)
initAcct(port.st, portfolios=port.st, initDate=initDate, initEq=initEq)
initOrders(portfolio=port.st, initDate=initDate)
#Initialize a strategy object
stratstoch <- strategy("stratstoch")
#set max pos --- not implemented
for(symbol in symbols){
addPosLimit(port.st, symbol, initDate, 1000, 1 )
}
print("setup completed")
###############################################################################################
#
# DEFINE STRATEGY
#
#
# Add
#
# (A) Indicators
# (B) Signals
# (C) Rules
#
#####
#
# (A) Add an indicator (ONE)
#
stratstoch <- add.indicator(strategy = stratstoch,
name = "stoch",
arguments = list( HLC = quote(HLC(mktdata)),
nFastK=nFastK,
nFastD=nFastD,
nSlowD=nSlowD,
maType=maType) )
#
# stochastic indicator produces 3 indicators described above, with column
headers
# (1) fastK.stoch.ind
# (2) fastD.stoch.ind
# (3) slowD.stoc.ind
#
#####
#
# (B) Add FOUR signals
#
#
# There are FOUR signals: (am using slowD.stoc.ind)
#
#The first is when stoch is GREATER THAN 0.20
stratstoch <- add.signal(strategy = stratstoch,
name="sigThreshold",
arguments = list(threshold=0.20,
column="slowD.stoch.ind",
relationship="gt",
cross=TRUE),
label="slowD.stoch.ind.gt.20")
#The second is when stoch is GREATER THAN OR EQUAL TO 0.80
stratstoch <- add.signal(strategy = stratstoch,
name="sigThreshold",
arguments = list(threshold=0.80,
column="slowD.stoch.ind",
relationship="gte",
cross=TRUE),
label="slowD.stoch.ind.gte.80")
#The third is when stoch is LESS THAN 0.80
stratstoch <- add.signal(strategy = stratstoch,
name="sigThreshold",
arguments = list(threshold=0.80,
column="slowD.stoch.ind",
relationship="lt",
cross=TRUE),
label="slowD.stoch.ind.lt.80")
#The fourth is when stoch is LESS THAN OR EQUAL TO 0.20
stratstoch <- add.signal(strategy = stratstoch,
name="sigThreshold",
arguments = list(threshold=0.20,
column="slowD.stoch.ind",
relationship="lte",
cross=TRUE),
label="slowD.stoch.ind.lte.20")
####
#
# (C) Add FOUR Rules
#
### NOTE
### --------
### we use osMaxPos to put trade on in layers, or to a maximum position (not
implemented)
#
# LONG orderside
# note: if we are LONG (indicator is from <20 to (>20 & <80) ) and indicator
falls back to <=20, we remain LONG
#
stratstoch <- add.rule(strategy = stratstoch,
name='ruleSignal',
arguments = list(sigcol="slowD.stoch.ind.gte.80",
sigval=TRUE,
orderqty='all',
ordertype='market',
TxnFees=.txn,
orderside='long',
pricemethod='market',
replace=TRUE),
label='Exit2SHORT', type='exit', path.dep=TRUE)
stratstoch <- add.rule(strategy = stratstoch,
name='ruleSignal',
arguments = list(sigcol="slowD.stoch.ind.gt.20",
sigval=TRUE,
orderqty=+.qty,
ordertype='market',
TxnFees=0,
orderside='long',
pricemethod='market',
replace=FALSE,
osFUN=osMaxPos),
label='EnterLONG', type='enter', path.dep=TRUE)
#
# SHORT orderside
# note: if we are SHORT (indicator is from >80 to (<80 & >20) ), and indicator
rises back to >=80, we remain SHORT
#
stratstoch <- add.rule(strategy = stratstoch,
name='ruleSignal',
arguments = list(sigcol="slowD.stoch.ind.lte.20",
sigval=TRUE,
orderqty='all',
ordertype='market',
TxnFees=.txn,
orderside='short',
pricemethod='market',
replace=TRUE),
label='Exit2LONG', type='exit', path.dep=TRUE)
stratstoch <- add.rule(strategy = stratstoch,
name='ruleSignal',
arguments = list(sigcol="slowD.stoch.ind.lt.80",
sigval=TRUE,
orderqty=-.qty,
ordertype='market',
TxnFees=0,
orderside='short',
pricemethod='market',
replace=FALSE,
osFUN=osMaxPos),
label='EnterSHORT', type='enter', path.dep=TRUE)
###############################################################################################
#
# BAR-BY-BAR PROCESSING
#
#Process the indicators and generate trades / Apply strategy to portfolio
start_t<-Sys.time()
out<-try(applyStrategy(strategy=stratstoch,
portfolios=port.st))
end_t<-Sys.time()
print("Strategy Loop:")
print(end_t-start_t)
###############################################################################################
#
# UPDATE PORTFOLIO ACCOUNT & EQUITY
#
updatePortf(Portfolio=port.st,Dates=paste('::',as.Date(Sys.time()),sep=''))
updateAcct(acct.st)
updateEndEq(acct.st)
for(symbol in symbols){
x11()
chart.Posn(Portfolio=port.st,Symbol=symbol)
}
###############################################################################################
###############################################################################################
#
# REPORTING
#
#
print(getOrderBook(port.st))
View(getTxns(Portfolio=port.st, Symbol=symbols))
#
# export various data files
#
#Stochastic indicators
mktdata <- mktdata
head(mktdata,30)
#write.zoo(mktdata, file="stochOSC_OverboughtOversold_mktdata.txt")
x11()
plot(mktdata$slowD.stoch.ind)
#Everything regarding the Portfolio
thePortfolio <- getPortfolio(port.st)
thePortfoliosummary <- thePortfolio$summary
thePortfoliosummary
#write.zoo(thePortfoliosummary,
file="stochOSC_OverboughtOversold_thePortfoliosummary.txt")
#
# getPortfolio chart
#
library(lattice)
x11()
plot(xyplot(getPortfolio('stoch')$summary))
#
# tradeStats
#
tstats <- tradeStats(port.st, symbols)
attributes(tstats)
tstats1 <- as.data.frame(t(tstats))
tstats1
tstats$Portfolio
tstats$Gross.Profits
###############################################################################################
#
# RETURNS & EQUITY
# ----------------
#
#
# Method 1: Standard (PortfReturns function)
#
#returns from strategy
rets1 <- PortfReturns(Account='stoch')
head(rets1,40)
tail(rets1,30)
#write.zoo(rets1, file="rets1.txt")
#cumulative returns (equity curve)
eqrets1<-na.omit(rets1)
eqrets1<-cumsum(rets1)
tail(eqrets1,10)
#GEOMETRIC=F, as summing PortfReturns
#plot cumulative returns
x11()
charts.PerformanceSummary(rets1,geometric=F,wealth.index=T)
R> sessionInfo()
R version 3.0.3 (2014-03-06)
Platform: x86_64-w64-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=English_United Kingdom.1252 LC_CTYPE=English_United
Kingdom.1252
[3] LC_MONETARY=English_United Kingdom.1252 LC_NUMERIC=C
[5] LC_TIME=English_United Kingdom.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] lattice_0.20-28
quantstrat_0.8.2 foreach_1.4.1
[4] blotter_0.8.18 PerformanceAnalytics_1.1.4
FinancialInstrument_1.1.9
[7] quantmod_0.4-1 Defaults_1.1-1 TTR_0.22-0.1
[10] xts_0.9-7 zoo_1.7-11
loaded via a namespace (and not attached):
[1] codetools_0.2-8 grid_3.0.3
iterators_1.0.6
[[alternative HTML version deleted]]
_______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should
go.