Saturday, February 6, 2010

Updated Tactical Asset Allocation Results

In November, I used the strategy in Mebane Faber's Tactical Asset Allocation paper to provide an introduction to blotter. Faber has updated the strategy's results through the end of 2009. For those interested, he expands on the paper in his book, The Ivy Portfolio.

Friday, February 5, 2010

R/Finance 2010: Registration Open

As posted by Dirk Eddelbuettel on R-SIG-Finance:

R / Finance 2010: Applied Finance with R
April 16 & 17, Chicago, IL, US

The second annual R / Finance conference for applied finance using R, the premier free software system for statistical computation and graphics, will be held this spring in Chicago, IL, USA on Friday April 16 and Saturday April 17.

Building on the success of the inaugural R / Finance 2009 event, this two-day conference will cover topics as diverse as portfolio theory, time-series analysis, as well as advanced risk tools, high-performance computing, and econometrics. All will be discussed within the context of using R as a primary tool for financial risk management and trading.

Invited keynote presentations by Bernhard Pfaff, Ralph Vince, Mark Wildi and Achim Zeileis are complemented by over twenty talks (both full-length and 'lightning') selected from the submissions.  Four optional tutorials are also offered on Friday April 16.

R / Finance 2010 is organized by a local group of R package authors and community contributors, and hosted by the International Center for Futures and Derivatives [ICFD] at the University of Illinois at Chicago.

Conference registration is now open. Special advanced registration pricing is available, as well as discounted pricing for academic and student registrations.

More details and registration information can be found at the website at

                      http://www.RinFinance.com

For the program committee:

    Gib Bassett, Peter Carl, Dirk Eddelbuettel, John Miller,
    Brian Peterson, Dale Rosenthal, Jeffrey Ryan

I hope to meet some of you there!

Sunday, January 10, 2010

LSPM with snow

My last post provided examples of how to use the LSPM package. Those who experimented with the code have probably found that constrained optimizations with horizons > 6 have long run-times (when calc.max >= horizon).

This post will illustrate how the snow package can increase the speed of the probDrawdown and probRuin functions on computers with multiple cores. This yields nearly linear improvements in run-times relative to the number of cores. (Improvements are nearly linear because there is overhead in setting up the cluster and communication between the nodes.)

The first optimization takes 346 seconds on my 2.2Ghz Centrino, while the second optimization (with snow) takes 193 seconds... nearly a 45% improvement.

# Load the libraries
library(LSPM)
library(snow)

# Create a Leverage Space Portfolio object
trades <- cbind(
c(-150,-45.33,-45.33,rep(13,5),rep(79.67,3),136),
c(253,-1000,rep(-64.43,3),253,253,448,rep(-64.43,3),253),
c(533,220.14,220.14,-500,533,220.14,799,220.14,-325,220.14,533,220.14) )
probs <- c(rep(0.076923077,2),0.153846154,rep(0.076923077,9))
port <- lsp(trades,probs)

# Optimization using one CPU core
system.time({
res1 <- optimalf(port,probDrawdown,0.1,DD=0.2,horizon=5,control=list(NP=30,itermax=100))
})

# Create snow socket cluster for both cores
clust <- makeSOCKcluster(2)

# Optimization using both CPU cores
system.time({
res2 <- optimalf(port,probDrawdown,0.1,DD=0.2,horizon=5,snow=clust,control=list(NP=30,itermax=100))
})

# Stop snow cluster
stopCluster(clust)

Saturday, January 2, 2010

LSPM Examples

I have received several requests for additional LSPM documentation over the past couple days and a couple months ago I promised an introduction to LSPM.

In this long-overdue post, I will show how to optimize a Leverage Space Portfolio with the LSPM package.  Please use the comments to let me know what you would like to see next.

Some copious notes before we get to the code:

These examples are based on revision 26 31 from r-forge and will not work under earlier revisions (and may not work with later revisions). LSPM is still in very alpha status.  Expect things to change, perhaps significantly.

These examples were run using DEoptim_1.3-3 (and LSPM revision 26 depends on that version) code from DEoptim_1.3-3 that has been bundled inside LSPM.  We are working with the DEoptim authors to address issues with more recent versions of DEoptim.  LSPM will un-bundle and use the most recent version of DEoptim as soon as the issues are resolved.

