2.7. ファクター

ファクターは、ある資産とある一時点から数値型を返す関数です。

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

パイプラインでは ファクター は最も一般的な用語であり、数値として返される計算結果を表します。 ファクターには入力値として列データと計算区間が必要です。

パイプラインにおける最も単純なファクターは、ビルトイン・ファクター と呼ばれるものです。 ビルトイン・ファクターは、一般的によく使われる計算を実行するために予め用意されています。 最初の例として、資産ごとに10日間の区間を動かしながら終値の平均値段を計算するファクターを作成しましょう。 指定した計算区間(10日間)を対象に入力データ(終値)の平均値を計算する SipleMovingAverate というビルトイン・ファクターを使います。 これを使うためには SimpleMovingAverage ビルトイン・ファクターと、 USEquityPricing dataset をインポートします。

from quantopian.pipeline import Pipeline
from quantopian.research import run_pipeline

# 前回のレッスンに加えて、USEquityPricing datasetをインポート
from quantopian.pipeline.data.builtin import USEquityPricing

# 前回のレッスンに加えて、SimpleMovingAverageビルトイン・ファクターをインポート
from quantopian.pipeline.factors import SimpleMovingAverage

2.8. ファクターの作成

前のレッスンで作成した make_pipeline 関数に戻って、 SimpleMovingAverage ファクターをインスタンス化します。 SimpleMovingAverage の作成には、SimpleMovingAverage にinput( BoundColumn 型のリスト)と、 window_length(移動平均の計算が受け取るデータ日数を表す整数値)という2つの引数を渡してコンストラクタを呼び出します。 ( BoundColumn については後ほど詳細に触れます。今の段階では、 BoundColumn がファクターを作成する上で必要な必要なものであるということだけ知っていれば十分です。)

以下の一行で、証券の10日間移動平均を計算する ファクター が出来上がります。

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

ここで重要なのは、ファクターの作成段階では、実際には計算を実行していないという点です。ファクターの作成は、関数を定義するのに似ています。 計算を実行するためには、ファクターをパイプラインに追加して、実行する必要があります。

2.9. ファクターをパイプラインに追加する

元となる空のパイプラインを、移動平均を計算するファクターにアップデートさせましょう。 まず始めに、ファクターのインスタンス化を make_pipeline 内に移動させます。 次に、columns (列名に対してファクター、フィルタ、あるいはクラシファイアを紐づける辞書型)引数を通じて、パイプラインにファクターの計算を指示します。 アップデートされた make_pipline 関数は、このような感じになるはずです。

def make_pipeline():

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

    return Pipeline(
        columns={
            '10_day_mean_close': mean_close_10
        }
    )

中身がどのようになっているかを確認するため、パイプラインを実行して結果を表示させます。

