Category Archives: adaptive


No, it’s not french and it’s not the movie.
It’s a fast-N-rough “Adaptive Multi strategy Multi Instrument” model.

Let’s assume we want to trade mean-reversion: If price moves down we buy, if it moves up we sell.

Possible Indicators from the blog-o-sphere:
DV2 here and here
BSI here or here
CRSI here
TD9 here

Question 1: Which Indicator to use?

One way to choose an indicator is to run backtests for each one (and each one’s parameters) and pick the one that has performed the best in the recent past. “Performance” can be pure profit or it can be any other metric we choose:  CAR/MDD (annual return/MaxDrawdown), Profit Factor, Expectancy or your very own “Bliss function“.
So if DV2 has performed best in the past 6 months, maybe we should use that to trade for the next few weeks.

Question 2: What should we trade? 

Just one instrument?
Why not backtest all indicators on all instrument and let the data tell us which instrument behaves best with which indicator? We can then trade that one. Did someone say “overfit”?.
Why not a bunch of instruments? A portfolio! Yes and we ‘ll throw some weights in there, too:
30% SPY 10% AAPL 10% XLU 20% IBM 30% GLD  … wightN*InstrumentN

I guess now we have to backtest the different indicators with these different weights on our instruments, too. What are we doing here? Let’s step back.

Question 3: What are we doing here?

We start with a set of selected assets (StockA, StockB,… StockN).
We bring in a  set of selected indicators (ind1, Ind2, …IndN).
We then build an “ammi” that picks and chooses from these two universes.
We optimize that “ammi” using some type of non-exhaustive optimization technique.

In other words we are creating a portfolio and trading each instrument inside the portfolio with each own indicator/strategy. So what’s the catch? There’s nothing new here. We could just trade SPY with DV2 and AAPL with RSI(3). Allocate 30% of capital to strategy “SPY” and 10% to strategy “AAPL”. Is there an advantage in mixing it all up?

For the purposes of this post we will assume:
1. Our optimizing target  is % profit.
2. We are investing a fixed percentage of current equity on each trade (i.e., 10% of Equity). In other words we are compounding.

By optimizing one instrument and one strategy, the optimizer will look for the most consistent “timing” to enter and exit trades.

By optimizing the whole AMMI, the optimizer is handed one more tool. Since it wants to maximize compound profit it can do so by minimizing max drawdown which in turn gets accomplished by minimizing correlations between the “weighted and traded” equity curves. So, in theory, the optimizer should not necessarily choose the best timing of each instrument/indicator but rather the best combination of instruments/strategies that are somewhat profitable and least correlated*. We hope that this criterion is more robust criterion than just timing.

Almost forgot! We also want to be able to change both the “instrument” and the “strategy” as time passes. That means we re-optimize every x days and trade with the fresh settings. Hence, the “Adaptive Multi strategy Multi Instrument” , a.k.a, AMMI, nick-name.

For the sake of simplicity, we will consider indicators RSI(2), RSI(3) and RSI(4). Possible thresholds are 0–>50 for a Buy signal and 50–>100 for a Sell signal. We will use 10 instruments that can have weights ranging from 5% –> 100%. We assume the standard 2x leverage can be used.

Let’s run an Out Of Sample test. In_Sample (IS) Optimization period is 2 years, Out_Of_Sample trading period (OOS) is 3 months.**
Optimization is done using Amibroker’s non-exhaustive CMAE plug-in set to run very few “runs” so as not to overfit (and not wait too long…). Target for the optimization is pure % Profit (hence the huge draw-downs).

Here’s the  result trading a few instruments and using RSI(2), RSI(3) and RSI(4) as possible indicators with varied thresholds. This is an OOS (out of sample, i.e., realistic) equity. At 40%+ (in the “good” version) draw-downs, it’s not something I would trade***. It’s just for illustration purposes.

Again. this is a rough “model”. It is best used as a starting point to get ideas going. It might also help to get a sense of how different data groups react to different indicators.  Instead of mean reverting indicators you could have trend following , or pattern based indicators. And instead of optimizing precise values you could fuzzify them.

* Adding a losing strategy to a profitable strategy may increased the Sharpe Ratio of the system.

**The In-Sample optimization will gives us the weights on the instruments as well as the indicator and the thresholds that were used to produce the best performance. An example would be 5% InstrA, 0% InstrB, 0%InsrC,70% InstrD,100% InstrE, 25% InstrF, etc. Indicator would be RSI(4) and lower and upper thresholds would be 30 and 70. Those set of parameters whould then be used to trade “live” (Out-Of-Sample) for the next three months. After that we would re-optimize (inclusive of the 3 months that were traded) and change param for the next 3 months.

