Back to Community
Capping the Leverage

I just started, so can someone please share a simple example algorithm or some code with me that caps the leverage at 1.0 without using the order_optimizer? Thanks

2 responses

Account leverage is defined as the sum of the absolute value of long and short positions divided by the portfolio value. For a leverage of one, the sum of the absolute values of position weights must equal 1.

So, if one has a series with all the securities and weights one wishes to hold, then divide the series by the sum of the absolute value of the weights to ensure the gross leverage is 1 something like this

    weights = weights / weights.abs().sum  

The general ordering logic would look like this.

    # Make two series of the longs and shorts and associated weights  
    # Ensure that all the short weights are negative (this is what tells order to short them)  
    # This would come from the algo's selection and weighting process  
    # Make sure to include any current securities if those are to be held

    # Combine the two series  
    weights = pd.concat([longs, shorts])

    # Divide by the sum of the abs value of the weights to ensure the gross leverage is 1  
    weights = weights / weights.abs().sum  
    # Order the stocks  
    for stock, weight in weights.iteritems():  
        if data.can_trade(stock):  
            order_target_percent(stock, weight)  
    # Close any positions not in our long or short list  
    for stock, position in context.portfolio.positions.iteritems():  
        if data.can_trade(stock) and stock not in weights.index:  
            order_target_percent(stock, 0)

Using the order_optimal_portfolio method is almost exactly the same but takes a few less lines of code and can be easily enhanced to incorporate other constraints. The attached algo shows a simple algo which incorporates both order approaches.

Clone Algorithm
0
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
"""
This is a sample algorithm on Quantopian for you to test and adapt.

One can either use the plain order methods or the optimize methods.
"""

# Import necessary Pipeline modules
from quantopian.pipeline import Pipeline
from quantopian.algorithm import attach_pipeline, pipeline_output

# Import specific filters and factors which will be used
from quantopian.pipeline.filters import QTradableStocksUS, StaticAssets
from quantopian.pipeline.factors import RSI, SimpleMovingAverage

# Import datasets which will be used
from quantopian.pipeline.data.builtin import USEquityPricing

# import optimize
import quantopian.optimize as opt
 
# Import pandas
import pandas as pd

def initialize(context):
    """
    Initialize constants, create pipeline, and schedule functions
    This uses the default slippage and commission models
    """
    # Universe we wish to trade
    # Place one or more desired symbols below
    context.MY_STOCKS = symbols('SPY', 'GLD')
    
    # Create our weights (evenly weighted)
    context.WEIGHT = 1.0 / len(context.MY_STOCKS)
        
    # Constants for min and max RSI
    context.MIN_RSI = 30
    context.MAX_RSI = 70

    # Make our pipeline and attach to the algo
    attach_pipeline(make_pipeline(context), 'my_pipe')

    # Place orders
    schedule_function(
        func=place_orders_using_order_method,
        date_rule=date_rules.week_start(),
        time_rule=time_rules.market_open()
    )
    

def make_pipeline(context):
    """
    Define a pipeline.
    This not only defines the data but also the logic to determine longs and shorts
    
    We break this code out into its own function to make it easier to
    test and modify in isolation. In particular, this function can be
    copy/pasted into research and run by itself.
    Parameters
    -------
    context : AlgorithmContext

    Returns
    -------
    pipe : Pipeline
        Represents computations we would like to perform on the assets
    """
    my_universe = StaticAssets(context.MY_STOCKS)
    
    # Create any needed factors.
    rsi = RSI(window_length=10)
    sma_10 = SimpleMovingAverage([USEquityPricing.close], window_length=10)
    sma_25 = SimpleMovingAverage([USEquityPricing.close], window_length=25)
  
    # Create any filters based upon these factors
    rsi_between_min_max = (rsi > context.MIN_RSI) & (rsi < context.MAX_RSI)
    
    # Rules to long and short stocks
    # Open (long or short) any securities meeting these rules
    # Anything held which isn't in either of these will be closed
    longs = (
        my_universe
        & rsi_between_min_max
        & (sma_10 < sma_25)
        )
    
    shorts = (
        my_universe
        & rsi_between_min_max
        & (sma_10 > sma_25)
        )
      
    # Create our pipeline
    pipe = Pipeline(
        columns={
            'longs': longs,
            'shorts': shorts,
        },
        screen=my_universe,
    )
    
    return pipe  
        
def before_trading_start(context, data):
    """
    Run our pipeline to fetch the actual data. 
    It's a good practice to place the pipeline execution here. 
    This gets allocated more time than scheduled functions.
    """
    context.output = pipeline_output('my_pipe')
    
def place_orders_using_optimize(context, data):
    """
    Use Optimize to place orders all at once
    """
    # Make a series of the longs and shorts and associated weights
    # Ensure that all the short weights are negative (this is what tells opt to short them)
    longs = pd.Series(context.WEIGHT, context.output.query('longs').index)
    shorts = pd.Series(-context.WEIGHT, context.output.query('shorts').index)

    # Combine the two
    weights = pd.concat([longs, shorts])
    
    # Create our TargetWeights objective
    target_weights = opt.TargetWeights(weights) 

    # Execute the order_optimal_portfolio method with above objective and constraint
    # No need to loop through the stocks. 
    # The order_optimal_portfolio does all the ordering at one time
    # Also closes any positions not in 'all_alphas'
    # As a bonus also checks for 'can_trade'
    # Could set constraints here if desired
    order_optimal_portfolio(
        objective = target_weights,
        constraints = []
    )
    
def place_orders_using_order_method(context, data):
    """
    Use order methods to place orders
    """
    # Make a series of the longs and shorts and associated weights
    # Ensure that all the short weights are negative (this is what tells order to short them)
    longs = pd.Series(context.WEIGHT, context.output.query('longs').index)
    shorts = pd.Series(-context.WEIGHT, context.output.query('shorts').index)

    # Combine the two
    weights = pd.concat([longs, shorts])

    # Divide by the abs value of the weights to ensure the gross leverage is 1
    weights = weights / weights.abs().sum()
    
    # Order the stocks
    for stock, weight in weights.iteritems():
        if data.can_trade(stock):
            order_target_percent(stock, weight)
            
    # Close any positions not in our long or short list
    for stock, position in context.portfolio.positions.iteritems():
        if data.can_trade(stock) and stock not in weights.index:
            order_target_percent(stock, 0)
There was a runtime error.
Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

Thank You! This was just I needed.