Back to Community
Simple Relative Strength Strategy is not trading - Help needed please

Hello Community,
I created a simple, long-only strategy that holds the top 3 stocks with the highest momentum over its 50-day average. In the Research Environment, my pipeline seems to work and outputs 3 stocks each day. I can't get the darn thing to actually trade in the IDE.

I've attached a notebook that contains both the research & IDE code I created.

Any help would be much appreciated.
Thank you,

Loading notebook preview...
Notebook previews are currently unavailable.
2 responses

Hello Michael,

Fix for this problem is fairly easy. On line 67 your code is

long_weight = 1 / len(context.longs)  

Which causes Python to do integer math and result get rounded down to 0. Just changing that 1 to 1.0 will allow Python to do floating point math instead of integer math and your code will run.

Clone Algorithm
5
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
#-------Import Packages-------#
import numpy as np
import pandas as pd
from datetime import datetime, timedelta

from quantopian.pipeline import Pipeline
from quantopian.algorithm import attach_pipeline,pipeline_output

from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.factors import SimpleMovingAverage
from quantopian.pipeline.factors import VWAP
from quantopian.pipeline.factors import AverageDollarVolume
from quantopian.pipeline import CustomFactor

from quantopian.pipeline.filters import QTradableStocksUS

from quantopian.pipeline.data import Fundamentals



#-------Initialize-------#

def initialize(context):
    
    # Rebalance everyday, 1 hour after open
    schedule_function(my_rebalance,date_rules.every_day(),time_rules.market_open(hours=1))

    # Record variables everyday, at market close    
    schedule_function(record_vars,date_rules.every_day(),time_rules.market_close())
    
    # creating a pipeline object called 'my_pipeline', that can be called
    # in the before_trading_start() function
    my_pipe = make_pipeline()
    attach_pipeline(my_pipe,'my_pipeline')
    
def record_vars(context,data):

    record(Leverage = context.account.leverage)
    record(Exposure = context.account.net_leverage)
    
    
#-------Rebalancing-------#

def my_rebalance(context,data):
    
    # How to handle existing positions
    for security in context.portfolio.positions:
        # Exit exisiting positions that are no longer in the pipeline
        if security not in context.longs and data.can_trade(security):
            order_target_percent(security,0)
            
    # Buying positions accoriding to my_compute_weights() function   
    for security in context.longs:
        if data.can_trade(security):
            order_target_percent(security,context.long_weight)
        #print(context.longs)        
    
#-------Calculating Target Weights-------#

def my_compute_weights(context):
    
    # if no positions are in our long list then 0% weight
    if len(context.longs)==0:
        long_weight = 0
    else:
        # 100% of the portfolio is divided equally between all the stocks in long list
        long_weight = 1.0 / len(context.longs)
    
    # return the weights to be used in our my_rebalance function
    return (long_weight)



#-------Before Trading Each Day-------#

def before_trading_start(context,data):
    context.output = pipeline_output('my_pipeline')
    
    # LONG
    # using the 'Longs' column of the output of our pipeline dataframe to create a list of securities to buy
    context.longs = context.output[context.output['Longs']].index.tolist()
    
    # Passing these outputs to our my_compute_weights()function
    context.long_weight = my_compute_weights(context)
    
    
    
#-------Pipeline-------#   


def make_pipeline():
    
    """FACTORS"""

    # Factor to find the 50-day Moving Average
    moving_average_50 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=50)

    # Factor to find the Last Closing Price
    last_close = USEquityPricing.close.latest

    # Factor that examines the percent difference between
    # the 50-Day Moving Average and the current price
    momentum_50 = (last_close - moving_average_50) / moving_average_50

    # Factor measuring the 30-day Average Dollar Volume
    dollar_volume = AverageDollarVolume(window_length=30)

    
    """FILTERS"""

    # Define the Universe of stocks to work with (Tradable Stocks)
    base_universe = QTradableStocksUS()

    # Filter to ensure Average Dollar Volume is greater than $50,000,000
    volume_filter = (dollar_volume > 50000000)

    # Filter that returns true for positive 50-day Momentum
    positive_momentum = momentum_50 > 0

   
    """ALTERNATE STRATEGY FILTERS"""
    # Comment one or the other

    """Alternate Filter 1"""
    # Filter that returns the top 1% of highest momentum stocks
    #highest_momentum = momentum_50day.percentile_between(99,100, mask=volume_filter)

    """Alternate Filter 2"""
    # Filter top 3 stocks with highest 50-day Momentum
    highest_momentum = momentum_50.top(3, mask=base_universe & volume_filter)
    #------------------------------#

    """COMBINATION FILTERS"""

    # Combination volum & momuntum filter
    combination_filter = positive_momentum & highest_momentum
    
     
    return Pipeline(
        columns={
            '50-Day Moving Average': moving_average_50,
            'Current Price': last_close,
            'Momentum': momentum_50,
            'Positive Momentum': positive_momentum,
            '30-Day Average Dollar Volume': dollar_volume,
            'Longs': highest_momentum
        },
        screen=(combination_filter)
    )
There was a runtime error.

Wow, thank you so much Mikko. You are an absolute genius. As you can probably tell, I just learned Python this month from a Udemy course, so I'm very new to this. I really appreciate your help!