Notebook
In [1]:
from quantopian.research import run_pipeline
from quantopian.pipeline import Pipeline
from quantopian.pipeline.factors import Latest
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.factors import CustomFactor, AverageDollarVolume, Returns, RSI, VWAP, SimpleMovingAverage
from quantopian.pipeline.filters import Q500US, Q1500US
from quantopian.pipeline.data import morningstar

import pandas as pd
import numpy as np
from scipy import stats
import alphalens
In [2]:
def demean_by_group(signal, grouping):
    """Calculates and subtracts the group mean from the signal.  
    Both inputs are 1-day np arrays.  Returns 1-day np array of demeaned values."""
    values_to_return = np.empty(signal.shape[0])
    options = set(grouping)
    for option in options:
        logical = grouping == option 
        mean_by_group = signal[logical].sum()/logical.size
        values_to_return[logical] = signal[logical] - mean_by_group
                
    return values_to_return
In [93]:
def make_factors():

    class Alpha5(CustomFactor):
        vwap_in = VWAP(window_length=2)
        vwap_in.window_safe = True
        inputs = [USEquityPricing.close, USEquityPricing.open, vwap_in]
        window_length = 10

        def compute(self, today, assets, out, close, open, vwap):
            v000 = open[-1]
            v00100 = np.empty((10, out.shape[0]))
            for i0 in range(1, 11):
                v00100[-i0] = vwap[-i0]
            v0010 = v00100.sum(axis=0)
            v0011 = np.full(out.shape[0], 10.0)
            v001 = v0010 / v0011
            v00 = v000 - v001
            v0 = stats.rankdata(v00)/np.float(out.shape[0])
            v10 = np.full(out.shape[0], -1.0)
            v11000 = close[-1]
            v11001 = vwap[-1]
            v1100 = v11000 - v11001
            v110 = stats.rankdata(v1100)/np.float(out.shape[0])
            v11 = np.abs(v110)
            v1 = v10 * v11
            out[:] = v0 * v1
            
    class Alpha8(CustomFactor):
        inputs = [Returns(window_length=2), USEquityPricing.open]
        window_length = 16

        def compute(self, today, assets, out, returns, open):
            v0 = np.full(out.shape[0], -1.0)
            v10000 = np.empty((5, out.shape[0]))
            for i0 in range(1, 6):
                v10000[-i0] = open[-i0]
            v1000 = v10000.sum(axis=0)
            v10010 = np.empty((5, out.shape[0]))
            for i0 in range(1, 6):
                v10010[-i0] = returns[-i0]
            v1001 = v10010.sum(axis=0)
            v100 = v1000 * v1001
            v101000 = np.empty((5, out.shape[0]))
            for i0 in range(11, 16):
                v101000[10-i0] = open[-i0]
            v10100 = v101000.sum(axis=0)
            v101010 = np.empty((5, out.shape[0]))
            for i0 in range(11, 16):
                v101010[10-i0] = returns[-i0]
            v10101 = v101010.sum(axis=0)
            v1010 = v10100 * v10101
            v101 = v1010 # delay
            v10 = v100 - v101
            v1 = stats.rankdata(v10)/np.float(out.shape[0])
            out[:] = v0 * v1
            
    class Alpha9(CustomFactor):
        inputs = [USEquityPricing.close]
        window_length = 7

        def compute(self, today, assets, out, close):
            v00 = np.full(out.shape[0], 0.0)
            v010 = np.empty((5, out.shape[0]))
            for i0 in range(1, 6):
                v0100 = np.empty((2, out.shape[0]))
                for i1 in range(1, 3):
                    v0100[-i1] = close[-i0 -i1]
                v010[-i0] = v0100[-1] - v0100[-2]
            v01 = np.min(v010, axis=0)
            v0 = v00 < v01
            v10 = np.empty((2, out.shape[0]))
            for i0 in range(1, 3):
                v10[-i0] = close[-i0]
            v1 = v10[-1] - v10[-2]
            v2000 = np.empty((5, out.shape[0]))
            for i0 in range(1, 6):
                v20000 = np.empty((2, out.shape[0]))
                for i1 in range(1, 3):
                    v20000[-i1] = close[-i0 -i1]
                v2000[-i0] = v20000[-1] - v20000[-2]
            v200 = np.max(v2000, axis=0)
            v201 = np.full(out.shape[0], 0.0)
            v20 = v200 < v201
            v210 = np.empty((2, out.shape[0]))
            for i0 in range(1, 3):
                v210[-i0] = close[-i0]
            v21 = v210[-1] - v210[-2]
            v220 = np.full(out.shape[0], -1.0)
            v2210 = np.empty((2, out.shape[0]))
            for i0 in range(1, 3):
                v2210[-i0] = close[-i0]
            v221 = v2210[-1] - v2210[-2]
            v22 = v220 * v221
            v2lgcl = np.empty(out.shape[0])
            v2lgcl[v20] = v21[v20]
            v2lgcl[~v20] = v22[~v20]
            v2 = v2lgcl
            vlgcl = np.empty(out.shape[0])
            vlgcl[v0] = v1[v0]
            vlgcl[~v0] = v2[~v0]
            out[:] = vlgcl

    class Alpha10(CustomFactor):
        inputs = [USEquityPricing.close]
        window_length = 6

        def compute(self, today, assets, out, close):
            v000 = np.full(out.shape[0], 0.0)
            v0010 = np.empty((4, out.shape[0]))
            for i0 in range(1, 5):
                v00100 = np.empty((2, out.shape[0]))
                for i1 in range(1, 3):
                    v00100[-i1] = close[-i0 -i1]
                v0010[-i0] = v00100[-1] - v00100[-2]
            v001 = np.min(v0010, axis=0)
            v00 = v000 < v001
            v010 = np.empty((2, out.shape[0]))
            for i0 in range(1, 3):
                v010[-i0] = close[-i0]
            v01 = v010[-1] - v010[-2]
            v02000 = np.empty((4, out.shape[0]))
            for i0 in range(1, 5):
                v020000 = np.empty((2, out.shape[0]))
                for i1 in range(1, 3):
                    v020000[-i1] = close[-i0 -i1]
                v02000[-i0] = v020000[-1] - v020000[-2]
            v0200 = np.max(v02000, axis=0)
            v0201 = np.full(out.shape[0], 0.0)
            v020 = v0200 < v0201
            v0210 = np.empty((2, out.shape[0]))
            for i0 in range(1, 3):
                v0210[-i0] = close[-i0]
            v021 = v0210[-1] - v0210[-2]
            v0220 = np.full(out.shape[0], -1.0)
            v02210 = np.empty((2, out.shape[0]))
            for i0 in range(1, 3):
                v02210[-i0] = close[-i0]
            v0221 = v02210[-1] - v02210[-2]
            v022 = v0220 * v0221
            v02lgcl = np.empty(out.shape[0])
            v02lgcl[v020] = v021[v020]
            v02lgcl[~v020] = v022[~v020]
            v02 = v02lgcl
            v0lgcl = np.empty(out.shape[0])
            v0lgcl[v00] = v01[v00]
            v0lgcl[~v00] = v02[~v00]
            v0 = v0lgcl
            out[:] = stats.rankdata(v0)/np.float(out.shape[0])
            
            
    class Alpha11(CustomFactor):
        vwap_in = VWAP(window_length=2)
        vwap_in.window_safe = True
        inputs = [USEquityPricing.volume, USEquityPricing.close, vwap_in]
        window_length = 4

        def compute(self, today, assets, out, volume, close, vwap):
            v0000 = np.empty((3, out.shape[0]))
            for i0 in range(1, 4):
                v00000 = vwap[-i0]
                v00001 = close[-i0]
                v0000[-i0] = v00000 - v00001
            v000 = np.max(v0000, axis=0)
            v00 = stats.rankdata(v000)/np.float(out.shape[0])
            v0100 = np.empty((3, out.shape[0]))
            for i0 in range(1, 4):
                v01000 = vwap[-i0]
                v01001 = close[-i0]
                v0100[-i0] = v01000 - v01001
            v010 = np.min(v0100, axis=0)
            v01 = stats.rankdata(v010)/np.float(out.shape[0])
            v0 = v00 + v01
            v100 = np.empty((4, out.shape[0]))
            for i0 in range(1, 5):
                v100[-i0] = volume[-i0]
            v10 = v100[-1] - v100[-4]
            v1 = stats.rankdata(v10)/np.float(out.shape[0])
            out[:] = v0 * v1
            
            
    class Alpha12(CustomFactor):
        inputs = [USEquityPricing.volume, USEquityPricing.close]
        window_length = 2

        def compute(self, today, assets, out, volume, close):
            v000 = np.empty((2, out.shape[0]))
            for i0 in range(1, 3):
                v000[-i0] = volume[-i0]
            v00 = v000[-1] - v000[-2]
            v0 = np.sign(v00)
            v10 = np.full(out.shape[0], -1.0)
            v110 = np.empty((2, out.shape[0]))
            for i0 in range(1, 3):
                v110[-i0] = close[-i0]
            v11 = v110[-1] - v110[-2]
            v1 = v10 * v11
            out[:] = v0 * v1
            
    class Alpha17(CustomFactor):
        adv20_in = SimpleMovingAverage(inputs=[USEquityPricing.volume], window_length=20)
        adv20_in.window_safe = True
        inputs = [USEquityPricing.volume, USEquityPricing.close, adv20_in]
        window_length = 10

        def compute(self, today, assets, out, volume, close, adv20):
            v000 = np.full(out.shape[0], -1.0)
            v00100 = np.empty((10, out.shape[0]))
            for i0 in range(1, 11):
                v00100[-i0] = close[-i0]
            v0010 = pd.DataFrame(v00100).rank().tail(1).as_matrix()[-1]/10.0
            v001 = stats.rankdata(v0010)/np.float(out.shape[0])
            v00 = v000 * v001
            v0100 = np.empty((2, out.shape[0]))
            for i0 in range(1, 3):
                v01000 = np.empty((2, out.shape[0]))
                for i1 in range(1, 3):
                    v01000[-i1] = close[-i0 -i1]
                v0100[-i0] = v01000[-1] - v01000[-2]
            v010 = v0100[-1] - v0100[-2]
            v01 = stats.rankdata(v010)/np.float(out.shape[0])
            v0 = v00 * v01
            v100 = np.empty((5, out.shape[0]))
            for i0 in range(1, 6):
                v1000 = volume[-i0]
                v1001 = adv20[-i0]
                v100[-i0] = v1000 / v1001
            v10 = pd.DataFrame(v100).rank().tail(1).as_matrix()[-1]/5.0
            v1 = stats.rankdata(v10)/np.float(out.shape[0])
            out[:] = v0 * v1

    #  (-1 * rank(((stddev(abs((close - open)), 5) + (close - open)) + correlation(close, open, 10))))
    class Alpha18(CustomFactor):
        inputs = [USEquityPricing.close, USEquityPricing.open]
        window_length = 10

        def compute(self, today, assets, out, close, open):
            v0 = np.full(out.shape[0], -1.0)
            v10000 = np.empty((5, out.shape[0]))
            for i0 in range(1, 6):
                v1000000 = close[-i0]
                v1000001 = open[-i0]
                v100000 = v1000000 - v1000001
                v10000[-i0] = np.abs(v100000)
            v1000 = np.std(v10000, axis=0)
            v10010 = close[-1]
            v10011 = open[-1]
            v1001 = v10010 - v10011
            v100 = v1000 + v1001
            v1010 = np.empty((10, out.shape[0]))
            for i0 in range(1, 11):
                v1010[-i0] = close[-i0]
            v1011 = np.empty((10, out.shape[0]))
            for i0 in range(1, 11):
                v1011[-i0] = open[-i0]
            v101 = pd.DataFrame(v1010).rolling(window=10).corr(pd.DataFrame(v1011)).tail(1).as_matrix()[-1]
            v10 = v100 + v101
            v1 = stats.rankdata(v10)/np.float(out.shape[0])
            out[:] = v0 * v1

    #  ((-1 * sign(((close - delay(close, 7)) + delta(close, 7)))) * (1 + rank((1 + sum(returns, 250)))))
    class Alpha19(CustomFactor):
        inputs = [USEquityPricing.close, Returns(window_length=2)]
        window_length = 250

        def compute(self, today, assets, out, close, returns):
            v00 = np.full(out.shape[0], -1.0)
            v01000 = close[-1]
            v010010 = close[-8]
            v01001 = v010010 # delay
            v0100 = v01000 - v01001
            v01010 = np.empty((8, out.shape[0]))
            for i0 in range(1, 9):
                v01010[-i0] = close[-i0]
            v0101 = v01010[-1] - v01010[-8]
            v010 = v0100 + v0101
            v01 = np.sign(v010)
            v0 = v00 * v01
            v10 = np.full(out.shape[0], 1.0)
            v1100 = np.full(out.shape[0], 1.0)
            v11010 = np.empty((250, out.shape[0]))
            for i0 in range(1, 251):
                v11010[-i0] = returns[-i0]
            v1101 = v11010.sum(axis=0)
            v110 = v1100 + v1101
            v11 = stats.rankdata(v110)/np.float(out.shape[0])
            v1 = v10 + v11
            out[:] = v0 * v1

    #  (((-1 * rank((open - delay(high, 1)))) * rank((open - delay(close, 1)))) * rank((open - delay(low, 1))))
    class Alpha20(CustomFactor):
        inputs = [USEquityPricing.high, USEquityPricing.close, USEquityPricing.open, USEquityPricing.low]
        window_length = 2

        def compute(self, today, assets, out, high, close, open, low):
            v000 = np.full(out.shape[0], -1.0)
            v00100 = open[-1]
            v001010 = high[-2]
            v00101 = v001010 # delay
            v0010 = v00100 - v00101
            v001 = stats.rankdata(v0010)/np.float(out.shape[0])
            v00 = v000 * v001
            v0100 = open[-1]
            v01010 = close[-2]
            v0101 = v01010 # delay
            v010 = v0100 - v0101
            v01 = stats.rankdata(v010)/np.float(out.shape[0])
            v0 = v00 * v01
            v100 = open[-1]
            v1010 = low[-2]
            v101 = v1010 # delay
            v10 = v100 - v101
            v1 = stats.rankdata(v10)/np.float(out.shape[0])
            out[:] = v0 * v1
            
    class Alpha23(CustomFactor):
        inputs = [USEquityPricing.high]
        window_length = 20

        def compute(self, today, assets, out, high):
            v0000 = np.empty((20, out.shape[0]))
            for i0 in range(1, 21):
                v0000[-i0] = high[-i0]
            v000 = v0000.sum(axis=0)
            v001 = np.full(out.shape[0], 20.0)
            v00 = v000 / v001
            v01 = high[-1]
            v0 = v00 < v01
            v10 = np.full(out.shape[0], -1.0)
            v110 = np.empty((3, out.shape[0]))
            for i0 in range(1, 4):
                v110[-i0] = high[-i0]
            v11 = v110[-1] - v110[-3]
            v1 = v10 * v11
            v2 = np.full(out.shape[0], 0.0)
            vlgcl = np.empty(out.shape[0])
            vlgcl[v0] = v1[v0]
            vlgcl[~v0] = v2[~v0]
            out[:] = vlgcl

    #  ((((delta((sum(close, 100) / 100), 100) / delay(close, 100)) < 0.05) || ((delta((sum(close, 100) / 100), 100) / delay(close, 100)) == 0.05)) ? (-1 * (close - ts_min(close, 100))) : (-1 * delta(close, 3)))
    class Alpha24(CustomFactor):
        inputs = [USEquityPricing.close]
        window_length = 201

        def compute(self, today, assets, out, close):
            v00000 = np.empty((101, out.shape[0]))
            for i0 in range(1, 102):
                v0000000 = np.empty((100, out.shape[0]))
                for i1 in range(1, 101):
                    v0000000[-i1] = close[-i0 -i1]
                v000000 = v0000000.sum(axis=0)
                v000001 = np.full(out.shape[0], 100.0)
                v00000[-i0] = v000000 / v000001
            v0000 = v00000[-1] - v00000[-101]
            v00010 = close[-101]
            v0001 = v00010 # delay
            v000 = v0000 / v0001
            v001 = np.full(out.shape[0], 0.05)
            v00 = v000 < v001
            v01000 = np.empty((101, out.shape[0]))
            for i0 in range(1, 102):
                v0100000 = np.empty((100, out.shape[0]))
                for i1 in range(1, 101):
                    v0100000[-i1] = close[-i0 -i1]
                v010000 = v0100000.sum(axis=0)
                v010001 = np.full(out.shape[0], 100.0)
                v01000[-i0] = v010000 / v010001
            v0100 = v01000[-1] - v01000[-101]
            v01010 = close[-101]
            v0101 = v01010 # delay
            v010 = v0100 / v0101
            v011 = np.full(out.shape[0], 0.05)
            v01 = v010 == v011
            v0 = v00 | v01
            v10 = np.full(out.shape[0], -1.0)
            v110 = close[-1]
            v1110 = np.empty((100, out.shape[0]))
            for i0 in range(1, 101):
                v1110[-i0] = close[-i0]
            v111 = np.min(v1110, axis=0)
            v11 = v110 - v111
            v1 = v10 * v11
            v20 = np.full(out.shape[0], -1.0)
            v210 = np.empty((4, out.shape[0]))
            for i0 in range(1, 5):
                v210[-i0] = close[-i0]
            v21 = v210[-1] - v210[-4]
            v2 = v20 * v21
            vlgcl = np.empty(out.shape[0])
            vlgcl[v0] = v1[v0]
            vlgcl[~v0] = v2[~v0]
            out[:] = vlgcl

    #  rank(((((-1 * returns) * adv20) * vwap) * (high - close)))
    class Alpha25(CustomFactor):
        vwap_in = VWAP(window_length=2)
        vwap_in.window_safe = True
        adv20_in = SimpleMovingAverage(inputs=[USEquityPricing.volume], window_length=20)
        adv20_in.window_safe = True
        inputs = [USEquityPricing.high, USEquityPricing.close, Returns(window_length=2), adv20_in, vwap_in]
        window_length = 1

        def compute(self, today, assets, out, high, close, returns, adv20, vwap):
            v00000 = np.full(out.shape[0], -1.0)
            v00001 = returns[-1]
            v0000 = v00000 * v00001
            v0001 = adv20[-1]
            v000 = v0000 * v0001
            v001 = vwap[-1]
            v00 = v000 * v001
            v010 = high[-1]
            v011 = close[-1]
            v01 = v010 - v011
            v0 = v00 * v01
            out[:] = stats.rankdata(v0)/np.float(out.shape[0])
            
            
    class Alpha33(CustomFactor):
        inputs = [USEquityPricing.close, USEquityPricing.open]
        window_length = 1

        def compute(self, today, assets, out, close, open):
            v00 = np.full(out.shape[0], -1.0)
            v0100 = np.full(out.shape[0], 1.0)
            v01010 = open[-1]
            v01011 = close[-1]
            v0101 = v01010 / v01011
            v010 = v0100 - v0101
            v011 = np.full(out.shape[0], 1.0)
            v01 = np.power(v010, v011)
            v0 = v00 * v01
            out[:] = stats.rankdata(v0)/np.float(out.shape[0])

    #  rank(((1 - rank((stddev(returns, 2) / stddev(returns, 5)))) + (1 - rank(delta(close, 1)))))
    class Alpha34(CustomFactor):
        inputs = [USEquityPricing.close, Returns(window_length=2)]
        window_length = 5

        def compute(self, today, assets, out, close, returns):
            v000 = np.full(out.shape[0], 1.0)
            v001000 = np.empty((2, out.shape[0]))
            for i0 in range(1, 3):
                v001000[-i0] = returns[-i0]
            v00100 = np.std(v001000, axis=0)
            v001010 = np.empty((5, out.shape[0]))
            for i0 in range(1, 6):
                v001010[-i0] = returns[-i0]
            v00101 = np.std(v001010, axis=0)
            v0010 = v00100 / v00101
            v001 = stats.rankdata(v0010)/np.float(out.shape[0])
            v00 = v000 - v001
            v010 = np.full(out.shape[0], 1.0)
            v01100 = np.empty((2, out.shape[0]))
            for i0 in range(1, 3):
                v01100[-i0] = close[-i0]
            v0110 = v01100[-1] - v01100[-2]
            v011 = stats.rankdata(v0110)/np.float(out.shape[0])
            v01 = v010 - v011
            v0 = v00 + v01
            out[:] = stats.rankdata(v0)/np.float(out.shape[0])
            
    class Alpha39(CustomFactor):
        adv20_in = SimpleMovingAverage(inputs=[USEquityPricing.volume], window_length=20)
        adv20_in.window_safe = True
        inputs = [USEquityPricing.volume, USEquityPricing.close, Returns(window_length=2), adv20_in]
        window_length = 250

        def compute(self, today, assets, out, volume, close, returns, adv20):
            v00 = np.full(out.shape[0], -1.0)
            v01000 = np.empty((8, out.shape[0]))
            for i0 in range(1, 9):
                v01000[-i0] = close[-i0]
            v0100 = v01000[-1] - v01000[-8]
            v01010 = np.full(out.shape[0], 1.0)
            v0101100 = np.empty((9, out.shape[0]))
            for i0 in range(1, 10):
                v01011000 = volume[-i0]
                v01011001 = adv20[-i0]
                v0101100[-i0] = v01011000 / v01011001
            v010110 = (v0101100 * (np.arange(1.0, 10, 1.0)/45)[:, np.newaxis]).sum(axis=0) # decay_linear
            v01011 = stats.rankdata(v010110)/np.float(out.shape[0])
            v0101 = v01010 - v01011
            v010 = v0100 * v0101
            v01 = stats.rankdata(v010)/np.float(out.shape[0])
            v0 = v00 * v01
            v10 = np.full(out.shape[0], 1.0)
            v1100 = np.empty((250, out.shape[0]))
            for i0 in range(1, 251):
                v1100[-i0] = returns[-i0]
            v110 = v1100.sum(axis=0)
            v11 = stats.rankdata(v110)/np.float(out.shape[0])
            v1 = v10 + v11
            out[:] = v0 * v1
            
    class Alpha42(CustomFactor):
        vwap_in = VWAP(window_length=2)
        vwap_in.window_safe = True
        inputs = [USEquityPricing.close, vwap_in]
        window_length = 1

        def compute(self, today, assets, out, close, vwap):
            v000 = vwap[-1]
            v001 = close[-1]
            v00 = v000 - v001
            v0 = stats.rankdata(v00)/np.float(out.shape[0])
            v100 = vwap[-1]
            v101 = close[-1]
            v10 = v100 + v101
            v1 = stats.rankdata(v10)/np.float(out.shape[0])
            out[:] = v0 / v1

    #  (ts_rank((volume / adv20), 20) * ts_rank((-1 * delta(close, 7)), 8))
    class Alpha43(CustomFactor):
        adv20_in = SimpleMovingAverage(inputs=[USEquityPricing.volume], window_length=20)
        adv20_in.window_safe = True
        inputs = [USEquityPricing.volume, USEquityPricing.close, adv20_in]
        window_length = 20

        def compute(self, today, assets, out, volume, close, adv20):
            v00 = np.empty((20, out.shape[0]))
            for i0 in range(1, 21):
                v000 = volume[-i0]
                v001 = adv20[-i0]
                v00[-i0] = v000 / v001
            v0 = pd.DataFrame(v00).rank().tail(1).as_matrix()[-1]/20.0
            v10 = np.empty((8, out.shape[0]))
            for i0 in range(1, 9):
                v100 = np.full(out.shape[0], -1.0)
                v1010 = np.empty((8, out.shape[0]))
                for i1 in range(1, 9):
                    v1010[-i1] = close[-i0 -i1]
                v101 = v1010[-1] - v1010[-8]
                v10[-i0] = v100 * v101
            v1 = pd.DataFrame(v10).rank().tail(1).as_matrix()[-1]/8.0
            out[:] = v0 * v1
            
    class Alpha47(CustomFactor):
        vwap_in = VWAP(window_length=2)
        vwap_in.window_safe = True
        adv20_in = SimpleMovingAverage(inputs=[USEquityPricing.volume], window_length=20)
        adv20_in.window_safe = True
        inputs = [USEquityPricing.volume, USEquityPricing.close, USEquityPricing.high, adv20_in, vwap_in]
        window_length = 6

        def compute(self, today, assets, out, volume, close, high, adv20, vwap):
            v000000 = np.full(out.shape[0], 1.0)
            v000001 = close[-1]
            v00000 = v000000 / v000001
            v0000 = stats.rankdata(v00000)/np.float(out.shape[0])
            v0001 = volume[-1]
            v000 = v0000 * v0001
            v001 = adv20[-1]
            v00 = v000 / v001
            v0100 = high[-1]
            v010100 = high[-1]
            v010101 = close[-1]
            v01010 = v010100 - v010101
            v0101 = stats.rankdata(v01010)/np.float(out.shape[0])
            v010 = v0100 * v0101
            v01100 = np.empty((5, out.shape[0]))
            for i0 in range(1, 6):
                v01100[-i0] = high[-i0]
            v0110 = v01100.sum(axis=0)
            v0111 = np.full(out.shape[0], 5.0)
            v011 = v0110 / v0111
            v01 = v010 / v011
            v0 = v00 * v01
            v100 = vwap[-1]
            v1010 = vwap[-6]
            v101 = v1010 # delay
            v10 = v100 - v101
            v1 = stats.rankdata(v10)/np.float(out.shape[0])
            out[:] = v0 - v1
            
    class Alpha57(CustomFactor):
        vwap_in = VWAP(window_length=2)
        vwap_in.window_safe = True
        inputs = [USEquityPricing.close, vwap_in]
        window_length = 32

        def compute(self, today, assets, out, close, vwap):
            v0 = np.full(out.shape[0], 0.0)
            v10 = np.full(out.shape[0], 1.0)
            v1100 = close[-1]
            v1101 = vwap[-1]
            v110 = v1100 - v1101
            v1110 = np.empty((2, out.shape[0]))
            for i0 in range(1, 3):
                v111000 = np.empty((30, out.shape[0]))
                for i1 in range(1, 31):
                    v111000[-i1] = close[-i0 -i1]
                v11100 = np.argmax(v111000, axis=0)
                v1110[-i0] = stats.rankdata(v11100)/np.float(out.shape[0])
            v111 = (v1110 * (np.arange(1.0, 3, 1.0)/3)[:, np.newaxis]).sum(axis=0) # decay_linear
            v11 = v110 / v111
            v1 = v10 * v11
            out[:] = v0 - v1
            
    class Alpha66(CustomFactor):
        vwap_in = VWAP(window_length=2)
        vwap_in.window_safe = True
        inputs = [USEquityPricing.high, USEquityPricing.open, USEquityPricing.low, vwap_in]
        window_length = 18

        def compute(self, today, assets, out, high, open, low, vwap):
            v0000 = np.empty((7, out.shape[0]))
            for i0 in range(1, 8):
                v00000 = np.empty((5, out.shape[0]))
                for i1 in range(1, 6):
                    v00000[-i1] = vwap[-i0 -i1]
                v0000[-i0] = v00000[-1] - v00000[-5]
            v000 = (v0000 * (np.arange(1.0, 8, 1.0)/28)[:, np.newaxis]).sum(axis=0) # decay_linear
            v00 = stats.rankdata(v000)/np.float(out.shape[0])
            v010 = np.empty((7, out.shape[0]))
            for i0 in range(1, 8):
                v0100 = np.empty((11, out.shape[0]))
                for i1 in range(1, 12):
                    v01000000 = low[-i0 -i1]
                    v01000001 = np.full(out.shape[0], 0.96633)
                    v0100000 = v01000000 * v01000001
                    v01000010 = low[-i0 -i1]
                    v010000110 = np.full(out.shape[0], 1.0)
                    v010000111 = np.full(out.shape[0], 0.96633)
                    v01000011 = v010000110 - v010000111
                    v0100001 = v01000010 * v01000011
                    v010000 = v0100000 + v0100001
                    v010001 = vwap[-i0 -i1]
                    v01000 = v010000 - v010001
                    v010010 = open[-i0 -i1]
                    v01001100 = high[-i0 -i1]
                    v01001101 = low[-i0 -i1]
                    v0100110 = v01001100 + v01001101
                    v0100111 = np.full(out.shape[0], 2.0)
                    v010011 = v0100110 / v0100111
                    v01001 = v010010 - v010011
                    v0100[-i1] = v01000 / v01001
                v010[-i0] = (v0100 * (np.arange(1.0, 12, 1.0)/66)[:, np.newaxis]).sum(axis=0) # decay_linear
            v01 = pd.DataFrame(v010).rank().tail(1).as_matrix()[-1]/7.0
            v0 = v00 + v01
            v1 = np.full(out.shape[0], -1.0)
            out[:] = v0 * v1
            
    class Alpha73(CustomFactor):
        vwap_in = VWAP(window_length=2)
        vwap_in.window_safe = True
        inputs = [USEquityPricing.open, USEquityPricing.low, vwap_in]
        window_length = 23

        def compute(self, today, assets, out, open, low, vwap):
            v0000 = np.empty((3, out.shape[0]))
            for i0 in range(1, 4):
                v00000 = np.empty((6, out.shape[0]))
                for i1 in range(1, 7):
                    v00000[-i1] = vwap[-i0 -i1]
                v0000[-i0] = v00000[-1] - v00000[-6]
            v000 = (v0000 * (np.arange(1.0, 4, 1.0)/6)[:, np.newaxis]).sum(axis=0) # decay_linear
            v00 = stats.rankdata(v000)/np.float(out.shape[0])
            v010 = np.empty((17, out.shape[0]))
            for i0 in range(1, 18):
                v0100 = np.empty((3, out.shape[0]))
                for i1 in range(1, 4):
                    v0100000 = np.empty((3, out.shape[0]))
                    for i2 in range(1, 4):
                        v010000000 = open[-i0 -i1 -i2]
                        v010000001 = np.full(out.shape[0], 0.147155)
                        v01000000 = v010000000 * v010000001
                        v010000010 = low[-i0 -i1 -i2]
                        v0100000110 = np.full(out.shape[0], 1.0)
                        v0100000111 = np.full(out.shape[0], 0.147155)
                        v010000011 = v0100000110 - v0100000111
                        v01000001 = v010000010 * v010000011
                        v0100000[-i2] = v01000000 + v01000001
                    v010000 = v0100000[-1] - v0100000[-3]
                    v01000100 = open[-i0 -i1]
                    v01000101 = np.full(out.shape[0], 0.147155)
                    v0100010 = v01000100 * v01000101
                    v01000110 = low[-i0 -i1]
                    v010001110 = np.full(out.shape[0], 1.0)
                    v010001111 = np.full(out.shape[0], 0.147155)
                    v01000111 = v010001110 - v010001111
                    v0100011 = v01000110 * v01000111
                    v010001 = v0100010 + v0100011
                    v01000 = v010000 / v010001
                    v01001 = np.full(out.shape[0], -1.0)
                    v0100[-i1] = v01000 * v01001
                v010[-i0] = (v0100 * (np.arange(1.0, 4, 1.0)/6)[:, np.newaxis]).sum(axis=0) # decay_linear
            v01 = pd.DataFrame(v010).rank().tail(1).as_matrix()[-1]/17.0
            v0 = np.maximum(v00, v01)
            v1 = np.full(out.shape[0], -1.0)
            out[:] = v0 * v1
        
    all_factors = {
        'Alpha1' : Alpha5,
        'Alpha2' : Alpha8,
        'Alpha3' : Alpha9,
        'Alpha4' : Alpha10,
        'Alpha5' : Alpha11,
        'Alpha6' : Alpha12,
        'Alpha7' : Alpha17,
        'Alpha8' : Alpha18,
        'Alpha9' : Alpha19,
        'Alpha10' : Alpha20,
        'Alpha11' : Alpha23,
        'Alpha12' : Alpha24,
        'Alpha13' : Alpha25,
        'Alpha14' : Alpha33,
        'Alpha15' : Alpha34,
        'Alpha16' : Alpha39,
        'Alpha17' : Alpha42,
        'Alpha18' : Alpha43,
        'Alpha19' : Alpha47,
        'Alpha20' : Alpha57,
        'Alpha21' : Alpha66,
        'Alpha22' : Alpha73

    }     
    return all_factors
In [94]:
universe = Q500US() #Q1500US() q500 is faster
factors = make_factors()
In [95]:
def make_history_pipeline(factors, universe):  
    factor_funs = {name: f(mask=universe) for name, f in factors.iteritems()}
    # create the sum of ranks
    #factor_funs["sum589"] = factor_funs['Alpha5'].rank() + factor_funs['Alpha8'].rank() + factor_funs['Alpha9'].rank()
    #factor_funs["sumtest"] = factor_funs['Alpha11'].rank() + factor_funs['Alpha12'].rank() + factor_funs['Alpha17'].rank() + factor_funs['Alpha19'].rank() + factor_funs['Alpha20'].rank()
    #factor_funs["sumtest"] = factor_funs['Alpha1'].rank() + factor_funs['Alpha2'].rank() + factor_funs['Alpha3'].rank() + factor_funs['Alpha4'].rank() + factor_funs['Alpha5'].rank()
    factor_funs["sumtest"] = factor_funs['Alpha1'].rank() + factor_funs['Alpha2'].rank() + factor_funs['Alpha3'].rank() + factor_funs['Alpha4'].rank() + factor_funs['Alpha5'].rank() + factor_funs['Alpha6'].rank() + factor_funs['Alpha7'].rank() + factor_funs['Alpha8'].rank() + factor_funs['Alpha9'].rank() + factor_funs['Alpha10'].rank() + factor_funs['Alpha11'].rank() + factor_funs['Alpha12'].rank() + factor_funs['Alpha13'].rank() + factor_funs['Alpha14'].rank() + factor_funs['Alpha15'].rank() + factor_funs['Alpha16'].rank() + factor_funs['Alpha17'].rank() + factor_funs['Alpha18'].rank() + factor_funs['Alpha19'].rank() + factor_funs['Alpha20'].rank() + factor_funs['Alpha21'].rank() + factor_funs['Alpha22'].rank()

    pipe = Pipeline(screen=universe, columns=factor_funs)
    return pipe

history_pipe = make_history_pipeline(factors, universe)
In [96]:
start = pd.Timestamp("2016-01-01")
end = pd.Timestamp("2016-12-31")
results = run_pipeline(history_pipe, start_date=start, end_date=end)
results.index.names = ['date', 'security']
results.head()
Out[96]:
Alpha1 Alpha10 Alpha11 Alpha12 Alpha13 Alpha14 Alpha15 Alpha16 Alpha17 Alpha18 ... Alpha21 Alpha22 Alpha3 Alpha4 Alpha5 Alpha6 Alpha7 Alpha8 Alpha9 sumtest
date security
2016-01-04 00:00:00+00:00 Equity(2 [ARNC]) -0.378404 -0.510713 0.290 -2.040000 0.332 0.338 0.390 -0.577920 5.363636 0.05625 ... -0.552857 -0.411765 0.10 0.247 0.025816 -0.10 -0.051433 -0.724 -1.120 4969.0
Equity(24 [AAPL]) -0.007680 -0.018580 0.000 -2.539534 0.996 0.970 0.937 -0.072576 1.143902 0.06250 ... -0.949143 -0.411765 2.09 0.964 0.968060 2.09 -0.001467 -0.016 1.512 8712.0
Equity(62 [ABT]) -0.290520 -0.136337 0.455 -6.065621 0.576 0.504 0.553 -0.691296 1.290503 0.01875 ... -1.261143 -0.508000 0.35 0.415 0.695528 -0.35 -0.036938 -0.512 -1.516 5168.0
Equity(67 [ADSK]) -0.142072 -0.240515 0.000 -17.790000 0.880 0.982 0.438 -1.047284 1.608527 0.10625 ... -1.090571 -0.666000 1.33 0.900 0.981400 1.33 -0.269819 -0.094 -1.582 6417.0
Equity(76 [TAP]) -0.247680 -0.115111 0.400 -0.470000 0.422 0.426 0.762 -1.541716 0.882038 0.07500 ... -0.970571 -0.564000 0.62 0.623 0.273904 -0.62 -0.049545 -0.622 -1.894 4918.0

5 rows × 23 columns

In [97]:
assets = results.index.levels[1].unique()
pricing = get_pricing(assets, start, end + pd.Timedelta(days=30), fields="open_price")
In [99]:
alphalens.tears.create_factor_tear_sheet(results["sumtest"], pricing, quantiles=3)
Returns Analysis
1 5 10
Ann. alpha 0.121 0.044 0.038
beta 0.122 0.128 0.145
Mean Period Wise Return Top Quantile (bps) 5.777 2.135 2.464
Mean Period Wise Return Bottom Quantile (bps) -3.492 -2.715 -2.575
Mean Period Wise Spread (bps) 9.277 4.844 5.029
Information Analysis
1 5 10
IC Mean 0.021 0.015 0.031
IC Std. 0.142 0.144 0.144
t-stat(IC) 2.380 1.644 3.457
p-value(IC) 0.018 0.101 0.001
IC Skew -0.145 0.571 0.319
IC Kurtosis -0.018 0.882 0.055
Ann. IR 2.375 1.641 3.451
Turnover Analysis
1
Quantile 1 Mean Turnover 0.453
Quantile 2 Mean Turnover 0.634
Quantile 3 Mean Turnover 0.486
1
Mean Factor Rank Autocorrelation 0.449
<matplotlib.figure.Figure at 0x7f08b8aec790>
In [ ]: