Hi - I am trying to convert a Quantopian Code to QC but its taking much more effort and time than what I expected since I am a beginner in Python. I wanted to ask if anyone here could help me convert the algo to QC?
Thanks!
QUANTCONNECT COMMUNITY
Hi - I am trying to convert a Quantopian Code to QC but its taking much more effort and time than what I expected since I am a beginner in Python. I wanted to ask if anyone here could help me convert the algo to QC?
Thanks!
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 QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect 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. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Nathan Swenson
Perhaps you can clone one on the existing versions of in and out strategy and then modify it to include the updated logic? Â The Flex 4 version looks like a solid one to work with.
S.T.E
Thanks but I need a bit more help than this! :)
I yet don't know how to code the stock selection part into it. If anyone would like to cooperate I can share the code.
Nathan Swenson
Are you specifying a number of stocks to trade into in place of QQQ/SPY, or do you want auto picking based on criteria? Specifying predetermined stocks should be easy. I don't know the autopicking routines. I'm also very new to this platform.
Derek Melchin
Hi S.T.E.,
Consider reviewing our Universe Selection documentation and Framework Boot Camp for a better understanding of stock selection. For further assistance, publish the Quantopian code to this forum.
Best,
Derek Melchin
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 QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect 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. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
S.T.E
"""
Based on 'In & Out' strategy by Peter Guenther 10-04-2020
expanded by Tentor Testivis and coded by Dan Whitnable (Quantopian)
AND
'Quality companies in an uptrend' by Chris Cain 11-22-2019
coded by Dan Whitnable (Quantopian) with bonds weights  fixed by Vladimir
"""
# Import necessary algo and Pipeline modules
import quantopian.algorithm as algo
from quantopian.pipeline import Pipeline
# Import specific filters and factors which will be used
from quantopian.pipeline.factors import CustomFactor, Returns
from quantopian.pipeline.filters import Q500US, Q1500US, Q3000US, QTradableStocksUS, StaticAssets
from quantopian.pipeline.factors import SimpleMovingAverage as SMAÂ
# Import datasets which will be used
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.data.morningstar import Fundamentals as ms
# import optimize
import quantopian.optimize as opt
# Import numpy and pandas because they rock
import numpy as np
import pandas as pd
class Mean_Over_STD(CustomFactor):
  window_length = 756
  def compute(self, today, assets, out, value):
      out[:] = np.nanmean(value, axis=0) / np.nanstd(value, axis=0)
class total_earning_growth(CustomFactor):
  window_length = 1
  def compute(self, today, assets, out, eps, dps, equity):
      out[:] = eps[0]+dps[0]+equity[0]
class acc_earning_growth(CustomFactor):
  window_length = 140
  def compute(self, today, assets, out, eps, dps, equity):
      out[:] = (eps[-1]+dps[-1]+equity[-1])/(eps[1]+dps[1]+equity[1])
class sales_growth(CustomFactor):
  window_length = 252
  def compute(self, today, assets, out, sales):
      out[:] = (sales[-1])/(sales[1])
