Back to Community
Need Help - Modify Algo to Maintain a Set Percentage of Gold at All Times

I'd like to modify the attached algo to maintain a 20% position in gold (using the 'GLD'
ETF).

Current = Buys 5 stocks and rebalances daily

Proposed = Buys 4 stocks (80% of holdings) and holds GLD (20% of holdings). Maintains this configuration after rebalancing.

Questions:
1) Is this possible? If so I'd like to get actual code modifications or a modified algo if someone is willing as my coding skills aren't real strong.

2) Can someone also help with the following warnings?

Your algorithm uses APIs that have been deprecated in favor of newer, more powerful versions. For more information, go here.
Line 109: Function update_universe is deprecated.
Line 45: Checking whether an asset is in data is deprecated.
Line 36: Checking whether an asset is in data is deprecated.
These deprecated APIs will stop working in the future. Please switch to the new APIs as soon as possible.

I would appreciate specifics or code modifications to fix this if possible.

Thanks,

Troy

Clone Algorithm
4
Loading...
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
"""
    Trading Strategy using Fundamental Data
    
    1. Filter stocks per fundamental criteria 
    2. Rank and purchase the top stocks
    3. Every day exit all the positions before entering new ones the next day
    4. Maintain 20% of portfolio (1 out of 5 positions) in gold using (GLD) ETF
    
"""

import pandas as pd
import numpy as np
from sqlalchemy import or_  

def initialize(context):
    # Dictionary of stocks and their respective weights
    context.stock_weights = {}
    # Count of days before rebalancing
    context.days = 0
    
    # Check our leverage, market exposure, and portfolio size and add them to
    # our custom time series plot using the record() function.
    schedule_function(record_daily_values,
                      date_rules.every_day(),
                      time_rules.market_close(hours=0,minutes=1))  
    
    # Rebalance monthly on the first day of the month at market open
    schedule_function(rebalance,
                      date_rule=date_rules.week_start(days_offset=0),
                      #date_rule=date_rules.month_start(),
                      time_rule=time_rules.market_open())
    
def rebalance(context, data):
    # Exit all positions before starting new ones
    for stock in context.portfolio.positions:
        if stock not in context.fundamental_df and stock in data:
            if data.can_trade(stock):
                order_target_percent(stock, 0)

    # Create weights for each stock
    weight = create_weights(context, context.stocks)

    # Rebalance all stocks to target weights
    for stock in context.fundamental_df:
        if stock in data:
          if weight != 0:
              if data.can_trade(stock):
                  log.info("Ordering %0.0f%% percent of %s" 
                       % (weight * 100, 
                          stock.symbol))
              
                  order_target_percent(stock, weight)
    
def before_trading_start(context, data): 

    """
      Called before the start of each trading day. 
      It updates our universe with the
      securities and values found from get_fundamentals.
    """
    
    num_stocks = 5
    
    fundamental_df = get_fundamentals(
        query(
            # put your query in here by typing "fundamentals."
            fundamentals.asset_classification.growth_score, # 0 to 100
            fundamentals.asset_classification.value_score, # 0 to 100
            fundamentals.asset_classification.growth_grade, # A,B,C,D,E,F
            fundamentals.asset_classification.financial_health_grade, # A,B,C,D,E,F
            fundamentals.asset_classification.profitability_grade, # A,B,C,D,E,F
            fundamentals.operation_ratios.roa,
            fundamentals.operation_ratios.current_ratio,
            fundamentals.valuation_ratios.fcf_ratio,
            fundamentals.valuation_ratios.pb_ratio,
            fundamentals.valuation_ratios.pcf_ratio,
            fundamentals.valuation_ratios.pe_ratio,
            fundamentals.valuation_ratios.ps_ratio
         )
        .filter(fundamentals.valuation.market_cap != None)
        .filter(fundamentals.valuation.shares_outstanding != None)
        #.filter(fundamentals.valuation_ratios.pb_ratio > 1.5) #best < 2.5
        #.filter(fundamentals.valuation_ratios.pb_ratio < 1.0) #best none
        #.filter(fundamentals.valuation_ratios.pe_ratio > 0) #best > 5
        #.filter(fundamentals.valuation_ratios.ps_ratio > 5) #off
        #.filter(fundamentals.valuation_ratios.pe_ratio < 9) #off
        .filter(fundamentals.valuation_ratios.dividend_yield >0)
        #.filter(fundamentals.valuation_ratios.fcf_yield < 2)
        #.filter(fundamentals.operation_ratios.current_ratio > 2) #best > 1.0
        #.filter(fundamentals.valuation.market_cap > 100e6) #best > 100e6
        #.filter(((fundamentals.valuation.market_cap*1.0) / (fundamentals.valuation.shares_outstanding*1.0)) < 5.0)  # Price; best < $8 
        #.filter(fundamentals.asset_classification.growth_score < 10)
        #.filter(fundamentals.asset_classification.value_score < 10)
        #.filter(or_(fundamentals.asset_classification.growth_grade == "A",fundamentals.asset_classification.growth_grade == "B"))
        #.filter(or_(fundamentals.asset_classification.financial_health_grade == "A",fundamentals.asset_classification.financial_health_grade == "B"))
        #.filter(or_(fundamentals.asset_classification.profitability_grade == "A",fundamentals.asset_classification.profitability_grade == "B"))
        #.order_by(fundamentals.valuation.market_cap.desc())
        .order_by(fundamentals.valuation_ratios.ps_ratio.desc())
        #.order_by(fundamentals.valuation_ratios.dividend_yield.asc())        
        .limit(num_stocks)
    )
 
    # Update list of stocks
    context.stocks = [stock for stock in fundamental_df]
    
    # Update context.fundamental_df with the securities that we need
    context.fundamental_df = fundamental_df[context.stocks]
    
    update_universe(context.fundamental_df.columns.values)   
    
    
