Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
class Returns vs DailyReturns (built-in factors)

What exactly is the difference between these two? Intuitively, Returns should give the percentage change between two prices and DailyReturn should return some kind of return series of daily returns but it seems to me they do exactly the same, as the following pipeline suggests

def make_pipeline():  
    base_universe = QTradableStocksUS()  
    daily_returns1 = DailyReturns(window_length=21, mask=base_universe)  
    daily_returns2 = Returns(window_length=21, mask=base_universe)  
    return_filter1 = daily_returns1.top(3)  
    return_filter2 = daily_returns2.top(3)  
    return Pipeline(  
    columns = {  
        'DailyReturns':daily_returns1,  
        'Returns':daily_returns2,  
    }, screen=return_filter1 & return_filter2)

run_pipeline(make_pipeline(), '2016-06-05', '2016-06-05')  

I am trying to generate some Pipeline output that is based on computations performed on the return time-series. Is there any way of doing that does not involve a CustomFactor?

6 responses

This may help in IDE:

from quantopian.algorithm import attach_pipeline, pipeline_output  
from quantopian.pipeline import Pipeline, factors, filters  
# ------------------------------------------  
STK_SET, PERIOD, N = filters.Q500US(), 21, 3  
# ------------------------------------------  
def initialize(context):  
    PR = factors.Returns(window_length = PERIOD + 1, mask = STK_SET)  
    DR = factors.DailyReturns(mask = STK_SET)  
    PR_best = PR.top(N)  
    DR_best = DR.top(N)  
    screen = PR_best | DR_best  
    attach_pipeline(Pipeline(columns = {'PR': PR, 'DR': DR}, screen = screen), 'my pipe')  

def before_trading_start(context, data):  
    output = pipeline_output('my pipe')  
    period_returns = output.sort_values(['PR'], ascending = False).head(N)  
    daily_returns = output.sort_values(['DR'], ascending = False).head(N)  

    print(period_returns, daily_returns)  

Try:
PERIOD = 21

2011-01-04 05:45 PRINT (
DR PR
Equity(16453 [CIEN]) 0.031354 0.380165
Equity(35006 [SD]) 0.015048 0.369004
Equity(239 [AIG]) 0.006593 0.352763,
DR PR
Equity(32618 [RVBD]) 0.075043 0.098461
Equity(4684 [MBI]) 0.064220 0.281124
Equity(700 [BAC]) 0.062921 0.215938)

PERIOD = 1

2011-01-04 05:45 PRINT (
DR PR
Equity(32618 [RVBD]) 0.075043 0.075043
Equity(4684 [MBI]) 0.064220 0.064220
Equity(700 [BAC]) 0.062921 0.062921,
DR PR
Equity(32618 [RVBD]) 0.075043 0.075043
Equity(4684 [MBI]) 0.064220 0.064220
Equity(700 [BAC]) 0.062921 0.062921)

DailyReturns() Calculates daily percent change in close price. Returns() Calculates the percent change in close price over the given window_length.

DailyReturns() should be the same as Returns(window_length = 2) only.

If you want to avoid CustomFactors, you could return Returns in Pipeline as you are doing now then do some computations on it outside of Pipeline (where you can work with Pandas/other libraries) before feeding it to the Optimizer.

Thank you both for your answers! That clarified quite a bit!

Could someone clarify further:
Vladimir compares Returns(window_length = 22) with DailyReturns() (no window_length argument set, so takes the default value of 2). Of course those will be different.
It's not yet clear to me what happens when both functions are called with the same argument:
Returns(window_length = 22) vs DailyReturns(window_length = 22)

  1. Are the results indeed always the same?
  2. If so, why do we have 2 different functions?
  3. If not, what's the difference?

@David Bijl

Good questions. I'll try to provide some answers:

  1. Are the results indeed always the same? Yes, the results are identical.
  2. If so, why do we have 2 different functions? The DailyReturns factor is simply for convenience since most of the time one wants the default window length of 2.
  3. If not, what's the difference? No difference. See the code below. Notice that DailyReturns is actually a subclass of Returns with the only difference being the default window_length = 2. The defaults can always be overridden which, in that case, makes the two identical.

class Returns(CustomFactor):  
    """  
    Calculates the percent change in close price over the given window_length.  
    **Default Inputs**: [EquityPricing.close]  
    """  
    inputs = [EquityPricing.close]  
    window_safe = True

    def _validate(self):  
        super(Returns, self)._validate()  
        if self.window_length < 2:  
            raise ValueError(  
                "'Returns' expected a window length of at least 2, but was "  
                "given {window_length}. For daily returns, use a window "  
                "length of 2.".format(window_length=self.window_length)  
            )

    def compute(self, today, assets, out, close):  
        out[:] = (close[-1] - close[0]) / close[0]


class DailyReturns(Returns):  
    """  
    Calculates daily percent change in close price.  
    **Default Inputs**: [EquityPricing.close]  
    """  
    inputs = [EquityPricing.close]  
    window_safe = True  
    window_length = 2

The code for most of Quantopian is open sourced under the Zipline project so one can easily find the actual logic. In this case the snipit above can be found here (https://github.com/quantopian/zipline/blob/master/zipline/pipeline/factors/basic.py)

Hope that helps.

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.

@Dan great help, thanks!