Tuesday, March 30, 2010

TTR_0.20-2 on CRAN

An updated version of TTR is now on CRAN. It fixes a couple bugs and includes a couple handy tweaks. Here's the full contents of the CHANGES file:

TTR version 0.20-2
Changes from version 0.20-1


NEW FEATURES:
  • Added VWAP and VWMA (thanks to Brian Peterson)
  • Added v-factor generalization to DEMA (thanks to John Gavin)

CHANGES:
  • Updated volatility() to handle univariate case of calc='close' (thanks to Cedrick Johnson)
  • Moved EMA, SAR, and wilderSum from .Fortran to .Call and used xts:::naCheck in lieu of TTR's NA check mechanism
  • RSI up/down momentum now faster with xts (thanks to Jeff Ryan)
  • If 'ratio' is specified in EMA but 'n' is missing, the traditional value of 'n' is approximated and returned as the first non-NA value (thanks to Jeff Ryan)

BUG FIXES:
  • Fix to stoch() when maType is a list and 'n' is not set in the list's 3rd element (thanks to Wind Me)
  • Fixed fastK in stoch() when smooth != 1
  • Fixed segfault caused by EMA when n < NROW(x) (thanks to Douglas Hobbs)
  • test.EMA.wilder failed under R-devel (thanks to Prof Brian Ripley)

24 comments:

Milk Trader said...

Can you describe how the various trading packages in R relate to one another. Specifically, xts, quantmod, blotter, lspm and ttr are the ones I'm interested in.

xts creates objects that are then passed into quantmod, I think. Is that right? How are the others related? It appears they are not competing packages, but rather complementary. Are there others I'm missing?

Joshua Ulrich said...

You're correct that they're complementary, but I would think of them as a toolkit rather than a workflow.

xts is a time series class; use it to store and manipulate data (e.g. convert it to/from other time series classes).

quantmod is probably best explained by the examples page on quantmod.com.

blotter keeps track instruments, transactions, portfolios and accounts for trading systems.

TTR contains technical indicators and other functions commonly used in creating trading algorithms.

LSPM contains functions to determine position size according to Ralph Vince's Leverage Space Portfolio Model.

You should look at:
quantstrat allows you to specify, build, and back-test quantitative financial trading and portfolio strategies.

PerformanceAnalytics is a library of econometric functions for performance and risk analysis and aims to aid practitioners and researchers in utilizing the latest research in analysis of non-normal return streams.

PortfolioAnalytics is a library of portfolio optimization and analysis routines and graphics.

Milk Trader said...

Thanks for quantstrat and Performance Analytics. Do any of these packages excel at the walk-forward technique, or out-of-sample backtesting on set-aside data whose parameters are determined by an objective function applied to a preceding window?

Let me explain that better. I'd like to determine a parameter set to trade a system for a pre-determined period, say six months. The first parameter set I choose is based on the most recent two years of backtest data. I run this "ideal" parameter set on the first six months of out-of-sample data and determine the results, which I set aside for later analysis. Then, I treat the six month out-of-sample data as in-sample data and choose my parameters based on a backtest of two years again. But this time, the oldest six months of original backtest data is replaced with the first walk-forward data (which was 6 months in our example). This technique is widely known and commonly used.

There is a matter of how one chooses the best parameters to walk-forward. Maximum net profit is the most intuitive, but not the ideal objective function. Other objective functions can get fairly complicated so the ability to program it is important.

Brian said...

PerformanceAnalytics has Return.portfolio and Return.rebalancing which can construct return series for portfolios based on a time series of weighting vectors.

PortfolioAnalytics has optimize.portfolio.rebalancing which conducts 'walk-forward' rebalancing on a periodic basis. All of the portfolio objectives in PortfolioAnalytics are layered and based on arbitrary R functions, not limited to simple single-objective or fixed approaches.

quantstrat does not yet have rebalancing or parameter optimization, though those functions will likely be added as parameterization is stabilized over the next couple months.

Milk Trader said...

It may be there is no R package for what I have in mind specifically, in which case maybe I can develop it.

Here is the basic idea.

Moving average crossover system that calculates the following results for each parameter set over 400 trading days.

Permutation #: 1
Parameter One: 10
Parameter Two: 30
Net Profit: 2,000
Max Drawdown: 3,000
Profit/Max DD: .6667
Perfect Profit: 100,000
Percent Perfect: .02
Correlation PP: .3211


And so on with data generation. But this is the start. Then, populate this array with results from each permutation.

Then, one would need to select a reasonable range of permutations and choose between brute force (for reasonable amount of permutations) or genetic algorithm, particle swarm (for unreasonable number of permutations).

Once this array is populated through permutation n, R would choose the one parameter set that exhibited the max or min of one of the elements of the array (eg, Maximum Net Profit). Once that parameter set is chosen, it is applied to the next 100 days of out-of-sample data and a new set of arrays would be populated. This process continues until you run out of data.

The results are then compiled into a new data frame that can be parsed for statistical analysis. ie, periodAverage <- mean(Results$NetProfit)

Many commercial off the shelf programs like TradersStudio, Amibroker and TradeStation (I believe) already do this, but doing this in R yields many advantages including the ability to script a set of statistical analysis, graph them and the like without being confined to a vendor-specific windowing interface. Extracting custom information from vectors is much easier than trying to generate custom views from the other programs as well.