def create_weights(context, stocks):
    """
        Takes in a list of securities and weights them all equally 
    """
    if len(stocks) == 0:
        return 0 
    else:
        weight = 1.0/len(stocks)
        return weight
        
def handle_data(context, data):
    pass

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   
def record_daily_values(context,data):

    record(leverage = context.account.leverage)
    record(market_exposure=context.account.net_leverage)

    # We also want to monitor the number of long and short positions in our portfolio over time. This
    # loop will check our positition sizes and add the count of longs and shorts to our custom time-series plot.
    longs = shorts = 0
    for position in context.portfolio.positions.itervalues():
        if position.amount > 0:
            longs += 1
        if position.amount < 0:
            shorts += 1
            
    record(long_count=longs, short_count=shorts)  
    # track how many positions we're holding
    record(num_positions = len(context.portfolio.positions))
There was a runtime error.
2 responses

This is a start. I modified the code to reduce the original weights to 0.8, then added code to buy gold at 25% of the total value of those positions.

Clone Algorithm
2
Loading...
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
"""
    Trading Strategy using Fundamental Data
    
    1. Filter stocks per fundamental criteria 
    2. Rank and purchase the top stocks
    3. Every day exit all the positions before entering new ones the next day
    4. Maintain 20% of portfolio (1 out of 5 positions) in gold using (GLD) ETF
    
"""

import pandas as pd
import numpy as np
from sqlalchemy import or_  

def initialize(context):
    # Add Gold ETF
    context.gold = symbol('GLD')
    # Dictionary of stocks and their respective weights
    context.stock_weights = {}
    # Count of days before rebalancing
    context.days = 0
    
    
    # Check our leverage, market exposure, and portfolio size and add them to
    # our custom time series plot using the record() function.
    schedule_function(record_daily_values,
                      date_rules.every_day(),
                      time_rules.market_close(hours=0,minutes=1))  
    
    # Rebalance monthly on the first day of the month at market open
    schedule_function(rebalance,
                      date_rule=date_rules.week_start(days_offset=0),
                      #date_rule=date_rules.month_start(),
                      time_rule=time_rules.market_open())
    schedule_function(gold_rebalance,
                      date_rule=date_rules.week_start(days_offset=0),
                      #date_rule=date_rules.month_start(),
                      time_rule=time_rules.market_open(minutes=30))
    
def rebalance(context, data):

    # Exit all positions before starting new ones
    for stock in context.portfolio.positions:
        if stock not in context.fundamental_df and stock in data:
            if data.can_trade(stock):
                order_target_percent(stock, 0)

    # Create weights for each stock
    weight = create_weights(context, context.stocks)

    # Rebalance all stocks to target weights
    for stock in context.fundamental_df:
        if stock in data:
          if weight != 0:
              if data.can_trade(stock):
                  log.info("Ordering %0.0f%% percent of %s" 
                       % (weight * 100, 
                          stock.symbol))
              
                  order_target_percent(stock, weight)
                
