Пример #1
0
def make_pipeline():
    all_assets_filter = (USEquityPricing.close.latest > 0)
    returns_5 = Returns(window_length=5)
    rsi = RSI(inputs=[USEquityPricing.close])
    macd = MovingAverageConvergenceDivergenceSignal(mask=all_assets_filter)
    ema = ExponentialWeightedMovingAverage(mask=all_assets_filter,
                                           inputs=[USEquityPricing.close],
                                           window_length=30,
                                           decay_rate=(1 - (2.0 / (1 + 15.0))))
    mean_5 = SimpleMovingAverage(inputs=[USEquityPricing.close],
                                 window_length=5,
                                 mask=all_assets_filter)
    mean_10 = SimpleMovingAverage(inputs=[USEquityPricing.close],
                                  window_length=10,
                                  mask=all_assets_filter)
    bb = BollingerBands(inputs=[USEquityPricing.close], window_length=20, k=2)
    return Pipeline(
        columns={
            'returns_5': returns_5,
            'RSI': rsi,
            'MACD': macd,
            'EMA': ema,
            'SMA_5': mean_5,
            'SMA_10': mean_10,
            'bb_upper': bb.upper,
            'bb_middle': bb.middle,
            'bb_lower': bb.lower
        },
        screen=all_assets_filter,
    )
    def make_screener(context):
        """ Daily screener for securities to trade """

        #  Average volume for last 2 weeks.
        average_volume = SimpleMovingAverage(inputs=[USEquityPricing.volume], window_length=10)

        # SMA for last 2 weeks.
        sma_10 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=10)

        # ATR for last 2 weeks
        average_true_range = SimpleMovingAverage(inputs=[USEquityPricing.high], window_length=10) - SimpleMovingAverage(inputs=[USEquityPricing.low], window_length=10)

        long, short = TrendFactor()

        # Takin securities with price between [5, 50], average volume over million and ATR >= 0.5
        return Pipeline(
            columns={
                'average_volume': average_volume,
                'average_true_range': average_true_range,
                'long': long,
                'short': short
            },
            screen=(
                (average_volume > minimum_daily_volume) &
                (sma_10 >= 5) &
                (sma_10 <= 50) &
                (average_true_range >= minimum_atr)
            )
        )
def make_pipeline():

    sentiment_score = SimpleMovingAverage(inputs=[stocktwits.bull_minus_bear],
                                          window_length=3,
                                          mask=QTradableStocksUS())

    return Pipeline(columns={
        'sentiment_score': sentiment_score,
    },
                    screen=sentiment_score.notnull())
Пример #4
0
 def test_downsample_windowed_factor(self):
     self.check_downsampled_term(
         SimpleMovingAverage(
             inputs=[TestingDataSet.float_col],
             window_length=5,
         )
     )
Пример #5
0
def mean_reversion_5day_sector_neutral_smoothed(window_length, universe,
                                                sector):
    """
    Generate the mean reversion 5 day sector neutral smoothed factor

    Parameters
    ----------
    window_length : int
        Returns window length
    universe : Zipline Filter
        Universe of stocks filter
    sector : Zipline Classifier
        Sector classifier

    Returns
    -------
    factor : Zipline Factor
        Mean reversion 5 day sector neutral smoothed factor
    """

    #TODO: Implement function

    return SimpleMovingAverage(inputs=[
        mean_reversion_5day_sector_neutral(window_length, universe, sector)
    ],
                               window_length=window_length).rank().zscore()
Пример #6
0
def mean_reversion_5day_sector_neutral_smoothed(window_length, universe,
                                                sector):
    """
    Generate the mean reversion 5 day sector neutral smoothed factor

    Paramètres
    ----------
    window_length : int
        Retourne la longueur de la fenêtre
    universe : Zipline Filter
        Univers des filtres des stocks
    sector : Zipline Classifier
        Classifieur de secteurs

    Returns
    -------
    factor : Zipline Factor
        Facteur de réversion moyenne sur 5 jours de secteur neutre(lissé)
    """

    unsmoothed_factor = mean_reversion_5day_sector_neutral(
        window_length, universe, sector)
    factor = SimpleMovingAverage(inputs=[unsmoothed_factor],
                                 window_length=window_length)\
        .rank()\
        .zscore()
    return factor
