from quantopian.pipeline import CustomFactor
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
import numpy as np
from scipy import stats
class MomentumScore(CustomFactor):
    """
    Computes Annualized Exponential Regression Slope * R2
    Pre-declares close as default inputs and `window_length` as
    125.
    """
    inputs = [USEquityPricing.close]
    window_length = 125
    def compute(self, today, assets, out, ts):
        # Make a list of consecutive numbers
        x=np.arange(ts.shape[0])
        # Get logs
        log_ts=np.log(ts)
        # Calculate regression values
        statistics=np.polyfit(x,log_ts,1,full=True)
        slope=statistics[0][0,:]
        r_value=statistics[1]
        # Annualize percent
        annualized_slope=(np.power(np.exp(slope),252)-1)*100
        # Adjust for fitness and return score
        out[:] = np.multiply(annualized_slope,np.power(r_value,2))
momentum_score = MomentumScore()
# Pipeline imports
from quantopian.pipeline import Pipeline
from quantopian.pipeline.filters import Q3000US
from scipy import stats
import numpy as np
# Pipeline definition
def  make_pipeline():
    base_universe = Q3000US()
    score = MomentumScore()
    # Create filter for top 350 and bottom 350
    # assets based on their sentiment scores
    top_scores = (
        score.top(300)
    )
    return Pipeline(
        columns={
            'score': score,
        },
        # Set screen as the intersection between our filter
        # and trading universe
        screen=(
            base_universe
            & top_scores
        )
    )
# Import run_pipeline method
from quantopian.research import run_pipeline
# Specify a time range to evaluate
period_start = '2003-01-01'
period_end = '2020-01-01'
# Execute pipeline over evaluation period
pipeline_output = run_pipeline(
    make_pipeline(),
    start_date=period_start,
    end_date=period_end
)
pipeline_output
# Import prices function
from quantopian.research import prices
# Get list of unique assets from the pipeline output
asset_list = pipeline_output.index.levels[1].unique()
# Query pricing data for all assets present during
# evaluation period
asset_prices = prices(
    asset_list,
    start=period_start,
    end=period_end
)
# Import Alphalens
import alphalens as al
# Get asset forward returns and quantile classification
# based on sentiment scores
factor_data = al.utils.get_clean_factor_and_forward_returns(
    factor=pipeline_output['score'],
    prices=asset_prices,
    max_loss=1
)
# Display first 5 rows
factor_data.head(5)
import pandas as pd
# Calculate factor-weighted long-short portfolio returns
ls_factor_returns = al.performance.factor_returns(factor_data)
# Plot cumulative returns for 5 day holding period
al.plotting.plot_cumulative_returns(ls_factor_returns['1D'], '1D', freq=pd.tseries.offsets.BDay());
al.plotting.plot_cumulative_returns(ls_factor_returns['5D'], '5D', freq=pd.tseries.offsets.BDay());
al.plotting.plot_cumulative_returns(ls_factor_returns['10D'], '10D', freq=pd.tseries.offsets.BDay());