def initialize(context):Â
  set_commission(commission.PerShare(cost=0.00, min_trade_cost=0.00))
  #########################################
  ## In & Out parameters ##################
  ## based on "New Strategy - In & out" ##
  context.WAIT_DAYS = 15 # min days of being out; 3 trading weeks
  context.XLI = symbol('XLI') # industrials
  context.DBB = symbol('DBB') # materials
  context.BIL = symbol('SHY') # bond / interest rate
  context.UUP = symbol('UUP') # USD index
  context.VIXY = symbol('TVIX')
  context.SIGNAL_UNIVERSE = symbols('XLI', 'DBB', 'SHY', 'UUP', 'TVIX')
  # Assets and associated weights when 'out' of the market
  # Any asset held but not in the list will be closed
  context.TRADE_WEIGHTS_OUT = {symbol('TIPZ'): 0.0,Â
                symbol('TYD'): 0.5, symbol('TMF'): 0.3
                }
  ##############################################
  ## Your stock selection strategy parameters ##
  ## based on "New Strategy - Quality companies in an uptrend ##
  # Set target number of securities to hold and top ROE qty to filter Â
  context.TARGET_SECURITIES = 10 Â
  context.TOP_ROIC_QTY = 50 #First sort by ROE
  # This is for the trend following filter Â
  context.SPY = symbol('SPY') Â
  context.TF_LOOKBACK = 126 Â
  context.TF_CURRENT_LOOKBACK = 10
  # This is for the determining momentum Â
  context.MOMENTUM_LOOKBACK_DAYS = 126 #Momentum lookback Â
  context.MOMENTUM_SKIP_DAYS = 6Â
  # Initialize any other variables before being used Â
  context.stock_weights = pd.Series()
  # Schedule functions Â
  schedule_function( Â
    # daily rebalance if OUT of the market
    rebalance_when_out_of_the_market, Â
    date_rules.every_day(),
    time_rules.market_open(minutes = 30)
  )Â
  schedule_function( Â
    # weekly rebalance if IN the market
    rebalance_when_in_the_market, Â
    date_rules.week_start(days_offset=4),
    time_rules.market_open(minutes = 30)
  )
  schedule_function( Â
    # record signals every day
    record_signals, Â
    date_rules.every_day(),
    time_rules.market_open()
  )
  algo.attach_pipeline(make_pipeline(context), 'pipeline') Â
  # context.tvix= sid(40515)#1.5x leveraged VIX ETF
  # context.vix=sid(38054)#2x leveraged VIX
  # schedule_function(ma_crossover_handling, date_rules.every_day(),time_rules.market_open(hours=1))
class Days_Since_True(CustomFactor):Â
  """
  Finds the number of days since a signal was last True
  Max lookback is 100
  """
  window_length = 100
  def compute(self, today, assets, out, input_factor):Â
    # Flip the factor first to last so argmax finds the last occurance
    # Set the earliest day to True so it always finds at least 1 TrueÂ
    input_factor[0] = True
    out[:] = np.argmax(np.flipud(input_factor), axis=0)    Â
def make_pipeline(context):
  ###############################
  ## In & Out pipeline content ##
  # Set universe to only the assets we use for signals
  mask_io = StaticAssets(context.SIGNAL_UNIVERSE)
  # Get the returns for basic metals, industrials and bonds
  # Get the cost of debt which is the inverse the bond returns
  returns = Returns(window_length=58, mask=mask_io)
  basic_metals_down = returns[context.DBB] < -.07
  industrial_sector_down = returns[context.XLI] < -.07
  short_term_bond_down = returns[context.BIL] < -.006
  cost_of_debt_up = short_term_bond_down
  dollar_up = returns[context.UUP] > .07
  vix_up = returns[context.VIXY] > 0.25
  # Bear signal if any one of the above is true
  bear_signal = (basic_metals_down |
          industrial_sector_down |
          cost_of_debt_up |
          dollar_up |
          vix_up
          )-
  days_since_last_bear_signal = Days_Since_True([bear_signal], mask=mask_io)
  # Go out of the market if bear in recent days
  go_out_of_the_market = days_since_last_bear_signal < context.WAIT_DAYSÂ
  ##################################################
  #Your stock selection strategy pipeline content ##
  universe = QTradableStocksUS() & Q3000US() & Q500US()
  cash_return = ms.cash_return.latest.rank(mask=universe)Â
  fcf_yield = ms.fcf_yield.latest.rank(mask=universe)
  ey = ms.earning_yield.latest.rank(mask=universe)
  rev_growth = ms.revenue_growth.latest.rank(mask=universe)
  roic = ms.roic.latest.rank(mask=universe)
  stable_roic = Mean_Over_STD(
    inputs=[ms.roic],
    mask=universe
  ).rank(mask=universe)
  ltd_to_eq = ms.long_term_debt_equity_ratio.latest.rank(mask=universe) Â
  value = (cash_return + fcf_yield).rank()
  qs=sales_growth(inputs=[ms.total_revenue],mask=universe).rank(mask=universe)
  profit=(ms.operation_income_growth.latest.rank(mask=universe))
  pg=ms.diluted_eps_growth.latest.rank().rank(mask=universe)
  quality = roic + ltd_to_eq + stable_roic
  # Create a 'momentum' factor. Â
  returns_overall = Returns(window_length=context.MOMENTUM_LOOKBACK_DAYS+context.MOMENTUM_SKIP_DAYS) Â
  returns_recent = Returns(window_length=context.MOMENTUM_SKIP_DAYS) Â
  momentum = returns_overall - returns_recent Â
  # Filters for top quality and momentum to use in our selection criteria Â
  top_quality = quality.top(context.TOP_ROIC_QTY, mask=universe) Â
  top_quality_momentum = momentum.top(context.TARGET_SECURITIES, mask=top_quality) Â
  pipe = Pipeline(columns={Â
      ## In & out pipeline output ##
      'go_out_of_the_market': go_out_of_the_market,
      'bear_signal': bear_signal,
      'days_since_last_bear_signal': days_since_last_bear_signal,
      'basic_metals_down': Days_Since_True([basic_metals_down], mask=mask_io) < context.WAIT_DAYS,
      'industrial_sector_down': Days_Since_True([industrial_sector_down], mask=mask_io) < context.WAIT_DAYS,
      'cost_of_debt_up': Days_Since_True([cost_of_debt_up], mask=mask_io) < context.WAIT_DAYS,
      'dollar_up': Days_Since_True([dollar_up], mask=mask_io) < context.WAIT_DAYS,
      'mask_io': mask_io,
      ## Your stock selection strategy pipeline output ## Â
      'top_quality_momentum': top_quality_momentum,
      'universe': universe,
      },
  )
  return pipe
