Back to Community
OLMAR 3.0 using new order and history features

Hi,

I updated the Quantopian-classic OLMAR algorithm to demonstrate the power and expressiveness of our new features (read more about them here). For more information on the OLMAR algorithm look around on the forums or read the original paper here.

The most useful new order method I think is order_target_percent() which is perfectly suited for rebalancing a portfolio to achieve a certain allocation given a vector of percentages. Before, OLMAR required an involved function to calculate how many shares have to be bought at which price to achieve the desired portfolio allocation. This is now 2 lines.

The history() function also obviates batchtransform which was mostly used to just return a dataframe -- the new method does this directly rather than requiring you to write a separate, decorated function.

Clone Algorithm
234
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 52b2f98d5561200741be7137
This backtest was created using an older version of the backtester. Please re-run this backtest to see results using the latest backtester. Learn more about the recent changes.
There was a runtime error.
Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

21 responses

Thanks Thomas,

We could consider a modification to the code that would perform the time-scale optimization described in the paper (the so-called BAH(OLMAR) algorithm). If I follow the paper correctly, this would mean running the algorithm 28 times per call to handle_data (for window lengths of 3 to 30 days).

I'm unclear how the author performed the computation. He states that one should "combine multiple experts’ portfolios weighted by their historical performance." But, he may be talking about using the projected daily return. Any idea?

Grant

Here's the BAH(OLMAR) code posted by Ben Vibhagool (https://www.quantopian.com/posts/olmar-implementation-fixed-bug).

Clone Algorithm
72
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 52b42f4755612025015a72ac
This backtest was created using an older version of the backtester. Please re-run this backtest to see results using the latest backtester. Learn more about the recent changes.
There was a runtime error.

Yeah, I agree Grant. Seems like the code should be pretty copy&pastable, no?

Hello Thomas,

When I try to run your code with an alternate set of stocks, I get an error (details below). As you'll see, the code executes fine for a while, and then crashes.

Any ideas?

Grant


    # http://www.investopedia.com/stock-analysis/cotd/bbry20130206.aspx  
    # http://blogs.marketwatch.com/thetell/2013/05/20/12-stocks-to-ride-sp-500-volatility-to-profits/  
    context.stocks = [sid(19831),sid(26892),sid(11224),sid(2673),sid(3384),  
                      sid(3455),sid(6257),sid(5214),sid(14064),sid(21418),  
                      sid(23328),sid(22996),sid(7674),sid(2),sid(10594)]  

There was a runtime error. See the more detailed error below. If you need help, please send us feedback.
IndexError: index -1 is out of bounds for axis 0 with size 0
File test_algorithm_sycheck.py:69, in handle_data
File test_algorithm_sycheck.py:110, in olmar
USER ALGORITHM:145, in simplex_projection
rho = np.where(u > (sv - b) / np.arange(1, p+1))[0][-1]

Thomas,

It seems that to optimize the algorithm, a portfolio of volatile but uncorrelated stocks needs to be identified. Any ideas how to do this? Perhaps a screen with set_universe could be developed?

Grant

Grant,

Indeed, that seems like a good insight. Did the paper mention that?

One manual way to do this would be to simple iterate over each stock in the universe and sum up the correlation coefficients with all other stocks and select the n smallest ones. It's not ideal though as you need to identify a subset that together is uncorrelated. Sounds like a huge combinatorial nightmare. Anyway, that would probably be a good start.

One thing I'm not sure about is how to change the stocks of the traded universe. Do we just sell the ones we don't want to trade anymore? Seems like the only reasonable thing.

Thomas

P.S. Not sure about the error you're getting. Maybe it means that one of the stocks stopped trading?

Thanks Thomas,

I'll think about how to articulate a separate post regarding the screening.

Grant

Hello Thomas,

Here's my first attempt at eliminating the window length as a free parameter. If I coded it correctly, the algorithm computes the OLMAR portfolio (using volume weights) for window lengths from 3 to 30 days. Then, the optimal portfolio is computed by weighting each OLMAR porfolio by its expected return, and then forming a normalized linear combination of the portfolio vectors. Note that this is not the BAH(OLMAR) approach described in the paper, since I am using expected returns, not cumulative historical ones.

Cheers,

Grant

Clone Algorithm
86
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 52c048993662ab074a0abbbc
This backtest was created using an older version of the backtester. Please re-run this backtest to see results using the latest backtester. Learn more about the recent changes.
There was a runtime error.

Here's the same algorithm as above, except backtested with the epsilon parameter set to zero (an equal dollar weighting is maintained across the portfolio). The overall return for the active trading is 54% versus 40% for no algorithmic periodic re-allocation.

Clone Algorithm
86
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 52c06411d0725d0747a3e6f9
This backtest was created using an older version of the backtester. Please re-run this backtest to see results using the latest backtester. Learn more about the recent changes.
There was a runtime error.

Grant: Looks great! Although quite sobering results, but I guess we would need to test this on a larger universe over a longer time period.

That makes me wonder about comparison of algos/parameters. There must be some work on significance testing (e.g. is 54% really better than 40% or is that within the margin of error?).

Hi Thomas,

I've been fiddling with the algorithm, trying to understand the potential. One problem is that NaNs creep into the data (even with filling on). So, I devised some code to run the algo only when there are no NaNs. Please have a look at https://www.quantopian.com/posts/avoid-nans-w-slash-history-api-most-efficient-approach. I'd appreciate your input.

