Friday, April 27, 2012

Real Time Structural Break

Yesterday as I played with bfast I kept thinking “Yes, but this is all in hindsight.  How can I potentially use this in a system?”  Fortunately, one of the fine authors very generously commented on my post Structural Breaks (Bull or Bear?):

Jan Verbesselt Apr 27, 2012 02:01 AM

Nice application! you can also detect seasonal breaks. also check some new near real-time disturbance detection functionality using bfastmonitor() http://bfast.r-forge.r-project.org/Verbesselt+Zeileis+Herold-2012.pdf
cheers, Jan”

And away I went on an unexpected but very pleasant journey into bfastmonitor.  Please see the following paper for all the details.

Jan Verbesselt, Achim Zeileis, Martin Herold (2011). Near Real-Time Disturbance
  Detection in Terrestrial Ecosystems Using Satellite Image Time Series: Drought
  Detection in Somalia. Working Paper 2011-18. Working Papers in Economics and
  Statistics, Research Platform Empirical and Experimental Economics, Universitaet
  Innsbruck. URL http://EconPapers.RePEc.org/RePEc:inn:wpaper:2011-18

Doing a walk-forward test seemed like the best method of testing and illustration, so I chose the excruciating and incredibly volatile period from late 2008 to early 2009 as our example.  Amazingly, it picked with no optimizing or manual intervention March 2009 as the breakpoint. Of course, we would not know this until the end of March, but picking real-time with only a month lag is unbelievable to me.  Please try it out, and let me know your results.  Of course, I already have the 30 year bond bull in mind as a next trial.

Thanks to Yihui Xie who resurfaced again (see posts on knitr) with his animation package, which I used to create a good old-fashioned animated GIF.  I wish I had time to play more with the prettier and more robust options offered by the package.

animation

R code from GIST:

#analyze breakpoints in realtime with the R package bfast
#please read the paper
#Jan Verbesselt, Achim Zeileis, Martin Herold (2011). Near Real-Time Disturbance
#Detection in Terrestrial Ecosystems Using Satellite Image Time Series: Drought
#Detection in Somalia. Working Paper 2011-18. Working Papers in Economics and
#Statistics, Research Platform Empirical and Experimental Economics, Universitaet
#Innsbruck. URL http://EconPapers.RePEc.org/RePEc:inn:wpaper:2011-18
#http://scholar.google.com/scholar?cluster=9016488513865299942&hl=en&as_sdt=0,1
#install r-forge development version of bfast
#install.packages("bfast", repos="http://R-Forge.R-project.org")
require(bfast)
require(quantmod)
require(animation) #Yihui Xie surfaces again
getSymbols("^GSPC",from="1950-01-01")
#convert to log price
#for the sake of this example, let's assume we are in January 2009
#and we will see how this progresses with a for loop to go through
#the painful months of late 2008 and early 2009
#to see when our real time monitoring detects a break
#get a vector of the dates
evaldates <- c("2008-09","2008-10","2008-11","2008-12",
"2009-01","2009-02","2009-03","2009-04",
"2009-05","2009-06")
saveGIF(
for(i in 1:length(evaldates)) {
#notice this removes the foresight bias by only going to the current month
GSPC.monthly <- log(to.monthly(GSPC)[paste("1990::",evaldates[i],sep=""),4])
#need ts representation so do some brute force conversion
GSPC.ts <- ts(as.vector(GSPC.monthly),start=as.numeric(c(format(index(GSPC.monthly)[1],"%Y"),format(index(GSPC.monthly)[1],"%m"))),frequency=12)
#since we know the peak was October of 2010 let's use that
#as our start point for real time monitoring
mon5y <- bfastmonitor(GSPC.ts,
start=c(2007,10))
plot(mon5y)
mtext(evaldates[i],col="green",cex=1.5)
}
)
#really does not work, but always nice to have more examples
#let's get the minimum and maximum for our first experiment
GSPC.max <- GSPC.monthly[which(GSPC.monthly==max(last(GSPC.monthly,"10 years")))]
GSPC.min <- GSPC.monthly[which(GSPC.monthly==min(last(GSPC.monthly,"10 years")))]
#for evaluation let's pick whatever point is farthest from most recent close
GSPC.eval <- GSPC.monthly[GSPC.monthly == ifelse(as.numeric(last(GSPC.monthly))-as.numeric(GSPC.min) <
abs(as.numeric(last(GSPC.monthly)-as.numeric(GSPC.max))),GSPC.max,GSPC.min)]
#start monitoring from the max or min farthest away from current
mon5y <- bfastmonitor(GSPC.ts,
start=as.numeric(c(format(index(GSPC.eval),"%Y"),
format(index(GSPC.eval),"%m"))))