def rebalance_when_out_of_the_market(context, data):
  # Get signal. All rows with non-missing values are the same. Just choose the first one.
  df = algo.pipeline_output('pipeline')Â
  go_out_of_the_market = df.loc[df.mask_io].go_out_of_the_market[0]
  if go_out_of_the_market:
    # Go all bonds
    order_optimal_portfolio( Â
      objective = opt.TargetWeights(context.TRADE_WEIGHTS_OUT),Â
      constraints = [] Â
    )
def rebalance_when_in_the_market(context, data):
  # Get signal. All rows with non-missing values are the same. Just choose the first one.
  df = algo.pipeline_output('pipeline')Â
  go_out_of_the_market = df.loc[df.mask_io].go_out_of_the_market[0]
  if not go_out_of_the_market:
    ## Your stock selection strategy ##
    df = algo.pipeline_output('pipeline') Â
    current_holdings = context.portfolio.positions
    #rule = 'top_quality_momentum & (trend_up or (not trend_up & index in @current_holdings))'
    rule = 'top_quality_momentum'
    stocks_to_hold = df[df['universe']].query(rule).index
    # Set desired stock weights Â
    # Equally weight Â
    stock_weight = 1.0 / context.TARGET_SECURITIES Â
    context.stock_weights = pd.Series(index=stocks_to_hold, data=stock_weight) Â
    order_optimal_portfolio( Â
      objective = opt.TargetWeights(context.stock_weights),Â
      constraints = [] Â
    )
def record_signals(context, data):
  df = algo.pipeline_output('pipeline')Â
  in_the_market = not df.loc[df.mask_io].go_out_of_the_market[0]
  dollar = df.dollar_up[0]
  debt = df.cost_of_debt_up[0]
  metals = df.basic_metals_down[0]
  industrials = df.industrial_sector_down[0]
  # Record values for testing
  record(in_the_market=in_the_market)
  record(dollar=dollar, debt=debt, metals=metals, industrials=industrials)
Jonathon Tzu
Hi, I had a similar-ish strategy, but I was wondering whether there was anyway to do the six month momentum indicator faster? I found a similar strategy to what I wanted to do on the quant connect forums, but it's taking way too long to backtest.Â
S.T.E
Hi Thanks for sharing, I think the momentum factor in the text strat performs better. I am still trying to get it work on Quantconnect but not even close!
S.T.E
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 QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect 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. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!