The first two examples are taken from Vince, Ralph (2009). The Leverage Space Trading Model. New York: John Wiley & Sons, Inc. The results will not match the book because of differences between optimization via DEoptim and Ralph's genetic algorithm implementation.  Ralph believes his genetic algorithm is getting hung up on a local maximum, whereas DEoptim is closer to the global solution.

    # Load the LSPM package
    library(LSPM)

    # Multiple strategy example (data found on pp. 84-87)
    trades <- cbind(
     c(-150,-45.33,-45.33,rep(13,5),rep(79.67,3),136),
     c(253,-1000,rep(-64.43,3),253,253,448,rep(-64.43,3),253),
     c(533,220.14,220.14,-500,533,220.14,799,220.14,-325,220.14,533,220.14) )
    probs
    <- c(rep(0.076923077,2),0.153846154,rep(0.076923077,9))
     

    # Create a Leverage Space Portfolio object
    port <- lsp(trades,probs)

    # DEoptim parameters (see ?DEoptim)
    # NP=30        (10 * number of strategies)
    # itermax=100  (maximum number of iterations)
    DEctrl
    <- list(NP=30,itermax=100)

    # Unconstrainted Optimal f (results on p. 87)
    res
    <- optimalf(port,control=DEctrl)

    # Drawdown-constrained Optimal f (results on p. 137)
    # Since horizon=12, this optimization will take about an hour
    res
    <- optimalf(port,probDrawdown,0.1,DD=0.2,horizon=12,calc.max=4,control=DEctrl)

    # Ruin-constrained Optimal f
    res
    <- optimalf(port,probRuin,0.1,DD=0.2,horizon=4,control=DEctrl)

    # Drawdown-constrained Optimal f
    res
    <- optimalf(port,probDrawdown,0.1,DD=0.2,horizon=4,control=DEctrl)

    Wednesday, November 18, 2009

    Tactical asset allocation using blotter

    blotter is an R package that tracks the P&L of your trading systems (or simulations), even if your portfolio spans many security types and/or currencies. This post uses blotter to track a simple two-ETF trading system.

    The contents of this post borrow heavily from code and comments in the "longtrend" demo script in the blotter package. Many thanks to Peter Carl and Brian Peterson for their hard work.

    The first chart shows the result of holding an equal-weight portfolio of SPY and IEF from 2002-07-31 to 2009-10-31. The 2008 bear market led to a 30% drawdown in this portfolio.


    The second chart shows the result of following Mebane Faber's tactical asset allocation approach using the same ETFs and time period. Though it did not perform as well as buy-and-hold through 2007, the 2008 bear market only caused a 5% drawdown for this strategy. Both observations are consistent with the conclusion in Faber's article.


    Without further ado, here's the code:

    # This code implements the strategy found in:
    # Faber, Mebane T., "A Quantitative Approach to Tactical Asset Allocation."
    # Journal of Risk Management (Spring 2007).

    # The article implements a simpler version of the 200-day SMA, opting for a
    # 10-month SMA because monthly data are more easily available in earlier
    # periods and lower granularity should translate to lower transaction costs.

    # The rules of the system are relatively simple:
    # - Buy when monthly price > 10-month SMA
    # - Sell and move to cash when monthly price < 10-month SMA

    # 1. All entry and exit prices are on the day of the signal at the close.
    # 2. All data series are total return series including dividends, updated monthly.
    # NOTE: For the purposes of this demo, we only use price returns.
    # 3. Cash returns are estimated with 90-day commercial paper. Margin rates for
    # leveraged models are estimated with the broker call rate.
    # NOTE: For the purposes of this demo, we ignore interest and leverage.
    # 4. Taxes, commissions, and slippage are excluded.

    # Data:
    # This demo uses monthly data downloaded from Yahoo Finance for two ETFs: SPY and
    # IEF. These were chosen to illustrate the classic stock/bond asset portfolio.
    # Though longer serires would be preferred, data for IEF begin in mid-2002.

    # Load required libraries
    library(quantmod)
    library(TTR)
    library(blotter) # r-forge revision 193
    library(PerformanceAnalytics)

    # Set initial values
    initDate='2002-07-31'
    endDate='2009-10-31'
    initEq=100000

    # Set currency and instruments
    currency("USD")
    stock("IEF",currency="USD",multiplier=1)
    stock("SPY",currency="USD",multiplier=1)

    # Load data with quantmod
    print("Loading data")
    symbols = c("IEF", "SPY")
    getSymbols(symbols, from=initDate, to=endDate, index.class=c("POSIXt","POSIXct"))

    # Adjust prices for splits/dividends (thanks pg)
    #IEF = adjustOHLC(IEF)
    #SPY = adjustOHLC(SPY)

    # Convert data to monthly frequency (to.weekly() needs drop.time=FALSE)
    IEF = to.monthly(IEF, indexAt='endof')
    SPY = to.monthly(SPY, indexAt='endof')

    # Set up indicators with TTR
    print("Setting up indicators")
    IEF$SMA = SMA(Cl(IEF), 10)
    SPY$SMA = SMA(Cl(SPY), 10)

    # Set up a portfolio object and an account object in blotter
    initPortf(name='default', symbols=symbols, initDate=initDate)
    initAcct(name='default', portfolios='default', initDate=initDate, initEq=initEq)
    verbose = TRUE

    # Create trades
    for( i in 10:NROW(SPY) ) {
      CurrentDate=time(SPY)[i]
      equity = getEndEq(Account='default', CurrentDate)

      for( symbol in symbols ) {
        sym = get(symbol)
        ClosePrice = as.numeric(Cl(sym[i,]))
        Posn = getPosQty(Portfolio='default', Symbol=symbol, Date=CurrentDate)
        UnitSize = as.numeric(trunc((equity/NROW(symbols))/ClosePrice))

        # Position Entry (assume fill at close)
        if( Posn == 0 ) {
        # No position, so test to initiate Long position
          if( Cl(sym[i,]) > sym[i,'SMA'] ) {
            # Store trade with blotter
            addTxn('default', Symbol=symbol, TxnDate=CurrentDate,
              TxnPrice=ClosePrice, TxnQty=UnitSize, TxnFees=0, verbose=verbose)
          }
        } else {
          # Have a position, so check exit
          if( Cl(sym[i,]) < sym[i,'SMA'] ) {
            # Store trade with blotter
            addTxn(Portfolio='default', Symbol=symbol, TxnDate=CurrentDate,
              TxnPrice=ClosePrice, TxnQty=-Posn, TxnFees=0, verbose=verbose)
          }
        }
      } # End symbols loop

      # Calculate P&L and resulting equity with blotter
      updatePortf(Portfolio='default', Dates=CurrentDate)
      updateAcct(name='default', Dates=CurrentDate)
      updateEndEq(Account='default', Dates=CurrentDate)

    } # End dates loop
     
    # Buy and Hold cumulative equity
    buyhold = cumprod( ( 1 + 0.5*ROC(Cl(IEF)) + 0.5*ROC(Cl(SPY)) )[-1] )

    # Final values
    cat('Tactical Asset Allocation Return: ',(getEndEq(Account='default', Date=CurrentDate)-initEq)/initEq,'\n')
    cat('Buy and Hold Return: ',tail(buyhold,1)-1,'\n')

    # Plot Strategy Summary
    png(filename="20091118_blotter_strategy.png", 720, 720)
    charts.PerformanceSummary(ROC(getAccount('default')$TOTAL$End.Eq)[-1],main="Tactical Asset Allocation")
    dev.off()

    # Plot Buy and Hold Summary
    png(filename="20091118_blotter_buyhold.png", 720, 720)
    charts.PerformanceSummary(ROC(buyhold)[-1],main="Buy & Hold")
    dev.off()

    Thursday, November 5, 2009

    opentick alternatives

    I've been getting a bit of traffic from people searching for opentick (the defunct company), so I've started a list of similar (but non-free) data providers.

    I'm not affiliated with any of these vendors, and the list is in no particular order. I'll update this post as more information becomes available.

    IQFeed
    - features, fees, API**
    - starts at $60/month*
    - OS: Windows
    - Same API as DTN.IQ

    eSignal
    - features, fees, API**
    - starts at $125/month*
    - OS: Windows

    eoddata
    - features, fees, API
    - some data are free, as low as 1-minute intraday data for $19.95/month
    - OS: Windows

    Notes:
    * plus exchange fees
    ** API access may cost extra

    Sunday, October 18, 2009

    Xasax closes shop

    Six months after shutting down opentick completely Xasax (opentick's parent company) has followed suit.

    It looks like Xasax hit funding problems in August... Inside Market Data mentions the above in this story. Here is the full story (subscription required).