Here's something I sorta stumbled upon by tinkering. Perhaps it is of interest to others. I'll post updates here, if I make improvements. Seems like an algo that would work with Robinhood, since it is long-only and trades weekly. I tagged it "market neutral" since the beta is -0.11. --Grant

Clone Algorithm

626

Loading...

There was an error loading this backtest.

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 numpy as np from pytz import timezone import scipy import pandas as pd def initialize(context): context.stocks = [ sid(8554), # SPY sid(32268), # SH sid(23921) ] # TLT context.x0 = np.zeros_like(context.stocks) schedule_function(trade,date_rules.week_start(days_offset=1),time_rules.market_open(minutes=30)) # schedule_function(trade,date_rules.week_end(),time_rules.market_open(minutes=30)) # schedule_function(close,date_rules.every_day(),time_rules.market_close(minutes=30)) set_commission(commission.PerTrade(cost=0)) set_long_only() context.eps = 0.01 def handle_data(context,data): leverage = context.account.leverage record(leverage = leverage) if leverage >= 3.0: print "Leverage >= 3.0" def trade(context, data): prices = history(20*390,'1m', 'price') ret = prices.pct_change()[1:].as_matrix(context.stocks) ret_sum = np.sum(ret,axis=0) bnds = [] limits = [0,1] for stock in context.stocks: bnds.append(limits) bnds = tuple(tuple(x) for x in bnds) cons = ({'type': 'eq', 'fun': lambda x: np.sum(x)-1.0}, {'type': 'ineq', 'fun': lambda x: np.dot(x,ret_sum) - context.eps}) res= scipy.optimize.minimize(variance, context.x0, args=ret,method='SLSQP',constraints=cons,bounds=bnds) if res.success: allocation = res.x allocation[allocation<0]=0 denom = np.sum(allocation) if denom != 0: allocation = allocation/denom else: allocation = [0,0,1] if get_open_orders(): return for i,stock in enumerate(context.stocks): order_target_percent(stock,allocation[i]) record(cons = np.dot(allocation,ret_sum)) print np.dot(allocation,ret_sum) # record(pct_sso = allocation[0]) # record(pct_sds = allocation[1]) # record(pct_tlt = allocation[2]) def close(context, data): for i,stock in enumerate(context.stocks): order_target_percent(stock,0) def variance(x,*args): p = np.squeeze(np.asarray(args)) Acov = np.cov(p.T) return np.dot(x,np.dot(Acov,x))

We have migrated this algorithm to work with a new version of the Quantopian API. The code is different than the original version, but the investment rationale of the algorithm has not changed. We've put everything you need to know here on one page.