Friday, August 12, 2011

Introduction to quantstrat

quantstrat provides a generic infrastructure to model and backtest signal-based quantitative strategies.  It is a high-level abstraction layer (built on xts, FinancialInstrument, blotter, etc.) that allows you to build and test strategies in very few lines of code.  quantstrat is still under heavy development but is being used every day on real portfolios.  We encourage you to send contributions and test cases to the project forums.

This post is a joint effort between me and Brian Peterson.  It will describe the underlying philosophy of quantstrat and how quantstrat implements that philosophy.  You may have seen some of this in Brian's Quantitative Strategy Development in R lightning talk at R/Finance 2011.

Generic Signal-Based Strategy Modeling

A signal-based strategy model first generates indicators.  Indicators are quantitative values derived from market data (e.g. moving averages, RSI, volatility bands, channels, momentum, etc.).  Indicators should be applied to market data in a vectorized (for fast backtesting) or streaming (for live execution) fashion, and are assumed to be path-independent (i.e. they do not depend on account / portfolio characteristics, current positions, or trades).

The interaction between indicators and market data are used to generate signals (e.g. crossovers, thresholds, multiples, etc.).  These signals are points in time at which you may want to take some action, even though you may not be able to.  Like indicators, signals may be applied in a vectorized or streaming fashion, and are assumed to be path-independent.

Rules use market data, indicators, signals, and current account / portfolio characteristics to generate orders.  Notice that rules about position sizing, fill simulation, order generation / management, etc. are separate from the indicator and signal generation process.  Unlike indicators and signals, rules are generally evaluated in a path-dependent fashion (path-independent rules are supported but are rare in real life) and are aware of all prior market data and current positions at the time of evaluation.  Rules may either generate new or modify existing orders (e.g. risk management, fill, rebalance, entry, exit).

How quantstrat Models Strategies

quantstrat uses FinancialInstrument to specify instruments (including their currencies) and uses blotter to keep track of transactions, valuations, and P&L across portfolios and accounts.

Indicators are often standard technical analysis functions like those found in TTR; and signals are often specified by the quantstrat sig* functions (i.e. sigComparison, sigCrossover, sigFormula, sigPeak, sigThreshold).  Rules are typically specified with the quantstrat ruleSignal function.

The functions used to specify indicators, signals, and rules are not limited to those mentioned previously.  The name parameter to add.indicator, add.signal, and add.rule can be any R function.  Because the supporting toolchain is built using xts objects, custom functions will integrate most easily if they return xts objects.

The strategy model is created in layers and makes use of delayed execution.  This means strategies can be applied--unmodified--to several different portfolios.  Before execution, quantstrat strategy objects do not know what instruments they will be applied to or what parameters will be passed to them.

For example, indicator parameters such as moving average periods or thresholds are likely to affect strategy performance.  Default values for parameters may (optionally) be set in the strategy object, or set at call-time via the parameters argument of applyStrategy (parameters is a named list, used like the arguments lists).

quantstrat models orders, which may or may not become transactions.  This provides a lot of extra ability to evaluate how the strategy is actually working, not working, or could be improved.  For example, performance strategies are often affected by how often resting limit orders are changed / replaced / canceled.  An order book allows the quantitative strategist to examine market conditions at the time these decisions are made. Also, the order history allows for easy computation of things that are important for many strategies, like order-to-fill ratios.

What's next?
  • Examples!  You can run some demos while you wait:
  • Strategy Evaluation
  • Parameter Evaluation


Var said...

Great idea, Josh. I'm looking forward to seeing the next posts! I think this will help many of us make a better use of Quantstrat. Many thanks!

Anonymous said...

package quantstrat is not available (for R version 2.13.1)

need manual compilation?

Thank you for your work, really helpful!

FBSP said...

From windows:

install.packages("quantstrat", repos="")
Installing package(s) into ‘C:/Users/Res1/Documents/R/win-library/2.13’
(as ‘lib’ is unspecified)
Warning in install.packages :
package ‘quantstrat’ is not available (for R version 2.13.1)

What do I do?

Joshua Ulrich said...

arippbbc and FBSP,

There's some issue with R-forge building quantstrat. We're working with the R-forge maintainers to find a solution.

In the meantime, you can try some of the solutions in the Windows packages section of the R Installation and Administration manual (e.g. win-builder).

FBSP said...

After I setup my windows box to compile R packages - using this link as a guide

(I did have manually add R to my system path variable.)

I was able to build blotter, FinancialInstrument, and quantstrat from source and and install it by following the directions on this post

JU if you send me an email I will send you the package tar.gz files that were created.

Joshua Ulrich said...

The Windows binary of quantstrat is now building on R-forge.

RaviAranke said...

FBSP's solution works for me.

loc said...

Try this:

Novice Pete said...

Hi all,
I'm very new to R but looking at getting the Quantstrat package but i can't manage /don't understand the method outlined above, can anyone either explain it in layman/idiot terms or provide an alternative solution?

Novice Pete said...

Just to let people know I have downloaded rtools but i didn't understand the next instructions regarding path setup in the links provided.

Joshua Ulrich said...

Hi Pete,

Garrett See has a nice answer on stackoverflow about how to build R-Forge packages from source.

Morten said...


Nice post, very helpful with demos and examples, thanks.

I tried running the example code directly from the post without any changing anything and I got the result that no trades were generated in:


although the and changed several times
between 0/1 in the out variable:

out <- try(applyStrategy(strategy=stratFaber, portfolios="faber"))

I'm running
R version 2.15.2 from Rstudio
quantstrat 0.7.7
blotter 0.8.13

Am I missing somthing, or does the example simply not work
on newer versions?

KR Morten