result = run_pipeline(make_pipeline(), '2015-05-05', '2015-05-05')
result
10_day_mean_close
2015-05-05 00:00:00+00:00 Equity(2 [AA]) 13.559500
Equity(21 [AAME]) 3.962500
Equity(24 [AAPL]) 129.025700
Equity(25 [AA_PR]) 88.362500
Equity(31 [ABAX]) 61.920900
Equity(39 [DDC]) 19.287072
Equity(41 [ARCB]) 37.880000
Equity(52 [ABM]) 32.083400
Equity(53 [ABMD]) 66.795000
Equity(62 [ABT]) 47.466000
Equity(64 [ABX]) 12.919000
Equity(66 [AB]) 31.547000
Equity(67 [ADSK]) 60.212000
Equity(69 [ACAT]) 36.331000
Equity(70 [VBF]) 18.767000
Equity(76 [TAP]) 74.632000
Equity(84 [ACET]) 19.873000
Equity(86 [ACG]) 7.810000
Equity(88 [ACI]) 0.996100
Equity(100 [IEP]) 91.821200
Equity(106 [ACU]) 18.641000
Equity(110 [ACXM]) 18.045500
Equity(112 [ACY]) 11.571000
Equity(114 [ADBE]) 76.072000
Equity(117 [AEY]) 2.423400
Equity(122 [ADI]) 63.205900
Equity(128 [ADM]) 48.788500
Equity(134 [SXCL]) NaN
Equity(149 [ADX]) 14.150500
Equity(153 [AE]) 54.099000
... ...
Equity(48961 [NYMT_O]) NaN
Equity(48962 [CSAL]) 29.992000
Equity(48963 [PAK]) 15.531875
Equity(48969 [NSA]) 13.045000
Equity(48971 [BSM]) 17.995000
Equity(48972 [EVA]) 21.413250
Equity(48981 [APIC]) 14.814000
Equity(48989 [UK]) 24.946667
Equity(48990 [ACWF]) 25.250000
Equity(48991 [ISCF]) 24.985000
Equity(48992 [INTF]) 25.030000
Equity(48993 [JETS]) 24.579333
Equity(48994 [ACTX]) 15.097333
Equity(48995 [LRGF]) 24.890000
Equity(48996 [SMLF]) 29.456667
Equity(48997 [VKTX]) 9.115000
Equity(48998 [OPGN]) NaN
Equity(48999 [AAPC]) 10.144000
Equity(49000 [BPMC]) 20.810000
Equity(49001 [CLCD]) NaN
Equity(49004 [TNP_PRD]) 24.750000
Equity(49005 [ARWA_U]) NaN
Equity(49006 [BVXV]) NaN
Equity(49007 [BVXV_W]) NaN
Equity(49008 [OPGN_W]) NaN
Equity(49009 [PRKU]) NaN
Equity(49010 [TBRA]) NaN
Equity(49131 [OESX]) NaN
Equity(49259 [ITUS]) NaN
Equity(49523 [TLGT]) NaN

8236 rows × 1 columns

これでパイプラインの出力に、8000超の全銘柄(画面上は途中まで)に対して計算された10日間終値移動平均の列が追加されました。 各行は、該当する証券と該当する日付における計算結果に対応しています。 この DataFrame は、 マルチインデックス (第1レベルは計算を行った日付を表す日時、第2レベルは証券に対応する Equity オブジェクト) を持っています。 例えば1行目(2015-05-05 00:00:00+00:00, Equity(2 [AA]))には、2015年5月5日のAA (訳者注:AAはアルコア社(アルミニウム、アルミニウム製品およびアルミナの世界的なメーカー)を表す証券コード) の mean_close_10 ファクターの計算結果が格納されます。

もし1日よりも長い期間パイプラインを実行すれば、その結果はこのようになります。

