from quantopian.pipeline import Pipeline
from quantopian.research import run_pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.factors import SimpleMovingAverage

2.13. フィルタ

フィルタとは、とある資産のある一時点からブール型の値を出力する関数です:

\[F(asset, timestamp) \rightarrow boolean\]

フィルタ は 計算過程やパイプラインの最終出力に含まれる証券の絞り込みに使われます。 フィルタ 作成には2つの一般的な方法があります。比較演算子と ファクター / クラシファイア メソッドを使う方法です。

2.14. 比較演算子

ファクタークラシファイア に用いられる比較演算子から フィルタ が作られます。 ここまで クラシファイア について触れていませんが、とにかく ファクター を使った例で進めていきます。 以下の例では、直近の終値が20ドルを超える場合に True を返すフィルタを作成します。

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

またこの例では、10日間平均が30日間平均を下回るる場合に True を返すフィルタを作成しています。

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 の値を持っていることに留意してください。

2.15. ファクター / クラシファイア メソッド

ファクタークラシファイア クラスが フィルタ を作成する方法は多様です。 相変わらず クラシファイア について触れていませんが ファクター を使った例で進めていきます(このあと クラシファイア メソッドを見ていきます)。 Factor.top(n) メソッドは、与えられた ファクター における上位 n 件の証券に True を返す フィルタ を作成します。 以下の例はすべての利用可能な証券のうち、日付ごとに終値が上位200位以内に含まれる銘柄に対し True を返すフィルタを作成します。

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

フィルタ を返す ファクター メソッドの一覧は、ここ を参照してください。

フィルタ を返す クラシファイア メソッドの一覧は、ここ を参照してください。

2.16. 売買代金(Dollar Volume)フィルタ

最初の例として、証券の30日間の平均売買代金が10,000,000ドルより大きい場合に True を返すフィルタを作成します。 まず、 30日間の平均売買代金を計算する AverageDollarVolume ファクターを作成します。 import文を使って組込みの AverageDollarVolume ファクターを利用可能にします。

from quantopian.pipeline.factors import AverageDollarVolume

次に、AverageDollarVolumeファクターをインスタンス化します。

dollar_volume = AverageDollarVolume(window_length=30)

AverageDollarVolume はデフォルトで USEquityPricing.closeUSEquityPricing.volume を利用しているため inputs 引数を指定する必要はありません。 さてこれで売買代金ファクターが用意できたので、booleanを使ったフィルタを作成できます。 以下の行で、dollar_volume が10,000,000よりも大きい証券に対して True を返すフィルタを作成します:

high_dollar_volume = (dollar_volume > 10000000)

フィルタの中がどのようになっているか確認するため、前のレッスンで作成したパイプラインにフィルタを追加します。

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
        }
    )

パイプラインを作成・実行すると、各証券に対してフィルタの結果を表すboolean値が入った high_dollar_volume 列が作られます。

result = run_pipeline(make_pipeline(), '2015-05-05', '2015-05-05')
result
high_dollar_volume percent_difference
2015-05-05 00:00:00+00:00 Equity(2 [AA]) True 0.017975
Equity(21 [AAME]) False -0.002325
Equity(24 [AAPL]) True 0.016905
Equity(25 [AA_PR]) False 0.021544
Equity(31 [ABAX]) False -0.019639
Equity(39 [DDC]) False 0.074730
Equity(41 [ARCB]) False 0.007067
Equity(52 [ABM]) False 0.003340
Equity(53 [ABMD]) True -0.024682
Equity(62 [ABT]) True 0.014385
Equity(64 [ABX]) True 0.046963
Equity(66 [AB]) False 0.013488
Equity(67 [ADSK]) True -0.003921
Equity(69 [ACAT]) False -0.007079
Equity(70 [VBF]) False 0.005507
Equity(76 [TAP]) True -0.008759
Equity(84 [ACET]) False -0.056139
Equity(86 [ACG]) False 0.010096
Equity(88 [ACI]) False -0.022089
Equity(100 [IEP]) False 0.011293
Equity(106 [ACU]) False 0.003306
Equity(110 [ACXM]) False -0.029551
Equity(112 [ACY]) False -0.057763
Equity(114 [ADBE]) True 0.009499
Equity(117 [AEY]) False 0.012543
Equity(122 [ADI]) True 0.009271
Equity(128 [ADM]) True 0.015760
Equity(134 [SXCL]) False NaN
Equity(149 [ADX]) False 0.007232
Equity(153 [AE]) False -0.112999
... ... ...
Equity(48961 [NYMT_O]) False NaN
Equity(48962 [CSAL]) True 0.000000
Equity(48963 [PAK]) False 0.000000
Equity(48969 [NSA]) True 0.000000
Equity(48971 [BSM]) True 0.000000
Equity(48972 [EVA]) True 0.000000
Equity(48981 [APIC]) False 0.000000
Equity(48989 [UK]) False 0.000000
Equity(48990 [ACWF]) False 0.000000
Equity(48991 [ISCF]) False 0.000000
Equity(48992 [INTF]) False 0.000000
Equity(48993 [JETS]) False 0.000000
Equity(48994 [ACTX]) False 0.000000
Equity(48995 [LRGF]) False 0.000000
Equity(48996 [SMLF]) False 0.000000
Equity(48997 [VKTX]) False 0.000000
Equity(48998 [OPGN]) False NaN
Equity(48999 [AAPC]) False 0.000000
Equity(49000 [BPMC]) False 0.000000
Equity(49001 [CLCD]) False NaN
Equity(49004 [TNP_PRD]) False 0.000000
Equity(49005 [ARWA_U]) False NaN
Equity(49006 [BVXV]) False NaN
Equity(49007 [BVXV_W]) False NaN
Equity(49008 [OPGN_W]) False NaN
Equity(49009 [PRKU]) False NaN
Equity(49010 [TBRA]) False NaN
Equity(49131 [OESX]) False NaN
Equity(49259 [ITUS]) False NaN
Equity(49523 [TLGT]) False NaN