Пример #7
0
    def test_downsample_non_windowed_factor(self):
        sma = SimpleMovingAverage(
            inputs=[TestingDataSet.float_col],
            window_length=5,
        )

        self.check_downsampled_term(((sma + sma) / 2).rank())
Пример #8
0
def mean_reversion_5day_sector_neutral_smoothed(window_length, universe,
                                                sector):
    unsmoothed_factor = -Returns(
        window_length=window_length,
        mask=universe).demean(groupby=sector).rank().zscore()
    return SimpleMovingAverage(inputs=[unsmoothed_factor],
                               window_length=window_length).rank().zscore()
Пример #9
0
def overnight_sentiment_smoothed(cto_window_length,
                                 trail_overnight_returns_window_length,
                                 universe):
    unsmoothed_factor = overnight_sentiment(
        cto_window_length, trail_overnight_returns_window_length, universe)
    return SimpleMovingAverage(inputs=[unsmoothed_factor], window_length=trail_overnight_returns_window_length) \
        .rank() \
        .zscore()
Пример #10
0
    def initialize(context):
        # Create, register and name a pipeline in initialize.
        pipe = Pipeline()
        context.attach_pipeline(pipe, 'AAPL')

        # Construct a simple moving average factor and add it to the pipeline.
        USEquityPricing需要本地自定义
        if True:
            sma_short = SimpleMovingAverage(inputs=[USEquityPricing.close],
                                            window_length=10)
        else:  #mid added
            data = Column(float64)
            dataset = DataSet()
            close = data.bind(dataset, 'aapl')
            sma_short = SimpleMovingAverage(inputs=[close], window_length=10)

        pipe.add(sma_short, 'sma_short')
Пример #11
0
def mean_reversion_sector_neutral_smoothed(window_length, universe, sector):
    """
    Smoothed version of mean_reversion_5day_sector_neutral. window_lenghth is used in returns and smoothing computations
    """
    unsmoothed_factor = mean_reversion_sector_neutral(window_length, universe,
                                                      sector)
    return SimpleMovingAverage(inputs=[unsmoothed_factor], window_length=window_length) \
        .rank() \
        .zscore()
Пример #12
0
def overnight_sentiment_smoothed(cto_window_length,
                                 trail_overnight_returns_window_length,
                                 universe):
    cto_out = CTO(mask=universe, window_length=cto_window_length)
    unsmoothed_factor = TrailingOvernightReturns(
        inputs=[cto_out],
        window_length=trail_overnight_returns_window_length).rank().zscore()
    return SimpleMovingAverage(
        inputs=[unsmoothed_factor],
        window_length=trail_overnight_returns_window_length).rank().zscore()
Пример #13
0
def momentum_smoothed(window_length, smooth_window_length, universe, sector):
    """
    Smoothed version of momentum. window_lenghth is used in returns and smoothing computations
     Parameters
    ----------
    smooth_window_length : int
        smoothing factor to applie to SimpleMovingAverage
    """
    unsmoothed_factor = momentum(window_length, universe, sector)
    return SimpleMovingAverage(inputs=[unsmoothed_factor], window_length=smooth_window_length) \
        .rank() \
        .zscore()