Brian said...

Please consider adding any development effort to quantstrat. This is what quantstrat is designed for, and the next major area of development is parameterization of signals and indicators, followed closely by parameter optimization.

Milk Trader said...

Can you explain how far along quantstrat is in the development cycle? R Forge shows version 0.2. Does it become functional at 1.0? And where is the best place to find the package's author and how could I input some ideas on walk-forward.

Thanks!

Joshua Ulrich said...

quantstrat is functional, but still in alpha status (meaning it may undergo some design changes).

You've been corresponding with two of quantstrat's authors. ;-) The best way to make contributions is to checkout the quantstrat source (part of the TradeAnalytics project) from r-forge and email your patches to the package maintainer.

Milk Trader said...

Thanks Joshua. I also look forward to presentations at R/Finance 2010 in Chicago.

G$ said...

I suppose there isn't any further documentation yet, other than the index html page?

Joshua Ulrich said...

G$,

TTR has complete documentation. What are you referring to?

G$ said...

sorry, i was following the thread. I was referring to blotter and quantstrat

Joshua Ulrich said...

The documentation for blotter and quantstrat is not complete, but there is a lot more documentation than just the index page.

steffi said...

Is there any presentations from R/Finance 2010 published to the general public?

Joshua Ulrich said...

steffi,

The presenters have recently been contacted to ask their permission, so (most of) the presentations should be available in the next few weeks. I will post once they're online.

Jack said...

Joshua, the R-forge TradeAnalytics page seems to be down. Is there anywhere else we can obtain a copy of these packages? Thanks.

Joshua Ulrich said...

Jack,

All the servers at the Vienna University of Economics and Business were affected by an electrical system failure earlier this week.

It appears r-forge is still experiencing issues. I would expect it to be resolved in a day or two. Send me an email if you would like me to send you the source code (not Windows binaries).

phil said...
This comment has been removed by the author.
phil said...

I have just run the demo files (e.g. macross) in quantstrat and played a bit with it. I am trying to complete the scripts to perform trade performance analysis and was wondering if anyone knows a function in quantstrat/quantmod to extract P&L by trade.

My intent is to have a trade table from which i can use to apply performance criteria by strategy and then develop an optimising routine for the strategy parameters.

Since this is an important part of an algo trading module I thought it may be part of the package and I may not know where to find it.

Brian said...

In reply to phil:

the function getPortfolio will return the portfolio object, which includes all the realized and unrealized P&L by transaction and in the portfolio based on how you mark the book.

There are no summary reports yet. They just haven't been more important than creating the framework itself.

If you have suggestions for what should be in a summary report, we'd love to hear it. Even better, of course, would be to provide code to the community, which we could include in the approporiate package (with attribution, of course)

phil said...

Many thank Brian. I got this working and will write the code over the coming weeks. One question though. When I run the demo(macross) and extract the results using getPosition(), this is what comes out.

$AAPL$txn
Txn.Qty Txn.Price ...
1999-12-31 0 0.00 ...
2001-06-26 100 23.75 ...

...

what is the command to extract specific info from the transaction results part of getPosition() into a proper data frame. It doesn't work when I type APPL$Txn.Qty

Phil

Brian said...

phil,

Try 'getPortfolio' instead. This is a list which should contain everything you should need. None of these are data.frame, because all of this data is time series data. data.frames have some useful properties for tabular data, but these are time series, and need to be indexed and subset as time series, which is why we use xts for all of it. Basically, each list element is a time series, and should be able to be manipulated as such. Hope this helps...

phil said...

Brian,

See below for more info. I may not have been specific enough in my query and I am still learning my way through the blotter/xts. The analysis uses JJG as the stock

>is.xts(JJG)
[1] TRUE

>getTxns(s$name) # gives a subset of getPortfolio() results
$JJG$txn
Txn.Qty Txn.Price Txn.Value
2000-12-31 0 0.00 0
2009-05-31 1000 45.67 45670
2009-05-31 1000 45.67 45670
2009-05-31 1000 45.67 45670

My intent is to extract those results in a format which I can manipulate to calculate performance measures on which I will write an optimisation routine on the strategy parameters. Where I am struggling is to find the syntax to extract those.

it appears that the results are not xts
>is.xts(JJG$txn)
NULL

it's neither a data frame
>JJG$txn[]
NULL

i apologize if this may sound basic to some of you but I really want to learn it and spent a considerable amount of time in trial and errors. Help appreciate

Phil

Brian said...

Phil,

You haven't actually extracted anything using the syntax you've shown here. All you did was display the information to your screen.

You'd have to assign it to a variable to manipulate it.

The data for blotter is stored in a 'list', in 'slots' (any introductory R text should cover this)

getTxns() extracts these from the environment they're stored in, and makes them available to you to assign to a variable.

So, let's use a reproducible example:

require('blotter')

demo('amzn_test')

getTxns(Portfolio='amzn_port',Symbol='amzn')

# the above command will print stuff to your screen

#let's assign the returned data to a variable instead
amzn_txns<-getTxns(Portfolio='amzn_port',Symbol='amzn')

# now we'll check it
class(amzn_txns)

# gives:
# [1] "transactions" "xts" "zoo"

#and the test phil tried before
is.xts(amzn_txns)

# gives:
#[1] TRUE