result = run_pipeline(make_pipeline(), '2015-05-05', '2015-05-07')
result
10_day_mean_close
2015-05-05 00:00:00+00:00 Equity(2 [AA]) 13.559500
Equity(21 [AAME]) 3.962500
Equity(24 [AAPL]) 129.025700
Equity(25 [AA_PR]) 88.362500
Equity(31 [ABAX]) 61.920900
Equity(39 [DDC]) 19.287072
Equity(41 [ARCB]) 37.880000
Equity(52 [ABM]) 32.083400
Equity(53 [ABMD]) 66.795000
Equity(62 [ABT]) 47.466000
Equity(64 [ABX]) 12.919000
Equity(66 [AB]) 31.547000
Equity(67 [ADSK]) 60.212000
Equity(69 [ACAT]) 36.331000
Equity(70 [VBF]) 18.767000
Equity(76 [TAP]) 74.632000
Equity(84 [ACET]) 19.873000
Equity(86 [ACG]) 7.810000
Equity(88 [ACI]) 0.996100
Equity(100 [IEP]) 91.821200
Equity(106 [ACU]) 18.641000
Equity(110 [ACXM]) 18.045500
Equity(112 [ACY]) 11.571000
Equity(114 [ADBE]) 76.072000
Equity(117 [AEY]) 2.423400
Equity(122 [ADI]) 63.205900
Equity(128 [ADM]) 48.788500
Equity(134 [SXCL]) NaN
Equity(149 [ADX]) 14.150500
Equity(153 [AE]) 54.099000
... ... ...
2015-05-07 00:00:00+00:00 Equity(48981 [APIC]) 14.646000
Equity(48989 [UK]) 24.878000
Equity(48990 [ACWF]) 25.036667
Equity(48991 [ISCF]) 24.875000
Equity(48992 [INTF]) 24.813000
Equity(48993 [JETS]) 24.343600
Equity(48994 [ACTX]) 15.020400
Equity(48995 [LRGF]) 24.788000
Equity(48996 [SMLF]) 29.370000
Equity(48997 [VKTX]) 9.232500
Equity(48998 [OPGN]) 4.950000
Equity(48999 [AAPC]) 10.167000
Equity(49000 [BPMC]) 20.906667
Equity(49001 [CLCD]) 8.010000
Equity(49004 [TNP_PRD]) 24.633333
Equity(49005 [ARWA_U]) 10.010000
Equity(49006 [BVXV]) NaN
Equity(49007 [BVXV_W]) NaN
Equity(49008 [OPGN_W]) 0.817500
Equity(49009 [PRKU]) NaN
Equity(49010 [TBRA]) NaN
Equity(49015 [ADAP]) NaN
Equity(49016 [COLL]) NaN
Equity(49017 [GLSS]) NaN
Equity(49018 [HTGM]) NaN
Equity(49019 [LRET]) NaN
Equity(49020 [MVIR]) NaN
Equity(49131 [OESX]) NaN
Equity(49259 [ITUS]) NaN
Equity(49523 [TLGT]) NaN

24705 rows × 1 columns

備考:Pipeline.add メソッドを用いることでも同様に Pipeline インスタンスに対してファクターを追加できます。 add を使う場合はこのような感じになります:>>> my_pipe = Pipeline() >>> f1 = SomeFactor(…) >>> my_pipe.add(f1, ‘f1’)

2.10. Latest

最もよく使われるビルトイン Factor は、 Latest です。 Latest ファクターは、与えられたデータ列中で最も直近の値を取得します。 このファクターは非常によく使われるので、他のファクターとは異なる方法でインスタンス化されます。 データ列から直近の値を取得するには、 .latest アトリビュートから取得するのが最良の方法です。 例として make_pipeline をアップデートして直近終値を取得するファクターを作成してパイプラインに追加してみましょう。

def make_pipeline():

    mean_close_10 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=10)
    latest_close = USEquityPricing.close.latest

    return Pipeline(
        columns={
            '10_day_mean_close': mean_close_10,
            'latest_close_price': latest_close
        }
    )

ここで再びパイプラインを作成し実行すると、出力されたdataframeには2つの列ができます。 一方は10日間終値移動平均の列で、もう一方は直近の終値の列になっています。

result = run_pipeline(make_pipeline(), '2015-05-05', '2015-05-05')
result.head(5)
10_day_mean_close latest_close_price
2015-05-05 00:00:00+00:00 Equity(2 [AA]) 13.5595 14.015
Equity(21 [AAME]) 3.9625 NaN
Equity(24 [AAPL]) 129.0257 128.699
Equity(25 [AA_PR]) 88.3625 NaN
Equity(31 [ABAX]) 61.9209 55.030

.latestファクター 以外のものを返すことがあります(訳者注:latest_close_priceに数値ではないNaNを含む)。 これ以外の起こり得る返り値の型については後ほどみていきます。

2.11. デフォルト入力

いくつかのファクターは、変更すべきでないデフォルト入力があります。たとえば VWAP ビルトイン・ファクター は常に USEquityPricing.closeUSEquityPricing.volume から計算されます。ファクターが常に同じ BoundColumns から計算される場合、 input 引数を明示せずにコンストラクタを呼び出せます。

from quantopian.pipeline.factors import VWAP
vwap = VWAP(window_length=10)

次のレッスンでは、ファクターの結合を見ていきます。