Very helpful Dan! Thank you so much. I also tried to use this method you showed above with Q1500US and Q3000US but it gave me an unidentified error. When using those other filters is there anything different I need to swap than Q500US? See below source code. Thanks!
"""
This is a sample algorithm using order_optimal_portfolio.
It rebalances the Q1500US everyday to maintain an equal weight portfolio.
"""
# Import necessary Pipeline modules
from quantopian.pipeline import Pipeline
from quantopian.algorithm import attach_pipeline, pipeline_output
# Import specific filters and factors which will be used
from quantopian.pipeline.filters import Q1500US, StaticAssets
from quantopian.pipeline.factors import Latest
# Import datasets which will be used
from quantopian.pipeline.data import USEquityPricing
# import optimize
import quantopian.optimize as opt
def initialize(context):
"""
Initialize constants, create pipeline, and schedule functions
This uses the default slippage and commission models
"""
# Set benchmark to an SP500 ETF to see how well we track
set_benchmark(symbol('SPY'))
# Make our pipeline and attach to the algo
my_pipe = make_pipeline()
attach_pipeline(my_pipe, 'my_pipe')
# Place orders at open every day
schedule_function(
func=place_orders_using_optimize,
date_rule=date_rules.every_day(),
time_rule=time_rules.market_open(minutes=15)
)
# Place orders at close every day
schedule_function(
func=place_orders_using_optimize,
date_rule=date_rules.every_day(),
time_rule=time_rules.market_close(minutes=15)
)
def make_pipeline():
"""
Define a pipeline.
This not only defines the data but also any logic if desired
We break this code out into its own function to make it easier to
test and modify in isolation. In particular, this function can be
copy/pasted into research and run by itself.
Parameters
-------
context : AlgorithmContext
Returns
-------
pipe : Pipeline
"""
q1500 = Q1500US()
# Create any needed factors.
# Just get price. Use Latest factor so we can supply a mask.
q1500_prices = Latest([USEquityPricing.close], mask=1500)
# Calc equal weight which is 1/qty_of_stocks
weight = 1.0 / q1500_prices.notnull_count()
# Create any filters based upon these factors
pass
# Create our pipeline. Just return the list of stocks and the weight.
pipe = Pipeline(
columns={'weight': weight},
screen=q1500,
)
return pipe
def place_orders_using_optimize(context, data):
"""
Use Optimize to place orders all at once
"""
# Run our pipeline to fetch the actual data.
pipe_data = pipeline_output('my_pipe')
# Do any dataframe manipulation and/or selection here
pass
# Create our TargetWeights objective
target_weights = opt.TargetWeights(pipe_data.weight)
# Execute the order_optimal_portfolio method with above objective and constraint
# No need to loop through the stocks.
# The order_optimal_portfolio does all the ordering at one time
# Also closes any positions not in target_weights
# As a bonus also checks for 'can_trade'
# Could set constraints here if desired
order_optimal_portfolio(objective=target_weights, constraints=[])