Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Can someone demonstrate a basic buy with the new rule , Order_optimal_portfolio

Can someone demonstrate a basic buy something like 'aapl' with the new rule , Order_optimal_portfolio and a monthly rebalance

I was only familiar with Order_target_percent

14 responses

Basically, create a pandas series or dict with the securities and the weights one wants to order. Then create a 'TargetWeights' objective from this series. Then execute the 'order_optimal_portfolio' method with these target weights.

    #Create a pandas series or dict with securities and weights of each to order  
    weights = pd.Series(index = symbols('AAPL', 'IBM'), data = [.1, .9])  


    # Create a TargetWeights object to set the order weights  
    # This will become the ordering objective  
    weight_objective = opt.TargetWeights(weights)  


    # Execute the order_optimal_portfolio method  
    order_optimal_portfolio(objective = weight_objective, constraints = [])

Unlike the 'order_target_percent' method, this orders everything all at once (no need to loop through the securities). It also checks for any open orders (no need to do that either) and as a bonus it also checks if the security can trade (no need to check 'data.can_trade'). It will also close any open positions which aren't included in the weights objective. If this closing behavior isn't desired, then add a 'Frozen' constraint (see https://www.quantopian.com/help#module-quantopian_optimize_constraints) and set the securities which one doesn't want to close.

Attached is an example.

Good luck.

Check Lecture 37 for a sample use of order_optimal_portfolio. for monthly rebalance check out sample code below for rebalancing on the first trading day of month. You can find such information in the help page

        schedule_function(func=rebalance,  
                      date_rule=date_rules.month_start(days_offset=0),  
                      time_rule=time_rules.market_open(hours=0,minutes=45),  
                      half_days=True)  

That's very helpful @Dan: I have some questions for Frozen(asset_or_assets, max_error_display=10):

  • Is the datatype for "asset_or_assets" also a Pandas Series or dict?
  • To set up the Frozen constraint, would it be simple as: constraints.append(opt.Frozen(myAssets)) for example?
  • If the assets only need to be frozen for a period (say 3~60 days while signals are valid), how are the assets unfrozen when required?
  • Will there be any buy/sell action to the frozen assets even as the others are being adjusted/optimized in weights by order_optimal_portfolio()?

Thanks

@Karl, I can try to answer one of your questions. The Frozen constraint I think can only apply to that invocation of order_optimal_portfolio. So you will probably need to keep supplying the frozen constraint as long as you want it. When you don't it frozen then you can either drop the constraint or supply a constraint to get rid of the asset. I don't think frozen etc. get stored along with the positions datastructure, and is just local to order_optimal_portfolio.

@Karl Welcome to the world of optimization. As one adds constraints, there's a greater chance that a solution that meets all the constraints can't be found. That's what the error is saying. It looks like in order to satisfy the 'DollarNeutral' constraint then you can't freeze all those securities and/or you can't have all those min/max position concentrations.

Attached is an algorithm with how I do my 'Frozen' constraint. I don't have the other constraints which it seems you have but it may give you some ideas? Basically just freeze the current holdings but subtract anything we DO want to trade. @Leo M is correct that the constraints don't get saved (unless you explicitly do so). I find the easiest is to set up a new objective and constraints each time one executes the 'order_optimal_portfolio' method.

    # Create a set of the current holdings we DONT want to trade  
    # This is simply the current holdings minus anything we want to trade  
    # Use this set to create a Frozen constraint  
    current_holdings_set = set(context.portfolio.positions.keys())  
    securities_to_trade_set = set(securities_to_trade_list)  
    securities_to_freeze = current_holdings_set - securities_to_trade_set  
    freeze_constraint = opt.Frozen(securities_to_freeze)

@Karl maybe you could experiment with varying the number of frozen assets and seeing where it breaks, then work off of that ?

Thanks, Dan & Leo M!

Getting into the nettles at present.. seems the pre-existing objective opt.MaximizeAlpha(context.pipeline_assets) may be taking offence :)

Update: Too hard basket for me.. thinking that there are 2 objective classes in Optimize API, I tried to initiate objectives = [ ] to append both opt.MaximizeAlpha() and opt.TargetWeights() using the objectives.append() method, same as initiating constraints = [ ] for appending various constraints.

InfeasibleConstraints errors no end!

