Back to Community
Help with validating trading volume/allocation for a backtest

Hello,

I have an algo that sorts stocks based on ROIC/PE ratio, and trades shorts/longs for 100 (50 long and 50 short) securities. However this algorithm only picks a small number of securities in the backtest. Can anyone please identify the error in the constraints that causes it to trade a much smaller volume and retain a large amount of cash?

Note: I am new to Quantopian and created this algo by editing a tutorial. I am learning the concepts, and your feedback can help me find the problem.

import quantopian.algorithm as algo  
from quantopian.pipeline import Pipeline  
from quantopian.pipeline.filters import QTradableStocksUS  
from quantopian.pipeline.factors import SimpleMovingAverage  
from quantopian.pipeline.filters.fundamentals import Q1500US  
import quantopian.optimize as opt  
from quantopian.pipeline.data import factset

MAX_GROSS_EXPOSURE = 1.0

MAX_POSITION_CONCENTRATION = 0.01

def initialize(context):  
    my_pipe = make_pipeline()  
    algo.attach_pipeline(my_pipe, 'my_pipeline')

    schedule_function(  
        my_rebalance,  
        date_rules.week_start(),  
        time_rules.market_open()  
        )  
def make_pipeline():  
    """  
    Create our pipeline.  
    """  
    roic_factor = factset.Fundamentals.roic_af.latest  
    pe = factset.Fundamentals.pe_af.latest  
    #roic_adj = roic_factor + pe  
    roic_farmula= roic_factor/pe  
    # Filter to select securities to go long.  
    longs = roic_farmula.top(50)

    # Filter to select securities to go shirt.  
    shorts = roic_farmula.bottom(50)     

    # Filter for all securities that we want to trade.  
    securities_to_trade = (shorts | longs)

    return Pipeline(  
        columns={  
            'longs': longs,  
            'shorts': shorts,  
            'roic_farmula': roic_farmula  
        },  
        screen=(securities_to_trade & QTradableStocksUS()),  
    )

def my_rebalance(context, data):  
    target_weights = compute_target_weights(context, data)  
    max_gross_exposure = opt.MaxGrossExposure(MAX_GROSS_EXPOSURE)  
    max_position_concentration = opt.PositionConcentration.with_equal_bounds(  
        -MAX_POSITION_CONCENTRATION,  
        MAX_POSITION_CONCENTRATION  
    )  
    # We want to constraint our portfolio to be dollar neutral (equal amount invested in  
    # long and short positions).  
    dollar_neutral = opt.DollarNeutral()  
    # Stores all of our constraints in a list.  
    constraints = [  
        max_gross_exposure,  
        max_position_concentration,  
        dollar_neutral,  
    ]

    if target_weights:  
        algo.order_optimal_portfolio(  
            objective = opt.TargetWeights(target_weights),  
            constraints = constraints  
            )

def before_trading_start(context, data):  
    pipe_results = algo.pipeline_output('my_pipeline')  
    context.longs = []  
    for sec in pipe_results[pipe_results['longs']].index.tolist():  
        if data.can_trade(sec):  
            context.longs.append(sec)

    context.shorts = []  
    for sec in pipe_results[pipe_results['shorts']].index.tolist():  
        if data.can_trade(sec):  
            context.shorts.append(sec)


def compute_target_weights(context, data):  
    weights = {}  
    if context.longs and context.shorts:  
        long_weight = 0.5/len(context.longs)  
        short_weight = -0.5/len(context.shorts)  
    else:  
        return weights  
    for security in context.portfolio.positions:  
        if security not in context.longs and security not in context.shorts:  
            weights[security] = 0  
    for security in context.longs:  
        weights[security] = long_weight  
    for security in context.shorts:  
        weights[security] = short_weight  
    return weights  
Loading notebook preview...
Notebook previews are currently unavailable.