Back to Community
50 DOLLARS FOR HELP! Screen Out Leveraged ETF's FIRST TO HELP I WILL SEND VIA PAY PAL

Hi Quantopian Fam!

I want to run this algorithm but screen out Leveraged ETF's. Can anyone help me do this? Your time and efforts are much appreciated!

This is a sample mean-reversion algorithm on Quantopian for you to test and adapt.

Algorithm investment thesis:

Top-performing stocks from last week will do worse this week, and vice-versa.

Every Monday, we rank high-volume stocks based on their previous 5 day returns.

We go long the bottom 20% of stocks with the WORST returns over the past 5 days.

We go short the top 20% of stocks with the BEST returns over the past 5 days.

This type of algorithm may be used in live trading and in the Quantopian Open.

Import the libraries we will use here

import numpy as np

The initialize function is the place to set your tradable universe and define any parameters.

def initialize(context):
# Use the top 1% of stocks defined by average daily trading volume.
set_universe(universe.DollarVolumeUniverse(23, 100))

# Set execution cost assumptions. For live trading with Interactive Brokers  
# we will assume a $1.00 minimum per trade fee, with a per share cost of $0.0075.  
set_commission(commission.PerShare(cost=0.0015, min_trade_cost=1.00))  

# Set market impact assumptions. We limit the simulation to  
# trade up to 2.5% of the traded volume for any one minute,  
# and  our price impact constant is 0.1.  
set_slippage(slippage.VolumeShareSlippage(volume_limit=0.04, price_impact=0.10))  

# Define the other variables  
context.long_leverage = 0.5  
context.short_leverage = -0.5  
context.lower_percentile = 50  
context.upper_percentile = 50  
context.returns_lookback = 5  

# Rebalance every Monday (or the first trading day if it's a holiday).  
# At 11AM ET, which is 1 hour and 30 minutes after market open.  
schedule_function(rebalance,  
                  date_rules.week_start(days_offset=0),  
                  time_rules.market_open(hours = 7, minutes = 0))  

The handle_data function is run every bar.

def handle_data(context,data):
# Record and plot the leverage of our portfolio over time.
record(leverage = context.account.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 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)

This rebalancing is called according to our schedule_function settings.

def rebalance(context,data):
# Get the last N days of prices for every stock in our universe.
prices = history(context.returns_lookback, '1d', 'price')

# Calculate the past 5 days' returns for each security.  
returns = (prices.iloc[-1] - prices.iloc[0]) / prices.iloc[0]  

# Remove stocks with missing prices.  
# Remove any stocks we ordered last time that still have open orders.  
# Get the cutoff return percentiles for the long and short portfolios.  
returns = returns.dropna()  
open_orders = get_open_orders()  
if open_orders:  
    eligible_secs = [sec for sec in data if sec not in open_orders]  
    returns = returns[eligible_secs]

# Lower percentile is the threshhold for the bottom 20%, upper percentile is for the top 20%.  
lower, upper = np.percentile(returns, [context.lower_percentile,  
                                       context.upper_percentile])  

# Select the X% worst performing securities to go long.  
long_secs = returns[returns <= lower]  

# Select the Y% best performing securities to short.  
short_secs = returns[returns >= upper]  

# Set the allocations to even weights in each portfolio.  
long_weight = context.long_leverage / len(long_secs)  
short_weight = context.short_leverage / len(short_secs)  

for security in data:  

    # Buy/rebalance securities in the long leg of our portfolio.  
    if security in long_secs:  
        order_target_percent(security, long_weight)  

    # Sell/rebalance securities in the short leg of our portfolio.  
    elif security in short_secs:  
        order_target_percent(security, short_weight)  

    # Close any positions that fell out of the list of securities to long or short.  
    else:  
        order_target(security, 0)  

log.info("This week's longs: "+", ".join([long_.symbol for long_ in long_secs.index]))  
log.info("This week's shorts: "  +", ".join([short_.symbol for short_ in short_secs.index]))  
7 responses

See the help page & security_lists.leveraged_etf_list. If this works for you, please donate $50 to your favorite charity.

See the help page & security_lists.leveraged_etf_list. If this works for you, please donate $50 to your favorite charity.

:)

Hi Grant!

Thank you for your help. What we are having trouble with is implementing this into our existing algorithm. For some reason we get runtime errors when we try. Any advice? Will donate $50 to the Make A Wish Foundation.

Thank you!

Best,
Alex

for security in data:  
    if security in security_lists.leveraged_etf_list:  
        continue  

That should work.

Hi Mikko!

Thank you kindly for your time! I'm new to this platform so sorry for my lack of understanding. Could you or someone help me implement it into this algorithm?

Thank you!
Alex

Clone Algorithm
1
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
# Import the libraries we will use here.
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.factors import AverageDollarVolume, Returns