7 comments:

  1. New to R and the entier scene. When I try to run the script, get the following error:

    Error: could not find function "bfastmonitor"

    I have ensured that all the required packages are installed and available.

    Any suggestions?

    ReplyDelete
  2. Glad you are reading and trying. The key line here is (remove the #):

    #install r-forge development version of bfast
    #install.packages("bfast", repos="http://R-Forge.R-project.org")

    bfastmonitor is in the development version. Let me know if you have any more trouble.

    ReplyDelete
  3. I did install the bfast package separately and still couldnt get it working. Following errors and warnings appear:

    Warning: dependency ‘raster’ is not available
    trying URL 'http://R-Forge.R-project.org/bin/windows/contrib/2.14/bfast_1.4.4.zip'
    Content type 'application/zip' length 96007 bytes (93 Kb)
    opened URL
    downloaded 93 Kb

    package ‘bfast’ successfully unpacked and MD5 sums checked

    The downloaded packages are in
    D:\Users\Senthil\AppData\Local\Temp\Rtmpk983Wo\downloaded_packages
    Loading required package: bfast
    Loading required package: strucchange
    Loading required package: sandwich
    Loading required package: MASS
    Loading required package: forecast
    Loading required package: parallel
    Loading required package: tseries
    Failed with error: ‘package ‘tseries’ could not be loaded’
    In addition: Warning messages:
    1: package ‘strucchange’ was built under R version 2.14.2
    2: package ‘sandwich’ was built under R version 2.14.2
    3: In library(pkg, character.only = TRUE, logical.return = TRUE, lib.loc = lib.loc) :
    there is no package called ‘tseries’
    Error: could not find function "bfastmonitor"

    ReplyDelete
  4. Thanks for the reply. I already have installed 'bfast' package manually. Still the same error and additional info as follows:
    -----------------------------------
    Loading required package: fracdiff
    Failed with error: ‘package ‘fracdiff’ could not be loaded’
    In addition: Warning message:
    In library(pkg, character.only = TRUE, logical.return = TRUE, lib.loc = lib.loc) :
    there is no package called ‘fracdiff’
    Loading required package: quantmod
    Loading required package: Defaults
    Loading required package: xts
    Loading required package: TTR
    Loading required package: animation
    Error: could not find function "bfastmonitor"
    ---------------------

    package 'fracdiff' could not be found in CRAN.

    ReplyDelete
  5. Further to the above, i installed one by one all the required packages shown in errors. Now i got stuck at

    I cannot find ImageMagick with convert = "convert"
    Warning messages:
    1: running command 'convert --version' had status 4
    2: In im.convert(img.files, output = movie.name, convert = convert, :
    ImageMagick not installed yet!

    Now there are no package or function for 'ImageMagick'.

    Will keep on exploring.

    ReplyDelete
  6. well done with persistence. Unless you just really want the animated GIF, you can # comment out the lines

    saveGIF(
    and then the closing ) below }

    If you would like the animated GIF then install ImageMagick http://www.imagemagick.org/script/index.php.

    Let me know if I can be of any help.

    ReplyDelete
  7. Nice application of bfastmonitor. What bothers me is that the blue line fit is nowhere close to the actual time series. It is supposed to be the fit to the last "model-stable" period in the training set. I wonder what would happen if tested with the training set ending sometime in early 2005, and whether it would pick the lower slope after 2005 as a structural break in the time series. Thanks for your article.

    ReplyDelete