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.

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 import math from pytz import timezone # globals for get_data batch transform decorator R_P = 0 #refresh period in days W_L = 5 #window length in days def initialize(context): context.stocks = [sid(1419),sid(12652),sid(6546),sid(5061),sid(6683)] for stock in context.stocks: print stock.symbol context.m = len(context.stocks) context.b_t = np.ones(context.m) / context.m context.eps = 1 # change epsilon here context.init = False context.previous_datetime = None def handle_data(context, data): current_datetime = get_datetime().astimezone(timezone('US/Eastern')) cash = context.portfolio.cash record(cash=cash) if not context.init: # Equal weighting portfolio for stock, percent in zip(context.stocks, context.b_t): order_target_percent(stock, percent) context.init = True # only execute algorithm once per day if context.previous_datetime != None: if current_datetime.day != context.previous_datetime.day: new_day = True algo_executed = False else: new_day = False else: new_day = False algo_executed = True context.previous_datetime = current_datetime if not new_day or algo_executed == True: return # skip tic if any orders are open or any stocks did not trade for stock in context.stocks: if bool(get_open_orders(stock)) or data[stock].datetime < get_datetime(): return # compute current portfolio allocations for i, stock in enumerate(context.stocks): context.b_t[i] = context.portfolio.positions[stock].amount*data[stock].price # Bring portfolio vector to unit length context.b_t = context.b_t / np.sum(context.b_t) # Compute new portfolio weights according to OLMAR algo. b_norm = olmar(context) # Rebalance Portfolio for stock, percent in zip(context.stocks, b_norm): order_target_percent(stock, percent) algo_executed = True def olmar(context): """Logic of the olmar algorithm. :Returns: b_norm : vector for new portfolio """ # get history -- prices and volums of the last 5 days (at close) prices = history(5, '1d', 'price') volumes = history(5, '1d', 'volume') # find relative moving volume weighted average price for each secuirty x_tilde = np.zeros(context.m) for i, stock in enumerate(context.stocks): vwa_price = np.dot(prices[stock], volumes[stock]) / np.sum(volumes[stock]) x_tilde[i] = vwa_price/prices[stock].ix[-1] ########################### # Inside of OLMAR (algo 2) x_bar = x_tilde.mean() # Calculate terms for lambda (lam) dot_prod = np.dot(context.b_t, x_tilde) num = context.eps - dot_prod denom = (np.linalg.norm((x_tilde-x_bar)))**2 # test for divide-by-zero case if denom == 0.0: lam = 0 # no portolio update else: lam = max(0, num/denom) b = context.b_t + lam*(x_tilde-x_bar) b_norm = simplex_projection(b) return b_norm def simplex_projection(v, b=1): """Projection vectors to the simplex domain Implemented according to the paper: Efficient projections onto the l1-ball for learning in high dimensions, John Duchi, et al. ICML 2008. Implementation Time: 2011 June 17 by [email protected] AT pmail.ntu.edu.sg Optimization Problem: min_{w}\| w - v \|_{2}^{2} s.t. sum_{i=1}^{m}=z, w_{i}\geq 0 Input: A vector v \in R^{m}, and a scalar z > 0 (default=1) Output: Projection vector w :Example: >>> proj = simplex_projection([.4 ,.3, -.4, .5]) >>> print proj array([ 0.33333333, 0.23333333, 0. , 0.43333333]) >>> print proj.sum() 1.0 Original matlab implementation: John Duchi ([email protected]) Python-port: Copyright 2012 by Thomas Wiecki ([email protected]). """ v = np.asarray(v) p = len(v) # Sort v into u in descending order v = (v > 0) * v u = np.sort(v)[::-1] sv = np.cumsum(u) rho = np.where(u > (sv - b) / np.arange(1, p+1))[0][-1] theta = np.max([0, (sv[rho] - b) / (rho+1)]) w = (v - theta) w[w<0] = 0 return w