Back to Community
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.

Clone Algorithm
2
Loading...
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
#
    set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.00))
#
#
# 
    
#
# 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)
    pipe.add(week, 'week')      
# Month    
    month = simple_momentum(window_length=20)
    pipe.add(month, 'month')  
# Quarter    
    quarter = simple_momentum(window_length=60)
    pipe.add(quarter, 'quarter')  
# Six Months   
    six_months = simple_momentum(window_length=125)  
    pipe.add(six_months, 'six_months')  
# 52 Weeks     
    one_year = simple_momentum(window_length=252) 
    pipe.add(one_year, 'one_year') 
    
    
  
#
# Define other factors that may be used in stock screening
#
    free_cash_flow = get_fcf_per_share()
    pipe.add(free_cash_flow, 'fcf')
    mkt_cap = market_cap()
    pipe.add(mkt_cap, 'mkt_cap')
    factor8 = get_last_close()
    pipe.add(factor8, 'factor_8')
    

    
    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)
    
    
def before_trading_start(context,data):

    
    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 data.can_trade(stock):
            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:
            if data.can_trade(stock):
                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.