As it relates to the opening post and optimal weights.....how does one code the weighting for pair (long short)......in the example below, one would need something like
weights = pd.Series(index = symbols('AAPL', 'IBM'), data = [.5, -.5]) and

weights = pd.Series(index = symbols('AAPL', 'IBM'), data = [-.5, -5])

I think I figured it out by laboring thru this

https://www.quantopian.com/lectures/example-long-short-equity-algorithm

OK....did not really get this figured out....I guess my question remains if only trading 2 variables ?

Blaine

Take a look at the attached backtest. It creates a portfolio of 2 stocks (AAPL and IBM) with half long AAPL and half short IBM. It uses

  weights = pd.Series(index = symbols('AAPL', 'IBM'), data = [.5, -.5])  
  weight_objective = opt.TargetWeights(weights)  
  order_optimal_portfolio(objective = weight_objective, constraints = [])

Is that what you were asking?

First off. thank you.
Secondly...I'm new, but learning quickly

Before your post I had done the code below...seems to work perfectly, however, looking at the logs I realized my program is taking any gains and re-investing daily along the way as long (in this simple example) fast_MA is above slow_MA.....what I would prefer to do is have the gains sit in cash until the next signal, as oposed to reinvesting along the way. I haven't found of figured out ordering process to do just that. To me, the daily reinvesting seems couter-intuitive as most signals decay and your re-investing into the decay.. I just want to do a lump sum investment, park gains in cash, then take all cash and re-invest on next signal.

#Create a pandas series or dict with securities and weights of each to order  
if ema_9 > ema_39:  
    weights = pd.Series(index = symbols('XYZ', 'AAPL'), data = [-.5, .5])  
else:  
    weights = pd.Series(index = symbols('XYZ', 'AAPL'), data = [.5, -.5]) 


# Create a TargetWeights object to set the order weights  
# This will become the ordering objective  
weight_objective = opt.TargetWeights(weights)  


# Execute the order_optimal_portfolio method  
order_optimal_portfolio(objective = weight_objective, constraints = [])  

Blaine
Great job persevering and getting this far. There's a fair size hurdle understanding the platform but you seem to be getting the hang of it.

First, it isn’t required to rebalance or order every day. Most of the ‘order_optimal_portfolio’ examples show this method being executed daily but one doesn’t need to. Simply place any desired logic before the order method and execute when desired. This will keep it from rebalancing and reinvesting any gains immediately.

Need a little more info though. What you mean by “I just want to do a lump sum investment, park gains in cash, then take all cash and re-invest on next signal.”.

It seems in your question you left out the step of closing the positions (ie recognizing the gains or losses)? I am envisioning this implies three or four signals:
-Open long/short
-Close all (take profit/loss so have all cash in portfolio)
-Open short/long
-Close all (take profit/loss so have all cash in portfolio)

This could be coded something like this


If open_long_short:  
    weights = pd.Series(index = symbols('XYZ', 'AAPL'), data = [.5, -.5])  
If open_short_long:  
    weights = pd.Series(index = symbols('XYZ', 'AAPL'), data = [-.5, .5])  
If close_all:  
    weights = pd.Series(index = symbols('XYZ', 'AAPL'), data = [0, 0])  

If open_long_short or open_short_long or close_all:  
    weight_objective = opt.TargetWeights(weights)  
    order_optimal_portfolio(objective = weight_objective, constraints = [])  

Creating these triggers is the next step. One will probably need to implement a 'edge' or 'one-shot' trigger to get these to execute exactly once.

Does this help?

Dan...again, thanks for your info, indeed it helps alot. I was in the hedge fund industry for 20 years, but I only seriously committed myself to Python and Quantopian over the last month or so. It seems like 'overnight' the bulb has gone off....the first inpiration was to finally get an Algo to run...of course this was not without the help of others here at Quantopian....notably Vladimir.

While I have not meticulously checked my logs yet, I believe I had some code similar to what your last post suggested ?!

after initialization i used this
context.currently_long_the_MAspread = False
context.currently_short_the_MAspread = False

And in my order i had this on the
buy side
context.currently_short_the_spread = True
context.currently_long_the_spread = False
sell side
context.currently_short_the_spread = False
context.currently_long_the_spread = True

I think these work since my system is either long or short...never OUT.