Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
State Dependent Pipeline

Hi!

I am trying to pass a variable to my pipeline so that I can change the window_length arguments depending on some other factor. You could change this depending on macroeconomic conditions, volatility, credit spreads, etc...

Below is a simple example where I try to manually change the window length from 10 to 100 but I wasn't able to get this to work. In fact, in my backtest when I put log.info() code into my pipeline function, I could only ever see make_pipeline() being executed once.

make_pipeline() doesn't take any context or data arguments so I am trying to figure out how can I make my window length dynamic and potentially dependent on various market states? Looks like I can't use global variables either.

Apologies if I'm making a dumb newbie Python error. Trying my best here. Thanks!

WIN_LENGTH = 10  
def make_pipeline():

  mean_close_XX = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=WIN_LENGTH)  
  log.info('Your window length is %d' % WIN_LENGTH)

  return Pipeline(  
    columns={  
      'XX_day_mean_close': mean_close_XX  
    }  
  )  
def before_trading_start(context, data):  
    global WIN_LENGTH  
    WIN_LENGTH = 100  
    po = pipeline_output('my_pipeline')  
5 responses

You can make a variable context.win_length = 10 in the function def initialize(context):

Then in your other functions you can access the context.win_length variable. Adding the "context." to the beginning and putting within the initialize function makes it a global variable.

def initialize(context):  
    context.WIN_LENGTH = 10  
def make_pipeline():

  mean_close_XX = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=context.WIN_LENGTH)  
  log.info('Your window length is %d' % context.WIN_LENGTH)

  return Pipeline(  
    columns={  
      'XX_day_mean_close': mean_close_XX  
    }  
  )  
def before_trading_start(context, data):  
    context.WIN_LENGTH  
    context.WIN_LENGTH = 100  
    po = pipeline_output('my_pipeline')  

Hope that solves your issue.
Best

Why thank you for your response! I gave it a worthy try but as expected I got an error:

NameError: global name 'context' is not defined.. in make_pipeline

I think the issue is that normally, I'd be able to use context but make_pipeline() does not take that session object as an argument and so it does not recognize it within that scope. Of course, not so with the other two functions initialize(context) and before_trading_start(context, data).

Maybe there is another easy solution.

Hi Tariq,

make_pipeline is not a pre-defined function. It's defined in the algorithm, so you can simply specify that you want context to be a parameter in the definition, and pass it as an argument when you call make_pipeline.

For example, you could do something like this:

def initialize(context):  
    context.my_var = 10  
    ...  
    my_pipe = make_pipeline(context)

def make_pipeline(context):  
    print context.my_var  
    ...  
    return Pipeline( ... )  

Does this help?

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.

Hi Jamie, interesting. I knew that make_pipeline was a custom function but was not clear on how to pass additional arguments when calling attach_pipeline. Thanks for the suggestion. Being able to use the context variable in a pipeline is a powerful feature.

However, I gave the suggestion a go and then created a plain vanilla momentum strategy that uses a shorter and shorter window as time passes by, decrementing the window by 1 day each day until it hits 10 days. The attached example, logs only the initial context.DYN_WINDOW, indicating that make_pipeline gets called only once, which is surprising to me. I thought it was calculated every day. Isn't it?

Hi Tariq,

Ah, I see what you are trying to do now. Yes, pipeline is run for every day in the simulation, but it is defined in initialize (in make_pipeline). It is defined only once (as initialize is run only once) so you won't be able to make state-dependent changes.

As a workaround, you could instead create a CustomFactor that changes its window length based on the value of today in the compute function.

If you haven't been through it already, I recommend going through the Pipeline Tutorial. Lesson 10 specifically covers CustomFactors which should help.