Inferring latent states using a Gaussian Hidden Markov Model

Example inspired by a scikit-learn example. I used this during my talk at the NYSE meetup earlier this week.

The idea is to predict hidden states in the daily price fluctuations and trading volume using a Hidden Markov Model (see the graphic). This model essentially assumes the existence of discrete hidden states. Each hidden state is associated with a certain probability of moving to another state at the next time point (thus, the current state is dependent on the previous one -- that's the Markov property). In addition, each hidden state is associated with emitting an observable event (in this case, fluctuation and volume) with a certain probability. This example tries to infer the hidden state transition probabilities, the observable events emitted, and then try to predict the hidden state of the current market.

wikipedia

Since we are continuously recomputing the HMM I set the previously learned means as a prior for the next model. So we are using the observed states we already learned for the next model.

Finally, this is so far just an analysis. Turning this into a trading strategy would require inferring what specific states mean and then place orders in response to that. This might not be quite as easy (you might want to look at the inferred means for this). But the Markov assumption that the current state depends on the previous will almost certainly be violated at least for the price fluctuations -- it is a well known fact that returns have almost 0 autocorrelation. Volume does, however, have autocorrelation so it might work better there. In addition, it's not clear that there are discrete states underneath. The state space could be continuous. If that's the case, a Kalman filter might be interesting to explore.

Clone Algorithm
285
Loading...
Backtest from to with initial capital ( data)
Custom data:
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Information Ratio
--
Benchmark Returns
--
Volatility
--
Max Drawdown
--
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
Information Ratio 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
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.
14 responses

Sorry to revive an old thread, but is their a video accompanying the NYSE link? I would love to see it!
Thanks,
Brandon

Hi Thomas, I agree with Brandon, it would be nice to look at the video, or at least to have access to the material of the presentations.

Hi guys,

Unfortunately there was no video recording of this talk. The notebook I used also has less descriptions than what can be found here. I'm happy to try and do a better job explaining what's going on (but note that there are good resources on HMMs online as well).

Related, Jess and I have been talking about how to extend this strategy so if something results from that we'll update it and hopefully provide a better description.

Thomas

Hello, I'm getting this compiling error on your alto.

Nonexistent property: variation on line 54.

Hi Marc,

I updated the backtest to use the more modern features available on Quantopian. To retrain the model monthly I'm using the new schedule_func (https://www.quantopian.com/help#ide-schedulefunction) and instead of a batch_transform I'm using history.

Let me know if you have any questions.

Thomas

Clone Algorithm
285
Loading...
Backtest from to with initial capital ( data)
Custom data:
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Information Ratio
--
Benchmark Returns
--
Volatility
--
Max Drawdown
--
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
Information Ratio 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
There was a runtime error.

Hi Thomas, your algo doesnt seem to load anymore, could you post it again?

Peter, did you use the last one I posted in this thread? That one works fine for me. Can you post the error you are getting?

Hi Thomas, it looks like you have a scheduled function for training. On live trading, would this execute in parallel with the algorithm, or does the algorithm wait until training is complete?

Grant, the algorithm would wait for the training to complete.

Ok, by the way, is there any support for long processes that execute outside of market hours?
If I started a task at market close, could it execute overnight or over the weekend?

Currently that's not implemented as we shut down the algos over night and restart them a few hours before open, but it's an interesting idea!

Hello Thomas,

What about before_trading_start(context)?

I posted some questions on https://www.quantopian.com/posts/before-trading-start-does-it-time-out, and on https://www.quantopian.com/posts/history-not-working-in-before-trading-start Grant Kot had asked when before_trading_start gets called prior to market open? So, depending on the answers, there could be a goodly chunk of time overnight to run code, right?

Also, above, you say "the algorithm would wait for the training to complete" but doesn't the standard 50-second time-out for handle_data also apply to a scheduled function? Or could bars be skipped while the scheduled function completes?

Grant

just wondering: i saw that the hmm functionality is deprecated in the current scikit version. will there be a workaround when you guys upgrade to 0.17 (and the hmm will be dropped from scikit) ?
thx

That's a good question. There's nothing planned right now but something like https://github.com/mattjj/pyhsmm would be really cool.