def initialize(context):
    """
    Called once at the start of the program. Any one-time
    startup logic goes here.    
    
    """
    # Define context variables that can be accessed in other methods of
    # the algorithm.
    context.long_leverage = .5
    context.short_leverage = -.5
    context.returns_lookback = 2

    
    
    # Rebalance every morning at 25 minutes after market open.
    schedule_function(rebalance,
                      date_rules.every_day(),
                      time_rules.market_open(hours=0, minutes=1))

    # Record tracking variables at the end of each day.
    schedule_function(record_vars,
                      date_rules.every_day(),
                      time_rules.market_close(minutes=1))

    # Create and attach our pipeline (dynamic stock selector), defined below.
    attach_pipeline(make_pipeline(context), 'mean_reversion_example')
    
  
def make_pipeline(context):
    """
    A function to create our pipeline (dynamic stock selector). The pipeline is used
    to rank stocks based on different factors, including builtin factors, or custom
    factors that you can define. Documentation on pipeline can be found here:
    https://www.quantopian.com/help#pipeline-title
    """
    # Create a pipeline object.

    # Create a dollar_volume factor using default inputs and window_length.
    # This is a builtin factor.
    dollar_volume = AverageDollarVolume(window_length=5)

    # Define high dollar-volume filter to be the top 5% of stocks by dollar volume.
    high_dollar_volume = dollar_volume.percentile_between(97, 100)
    
    # Create a recent_returns factor with a 5-day returns lookback for all securities
    # in our high_dollar_volume Filter. This is a custom factor defined below (see 
    # RecentReturns class).
    recent_returns = Returns(window_length=context.returns_lookback, mask=high_dollar_volume)

    # Define high and low returns filters to be the bottom 0.75% and top 99.25% of
    # securities in the high dollar-volume group.
    low_returns = recent_returns.percentile_between(0,10)
    high_returns = recent_returns.percentile_between(90,100)

    # Define a column dictionary that holds all the Factors
    pipe_columns = {
            'low_returns':low_returns,
            'high_returns':high_returns,
            'recent_returns':recent_returns,
            'dollar_volume':dollar_volume
            }

    # Add a filter to the pipeline such that only high-return and low-return
    # securities are kept.
    pipe_screen = (low_returns | high_returns)
    
    


    # Create a pipeline object with the defined columns and screen.
    pipe = Pipeline(columns=pipe_columns,screen=pipe_screen)
    
  

    return pipe

def before_trading_start(context, data):
    """
    Called every day before market open. This is where we get the securities
    that made it through the pipeline.
    """

    # Pipeline_output returns a pandas DataFrame with the results of our factors
    # and filters.
    context.output = pipeline_output('mean_reversion_example')

    # Sets the list of securities we want to long as the securities with a 'True'
    # value in the low_returns column.
    context.long_secs = context.output[context.output['low_returns']]

    # Sets the list of securities we want to short as the securities with a 'True'
    # value in the high_returns column.
    context.short_secs = context.output[context.output['high_returns']]

    # A list of the securities that we want to order today.
    context.security_list = context.long_secs.index.union(context.short_secs.index).tolist()

    # A set of the same securities, sets have faster lookup.
    context.security_set = set(context.security_list)

def compute_weights(context):
    """
    Compute weights to our long and short target positions.
    """

    # Set the allocations to even weights for each long position, and even weights
    # for each short position.
    long_weight = context.long_leverage / len(context.long_secs)
    short_weight = context.short_leverage / len(context.short_secs)
    
    return long_weight, short_weight

def rebalance(context,data):
    """
    This rebalancing function is called according to our schedule_function settings.
    """

    long_weight, short_weight = compute_weights(context) 
    
    

    # For each security in our universe, order long or short positions according
    # to our context.long_secs and context.short_secs lists.
    for stock in context.security_list:
        if data.can_trade(stock):
            if stock in context.long_secs.index:
                order_target_percent(stock, long_weight)
            elif stock in context.short_secs.index:
                order_target_percent(stock, short_weight)
  
    # Sell all previously held positions not in our new context.security_list.
    for stock in context.portfolio.positions:
        if stock not in context.security_set and data.can_trade(stock):
            order_target_percent(stock, 0)

    # Log the long and short orders each week.
    log.info("This days's longs: "+", ".join([long_.symbol for long_ in context.long_secs.index]))
    log.info("This days's shorts: "  +", ".join([short_.symbol for short_ in context.short_secs.index]))


def record_vars(context, data):
    """
    This function is called at the end of each day and plots certain variables.
    """

    # Check how many long and short positions we have.
    longs = shorts = 0
    for position in context.portfolio.positions.itervalues():
        if position.amount > 0:
            longs += 1
        if position.amount < 0:
            shorts += 1

    # Record and plot the leverage of our portfolio over time as well as the
    # number of long and short positions. Even in minute mode, only the end-of-day
    # leverage is plotted.
    record(leverage = context.account.leverage, long_count=longs, short_count=shorts)

There was a runtime error.

There you go.

Added set_do_not_order_list(security_lists.leveraged_etf_list) at Initialize.

Added

for stock in context.security_list:
if stock not in security_lists.leveraged_etf_list and data.can_trade(stock):

in Rebalance.

Clone Algorithm
3
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
# Import the libraries we will use here.
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.factors import AverageDollarVolume, Returns