Пример #14
0
    def test_SMA(self):
        engine = SimplePipelineEngine(
            lambda column: self.pipeline_loader,
            self.env.trading_days,
            self.finder,
        )
        window_length = 5
        assets = self.all_assets
        dates = date_range(
            self.first_asset_start + self.trading_day,
            self.last_asset_end,
            freq=self.trading_day,
        )
        dates_to_test = dates[window_length:]

        SMA = SimpleMovingAverage(
            inputs=(USEquityPricing.close, ),
            window_length=window_length,
        )

        results = engine.run_pipeline(
            Pipeline(columns={'sma': SMA}),
            dates_to_test[0],
            dates_to_test[-1],
        )

        # Shift back the raw inputs by a trading day because we expect our
        # computed results to be computed using values anchored on the
        # **previous** day's data.
        expected_raw = rolling_mean(
            self.writer.expected_values_2d(
                dates - self.trading_day,
                assets,
                'close',
            ),
            window_length,
            min_periods=1,
        )

        expected = DataFrame(
            # Truncate off the extra rows needed to compute the SMAs.
            expected_raw[window_length:],
            index=dates_to_test,  # dates_to_test is dates[window_length:]
            columns=self.finder.retrieve_all(assets),
        )
        self.write_nans(expected)
        result = results['sma'].unstack()
        assert_frame_equal(result, expected)
    def get_moving_average(self,
                           start_date,
                           end_date,
                           assets=None,
                           window_length=63):
        moving_average = SimpleMovingAverage(inputs=[USEquityPricing.close],
                                             window_length=window_length)

        pipeline = Pipeline(columns={'moving_average': moving_average})

        if assets is not None:
            pipeline.set_screen(StaticAssets(assets))

        df = self._run_pipeline(pipeline, start_date, end_date)

        return df
Пример #16
0
def make_pipeline():
    """
    Create a pipeline with the following rules:

    screen
    - common stocks only
    - must be liquid (top 10% by dollar volume)
    - must be above 20-day moving average
    - must not be too cheap or too expensive

    columns
    - 20-day moving average
    - prior low
    - standard deviation of closing prices
    """
    mavg = SimpleMovingAverage(window_length=20, inputs=[EquityPricing.close])

    are_common_stocks = SecuritiesMaster.usstock_SecurityType2.latest.eq(
        "Common Stock")
    are_liquid = AverageDollarVolume(window_length=30).percentile_between(
        90, 100)
    are_above_mavg = EquityPricing.close.latest > mavg
    are_not_too_cheap = EquityPricing.close.latest > 10
    are_not_too_expensive = EquityPricing.close.latest < 2000

    pipeline = Pipeline(columns={
        "mavg":
        mavg,
        "prior_low":
        EquityPricing.low.latest,
        "std":
        ExponentialWeightedMovingStdDev(inputs=[EquityPricing.close],
                                        window_length=63,
                                        decay_rate=0.99)
    },
                        screen=(are_common_stocks
                                & are_liquid
                                & are_above_mavg
                                & are_not_too_cheap
                                & are_not_too_expensive))

    return pipeline
Пример #17
0
def factor_pipe(context):
    '''
        function to set up a pipeline to retrieve all active syms. 
        We can add filters here as well.
    '''
    pipe = Pipeline()

    sma_20 = SimpleMovingAverage(inputs=[EquityPricing.close],
                                 window_length=20)
    # Pick the top 50% of stocks ranked by dollar volume
    dollar_volume = AvgDailyDollarVolumeTraded(window_length=252)
    high_dollar_volume = dollar_volume.percentile_between(50, 100)
    # Remove penny stocks
    no_penny_stocks = sma_20 > 1
    filtered_assets = high_dollar_volume & no_penny_stocks
    pipe.set_screen(filtered_assets)

    pipe.add(sma_20, 'sma_20')
    for m in context.agent.models:
        pipe.add(m.factor(inputs=[EquityPricing.close], window_length=252),
                 m.name)

    return pipe