8236 rows × 2 columns

2.17. スクリーニング

通常、パイプラインはQuantopianのデータベースに存在するすべての資産を対象に、日付ごとに計算結果を出力します。 しかしながら、特定の基準を満たした証券の部分集合だけが必要なケースが頻繁に起こります(例えば、日々の取引が活発で注文が即座に成立するような銘柄のみが必要となることがあります)。 パイプラインの中で screen キーワードを使うと、パイプラインの実行でフィルタが False を返した銘柄をふるい落とすことができます。

出力結果を30日間の平均売買代金が10,000,000ドルよりも大きい証券だけに絞り込むには、screen の引数として high_dollar_volume をあてはめるだけです。 make_pipeline はこのような感じになります:

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
    )

実行すると、パイプラインの出力にはそれぞれの日付において high_dollar_volume フィルタを通過した証券のみが含まれています。 例えばこのパイプラインを2015年5月5日に対して実行した出力結果は、約2,100銘柄程度となります。

(翻訳者注:以下のソースコードはprint文がpython2の文法であるため、python3では通常エラーとなる)

result = run_pipeline(make_pipeline(), '2015-05-05', '2015-05-05')
print 'Number of securities that passed the filter: %d' % len(result)
result
Number of securities that passed the filter: 2110
percent_difference
2015-05-05 00:00:00+00:00 Equity(2 [AA]) 0.017975
Equity(24 [AAPL]) 0.016905
Equity(53 [ABMD]) -0.024682
Equity(62 [ABT]) 0.014385
Equity(64 [ABX]) 0.046963
Equity(67 [ADSK]) -0.003921
Equity(76 [TAP]) -0.008759
Equity(114 [ADBE]) 0.009499
Equity(122 [ADI]) 0.009271
Equity(128 [ADM]) 0.015760
Equity(154 [AEM]) 0.026035
Equity(161 [AEP]) 0.010405
Equity(166 [AES]) 0.022158
Equity(168 [AET]) 0.005853
Equity(185 [AFL]) -0.002239
Equity(197 [AGCO]) 0.032124
Equity(216 [HES]) 0.036528
Equity(239 [AIG]) 0.012322
Equity(253 [AIR]) -0.012412
Equity(266 [AJG]) 0.012267
Equity(270 [AKRX]) -0.024963
Equity(273 [ALU]) -0.021750
Equity(300 [ALK]) 0.015147
Equity(301 [ALKS]) -0.033228
Equity(328 [ALTR]) 0.012284
Equity(337 [AMAT]) -0.050162
Equity(351 [AMD]) -0.101477
Equity(353 [AME]) -0.003008
Equity(357 [TWX]) 0.000365
Equity(368 [AMGN]) 0.008860
... ...
Equity(48126 [HABT]) 0.063080
Equity(48129 [UBS]) 0.025888
Equity(48169 [KLXI]) 0.021062
Equity(48215 [QSR]) 0.037460
Equity(48220 [LC]) -0.035048
Equity(48317 [JUNO]) -0.103370
Equity(48384 [QRVO]) -0.050578
Equity(48465 [SWNC]) 0.061669
Equity(48486 [BOX]) -0.003837
Equity(48531 [VSTO]) 0.017196
Equity(48543 [SHAK]) 0.175877
Equity(48544 [HIFR]) 0.027339
Equity(48547 [ONCE]) -0.112191
Equity(48575 [XHR]) -0.008521
Equity(48629 [INOV]) -0.068366
Equity(48662 [JPM_PRF]) 0.002978
Equity(48672 [TOTL]) 0.000991
Equity(48730 [AGN_PRA]) -0.008843
Equity(48821 [CJES]) 0.099492
Equity(48823 [SEDG]) 0.056643
Equity(48863 [GDDY]) -0.003563
Equity(48892 [IGT]) 0.005591
Equity(48925 [ADRO]) -0.076840
Equity(48933 [PRTY]) -0.001741
Equity(48934 [ETSY]) -0.030142
Equity(48943 [VIRT]) -0.009077
Equity(48962 [CSAL]) 0.000000
Equity(48969 [NSA]) 0.000000
Equity(48971 [BSM]) 0.000000
Equity(48972 [EVA]) 0.000000

2110 rows × 1 columns

2.18. フィルタの反転

~ 演算子はフィルタの反転に使われ、 True 値を False 値に置き換えます(逆もしかり)。 例えば、売買代金の少ない証券にフィルタをかける場合は以下のように書きます:

low_dollar_volume = ~high_dollar_volume

この場合、過去30日間の平均売買代金が10,000,000ドル以下の銘柄に対して True が返ります。

次のレッスンでは、フィルタの結合について見ていきます。