Grant

Hi,

I am not sure this is the latest post? It appears the algo is not interesting enough since the trading costs kill the results? In my opinion it is not a 'learning' algorithm. It is more a calculated heuristic formula which is run based on a fixed set of mathematical rules. A neural network which can be (re)trained or to which datasets can be added or removed is more something that is learning from it data. I believe this algorithm needs something to test in advance or during the run if a stock is still mean-reversing. If a stock is not, it won't attribute to a buy/hold strategy. Also a sell/hold (short) should be added so that the algo also has returns in a bear market.

I did not look into the BAT(OLMAR) yet. Are there still people out there to explore this algo, or is it offline due to unsufficient returns?

J.

Hello Quant Trader,

It's been awhile since I worked on this. I have not been able to get it to the point where it'd make sense in live trading with real money, but perhaps somebody else was successful.

Grant

Hi Grant,
Thank you for your update. I am just reflecting a couple of things here, and I am wondering if you are interested in making this algo to run. My findings are next:
1. I have added the OLMAR function also to the initialization part since I noticed that half of the portfolio is sold and new positions are bought upon initialization. By having the OLMAR algo run over the initial portfolio this won't happen.
2. I do not believe you should run this algo over a small set of stocks to beat the benchmark. This also is perfectly for stocks which do have a mean-reversion behaviour. If you do have a limited amount of stocks not having this behaviour, or the stocks selected do not beat the benchmark since the are simple the 'bottom' of the market a simple buy-hold-sell won't help. Basically all stocks should be added.
3. It does not make sense to have stocks in which are not mean-reversion, so stocks must be tested before adding to the portfolio.
4. Adding a whole bunch of stocks is fine once they behave similar to the index and you do not change your portfolio often. If that happens you are making the broker rich, or market is quite volatile and then the question is if this behaviour is allowed. I was thinking of a set of 100 stocks and only trade with half of them? Then the good performers stay in, and the losers are changed by new winners.
5. I would also like to experiment with the volume/ price history. What if the volume is faster, so detecting a momentum of volume instead of price?
6. Trading costs are for stocks limited to 5 USD per trade? So only trade if it makes sense to earn 5 USD by a portfolio change?
7. I believe the BAH(OLMAR) algorithm should be implemented. If you look at the paper you see that its behaviour is flat and less dependent on epsilon and stock market used. I believe this also makes sense, the window in which stocks change momentum or are mean reverting are not the same, so it makes sense to buy a stock with a half life of 5 days and sell it after 10 days, and buy another stock with a different 'speed' / half life time of 30 days and sell it after 60 days.

In general I believe this algo has some potential since statistically it takes the best hold-buy stocks at their best moments. That means if you would buy the complete benchmark you would also buy the worst hold-buy stocks. So this algo must outperform the benchmark (a large spectrum of stocks).

Are you interested in teaming up? GitHub is in my Visual Studio / PVTS so we can exchange easily if you like. I would like to run it also offline with data from yahoo or other sources since I need the intellisense and step-in-step debugger to see how Python works :-).

J.

Hi J./Quant Trader,

Thanks for the offer to collaborate. I've scaled back my efforts on Quantopian, and have some other interests and obligations.

Best wishes,

Grant

Hi,

I encounter next error:

IndexError: index out of bounds

USER ALGORITHM:253, in simplex_projection

rho = np.where(u > (sv - b) / np.arange(1, p+1))[0][-1]  

Is there a way to find out when it occurs? It would be nice to have more 'dump' with data. For instance the data to limit debugging. I will add a try-catch .

J.

J, are you still experiencing the IndexError? If so, you can invite me to the algorithm via collab ([email protected]) and I'll help debug. We'll get the code up and running!

Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

I updated the code to use the new schedule_function() which cleans it up quite a bit.

Clone Algorithm
137
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 549e9b46ad2987287ccb3852
There was a runtime error.

Hi,
New here :)

Thank you for the algo, it seems amazing, I've tried to use the universe function and set the context.stocks to that universe but I keep getting the same error as someone mentioned before:

IndexError: index out of bounds

USER ALGORITHM:141, in simplex_projection

rho = np.where(u > (sv - b) / np.arange(1, p+1))[0][-1]  

Alisa, I've invited you to collaborate as you suggested above, i hope that's fine.
Once i'll get the backtest running i'll share the results here as well.

Thanks,
Z.

Hi Z and welcome to Quantopian,

I also tried changing the algorithm but it turns out that it's quite tricky. The reason is that as the universe changes (new symbols come in, old ones drop out), we have to update the portfolio vector (context.b I think) as well in a clever way and have to exit positions of symbols that disappeared. I gave this a fair shot quite a while back but couldn't get it to work so it probably requires some tinkering. Having said that, I think it would be great if the algorithm could work with a universe.

Thomas

I'm attaching my attempt from back then. It seems to run at least and you can see the logic. I think the problem is that not necessarily the size changes (as the logic implements here-within) but the symbols and there is no mechanism I know which tells you which symbols appeared and disappeared during universe roll-over. Another issue is that this is an older OLMAR algorithm (probably v2).

Clone Algorithm
224
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 54e59b5690d23654078018ec
There was a runtime error.