Пример #18
0
    def test_window_safety_of_slices(self):
        """
        Test that slices correctly inherit the `window_safe` property of the
        term from which they are derived.
        """
        col = self.col
        my_asset = self.asset_finder.retrieve_asset(self.sids[0])

        # SimpleMovingAverage is not window safe.
        sma = SimpleMovingAverage(inputs=[self.col], window_length=10)
        sma_slice = sma[my_asset]

        class UsesSlicedInput(CustomFactor):
            window_length = 2
            inputs = [sma_slice]

            def compute(self, today, assets, out, sma_slice):
                pass

        with self.assertRaises(NonWindowSafeInput):
            self.run_pipeline(
                Pipeline(columns={'uses_sliced_input': UsesSlicedInput()}),
                self.pipeline_start_date,
                self.pipeline_end_date,
            )

        # Make sure that slices of custom factors are not window safe.
        class MyUnsafeFactor(CustomFactor):
            window_length = 2
            inputs = [col]

            def compute(self, today, assets, out, col):
                pass

        my_unsafe_factor = MyUnsafeFactor()
        my_unsafe_factor_slice = my_unsafe_factor[my_asset]

        class UsesSlicedInput(CustomFactor):
            window_length = 2
            inputs = [my_unsafe_factor_slice]

            def compute(self, today, assets, out, my_unsafe_factor_slice):
                pass

        with self.assertRaises(NonWindowSafeInput):
            self.run_pipeline(
                Pipeline(columns={'uses_sliced_input': UsesSlicedInput()}),
                self.pipeline_start_date,
                self.pipeline_end_date,
            )

        # Create a window safe factor.
        class MySafeFactor(CustomFactor):
            window_length = 2
            inputs = [col]
            window_safe = True

            def compute(self, today, assets, out, col):
                pass

        my_safe_factor = MySafeFactor()
        my_safe_factor_slice = my_safe_factor[my_asset]

        # Make sure that correlations are not safe if either the factor *or*
        # the target slice are not window safe.
        with self.assertRaises(NonWindowSafeInput):
            my_unsafe_factor.pearsonr(
                target=my_safe_factor_slice,
                correlation_length=10,
            )

        with self.assertRaises(NonWindowSafeInput):
            my_safe_factor.pearsonr(
                target=my_unsafe_factor_slice,
                correlation_length=10,
            )
Пример #19
0
 def test_downsample_nonwindowed_classifier(self):
     sma = SimpleMovingAverage(
         inputs=[TestingDataSet.float_col],
         window_length=5,
     )
     self.check_downsampled_term(sma.quantiles(5))
Пример #20
0
 def test_downsample_nonwindowed_filter(self):
     sma = SimpleMovingAverage(
         inputs=[TestingDataSet.float_col],
         window_length=5,
     )
     self.check_downsampled_term(sma > 5)
Пример #21
0
 def test_downsample_windowed_filter(self):
     sma = SimpleMovingAverage(
         inputs=[TestingDataSet.float_col],
         window_length=5,
     )
     self.check_downsampled_term(All(inputs=[sma.top(4)], window_length=5))
Пример #22
0
#
# Now that you know how build a pipeline and execute it, in this section we will see how we can add factors and filters to our pipeline. These factors and filters will determine the computations we want our pipeline to compute each day.
#
# We can add both factors and filters to our pipeline using the `.add(column, name)` method of the `Pipeline` class. The `column` parameter represetns the factor or filter to add to the pipeline. The `name` parameter is a string that determines the name of the column in the output Pandas Dataframe for that factor of fitler. As mentioned earlier, each factor and filter will appear as a column in the output dataframe of our pipeline. Let's start by adding a factor to our pipeline.
#
# ### Factors
#
# In the code below, we will use Zipline's built-in `SimpleMovingAverage` factor to create a factor that computes the 15-day mean closing price of securities. We will then add this factor to our pipeline and use `.show_graph()` to see a diagram of our pipeline with the factor added.

# In[ ]:


from zipline.pipeline.factors import SimpleMovingAverage

# Create a factor that computes the 15-day mean closing price of securities
mean_close_15 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=15)

# Add the factor to our pipeline
pipeline.add(mean_close_15, "15 Day MCP")

# Render the pipeline as a DAG
pipeline.show_graph()


# In the diagram above we can clearly see the factor we have added. Now, we can run our pipeline again and see its output. The pipeline is run in exactly the same way we did before.

# In[ ]:


