Quantopian Tutorial2 Lesson5,6 フィルターと組み合わせ

[前回](https://qiita.com/isaotinen/items/d190ce61df2686552b6a)の続き。

###フィルター
フィルタはアセットと時間からブール値を返す。
パイプラインの最終出力を絞り込むために使われる。比較操作を使う方法とと`Factor`/`Classifier`メソッドを使う方法の2種類がある。

###比較操作
`Factors`と`Classifiers`を比較することで`Filters`を作る。`Classifiers`はまだ見ていないので、`Factors`のみ使う例をとりあげる。次の例は最新の終値が20
ドルを超えると`True`を返すフィルタを作る。

```py3
last_close_price = USEquityPricing.close.latest
close_price_filter = last_close_price > 20
```

次の例は10日間の平均が30日間の平均を下回るたびに`True`を返すフィルタを作る。

```py3
mean_close_10 = SimpleMovingAverage(
    inputs=[USEquityPricing.close],
    window_length=10
)
mean_close_30 = SimpleMovingAverage(
    inputs=[USEquityPricing.close],
    window_length=30
)
mean_crossover_filter = mean_close_10 < mean_close_30
```

フィルターは毎日True/Falseを返す。

###Factor/Classifierメソッド
`Factor`や`Classifier`の様々なメソッドは`Filters`を返す。ここでも`Factor`メソッドのみ用いた例を見る。
`Factor.top(n)`メソッドは、毎日特定要因の上位n個の証券に対して`True`を返す`Filter`を生成する。
次の例はすべての証券のうち最終価格が上位200位入った証券について`True`を返すフィルターを作る。

```py3
last_close_price = USEquityPricing.close.latest
top_close_price_filter = last_close_price.top(200)
```

`Filters`を返す`Factor`メソッド一覧は[こちら](https://www.quantopian.com/help#quantopian_pipeline_factors_Factor)。
`Filters`を返す`Classifier`メソッド一覧は[こちら](https://www.quantopian.com/help#quantopian_pipeline_classifiers_Classifier)。
（本家一覧に飛びます）

###ドルボリュームフィルター
30日間の平均ドルボリュームが10,000,000ドルを超えている場合に`True`を返すフィルターを作成する。まずはじめに`AverageDollarVolume`計数を作成して30日間の平均ドルボリュームを計算する必要がある。
`AverageDollarVolume`フィルターをインポートするには`SimpleMovingAverage`をインポートするために使用した行に追加する。

```py3
from quantopian.pipeline.factors import AverageDollarVolume, SimpleMovingAverage
```

ファクターをインスタンス化する。

```py3
dollar_volume = AverageDollarVolume(window_length=30)
```

デフォルトでは`AverageDollarVolume`は`USEquityPricing.close`と`USEquityPricing.volume`を`input`として使用しているので指定しない。
係数が得られたのでブール式でフィルターを作成できる。次の例は`dollar_volume`が10,000,000ドルを超える証券に対して`True`を返すフィルターを作成する。

```py3
high_dollar_volume = (dollar_volume > 10000000)
```

パイプラインに列を追加する。

```py3
def make_pipeline():

    mean_close_10 = SimpleMovingAverage(
        inputs=[USEquityPricing.close],
        window_length=10
    )
    mean_close_30 = SimpleMovingAverage(
        inputs=[USEquityPricing.close],
        window_length=30
    )

    percent_difference = (mean_close_10 - mean_close_30) / mean_close_30

    dollar_volume = AverageDollarVolume(window_length=30)

    high_dollar_volume = (dollar_volume > 10000000)

    return Pipeline(
        columns={
            'percent_difference': percent_difference,
            'high_dollar_volume': high_dollar_volume
        },
    )

result = run_pipeline(make_pipeline(), '2015-05-05', '2015-05-05')
result.head()
```

パイプラインを作成して実行すると、各証券の結果に対応するブール値を持つ列`high_dollar_volume`が作成される。
![pipeline1_l5_screenshot1-9fcea3e7763d7448578e96003013f93f91323c7bcef4b88e74a5ed4e9c8e86af.png](https://qiita-image-store.s3.amazonaws.com/0/200508/a2d98e3a-f92a-32a1-6232-fd70b92f22b7.png)

###スクリーンの適用
デフォルトでは、パイプラインはQuantopianデータベース内のすべてのアセットに対して毎日計算値を生成するが、大抵我々が気にするのは特定の基準を満たすものの証券のみである。フィルターが`False`のものを無視するようにパイプラインに指示するには、`screen`キーワードを使用する。
30日平均ドルの金額が10,000,000ドルを超える有価証券のパイプライン出力をスクリーニングするには、`high_dollar_volume`フィルターを`screen`引数に渡す。`make_pipeline`は以下のようになる。
これを実行すると`high_dollar_volume`を渡した証券のみ出力が生成される。

```py3
def make_pipeline():

  mean_close_10 = SimpleMovingAverage(
      inputs=[USEquityPricing.close],
      window_length=10
  )
  mean_close_30 = SimpleMovingAverage(
      inputs=[USEquityPricing.close],
      window_length=30
  )

  percent_difference = (mean_close_10 - mean_close_30) / mean_close_30

  dollar_volume = AverageDollarVolume(window_length=30)
  high_dollar_volume = (dollar_volume > 10000000)

  return Pipeline(
      columns={
          'percent_difference': percent_difference
      },
      screen=high_dollar_volume
  )
result = run_pipeline(make_pipeline(), '2015-05-05', '2015-05-05')
print 'Number of securities that passed the filter: %d' % len(result)
```

（訳注:len()はリストの要素数を取得。%dは%記法）
![pipeline1_l5_screenshot2-e7194b4b7fce145bdc4343afde0e9ba602b8cc5d3a4868a40d497f4d1f7460c1.png](https://qiita-image-store.s3.amazonaws.com/0/200508/0833fbde-442c-671e-4c7b-15d05ff8c030.png)

###フィルターの反転
フィルターを反転するには`~`演算子をフィルターの前につける。

```py3
 low_dollar_volume =~high_dollar_volume 
```

###フィルターの結合
フィルターを組み合わせるには`&`(and)または`|`(or)演算子を用いる。
以下の例では平均ドルボリュームの上位10%かつ最新の終値が20ドルを超える有価証券を選別する。まず`AverageDollarVolume`と`percentile_between`フィルターを作成する。

```py3
high_dollar_volume = dollar_volume.percentile_between(90, 100)
```

※`percentile_between`は`Filter`を返す`Factor`メソッド。
次に`latest_close`係数を作成し、20ドル以上で終了した有価証券のフィルターを定義する。

```py3
latest_close = USEquityPricing.close.latest
above_20 = latest_close > 20
```

`&`を用いて`high_dollar_volume`フィルターと`above_20`フィルターを組み合わせることができる。

```py3
 is_tradeable = high_dollar_volume＆above_20
```

両方のフィルターが`True`のときのみ`True`を返す。
このフィルターをパイプラインのスクリーンとして使用する場合、`is_tradeable`に`screen`を設定する。

```py3
def make_pipeline():

    mean_close_10 = SimpleMovingAverage(
        inputs=[USEquityPricing.close],
        window_length=10
    )
    mean_close_30 = SimpleMovingAverage(
        inputs=[USEquityPricing.close],
        window_length=30
    )

    percent_difference = (mean_close_10 - mean_close_30) / mean_close_30

    dollar_volume = AverageDollarVolume(window_length=30)
    high_dollar_volume = dollar_volume.percentile_between(90, 100)

    latest_close = USEquityPricing.close.latest
    above_20 = latest_close > 20

    is_tradeable = high_dollar_volume & above_20

    return Pipeline(
        columns={
            'percent_difference': percent_difference
        },
        screen=is_tradeable
    )
result = run_pipeline(make_pipeline(), '2015-05-05', '2015-05-05')
print 'Number of securities that passed the filter: %d' % len(result)
```

![pipeline1_l6_screenshot1-5b1f4d747519f40ed5f8686dae69230290aad50071b340eb235ae70933917ae1.png](https://qiita-image-store.s3.amazonaws.com/0/200508/ed5227ae-2c35-f92a-59fb-244e95e09914.png)
###所感
この内容とは直接関係ないが、公式ホームページのWorkshop欄を見てみると割と頻繁に、しかも世界各地でワークショップが開かれていて羨ましい。オンライン配信とかないのかな。とか思ったらWebinarってオンラインのセミナーらしいので一度登録してみるか。（レベルがどれくらいかはわからんけど）