def initialize(context):
    """
    Called once at the start of the program. Any one-time
    startup logic goes here.    
    
    """
    set_do_not_order_list(security_lists.leveraged_etf_list)
    
    # Define context variables that can be accessed in other methods of
    # the algorithm.
    context.long_leverage = .5
    context.short_leverage = -.5
    context.returns_lookback = 2

    
    
    # Rebalance every morning at 25 minutes after market open.
    schedule_function(rebalance,
                      date_rules.every_day(),
                      time_rules.market_open(hours=0, minutes=1))

    # Record tracking variables at the end of each day.
    schedule_function(record_vars,
                      date_rules.every_day(),
                      time_rules.market_close(minutes=1))

    # Create and attach our pipeline (dynamic stock selector), defined below.
    attach_pipeline(make_pipeline(context), 'mean_reversion_example')
    
  
def make_pipeline(context):
    """
    A function to create our pipeline (dynamic stock selector). The pipeline is used
    to rank stocks based on different factors, including builtin factors, or custom
    factors that you can define. Documentation on pipeline can be found here:
    https://www.quantopian.com/help#pipeline-title
    """
    # Create a pipeline object.

    # Create a dollar_volume factor using default inputs and window_length.
    # This is a builtin factor.
    dollar_volume = AverageDollarVolume(window_length=5)

    # Define high dollar-volume filter to be the top 5% of stocks by dollar volume.
    high_dollar_volume = dollar_volume.percentile_between(97, 100)
    
    # Create a recent_returns factor with a 5-day returns lookback for all securities
    # in our high_dollar_volume Filter. This is a custom factor defined below (see 
    # RecentReturns class).
    recent_returns = Returns(window_length=context.returns_lookback, mask=high_dollar_volume)

    # Define high and low returns filters to be the bottom 0.75% and top 99.25% of
    # securities in the high dollar-volume group.
    low_returns = recent_returns.percentile_between(0,10)
    high_returns = recent_returns.percentile_between(90,100)

    # Define a column dictionary that holds all the Factors
    pipe_columns = {
            'low_returns':low_returns,
            'high_returns':high_returns,
            'recent_returns':recent_returns,
            'dollar_volume':dollar_volume
            }

    # Add a filter to the pipeline such that only high-return and low-return
    # securities are kept.
    pipe_screen = (low_returns | high_returns)
    
    


    # Create a pipeline object with the defined columns and screen.
    pipe = Pipeline(columns=pipe_columns,screen=pipe_screen)
    
  

    return pipe

def before_trading_start(context, data):
    """
    Called every day before market open. This is where we get the securities
    that made it through the pipeline.
    """

    # Pipeline_output returns a pandas DataFrame with the results of our factors
    # and filters.
    context.output = pipeline_output('mean_reversion_example')

    # Sets the list of securities we want to long as the securities with a 'True'
    # value in the low_returns column.
    context.long_secs = context.output[context.output['low_returns']]

    # Sets the list of securities we want to short as the securities with a 'True'
    # value in the high_returns column.
    context.short_secs = context.output[context.output['high_returns']]

    # A list of the securities that we want to order today.
    context.security_list = context.long_secs.index.union(context.short_secs.index).tolist()

    # A set of the same securities, sets have faster lookup.
    context.security_set = set(context.security_list)

def compute_weights(context):
    """
    Compute weights to our long and short target positions.
    """

    # Set the allocations to even weights for each long position, and even weights
    # for each short position.
    long_weight = context.long_leverage / len(context.long_secs)
    short_weight = context.short_leverage / len(context.short_secs)
    
    return long_weight, short_weight

def rebalance(context,data):
    """
    This rebalancing function is called according to our schedule_function settings.
    """

    long_weight, short_weight = compute_weights(context) 
    
    

    # For each security in our universe, order long or short positions according
    # to our context.long_secs and context.short_secs lists.
    for stock in context.security_list:
        if stock not in security_lists.leveraged_etf_list and data.can_trade(stock):
            if stock in context.long_secs.index:
                order_target_percent(stock, long_weight)
            elif stock in context.short_secs.index:
                order_target_percent(stock, short_weight)
  
    # Sell all previously held positions not in our new context.security_list.
    for stock in context.portfolio.positions:
        if stock not in context.security_set and data.can_trade(stock):
            order_target_percent(stock, 0)

    # Log the long and short orders each week.
    log.info("This days's longs: "+", ".join([long_.symbol for long_ in context.long_secs.index]))
    log.info("This days's shorts: "  +", ".join([short_.symbol for short_ in context.short_secs.index]))


def record_vars(context, data):
    """
    This function is called at the end of each day and plots certain variables.
    """

    # Check how many long and short positions we have.
    longs = shorts = 0
    for position in context.portfolio.positions.itervalues():
        if position.amount > 0:
            longs += 1
        if position.amount < 0:
            shorts += 1

    # Record and plot the leverage of our portfolio over time as well as the
    # number of long and short positions. Even in minute mode, only the end-of-day
    # leverage is plotted.
    record(leverage = context.account.leverage, long_count=longs, short_count=shorts)

There was a runtime error.