Portfolio Limits

Hello all,

I working on this algo and Im stuck with something that I thought would be relatively simple.

-I want this to buy a total of 31 stocks
- 17 Large cap
- 8 Mid cap
- 6 Small cap
-Every month at rebalance check the portfolio if any stocks are down from their cost basis

-Sell the ones that are down and buy from stock list to replenish portfolio to the 31 stocks.

Im missing the last piece of replenishing portfolio to the 31 stocks.

Im still learning python so im sure thats my limitation here. Any help with coding that piece would be appreciated.

2
Backtest from to with initial capital
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
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline
from quantopian.pipeline import CustomFactor
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.data import morningstar
from quantopian.pipeline.factors import AverageDollarVolume, SimpleMovingAverage
from quantopian.pipeline.filters.morningstar import IsPrimaryShare

import numpy as np
from collections import defaultdict

#
# define custom classes
#
class simple_momentum(CustomFactor):
inputs = [USEquityPricing.close]
window_length = 1

def compute(self, today, assets, out, close):
out[:] = close[-1]/close[0]

class market_cap(CustomFactor):
inputs = [USEquityPricing.close, morningstar.valuation.shares_outstanding]
window_length = 1

def compute(self, today, assets, out, close, shares):
out[:] = close[-1] * shares[-1]

class get_fcf_per_share(CustomFactor):
inputs = [morningstar.valuation_ratios.cash_return]
window_length = 1

def compute(self, today, assets, out, cash_return):
out[:] = cash_return

class get_last_close(CustomFactor):
inputs = [USEquityPricing.close]
window_length = 1

def compute(self, today, assets, out, close):
out[:] = close[-1]

def initialize(context):

#: Declares which stocks we currently held and how many days we've held them dict[stock:days_held]

schedule_function(cancel_open_orders, date_rules.every_day(),
time_rules.market_close())

#
# schedule methods
#
schedule_function(func=periodic_rebalance,
date_rule=date_rules.month_start(days_offset=5),
time_rule=time_rules.market_open(), half_days=True)
#
# set portfolis parameters
#
set_do_not_order_list(security_lists.leveraged_etf_list)
context.acc_leverage = 1.0

#
# Set commission model to be used
#
#
#
#

#
# Establish pipeline
#
pipe = Pipeline()
attach_pipeline(pipe, 'ranked_stocks')
#
# Define the five momentum factors used in ranking stocks
#

# Week
week = simple_momentum(window_length=5)
# Month
month = simple_momentum(window_length=20)
# Quarter
quarter = simple_momentum(window_length=60)
# Six Months
six_months = simple_momentum(window_length=125)
# 52 Weeks
one_year = simple_momentum(window_length=252)

#
# Define other factors that may be used in stock screening
#
free_cash_flow = get_fcf_per_share()
mkt_cap = market_cap()
factor8 = get_last_close()

ytd_filter = six_months > one_year   # only consider stocks with six month performance greater than one year
mkt_cap_filter = mkt_cap > 2000000000   # only consider stocks mkt cap above 2b
free_cash_flow_filter = free_cash_flow > 0 # only consider stocks with positive free cash flow
close_price_filter = factor8 > 5.00  # only consider stocks that close above this value

common_stock = morningstar.share_class_reference.security_type.latest.eq('ST00000001')
not_lp_name = ~morningstar.company_reference.standard_name.latest.matches('.* L[\\. ]?P\.?\$')
not_lp_balance_sheet = morningstar.balance_sheet.limited_partnership.latest.isnull()
have_data = morningstar.valuation.market_cap.latest.notnull()
not_otc = ~morningstar.share_class_reference.exchange_id.latest.startswith('OTC')
not_wi = ~morningstar.share_class_reference.symbol.latest.endswith('.WI')
not_depository = ~morningstar.share_class_reference.is_depositary_receipt.latest
primary_share = IsPrimaryShare()

#
# Establish screen used to establish candidate stock list
#
# Establish screen to filter unwanted

total_filter = (common_stock
& not_lp_name
& not_lp_balance_sheet
& have_data
& not_otc
& not_wi
& not_depository
& primary_share
& ytd_filter
& mkt_cap_filter
& free_cash_flow_filter
& close_price_filter
)

pipe.set_screen(total_filter)

context.holdings_bottom_large_cap = 17

context.holdings_bottom_mid_cap = 8

context.holdings_bottom_small_cap = 6

context.output = pipeline_output('ranked_stocks')

ranked_large_cap_stocks = context.output[context.output.mkt_cap > 25000000000]
ranked_mid_cap_stocks = context.output[context.output.mkt_cap > 10000000000]
ranked_small_cap_stocks = context.output[context.output.mkt_cap > 5000000000]

#
# Establishing ranking based on different market caps Large, Mid and Small. Sorting by six months return.
#

#
# Large Cap
#

context.stock_factors_bottom_large_cap = ranked_large_cap_stocks.sort(['six_months'], ascending=True).iloc[:context.holdings_bottom_large_cap]

#
# Mid cap
#

context.stock_factors_bottom_mid_cap = ranked_mid_cap_stocks.sort(['six_months'], ascending=True).iloc[:context.holdings_bottom_mid_cap]

#
# Small Cap
#

context.stock_factors_bottom_small_cap = ranked_small_cap_stocks.sort(['six_months'], ascending=True).iloc[:context.holdings_bottom_small_cap]

context.stock_list_bottom_large_cap_set = set(context.stock_factors_bottom_large_cap.index)
context.stock_list_large_cap_set = context.stock_list_bottom_large_cap_set

context.stock_list_bottom_mid_cap_set = set(context.stock_factors_bottom_mid_cap.index)
context.stock_list_mid_cap_set = context.stock_list_bottom_mid_cap_set

context.stock_list_bottom_small_cap_set = set(context.stock_factors_bottom_small_cap.index)
context.stock_list_small_cap_set = context.stock_list_bottom_small_cap_set

context.stock_list_large_mid_set = context.stock_list_large_cap_set.union(context.stock_list_mid_cap_set)
context.stock_list_set = context.stock_list_small_cap_set.union(context.stock_list_large_mid_set)

def cancel_open_orders(context, data):
for stock in get_open_orders():
for order in get_open_orders(stock):
cancel_order(order)

def periodic_rebalance(context,data):

# Get any stocks we ordered last time that still have open orders.
open_orders = get_open_orders()

for stock in context.portfolio.positions:
costBasis = context.portfolio.positions[stock].cost_basis
if 'price' < costBasis:
order_target(stock, 0)

long_weight = context.acc_leverage / len(context.stock_list_set)
for stock in context.stock_list_set:
if stock not in open_orders:
order_target_percent(stock, long_weight)

n10 = len(context.stock_list_set)
record(leverage=context.account.leverage,
positions= len(context.portfolio.positions),
candidates=n10)


There was a runtime error.