<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Example
Step1:  Example
Step3:  Example
<ASSISTANT_TASK:>
Python Code:
from zipline.pipeline.data import USEquityPricing as USEP
from zipline.pipeline.factors import SimpleMovingAverage
# sma30 and sma90 are Factors.
# Factors represent computations producing numerical-valued outputs.
sma30 = SimpleMovingAverage(inputs=[USEP.close], window_length=30)
sma90 = SimpleMovingAverage(inputs=[USEP.close], window_length=90)
# Comparisons between Factors produce Filters.
# Filters represent computations producing boolean-valued outputs.
screen = (sma30 > sma90)
example0 = Pipeline(
    columns={"sma30": sma30, "sma90": sma90},
    screen=screen,
)
example0
example0.show_graph('svg')
results0 = engine.run_pipeline(example0, start_date, end_date)
results0
Explanation: Example: Less Simple Momentum
Compute 30 and 90 day moving averages.
Consider assets whose 30 day average is greater than 90 day average.
Intuition is that assets with higher short averages are "on the way up".
End of explanation
from zipline.pipeline.factors import VWAP
vwap30 = VWAP(window_length=30)
vwap90 = VWAP(window_length=90)
# Arithmetic operations between Factors produce new Factors.
vwap_pct_change = ((vwap30 - vwap90) / vwap30)
# rank() is a method available on any Factor instance.
# It produces a new Factor containing the numerical rank of each
# asset after sorting the underyling Factor values.
vwap_pct_change_rank = vwap_pct_change.rank(ascending=False)
# top() is another method available on Factors.  It produces a Filter
# representing the top N assets sorted by the underlying Factor values.
top200 = vwap_pct_change.top(200)
example1 = Pipeline(
    columns={
        "rank": vwap_pct_change_rank,
        "pct_change": vwap_pct_change,
    },
    screen=top200,
)
example1.show_graph()
engine.run_pipeline(example1, start_date, end_date)
Explanation: Example: Less Simple Momentum
Compute 30 and 90 day Volume-Weighted Average Price
Rank assets by percent difference in 30-day VWAP vs 90-day VWAP.
End of explanation
import numpy as np
from zipline.pipeline import CustomFactor
class MaxDrawdown(CustomFactor):
    
    Factor computing the maximum drawdown 
    an asset has taken in the last N days.
    
    inputs = [USEP.close]
    def compute(self, today, assets, out, closes):
        # The difference between each day and the max of all
        # earlier days in the period.
        drawdowns = fmax.accumulate(closes, axis=0) - closes
        drawdowns[isnan(drawdowns)] = np.NINF
        drawdown_ends = np.nanargmax(drawdowns, axis=0)
        # This is slow in pure Python.
        # Cython or Numba could accelerate this substantially.
        for i, end in enumerate(drawdown_ends):
            peak = nanmax(data[:end + 1, i])
            out[i] = (peak - data[end, i]) / data[end, i]
                    
maxdd_90 = MaxDrawdown(window_length=90)
# rank() takes an optional `mask` keyword, which can be passed a Filter
# to signify "Compute rank() only for assets for which the Filter 
# returned True.
masked_rank = vwap_pct_change.rank(mask=maxdd_90.bottom(200))
example2 = Pipeline(
    columns={
        'masked_rank': masked_rank
    },
    screen=maxdd_90.bottom(200),
)
example2.show_graph('svg')
engine.run_pipeline(example1, start_date, end_date)
Explanation: Example: Custom Factors and Masking
End of explanation
<END_TASK>