# Set starting and end dates
start_date = pd.Timestamp("2014-01-06", tz="utc")
Пример #23
0
    def test_compute_with_adjustments(self):
        dates, assets = self.dates, self.assets
        low, high = USEquityPricing.low, USEquityPricing.high
        apply_idxs = [3, 10, 16]

        def apply_date(idx, offset=0):
            return dates[apply_idxs[idx] + offset]

        adjustments = DataFrame.from_records([
            dict(
                kind=MULTIPLY,
                sid=assets[1],
                value=2.0,
                start_date=None,
                end_date=apply_date(0, offset=-1),
                apply_date=apply_date(0),
            ),
            dict(
                kind=MULTIPLY,
                sid=assets[1],
                value=3.0,
                start_date=None,
                end_date=apply_date(1, offset=-1),
                apply_date=apply_date(1),
            ),
            dict(
                kind=MULTIPLY,
                sid=assets[1],
                value=5.0,
                start_date=None,
                end_date=apply_date(2, offset=-1),
                apply_date=apply_date(2),
            ),
        ])
        low_base = DataFrame(self.make_frame(30.0))
        low_loader = DataFrameLoader(low, low_base.copy(), adjustments=None)

        # Pre-apply inverse of adjustments to the baseline.
        high_base = DataFrame(self.make_frame(30.0))
        high_base.iloc[:apply_idxs[0], 1] /= 2.0
        high_base.iloc[:apply_idxs[1], 1] /= 3.0
        high_base.iloc[:apply_idxs[2], 1] /= 5.0

        high_loader = DataFrameLoader(high, high_base, adjustments)

        engine = SimplePipelineEngine(
            {
                low: low_loader,
                high: high_loader
            }.__getitem__,
            self.dates,
            self.asset_finder,
        )

        for window_length in range(1, 4):
            low_mavg = SimpleMovingAverage(
                inputs=[USEquityPricing.low],
                window_length=window_length,
            )
            high_mavg = SimpleMovingAverage(
                inputs=[USEquityPricing.high],
                window_length=window_length,
            )
            bounds = product_upper_triangle(range(window_length, len(dates)))
            for start, stop in bounds:
                results = engine.run_pipeline(
                    Pipeline(columns={
                        'low': low_mavg,
                        'high': high_mavg
                    }),
                    dates[start],
                    dates[stop],
                )
                self.assertEqual(set(results.columns), {'low', 'high'})
                iloc_bounds = slice(start, stop + 1)  # +1 to include end date

                low_results = results.unstack()['low']
                assert_frame_equal(low_results, low_base.iloc[iloc_bounds])

                high_results = results.unstack()['high']
                assert_frame_equal(high_results, high_base.iloc[iloc_bounds])
Пример #24
0
 def test_downsample_nonwindowed_classifier(self):
     sma = SimpleMovingAverage(
         inputs=[TestingDataSet.float_col],
         window_length=5,
     )
     self.check_downsampled_term(sma.quantiles(5))
Пример #25
0
 def test_downsample_windowed_filter(self):
     sma = SimpleMovingAverage(
         inputs=[TestingDataSet.float_col],
         window_length=5,
     )
     self.check_downsampled_term(All(inputs=[sma.top(4)], window_length=5))
Пример #26
0
# In[ ]:

from zipline.pipeline.factors import Returns
from zipline.pipeline.factors import SimpleMovingAverage

# create a pipeline called p
p = Pipeline(screen=universe)
# create a factor of one year returns, deman by sector, then rank
factor = (
    Returns(window_length=252, mask=universe).demean(groupby=Sector(
    )).  #we use the custom Sector class that we reviewed earlier
    rank().zscore())

# Use this factor as input into SimpleMovingAverage, with a window length of 5
# Also rank and zscore (don't need to de-mean by sector, s)
factor_smoothed = (SimpleMovingAverage(inputs=[factor],
                                       window_length=5).rank().zscore())

# add the unsmoothed factor to the pipeline
p.add(factor, 'Momentum_Factor')
# add the smoothed factor to the pipeline too
p.add(factor_smoothed, 'Smoothed_Momentum_Factor')

# ## visualize the pipeline
#
# Note that if the image is difficult to read in the notebook, right-click and view the image in a separate tab.

# In[ ]:

p.show_graph(format='png')

