Combining Factors

Factors can be combined, both with other Factors and with scalar values, via any of the builtin mathematical operators (+, -, *, etc). This makes it easy to write complex expressions that combine multiple Factors. For example, constructing a Factor that computes the average of two other Factors is simply:

>>> f1 = SomeFactor(...)
>>> f2 = SomeOtherFactor(...)
>>> average = (f1 + f2) / 2.0

In this lesson, we will create a pipeline that creates a relative_difference factor by combining a 10-day average factor and a 30-day average factor.

As usual, let's start with our imports:


In [1]:
from quantopian.pipeline import Pipeline
from quantopian.research import run_pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.factors import SimpleMovingAverage

For this example, we need two factors: a 10-day mean close price factor, and a 30-day one:


In [2]:
mean_close_10 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=10)
mean_close_30 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=30)

Then, let's create a percent difference factor by combining our mean_close_30 factor with our mean_close_10 factor.


In [3]:
percent_difference = (mean_close_10 - mean_close_30) / mean_close_30

In this example, percent_difference is still a Factor even though it's composed as a combination of more primitive factors. We can add percent_difference as a column in our pipeline. Let's define make_pipeline to create a pipeline with percent_difference as a column (and not the mean close factors):


In [4]:
def make_pipeline():

    mean_close_10 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=10)
    mean_close_30 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=30)

    percent_difference = (mean_close_10 - mean_close_30) / mean_close_30

    return Pipeline(
        columns={
            'percent_difference': percent_difference
        }
    )

Let's see what the new output looks like:


In [6]:
result = run_pipeline(make_pipeline(), '2015-05-05', '2015-05-05')
result


Out[6]:
percent_difference
2015-05-05 00:00:00+00:00 Equity(2 [AA]) 0.017975
Equity(21 [AAME]) -0.002325
Equity(24 [AAPL]) 0.016905
Equity(25 [AA_PR]) 0.021544
Equity(31 [ABAX]) -0.019639
Equity(39 [DDC]) 0.074730
Equity(41 [ARCB]) 0.007067
Equity(52 [ABM]) 0.003340
Equity(53 [ABMD]) -0.024682
Equity(62 [ABT]) 0.014385
Equity(64 [ABX]) 0.046963
Equity(66 [AB]) 0.013488
Equity(67 [ADSK]) -0.003921
Equity(69 [ACAT]) -0.007079
Equity(70 [VBF]) 0.005507
Equity(76 [TAP]) -0.008759
Equity(84 [ACET]) -0.056139
Equity(86 [ACG]) 0.010096
Equity(88 [ACI]) -0.022089
Equity(100 [IEP]) 0.011293
Equity(106 [ACU]) 0.003306
Equity(110 [ACXM]) -0.029551
Equity(112 [ACY]) -0.057763
Equity(114 [ADBE]) 0.009499
Equity(117 [AEY]) 0.012543
Equity(122 [ADI]) 0.009271
Equity(128 [ADM]) 0.015760
Equity(134 [SXCL]) NaN
Equity(149 [ADX]) 0.007232
Equity(153 [AE]) -0.112999
... ...
Equity(48961 [NYMT_O]) NaN
Equity(48962 [CSAL]) 0.000000
Equity(48963 [PAK]) 0.000000
Equity(48969 [NSA]) 0.000000
Equity(48971 [BSM]) 0.000000
Equity(48972 [EVA]) 0.000000
Equity(48981 [APIC]) 0.000000
Equity(48989 [UK]) 0.000000
Equity(48990 [ACWF]) 0.000000
Equity(48991 [ISCF]) 0.000000
Equity(48992 [INTF]) 0.000000
Equity(48993 [JETS]) 0.000000
Equity(48994 [ACTX]) 0.000000
Equity(48995 [LRGF]) 0.000000
Equity(48996 [SMLF]) 0.000000
Equity(48997 [VKTX]) 0.000000
Equity(48998 [OPGN]) NaN
Equity(48999 [AAPC]) 0.000000
Equity(49000 [BPMC]) 0.000000
Equity(49001 [CLCD]) NaN
Equity(49004 [TNP_PRD]) 0.000000
Equity(49005 [ARWA_U]) NaN
Equity(49006 [BVXV]) NaN
Equity(49007 [BVXV_W]) NaN
Equity(49008 [OPGN_W]) NaN
Equity(49009 [PRKU]) NaN
Equity(49010 [TBRA]) NaN
Equity(49131 [OESX]) NaN
Equity(49259 [ITUS]) NaN
Equity(49523 [TLGT]) NaN

8235 rows × 1 columns

In the next lesson, we will learn about filters.