Back to Community
Issues meeting all 7 constraints

Hi guys,
I'm trying to start this algorithm by meeting all restrictions, but I can't seem to meet the leverage req's or the turnover req's

import talib as ta 

from quantopian.pipeline.data import morningstar

import numpy as np  
import time  
import datetime  
import pandas as pd  
import talib  
import quantopian.optimize as opt

from quantopian.pipeline.filters import QTradableStocksUS  
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 CustomFactor,SimpleMovingAverage  
from quantopian.pipeline.data.psychsignal import stocktwits


#from quantopian.pipeline.data.zacks import EarningsSurprises


def initialize(context):  
    context.max_leverage = 1.1  
    context.max_pos_size = 0.05  
    context.max_turnover = 0.65


def handle_data(context, data):  
    pass


def make_pipeline(context):  
    pipe=Pipeline()  
    universe = QTradableStocksUS()  
    sentiment_score = SimpleMovingAverage(  
        inputs=[stocktwits.bull_minus_bear],  
        window_length=3,  
        mask=QTradableStocksUS()  
    )  
    pipe.add(sentiment_score,'sentiment_score')  
    Price_Range = PriceRange(window_length=3,mask = universe)  
    pipe.add(Price_Range,'Price Range')  
    Volume_Mean5 = VolumeFactor(window_length=5,mask = universe)  
    pipe.add(Volume_Mean5,'Volume_Mean5')  
    pipe.set_screen((Volume_Mean5>=1000000)&(Price_Range>300)&(Price_Range<10000) &sentiment_score.notnull())  
    return pipe




def rebalance(context, data):  
  # Retrieve alpha from pipeline output  
  alpha = context.pipeline_data.sentiment_score

  if not alpha.empty:  
      # Create MaximizeAlpha objective  
      objective = opt.MaximizeAlpha(alpha)

      # Create position size constraint  
      constrain_pos_size = opt.PositionConcentration.with_equal_bounds(  
          -context.max_pos_size,  
          context.max_pos_size  
      )

      # Constrain target portfolio's leverage  
      max_leverage = opt.MaxGrossExposure(context.max_leverage)

      # Ensure long and short books  
      # are roughly the same size  
      dollar_neutral = opt.DollarNeutral()  
      beta_neutral = opt.FactorExposure(  
        pipeline_data[['beta']],  
        min_exposures={'beta': -0.05},  
        max_exposures={'beta': 0.05},  
    )  
      # Constrain portfolio turnover  
      max_turnover = opt.MaxTurnover(context.max_turnover)

      # Rebalance portfolio using objective  
      # and list of constraints  
      algo.order_optimal_portfolio(  
          objective=objective,  
          constraints=[  
              constrain_pos_size,  
              max_leverage,  
              beta_neutral,  
              dollar_neutral,  
              max_turnover,  
          ]  
      )  
3 responses

hello,

A lot of parts are missing (your custom factors, before_trading_start block and other important steps). Make sure to read and understand the tutorials and try to adapt the examples algos before building your own from scratch.

However I managed to build something, I replace some filter to adapt with the custom factors I wrote (yours were missing).

Clone Algorithm
7
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 talib as ta 

from quantopian.pipeline.data import morningstar

import numpy as np  
import time  
import datetime  
import pandas as pd  
import talib  
import quantopian.optimize as opt
import quantopian.algorithm as algo

from quantopian.pipeline.filters import QTradableStocksUS  
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 CustomFactor,SimpleMovingAverage,RollingLinearRegressionOfReturns
from quantopian.pipeline.classifiers.fundamentals import Sector
from quantopian.pipeline.data.psychsignal import stocktwits


class PriceRange(CustomFactor):  
    inputs = [USEquityPricing.high, USEquityPricing.low]

    def compute(self, today, assets, out, highs, lows):  
        out[:] = np.nanmax(highs, axis=0) - np.nanmin(lows, axis=0)
        
class VolumeFactor(CustomFactor):  
    inputs = [USEquityPricing.volume]

    def compute(self, today, assets, out, volume):  
        out[:] = np.nanmean(volume, axis=0)


def initialize(context):  
    context.max_leverage = 1.1  
    context.max_pos_size = 0.05  
    context.max_turnover = 0.65
    
    my_pipe = make_pipeline()
    algo.attach_pipeline(my_pipe, 'my_pipeline')
    
    schedule_function(
        rebalance,
        date_rules.every_day(),
        time_rules.market_open()
    )


def make_pipeline():
    pipe = Pipeline()
    
    universe = QTradableStocksUS()  
    sentiment_score = SimpleMovingAverage(  
        inputs=[stocktwits.bull_minus_bear],  
        window_length=3,  
        mask=QTradableStocksUS()  
    )  
    pipe.add(sentiment_score,'alpha')  
    Price_Range = PriceRange(window_length=3,mask = universe)  
    pipe.add(Price_Range,'Price Range')  
    Volume_Mean5 = VolumeFactor(window_length=5,mask = universe)  
    pipe.add(Volume_Mean5,'Volume_Mean5')  
    beta = 0.66*RollingLinearRegressionOfReturns(
                    target=sid(8554),
                    returns_length=5,
                    regression_length=260,
                    mask=sentiment_score.notnull() & Sector().notnull()
                    ).beta + 0.33*1.0
    pipe.add(beta,'beta') 
    pipe.set_screen((Volume_Mean5>=1000000)&(Price_Range>3)&(Price_Range<10) &sentiment_score.notnull()&beta.notnull())  
    return pipe

def before_trading_start(context, data):
    # Store our pipeline output DataFrame in context
    context.pipeline_data = algo.pipeline_output('my_pipeline')


def rebalance(context, data):  
    # Retrieve alpha from pipeline output
    pipeline_data = context.pipeline_data
    print(pipeline_data)

    if not pipeline_data.alpha.empty:  
        # Create MaximizeAlpha objective  
        objective = opt.MaximizeAlpha(pipeline_data.alpha)

        # Create position size constraint  
        constrain_pos_size = opt.PositionConcentration.with_equal_bounds(  
            -context.max_pos_size,  
            context.max_pos_size  
        )

        # Constrain target portfolio's leverage  
        max_leverage = opt.MaxGrossExposure(context.max_leverage)

        # Ensure long and short books  
        # are roughly the same size  
        dollar_neutral = opt.DollarNeutral()  
        beta_neutral = opt.FactorExposure(
            pipeline_data[['beta']],  
            min_exposures={'beta': -0.05},  
            max_exposures={'beta': 0.05},
        )  
        # Constrain portfolio turnover  
        max_turnover = opt.MaxTurnover(context.max_turnover)

        # Rebalance portfolio using objective  
        # and list of constraints  
        algo.order_optimal_portfolio(  
            objective=objective,  
            constraints=[  
                constrain_pos_size,  
                max_leverage,  
                beta_neutral,  
                dollar_neutral,  
                max_turnover,  
            ]  
        )
There was a runtime error.

How do I restrict the min Leverage is there such a thing as

min_leverage = opt.MinGrossExposure(context.min_leverage)  

Some of the constraints are not respected because the filters are too restrictive. The optimizer is not a magic tool that will make your algo respect all the constraint. Sometimes the optimisation fails because the alpha factors and the filters you use result to either an insufficient number of securities to trade or an over-exposure to a sector / risk factor or a turnover that is too high (force it to be under 65% will thus decrease your leverage), etc.
Review the pipeline part instead of the optimisation process.