def gold_rebalance(context,data):    
    # Get Portfolio Size
    position_size = context.portfolio.positions_value
    gold_order = position_size*0.25
    order_target_value(context.gold, gold_order)
    
    
def before_trading_start(context, data): 

    """
      Called before the start of each trading day. 
      It updates our universe with the
      securities and values found from get_fundamentals.
    """
    
    num_stocks = 4
    
    fundamental_df = get_fundamentals(
        query(
            # put your query in here by typing "fundamentals."
            fundamentals.asset_classification.growth_score, # 0 to 100
            fundamentals.asset_classification.value_score, # 0 to 100
            fundamentals.asset_classification.growth_grade, # A,B,C,D,E,F
            fundamentals.asset_classification.financial_health_grade, # A,B,C,D,E,F
            fundamentals.asset_classification.profitability_grade, # A,B,C,D,E,F
            fundamentals.operation_ratios.roa,
            fundamentals.operation_ratios.current_ratio,
            fundamentals.valuation_ratios.fcf_ratio,
            fundamentals.valuation_ratios.pb_ratio,
            fundamentals.valuation_ratios.pcf_ratio,
            fundamentals.valuation_ratios.pe_ratio,
            fundamentals.valuation_ratios.ps_ratio
         )
        .filter(fundamentals.valuation.market_cap != None)
        .filter(fundamentals.valuation.shares_outstanding != None)
        #.filter(fundamentals.valuation_ratios.pb_ratio > 1.5) #best < 2.5
        #.filter(fundamentals.valuation_ratios.pb_ratio < 1.0) #best none
        #.filter(fundamentals.valuation_ratios.pe_ratio > 0) #best > 5
        #.filter(fundamentals.valuation_ratios.ps_ratio > 5) #off
        #.filter(fundamentals.valuation_ratios.pe_ratio < 9) #off
        .filter(fundamentals.valuation_ratios.dividend_yield >0)
        #.filter(fundamentals.valuation_ratios.fcf_yield < 2)
        #.filter(fundamentals.operation_ratios.current_ratio > 2) #best > 1.0
        #.filter(fundamentals.valuation.market_cap > 100e6) #best > 100e6
        #.filter(((fundamentals.valuation.market_cap*1.0) / (fundamentals.valuation.shares_outstanding*1.0)) < 5.0)  # Price; best < $8 
        #.filter(fundamentals.asset_classification.growth_score < 10)
        #.filter(fundamentals.asset_classification.value_score < 10)
        #.filter(or_(fundamentals.asset_classification.growth_grade == "A",fundamentals.asset_classification.growth_grade == "B"))
        #.filter(or_(fundamentals.asset_classification.financial_health_grade == "A",fundamentals.asset_classification.financial_health_grade == "B"))
        #.filter(or_(fundamentals.asset_classification.profitability_grade == "A",fundamentals.asset_classification.profitability_grade == "B"))
        #.order_by(fundamentals.valuation.market_cap.desc())
        .order_by(fundamentals.valuation_ratios.ps_ratio.desc())
        #.order_by(fundamentals.valuation_ratios.dividend_yield.asc())        
        .limit(num_stocks)
    )
 
    # Update list of stocks
    context.stocks = [stock for stock in fundamental_df]
    
    # Update context.fundamental_df with the securities that we need
    context.fundamental_df = fundamental_df[context.stocks]
    
    update_universe(context.fundamental_df.columns.values)   
    
    
def create_weights(context, stocks):
    """
        Takes in a list of securities and weights them all equally 
    """
    if len(stocks) == 0:
        return 0 
    else:
        weight = 1.0/len(stocks)
        return weight*0.8 # Added reduction to weight
        
def handle_data(context, data):
    pass

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   
def record_daily_values(context,data):

    record(leverage = context.account.leverage)
    record(market_exposure=context.account.net_leverage)

    # We also want to monitor the number of long and short positions in our portfolio over time. This
    # loop will check our positition sizes and add the count of longs and shorts to our custom time-series plot.
    longs = shorts = 0
    for position in context.portfolio.positions.itervalues():
        if position.amount > 0:
            longs += 1
        if position.amount < 0:
            shorts += 1
            
    record(long_count=longs, short_count=shorts)  
    # track how many positions we're holding
    record(num_positions = len(context.portfolio.positions))
There was a runtime error.

Thanks Frank! I appreciate the help and quick response. That's what I was looking for on Question #1.

Thanks again,

Troy