# ## run pipeline and view the factor data
Пример #27
0
def run_data_pipeline(engine, universe, start_date, end_date):

    pipeline = Pipeline(screen=universe)

    sector = Sector()

    # Alpha Factors :

    pipeline.add(DownsideRisk(), 'Downside Risk (Sortino Ratio)')

    pipeline.add(Vol3M(), '3 Month Volatility')

    pipeline.add(momentum_1yr(252, universe, sector), 'Momentum_1YR')

    pipeline.add(
        mean_reversion_5day_sector_neutral_smoothed(20, universe, sector),
        'Mean_Reversion_Sector_Neutral_Smoothed')

    pipeline.add(overnight_sentiment_smoothed(2, 10, universe),
                 'Overnight_Sentiment_Smoothed')

    pipeline.add(rsi_sector_neutral(15, universe, sector),
                 'RSI_Sector_Neutral_15d')

    pipeline.add(rsi_sector_neutral(30, universe, sector),
                 'RSI_Sector_Neutral_30d')

    beta_factor = (RegressionAgainstTime(mask=universe).beta.rank().zscore())

    gamma_factor = (RegressionAgainstTime(mask=universe).gamma.rank().zscore())

    conditional_factor = (beta_factor * gamma_factor).rank().zscore()

    pipeline.add(beta_factor, 'time_beta')

    pipeline.add(gamma_factor, 'time_gamma')

    pipeline.add(conditional_factor, 'conditional_factor')

    # Universal Quant Features :

    pipeline.add(
        AnnualizedVolatility(window_length=20, mask=universe).rank().zscore(),
        'volatility_20d')

    pipeline.add(
        AnnualizedVolatility(window_length=120, mask=universe).rank().zscore(),
        'volatility_120d')

    pipeline.add(
        AverageDollarVolume(window_length=20, mask=universe).rank().zscore(),
        'adv_20d')

    pipeline.add(
        AverageDollarVolume(window_length=120, mask=universe).rank().zscore(),
        'adv_120d')

    pipeline.add(sector, 'sector_code')

    # Regime Features :

    pipeline.add(
        SimpleMovingAverage(inputs=[MarketDispersion(mask=universe)],
                            window_length=20), 'dispersion_20d')

    pipeline.add(
        SimpleMovingAverage(inputs=[MarketDispersion(mask=universe)],
                            window_length=120), 'dispersion_120d')

    pipeline.add(MarketVolatility(window_length=20), 'market_vol_20d')

    pipeline.add(MarketVolatility(window_length=120), 'market_vol_120d')

    # Target
    # Let's try to predict the go forward 1-week return. When doing this, it's important to quantize the target. The factor we create is the trailing 5-day return

    pipeline.add(
        Returns(window_length=5, mask=universe).quantiles(2), 'return_5d')

    pipeline.add(
        Returns(window_length=5, mask=universe).quantiles(25), 'return_5d_p')

    # Running the Pipeline

    all_factors = engine.run_pipeline(pipeline, start_date, end_date)

    # Computing Date Features

    all_factors = compute_date_features(all_factors, start_date, end_date)

    # One Hot Encoding Sectors

    all_factors = one_hot_encode_sectors(all_factors)

    # Shifted Target For Training The Model

    all_factors['target'] = all_factors.groupby(level=1)['return_5d'].shift(-5)

    return all_factors
Пример #28
0
# In[64]:


class MarketDispersion(CustomFactor):
    inputs = [DailyReturns()]
    window_length = 1
    window_safe = True

    def compute(self, today, assets, out, returns):
        # returns are days in rows, assets across columns
        out[:] = np.sqrt(np.nanmean((returns - np.nanmean(returns))**2))


pipeline.add(
    SimpleMovingAverage(inputs=[MarketDispersion(mask=universe)],
                        window_length=20), 'dispersion_20d')
pipeline.add(
    SimpleMovingAverage(inputs=[MarketDispersion(mask=universe)],
                        window_length=120), 'dispersion_120d')

# In[67]:


class MarketVolatility(CustomFactor):
    inputs = [DailyReturns()]
    window_length = 1
    window_safe = True

    def compute(self, today, assets, out, returns):
        mkt_returns = np.nanmean(returns, axis=1)
        out[:] = np.sqrt(260. * np.nanmean(