Notebook

Constructing a Pipeline in Research

This example comes from a request in the forums. The original post can be found here: https://www.quantopian.com/posts/ranking-system-based-on-trading-volume-slash-shares-outstanding

It has also been used as the core pipeline API example. The notebooks below shows how you would compute this pipeline here in a research notebooks.

The original request was:

I am stuck trying to build a stock ranking system with two signals:

  1. Trading Volume/Shares Outstanding.
  2. Price of current day / Price of 60 days ago. Then rank Russell 2000 stocks every month, long the top 5%, short the bottom 5%.
In [1]:
from quantopian.pipeline import Pipeline
from quantopian.pipeline import CustomFactor
from quantopian.research import run_pipeline
from quantopian.pipeline.data import morningstar
from quantopian.pipeline.data.builtin import USEquityPricing

Custom factors are written exactly the same as in the backtester.

Documentation can be found here: https://www.quantopian.com/help#quantopian_pipeline_Pipeline

In [2]:
class Liquidity(CustomFactor):   
    
    # Pre-declare inputs and window_length
    inputs = [USEquityPricing.volume, morningstar.valuation.shares_outstanding] 
    window_length = 1
    
    # Compute factor1 value
    def compute(self, today, assets, out, volume, shares):       
        out[:] = volume[-1]/shares[-1]
In [3]:
class Momentum(CustomFactor):   
    
    # Pre-declare inputs and window_length
    inputs = [USEquityPricing.close] 
    window_length = 60
    
    # Compute factor2 value
    def compute(self, today, assets, out, close):       
        out[:] = close[-1]/close[0]
In [4]:
class MarketCap(CustomFactor):   
    
    # Pre-declare inputs and window_length
    inputs = [USEquityPricing.close, morningstar.valuation.shares_outstanding] 
    window_length = 1
    
    # Compute market cap value
    def compute(self, today, assets, out, close, shares):       
        out[:] = close[-1] * shares[-1]

Factors and filters are constructed the same way as in the backtester.

In [5]:
liquidity = Liquidity()
momentum = Momentum()
mkt_cap = MarketCap()

mkt_cap_rank = mkt_cap.rank(ascending=False)
russell_2000 = (1000 > mkt_cap_rank) & (mkt_cap_rank <= 3000)

liquidity_rank = liquidity.rank(mask=russell_2000, ascending=False)
momentum_rank = momentum.rank(mask=russell_2000,  ascending=False)
combo_raw = (liquidity_rank+momentum_rank)/2
combo_rank = combo_raw.rank(mask=russell_2000,  ascending=True)

Pipelines are also constructed in exactly the same way as the backtester. This can be done one column at a time.....

In [6]:
pipe = Pipeline()
       
pipe.add(liquidity, 'liquidity')
pipe.add(momentum, 'momentum')
pipe.add(liquidity_rank, 'liq_rank')
pipe.add(momentum_rank, 'mom_rank')
pipe.add(combo_raw, 'combo_raw')
pipe.add(combo_rank, 'combo_rank')
pipe.set_screen(russell_2000 & (momentum.eq(momentum)))

...or all at once.

In [7]:
pipe = Pipeline(
    columns={'mkt_cap':mkt_cap, 
             'momentum':momentum, 
             'liquidity':liquidity, 
             'liquidity_rank':liquidity_rank, 
             'momentum_rank':momentum_rank,
             'combo_raw':combo_raw,
             'combo_rank':combo_rank
            },
    screen=(russell_2000 & (momentum.eq(momentum))), 
)

The show_graph() method of pipeline objects produces a graph to show how it is being calculated.

In [8]:
pipe.show_graph(format='png')
Out[8]:

run_pipeline will produce the output of your pipeline.

In research, you must specify a start and end date. The results are a heirarchical dataframe, where the pipeline output for each day is included. The output shows the results that the pipeline would generate in before_trading_start on that day, using the data of the day before. This is different from the backtest, where only the results of the given day are included on any day.