***Unless you know what you are doing, optimizing a system for Max Profit, is a fairly bad idea. It will tend to pick few winners and not diversify (i.e., in hindsight it will tend to pick 100% APPLE). 


The code in Amibroker:

//----Code by Sanz P.-----------------------------------------------------//
//----Place the instruments on a watchlist and select it under Parameters
//----Optimize/Walk Forward on that watchlist
function Set2D( tablename, x, y, value )
{VarSet( tablename + StrFormat("%03.0f%03.0f", x, y ), value );}
function Get2D( tablename, x, y )
{return VarGet( tablename + StrFormat("%03.0f%03.0f", x, y ) );}
OptimizerSetOption("Runs", 3 );
OptimizerSetOption("MaxEval", 300 );
WatchlistNumber =Param("Choose Watchlist with Tickers",12,0,30,1);
TickerList= CategoryGetSymbols( categoryWatchlist , WatchlistNumber ) ;
for( n=0; (instrument=StrExtract( TickerList, n)) != ""; n++)
set2d( tablename, n, 0, n );
for( n=0; (instrument=StrExtract( TickerList, n)) != ""; n++)
set2d( tablename, n, 1 , Optimize("Ticker"+n+ "Position",20,0,50,5) ); //pos
set2d( tablename, n, 2 , Optimize("Ind"+n,2,0,2,1) ); //ind
set2d( tablename, n, 3 , Optimize("Thrsh"+n,20,0,100,5) ); //thr
for( n=0; (instrument=StrExtract( TickerList, n)) != ""; n++)
if (Name()== instrument)
indicatorcode=get2d( tablename, n, 2 );
case 0:
case 1:
case 2:
PositionSize= - get2d( tablename, n, 1 );
thresh=get2d( tablename, n, 3 );

Better than mean-reversion? An Adaptive Multi-Strategy System

Mean reversion strategies have been very popular since 2009. They have performed exceptionally well for the past 10 years, performing well even during the 2008-09 bear market. Different versions have been popularized, notably by Larry Connors and Cezar Alvarez (previous post) as well as many others in the blog-o-spere such as David Varadi of CSS analytics (DV2) and Michael Stokes @ MarketSci. Some use the RSI indicator, some use a short term simple moving average, some use boillinger bands, etc. The concept is the same: If price moved up  today, it will tend to revert (come down) tomorrow.

Here’s a couple of simple mean reverting strategies using a short term RSI (Relative Strength Index) , trading the ^GSPC index. They buy on oversold and sell on overbought. Long only.

Looks nice, doesn’t it? We barely see the 2008-2009 draw-down that  Buy-N-Hold suffered.
There is a “but”…

Look at the same strategy starting in 1960:


This is telling us that for the last 10 years the market has changed and has become mean reverting. There might be fundamental reasons for this and although it is unlikely the market will return to pre-2000 behavior, it is not inconceivable.

Let’s say we traded the oposite strategy. Buy if short term RSI is high, sell if it’s low.

As expected, it does well up to 2000, then it’s a disaster. Notice that for the period 2010-2012, it has not performed as badly as expected. Others on the blog-o-spere have mentioned this: Mean-reverting strategies have not performed as well starting 2010.

So knowing what we now know, how would an adaptive strategy work.

The Master strategy Includes:
A. 6 Mean Reversion strategies:
Instead of deciding on which RSI period and thresholds to use, we use 6 different versions (RSI(2), RSI(3) and RSI(4), each with different thresholds).
2. One Non-Mean-Revting strategy: If RSI(2) crosses 50 up then buy. If it crosses below, sell.

Allocation Rules:
We measure risk adjusted performance for the last 600 bars for each of the 7 strategies. The top 5 get allocated capital;
Best gets 50% of account to trade with
2nd gets 40. 3rd gets 30, etc.
Total allocation is 150%, meaning if all strategies were trading we would have to use 1.5x leverage.

In the second pane, the graph represents positions taken by the trend-following strategy.
In the third pane, the graphs represent positions taken by the various mean reverting strategies.

Up to 2002 the system takes positions mostly in the trend following strategy while starting as early as 1996 mean-reverting strategies start increasing positions and eventually take over by 2004.
Keep in mind that although the graph looks great, there is a 3 year period (2000-2003) of continuous draw-down as the environment changes and the strategy tries to adapt.

You may also notice that the “trend-following” RSI strategy (buy on up, sell on down) briefly started traded in August 2011, after being inactive for 9 years… Something to think about.