I very new to this, and I've written this (my first) mean reversion algo which calculates a hedge ratio using linear regression between USO and GLD and then buys/sells depending on the deviation of the portfolio price from the mean. It hasn't turned out very well, unsurprisingly, and the results vary wildly depending on what I set as the lookback period. I was wondering if anyone could point out if I have fundamentally misunderstood how this strategy works. Pointers on my terrible, terrible code would also be appreciated.

Clone Algorithm

4

Loading...

There was an error loading this backtest.
Retry

Backtest from
to
with
initial capital

Cumulative performance:

Algorithm
Benchmark

Custom data:

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 |

import pandas as pd import numpy as np from pandas.stats.api import ols def initialize(context): #trading only GLD and USO ETfs context.securities = symbols('GLD', 'USO') #pretty arbitrary lookback for moving mean and std of portfolio price context.lookback = 10 #to track portfolio price context.yPort = [] # Rebalance every day, 1 hour after market open. schedule_function(my_rebalance, date_rules.every_day(), time_rules.market_close(minutes = 10)) # Record tracking variables at the end of each day. schedule_function(my_record_vars, date_rules.every_day(), time_rules.market_close()) def before_trading_start(context, data): lb = context.lookback #ETF recent prices x = data.history(symbol('GLD'), 'close', lb, '1d') y = data.history(symbol('USO'), 'close', lb, '1d') #linear regression to get hedge ratio (coffeccient of x) df = pd.DataFrame({'GLD':x, 'USO':y}) res = ols(y=df['USO'], x=df['GLD']) context.hr = res.beta['x'] def my_rebalance(context,data): lb = context.lookback #get current ETF prices at near end of day x = data.current(symbol('GLD'), 'price') y = data.current(symbol('USO'), 'price') #price of unit portfolio port = y - context.hr*x #keep track of portfolio prices context.yPort.append(port) #only need previous lookback number of prices if len(context.yPort) > lb + 1: context.yPort = context.yPort[1::] #after enough portfolio prices have been determined if len(context.yPort) == lb + 1: #moving average and std of portfolio prices ma = np.mean(context.yPort[:lb]) ms = np.std(context.yPort[:lb]) #Z-score of current portfolio value z = (port - ma)/ms #order ETFs depending on current hedge ratio and multiplied by Z-score, pumped up by an arbitrary factor order_target_value(symbol('GLD'), 10000*z*context.hr*x) order_target_value(symbol('USO'), -10000*z*y) def my_record_vars(context, data): record(leverage = context.account.leverage) record(hedgeRatio = context.hr)