In [11]:
run_pipeline(pipe, start_date='2015-11-01', end_date='2015-11-25')
Out[11]:
combo_rank combo_raw liquidity liquidity_rank mkt_cap momentum momentum_rank
2015-11-02 00:00:00+00:00 Equity(2 [AA]) 205 334.5 0.026191 25 1.092809e+10 0.949045 644
Equity(24 [AAPL]) 197 329.5 0.007660 345 6.884719e+11 1.034317 314
Equity(62 [ABT]) 870 736.5 0.004196 654 6.669633e+10 0.898867 819
Equity(64 [ABX]) 33 119.5 0.014081 111 8.956310e+09 1.094126 128
Equity(67 [ADSK]) 83 210.5 0.012625 142 1.256640e+10 1.040920 279
Equity(76 [TAP]) 114 238.5 0.006361 451 1.635491e+10 1.206849 26
Equity(100 [IEP]) 628 555.5 0.000593 890 9.903008e+09 1.056484 221
Equity(114 [ADBE]) 367 435.0 0.003523 701 4.437387e+10 1.072551 169
Equity(122 [ADI]) 360 432.5 0.005754 488 1.884699e+10 1.016251 377
Equity(128 [ADM]) 638 559.5 0.004385 632 2.833556e+10 0.989395 487
Equity(154 [AEM]) 9 53.5 0.014819 99 6.116318e+09 1.283882 8
Equity(157 [AEG]) 990 939.5 0.000310 920 1.643037e+10 0.802256 959
Equity(161 [AEP]) 575 534.0 0.004605 616 2.775031e+10 0.997359 452
Equity(166 [AES]) 861 728.0 0.004910 586 7.698755e+09 0.874258 870
Equity(168 [AET]) 224 348.0 0.010606 206 4.008292e+10 0.988444 490
Equity(185 [AFL]) 402 455.0 0.005974 470 2.766013e+10 1.001188 440
Equity(216 [HES]) 150 284.5 0.011884 165 1.615087e+10 1.009622 404
Equity(239 [AIG]) 424 463.0 0.005823 481 8.409725e+10 0.999575 445
Equity(266 [AJG]) 599 546.0 0.007489 361 7.286244e+09 0.926394 731
Equity(273 [ALU]) 369 435.5 0.002049 797 1.136634e+10 1.122563 74
Equity(300 [ALK]) 455 475.0 0.006702 427 9.884707e+09 0.980036 523
Equity(301 [ALKS]) 146 279.5 0.007133 389 1.069249e+10 1.071014 170
Equity(328 [ALTR]) 187 322.0 0.006722 424 1.582223e+10 1.056494 220
Equity(337 [AMAT]) 310 404.0 0.007713 342 2.065390e+10 0.993466 466
Equity(353 [AME]) 270 384.0 0.008060 322 1.323777e+10 0.999143 446
Equity(357 [TWX]) 654 569.5 0.005852 478 6.212554e+10 0.944601 661
Equity(368 [AMGN]) 774 647.5 0.005213 549 1.202680e+11 0.921999 746
Equity(410 [AN]) 155 292.0 0.008171 314 7.205256e+09 1.043600 270
Equity(438 [AON]) 605 549.5 0.007516 359 2.628574e+10 0.923678 740
Equity(448 [APA]) 131 264.5 0.010989 193 1.778002e+10 1.028227 336
... ... ... ... ... ... ... ... ...
2015-11-25 00:00:00+00:00 Equity(46979 [JD]) 155 284.5 0.005096 486 4.149618e+10 1.218675 83
Equity(47063 [ANET]) 411 464.5 0.006934 312 4.969008e+09 1.038659 617
Equity(47163 [MRKT]) 861 730.5 0.001933 797 5.447681e+09 1.025124 664
Equity(47207 [SERV]) 165 291.5 0.008831 204 5.069065e+09 1.101963 379
Equity(47272 [LMCK]) 604 554.5 0.003860 628 1.320057e+10 1.076731 481
Equity(47274 [EXCU]) 987 907.5 0.000160 939 3.583634e+10 0.937162 876
Equity(47303 [D_CUC]) 941 834.5 0.000122 953 2.872987e+10 1.008973 716
Equity(47415 [SYF]) 298 390.5 0.037030 10 2.613852e+10 0.988959 771
Equity(47430 [MBLY]) 828 698.0 0.005563 426 9.429651e+09 0.809392 970
Equity(47740 [BABA]) 129 259.5 0.005354 452 2.016114e+11 1.246394 67
Equity(47752 [CDK]) 877 747.0 0.002147 784 7.741666e+09 1.010462 710
Equity(47764 [AVAL]) 953 855.0 0.000136 950 5.604172e+09 0.991655 760
Equity(47777 [CFG]) 173 300.0 0.008135 240 1.402165e+10 1.107145 360
Equity(47780 [ICL]) 996 951.0 0.000081 970 6.453796e+09 0.875220 932
Equity(47888 [FCAU]) 882 750.5 0.001480 822 1.791890e+10 1.020528 679
Equity(47912 [ZAYO]) 718 610.5 0.007176 295 5.837068e+09 0.887329 926
Equity(47921 [KEYS]) 776 648.5 0.005052 489 5.180718e+09 0.978397 808
Equity(48009 [LBRD_A]) 949 849.0 0.000684 883 5.436367e+09 0.976283 815
Equity(48010 [LBRD_K]) 913 805.0 0.001401 827 5.407477e+09 0.986820 783
Equity(48065 [AXTA]) 786 656.5 0.003482 670 6.714246e+09 1.031062 643
Equity(48124 [WF]) 760 635.0 0.000012 988 5.731782e+09 1.129039 282
Equity(48129 [UBS]) 969 889.0 0.000297 922 7.019833e+10 0.948174 856
Equity(48215 [QSR]) 930 821.0 0.001658 809 1.682914e+10 0.967483 833
Equity(48317 [JUNO]) 28 100.0 0.009024 196 4.969833e+09 1.603267 4
Equity(48384 [QRVO]) 222 343.0 0.014650 78 8.332430e+09 1.043218 608
Equity(48863 [GDDY]) 349 424.5 0.002082 788 4.849445e+09 1.251303 61
Equity(49025 [EQGP]) 993 927.0 0.000841 867 6.111148e+09 0.739452 987
Equity(49040 [ANTX]) 961 863.0 0.001075 844 1.169250e+10 0.929376 882
Equity(49048 [BKFS]) 843 712.0 0.001000 853 5.123894e+09 1.051448 571
Equity(49051 [APLE]) 543 525.5 0.002171 781 7.272742e+09 1.133503 270

17929 rows × 7 columns

In [ ]: