Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
CDF as a momentum signal

How do I convert this into a custom factor? Is the information coefficient significant?

1 response

hello,

import numpy as np  
import pandas as pd  
from quantopian.pipeline import Pipeline  
from quantopian.research import run_pipeline  
from quantopian.pipeline import CustomFactor  
from quantopian.pipeline.data import USEquityPricing  
from quantopian.pipeline.filters import QTradableStocksUS  
from quantopian.pipeline.classifiers.morningstar import Sector

from statsmodels.nonparametric.api import KDEMultivariateConditional as KMC  
import scipy as sp  
from sklearn.decomposition import PCA

period_start='2017-01-02'  
period_end='2019-12-31'

def cdf(returns, factors, count):  
    F = factors  
    cdf = np.zeros((count, returns.shape[1]))  
    for j in range(0, returns.shape[1]):  
        R = returns[:, j]  
        kde = KMC(endog=R,  
                  exog=F,  
                  dep_type='c',  
                  indep_type='c' * F.shape[1],  
                  bw='normal_reference')  
        cdf[:, j] = kde.cdf(R[-count:], F[-count:]) - 0.5  
    return cdf

class myFactor(CustomFactor):  
    inputs=[USEquityPricing.close]  
    window_length=90  
    def compute(self, today, assets, out, close):  
        r = np.nan_to_num(np.diff(np.log(close), axis=0)) #plutot dropna avec pandas ?  
        factors = PCA(0.8).fit_transform(r)  
        cdfs = cdf(r, factors, 40).cumsum(axis=0)  
        cdfs = cdfs - np.mean(cdfs, axis=0)  
        out[:] = sp.stats.zscore(cdfs[-1])  
class returns(CustomFactor):  
    inputs=[USEquityPricing.close]  
    window_length=90  
    def compute(self, today, assets, out, close):  
        r = np.nan_to_num(np.diff(np.log(close), axis=0))  
        out[:] = np.mean(r,axis=0)  

universe = QTradableStocksUS() & Sector().eq(309)

rets = returns(mask=universe)  
universe=universe&rets.notnull()  
alpha = myFactor(mask=universe)

pipe = Pipeline(  
    columns={  
        'alpha': alpha  
    },  
    screen=universe & alpha.notnull()  
)
data_output = run_pipeline(pipe, period_start, period_end)  
data_output.head()