LoginSignup
9
8

More than 5 years have passed since last update.

Quantopian Writing a Contest Algorithm 翻訳

Last updated at Posted at 2018-11-29

こんにちは.しんせいたろうです.
今年はQuantopianヤクザになりたいと思っていたんですが,なれませんでした.

でも何かを残さないと行けないと思い,

Quantopian Tutorialsを意訳してみたいと思います.

メモ

  • 訳をしながら?と思ったところは,原文のママにしています.実際のコンテストに応募しますので,その途中で理解出来た時に書き直します.
  • また,補足が必要なところは(訳者注)として補足しています.
  • 文中に出てくる allocation とは,Quantopianが良いアルゴリズムを自分達のFundに組み入れることを意味しています.彼らはコンテスト上位者のアルゴリズムを借りて自社のファンドに組入れ運用しています.詳しくはこちらを参照してください.
  • 訂正,質問,なんでも歓迎です.宜しくお願いします.
  • 最新更新日: 2018/11/29

このチュートリアルは,

  • Quantopian Contest をの概要とコンテストの仕組み(lesson 1)
  • コンテストの基準の説明(lessons 2-10) (訳者注;アルゴリズムに守らなくてはいけないルールがあり,そのルールにしたがっていないストラテジは応募不可)
  • 基準をクリアするためにはどのようにアルゴリズムを書きなおせばいいのか(lessons 2-10)
  • 基準を満たしているかテストする方法(Lesson10)

を含みます.

しかし,

  • Quantopianでどのようにリサーチして,ストラテジーに埋め込むか

は説明しません.その目的の方はQuantopian Tutorialsを参照してください.

LESSON 1 Introduction

Contest Overview (コンテスト概要)

本コンテストは,Quantopianを使って記述された数量分析的取引アルゴリズムを毎日評価し,上位アルゴリズムには賞金を与えるコンテストです.コンテストは,クロスセクション,ロングショートストラテジーを評価する目的で作られています.参加するアルゴリズムはいくつかの基準にしたがっていなくてはいけません.このチュートリアルで,満たさなくては行けない基準の説明と,どのようにしたら満たせるようになるかを簡単に説明します.

Criteria 基準

参加するアルゴリズムは,以下の基準を満たさなくてはいけません.この基準は,多業種の銘柄を対象に,Long Shortストラテジであることをベースにすえ,Quantopian の allocation process に沿った形で行われます.

  • 儲かっていること
  • レバレッジは0.8〜1.1倍以内であること
  • 特定の銘柄に偏っていないこと
  • SPYに対して低いベータであること
  • Turnover が63日移動平均で5%〜65%の間にあること.(訳者注;Turnoverについては後述)
  • ロングショート戦略であること
  • 流動性が十分ある銘柄を取引すること
  • 偏ったセクターに対してのみ投資をしないこと.
  • スタイルファクターに対して,低いリスクであること.(訳者注:style factor:Quantopianが定義しているマーケットリスクファクター)
  • Optimize APIを使って注文をだすこと

基準の詳細はQuantopian Contest Rulesを参照してください.

Lesson11で,あなたが書いたアルゴリズムが基準をクリアできているかどうか確認する方法を載せています.今すぐ試したい人はそちらへどうぞ.

アルゴリズムを応募する

コンテストに参加するには,full backtest を実行したあと,Enter Contest を押すだけです.応募されたアルゴリズムは,直近二年間のデータを使って,上記すべての基準を満たしているかどうかテストされます.テストをパスすると,翌日から毎日評価され,ランキングされます.上位に入ればリーダーボードに掲載されます.テストに不合格の場合は,不合格通知と,どの基準で落ちたかのお知らせがEmailで届きます.

スコアとランキング

コンテストのテストに合格したアルゴリズムは,毎営業日(米のマーケットが開いている日),スコアリングされ,ランキングされます.
スコアは日々の収益とボラティリティで評価されます.収益が高く,ボラティリティが低いアルゴリズムが高いスコアを与えられます.

アルゴリズムのスコアはVADRsと呼ばれるスコアの合計値です.計算式は以下の通りです.

(訳者注:VADRsに関しては, Quantopian Contest RulesScoring and Ranking を確認して下さい.)

毎営業日,取引終了後,参加アルゴリズムは評価され,トップ10には賞金が授与されます.
Lesson1では,コンテストの概要と,アルゴリズム基準,その評価方法簡単に学びました.このあとは,コンテスト基準の満たし方について説明します.

LESSON 2

Order with Optimize API (Optimize APIで注文)

注文はorder_optimal_portfolioを必ず使わなくてはいけません.他のオーダー関数は使用不可です.

order_optimal_portfolio がOptimize APIのコア関数です.

Why?

order_optimal_portfolio 関数は,Quantopianがライブトレーディングで使っている唯一のオーダー関数です.
(訳者注:Quantopianはファンドを運用しています).
コミュニティにもアルゴリズムを作るときに最初からOptimize API を使うように奨励しています.

この基準を満たすには?

order_optimal_portfolio 関数の基本的な使い方は,Lesson 7 of the Getting Started tutorialにあります.
コンテストでは, order_optimal_portfolio 関数を使って,ポートフォリオをリバランスすることがルールです.

Lesson7以外にも,order_optimal_portfolio 関数を使ったアルゴリズムのチュートリアルがありますのでご参照ください.

order_optimal_portfolio 関数ドキュメンテーションは,こちら,チュートリアルノートブックはこちらを参照してください.

LESSON 3

Liquid Universe (流動性を確保したユニバース)

アルゴリズムは必ず,QTradableStocksUS に入っている銘柄から選ばなくてはいけません.(QTradableStocksUS,略;QTU)

(訳者注:Quantopianで取り扱う事ができる銘柄は,アメリカ市場に上場している全銘柄です.しかしコンテストでは,全銘柄を対象にせず彼らが選んだ銘柄ユニバースである QTradableStocksUS を使うことが求められます.)

Why?

ユニバース(訳者注;ユニバースとは,対象とする株式銘柄群のこと.最初に銘柄群を作成し,そこから何らかのフィルターにかけて,投資すべき銘柄を選ぶ)はストラテジーの根幹です.

ユニバースは,銘柄数がより大きい方がよいのですが,投資対象プラットフォームとして適当であるべきでもあります.Quantopianにとって,ユニバースとは,自社のリスクマネジメント方法でもある,複数のアルゴリズムを使ったポートフォリオを形成できる銘柄群であること,なおかつ取引コストを許容できる範囲に収めることができる銘柄群であることです.

QTradableStocksUS はその要件を満たす最大のユニバースです.

この基準を満たすには?

QTradableStocksUS をパイプラインで使い,フィルターをかけて銘柄を選出してください.パイプラインについては,こちらをご覧ください.もし,個別銘柄を取引したい場合は,それが,QTUに入っているかどうかを確かめてから, order_optimal_portfolioで注文することになります.

QTradableStocksUS をパイプラインで使ってスクリーニングするにはこのようなコードを書きます.

from quantopian.pipeline import Pipeline
from quantopian.pipeline.experimental import QTradableStocksUS

def make_pipeline():

    return Pipeline(
        columns={
            # Your pipeline columns go here.
        },
        screen=QTradableStocksUS()
    )

メモ:スクリーニング方法はいくつかあります.上記のように screen オプションに渡したり, mask オプションに渡したりします.詳しくは Pipeline tutorialを参照してください.

その他,QTradableStocksUS の使い方は,以下を参照してください.

LESSON 4

Position Concentration (投資比率制約)

アルゴリズムは,一つの銘柄に資金の5%以上を投資しては行けません.

Why?

一つの銘柄に対して過度に投資することは,アルゴリズムをポジションリスクに晒す事になります.もし,価格変化の大きい一つの銘柄に資金の大部分を投資した場合,ポートフォリオの価値も大きく変化します.たくさんの銘柄を少しずつ持つ事で,大きなドローダウンに晒されるリスクを軽減します.

この基準を満たすには?

order_optimal_portfolio で注文を出す時,PositionConcentration で制約条件を付加します.例えば,各銘柄に投資する資金を1%未満にしたい場合は,

import quantopian.algorithm as algo
import quantopian.optimize as opt

MAX_SHORT_POSITION_SIZE = 0.01  # 1%
MAX_LONG_POSITION_SIZE = 0.01   # 1%

# ポジション制約を定義
constrain_pos_size = opt.PositionConcentration.with_equal_bounds(
    -MAX_SHORT_POSITION_SIZE,
    MAX_LONG_POSITION_SIZE,
)

# 定義をorder_optimal_portfolioに渡す
algo.order_optimal_portfolio(
    objective=my_objective, #Fill in with your objective function.
    constraints=[
        constrain_pos_size,
    ],
)

アルゴリズムが,価格変動によって一時的に偏った銘柄に投資する可能性は有りえます.それを加味して,大きくても5%のリミットをかけておくのがよいでしょう.

PositionConcentration の使い方の例はこちらも参照してください.

LESSON 5

Long/Short (ロングショート戦略)

アルゴリズムは,10%以下の net dollar exposureでなくてはいけません.つまり,買いポジションと売りポジションの差額がトータル資金に対して10%以上になってはいけません.もし満額投資していた場合,買い,売りどちらのポジションも,資金に対して55%以上の投資を行ってはいけません.

Why?

クロスセクション,ロングショート戦略は,ユニバースに含まれる銘柄それぞれの期待値に対して投資する方法です.
たとえば,銘柄Aに10%の値上がり,銘柄Bに5%の値上がりを見込んでいる時,クロスセクション戦略を取っている場合,Aをロングし,Bをショートするでしょう.というのも,AはBに対してより値上がりすると期待しているからです.
結果,クロスセクション,ロングショートストラテジーは必ず,ロングだけもしくはショートだけの戦略にはなりえません.今回のコンテストは,このような戦略のアルゴリズムを対象としているため,ロングとショートの投資バランスを決める必要があります.
クロスセクション,ロングショートストラテジーに関する学習は,こちらのレクチャーを参照してください.(訳者注;リンクが貼ってなかったので,どちらのレクチャーか不明)

この基準を満たすには?

order_optimal_portfolio で注文する時,DollarNeutral で制約条件を付加します.

DollarNeutral の使用例:

import quantopian.algorithm as algo
import quantopian.optimize as opt

# Define the dollar neutral constraint.
dollar_neutral = opt.DollarNeutral()

# Supply the constraint to order_optimal_portfolio.
algo.order_optimal_portfolio(
    objective=my_objective, #Fill in with your objective function.
    constraints=[
        dollar_neutral,
    ],
)

DollarNeutral 制約を付けても,ロングショートを持つポートフォリオの価値は,サイズに多少の幅が出ます.これは,ポートフォリオ内の銘柄の価格変動によって生じます.たとえば,買いポジションのすべてが値上がりし,売りポジションの価格が変わらなかった場合,ロング側の価値が上がります.投資銘柄に偏りが無く,(少なくとも2週間に一度以上の)リバランスを行っている限り,DollarNeutral 制約は,コンテストの制約である10%以下をキープするはずです.

その他の DollarNeutral の使用例はこちらを参照してください.

LESSON 6

Turnover 投資資金とポートフォリオ価値の比率

Quantopianが定義するTurnoverとは,

一日の投資資金の絶対値 / トータルのポートフォリオ価値

アルゴリズムのTurnoverは,63日営業日移動平均で5%〜65%でなくてはいけません.Turnoverの一日の最大値は0%〜200%です.

訳者注: 例えば,全資金をAAPLに投資していたとします.ある日それを全部処分し,同時にFBに全資金を投資したとすると.100%の売りと100%の買いを同日に行ったことになるので,200%という数字がでます.

Turnoverに関しては,Forumに投稿された,What is the "turnover"をご覧下さい.もしくは,turnoverを算出しているソースdef get_turnover()のドキュメント部分を参照して下さい.

Why?

下限が5%の理由は,より活発な取引回数を促すためです.
少ない取引回数は,アルゴリズムの評価期間を長引かせます.(訳者注:滅多に起こらないシグナルを評価するには長い評価期間が必要だということ.)
取引機会が多いと,比較的早く取引サンプルを集める事ができます.
現在,Quantopianのリスクモデルは,保有期間が2-3日以内のアルゴリズムをサポートしていません.というのも,日中に大きな取引ボリュームのあるアルゴリズムをリスクモデルが正しく評価できないからです.
大きなTurnoverは,取引コストが大きくなりがちですので,その意味でも避けるべきです.

この基準を満たすには?

turnoverを決める方法は2つあります.アルファシグナルのボラティリティと取引頻度です.

アルファシグナルのボラティリティは,リサーチ段階でAlphalensを使って分析してください.コンテストの基準を満たすためには,3〜40日の期間でテストしてみるとよいでしょう.

次にリバランススケジュールでコントロールします.

コンテストでは,schedule_function を使って,日次もしくは週次ベースで取引することが求められます.アルゴリズムを作成する時に,色々な取引頻度で試し,バックテストでturnoverを確認しましょう.その時に Pyfolio を使います.

日次ベースでリバランスをするスケジュールの例:

def initialize(context):
    # 毎日オープン後45分後にリバランスをする
    schedule_function(
        func=my_rebalance,  
        date_rule=date_rules.every_day(),  
        time_rule=time_rules.market_open(hours=0,minutes=45)
    )

def my_rebalance(context, data):

その他 turnover 制約に関してはこちらを参照してください.

LESSON 7

Leverage (レバレッジ)

資金に対して投資比率は,毎日 0.8x-1.1x 以内です.つまり常にアルゴリズムは想定資本の80%〜110%を投資していなくてはいけないということになります.
たとえば,1000万ドルの資金を持っていたとして,500万ドルの買いポジション,500万ドルの売りポジションを持っている場合は,レバレッジは1x(100%投資)になり,コンテストの条件を満たしている事になります.

Why?

上限は,コンテストに参加しているアルゴリズムを平等に評価するための正規化手順として指定しています.下限は,アルゴリズムは毎日必ず何らかのアセットに投資していなくてはいけない状態を作るために指定しています.allocation process に基づいた条件です.

レバレッジは,一日の終にチェックされます.つまりアルゴリズムはオーバーナイトでポジションを保有していなくてはいけません.これは,現在のQuantopianリスクモデルが,マーケットのクローズ時から翌日のクローズ時に保有しているポジションに対してリスクを計測するように設計されているからです.

この基準を満たすには?

レバレッジの最大量をコントロールするためには,order_optimal_portfolioMaxGrossExposure で制限条件を付加します.以下の例は,レバレッジを 1x に保つように制限を掛けた例です.

import quantopian.algorithm as algo
import quantopian.optimize as opt

MAX_GROSS_LEVERAGE = 1.0  # 1x

# Define the max leverage constraint.
constrain_gross_leverage = opt.MaxGrossExposure(MAX_GROSS_LEVERAGE)

# Supply the constraint to order_optimal_portfolio.
algo.order_optimal_portfolio(
    objective=my_objective, #Fill in with your objective function.
    constraints=[
        constrain_gross_leverage,
    ],
)

MaxGrossExposure をつけた場合でも,いくつかの理由で,指定したレバレッジの最大値を超えてしまうこともあります.コンテストの 1.1x は,時折1xを超えてしまっても,コンテスト失格にならないように,バッファをもたせるためです.レバレッジの変動は,複数の銘柄を保有することで押さえることができます.

レバレッジの下限を満たすには, order_optimal_portfolio に,objective関数を,多数の銘柄セットとともに渡します.上限とは違い,下限は制限条件を渡すだけではコントロールできません.少なくとも100以上の銘柄セットとともに objective 関数を渡すことで, Optimize API が制約条件にあった銘柄を探せるようにしておくべきです.

レバレッジ制約に関するその他の例は,こちらを参照してください.

LESSON 8

Beta-to-SPY (SPYにたいするβ)

アルゴリズムとマーケットとの相関を低く保たなくてはいけません.
具体的には,SPYに対してベータ値は0.3以下でなくては行けません.

Why?

allocation の観点から,アルゴリズムはマーケットリスクに大きく晒されてはいけません.マーケットに相関がある場合,マーケット指標を買えばよいと言うことになります.コンテストではマーケットニュートラルであるアルゴリズムが求められます.

この基準を満たすには?

マーケットニュートラルな戦略を取るには,まず,アルファがマーケットに相関していてはいけません.全期間において,アルファファクターは,マーケットと関係ない動きをしなくてはいけません.
アルファがマーケットニュートラルであれば,そのアルファを使って導き出したウェイトを MaximizeAlphaで使うことができます.

その他の方法は,銘柄毎のSPYに対するベータをヒストリカルデータから取得し,FactorExposure 制約を作り,order_optimal_portfolio に 渡すという方法もあります.
しかしこの方法は,各銘柄のSPYにたいするベータ値がポートフォリオ全体のベータ値を予測するもの,という仮定に基づいた方法です.これはどんなアルゴリズムにも当てはまるわけではありません.特定の戦略においては上手くいかないケースがありえます.

以下は,FactorExposure を使った例です.

import quantopian.algorithm as algo
import quantopian.optimize as opt

from quantopian.pipeline import Pipeline
from quantopian.pipeline.factors import SimpleBeta

def initialize(context):
    # パイプラインにSPY to Beta を定義
    beta = SimpleBeta(
                    target=sid(8554),# 8554=SPYのID
                    regression_length=260, # 過去260日(1年)分のベータ値をみる
                    )

    pipe = Pipeline(
        columns={
            'beta': beta,
        },
        screen=beta.notnull(),
    )
    algo.attach_pipeline(pipe, 'pipe')

def before_trading_start(context, data):
    # 毎日算出
    context.pipeline_data = algo.pipeline_output('pipe')

def do_portfolio_construction(context, data):
    pipeline_data = context.pipeline_data

    # ヒストリカルにみて,-0.05〜+0.05のベータ値を取得した銘柄だけにするためのフィルター
    beta_neutral = opt.FactorExposure(
        pipeline_data[['beta']],
        min_exposures={'beta': -0.05},
        max_exposures={'beta': 0.05},
    )

    # 制約を渡す
    algo.order_optimal_portfolio(
        objective=my_objective, #Fill in with your objective function.
        constraints=[
            beta_neutral,
        ],
    )

その他の,ベータニュートラルの例はこちらを参照して下さい.

LESSON 9

Risk Model Exposure (リスクモデルエクスポージャ)

Quantopian risk model で定義している通り,アルゴリズムはどのセクターにも20%以上の資金を投資をしてはいけません.リスクモデルでは,11業種を定義しています.

Basic Materials / Technology / Real Estate / Energy / Communication Services / Health Care / Financial Services / Consumer Cyclical / Industrials / Consumer Defensive / Utilities

また,スタイルファクターという独自定義があり,各スタイルファクターは±40%を超えてはいけません.
スタイルファクターは5つあります.

Size / Value / Momentum / Short-Term Reversal / Volatility

リスクファクターは,63日移動平均のネットエクスポージャで計算されます.各セクターに対して毎日-20%から+20%のエクポージャーでなくてはいけません.同様に,スタイルファクターは-40%から40%のエクスポージャーでなくてはいけません.
この範囲になければ,コンテストには参加できません.

Why?

リスクモデルは,マーケットに対するQuantopianの考え方を「成文化」したものです.
リスクモデルは,Quantopian’s investor clients が特定のリスクエクポージャー明らかにしたいという望みを形にしたものです.
コンテストの目的の一つは,Allocationにふさわしいアルゴリズム構築の奨励です.
リスクモデルで定義されたファクターに対してエクスポージャーが低い状態を維持するアルゴリズムを書くことで,Quantopianの allocation プロセスに沿ったアルゴリズムを書くことができます.

この基準を満たすには?

ふた通り方法があります.ひとつは,アルファを,セクターもしくはスタイルファクターに対して独立であるように構築する方法です.
これはリサーチで分析しながら構築します.

もうひとつは,order_optimal_portfolioに制約条件を渡す方法です.risk_loading_pipelineを使って各銘柄のヒストリカルリスクファクターを取得できます.それを使って RiskModelExposure で制限を作成し,order_optimal_portfolioに渡します.

以下は,セクターに18%,スタイルファクターに36%のエクポージャーリミットを付けた例です.

import quantopian.algorithm as algo
import quantopian.optimize as opt

from quantopian.pipeline.experimental import risk_loading_pipeline  

def initialize(context):
    # Attach the risk loading pipeline to our algorithm.
    algo.attach_pipeline(risk_loading_pipeline(), 'risk_loading_pipeline')

def before_trading_start(context, data):
    # Get the risk loading data every day.
    context.risk_loading_pipeline = pipeline_output('risk_loading_pipeline')

def place_orders(context, data):  
    # Constrain our risk exposures. We're using version 0 of the default bounds
    # which constrain our portfolio to 18% exposure to each sector and 36% to
    # each style factor.
    constrain_sector_style_risk = opt.experimental.RiskModelExposure(  
        risk_model_loadings=context.risk_loading_pipeline,  
        version=0,
    )

    # Supply the constraint to order_optimal_portfolio.
    algo.order_optimal_portfolio(  
        objective=my_objective,  #Fill in with your objective function.
        constraints=[constrain_sector_style_risk],  
    )

コンテストが課した制約は20%と40%なのですが,ヒストリカルデータを使って算出した制約条件を出しているため,バッファを持たせて18%と36%にしています.

各リスクエクスポージャーの動きは様々です.例えば,銘柄のセクターエクスポージャはいくつかのスタイルファクターほど変化はしません. 14日移動期間で算出されるshort-term reversal risk factorが最も激しく変動します.

もし, short-term reversal risk factorのコントロールが上手く行かない場合は,ヒストリカルエクスポージャを36%にデフォルトで制限してみてもいいでしょう.
これを行うには,order_optimal_portfolio にこのように渡します.

constrain_sector_style_risk = opt.experimental.RiskModelExposure(  
    risk_model_loadings=context.risk_loading_pipeline,  
    version=0,  
    min_momentum=-0.1,  
    max_momentum=0.1,  
)

RiskModelExposureversion を上記のように特定してしまう事もできます.(version=0)もしくは,version=opt.Newest とセットすれば,最新のバージョンを使うようになります.
コンテストでは,特定のバージョンを選ぶことが求められます.

リスクエクスポージャーに関するその他の例はこちらを参照して下さい.

LESSON 10

Positive Returns

アルゴリズムは収益を出していなくてはいけません.収益はコンテストに参加した当日からチェックされます.収益は直近2年間計算されます.収益は0以上でなくては,コンテストでアクティブステイタスにはなれません.

Why?

継続的に収益を上げるアルゴリズムに allocation を与えようとしているからです.

この基準を満たすには?

アルファを持つストラテジーを書くことですが,なかなか見つからない場合は,フォーラムレクチャーでアイデアを探したり,リサーチしたりして下さい.

LESSON 11

Testing If Your Algorithm Meets the Criteria (基準をパスするかをテストする)

コンテストに応募する前に,あなたのアルゴリズムがコンテスト基準を満たすかどうかテストできます.直近2年のフルバックテストを実行し,BACKTEST_IDを取得します.IDはURLの一番最後の部分です.

https://www.quantopian.com/algorithms/ALGORITHM_ID/BACKTEST_ID

そして,このNotebookをクローンして,BACKTEST_IDを書き換え実行して下さい.すると,このような実行結果がみれます.

全部のテストに PASS したら,コンテストに応募できます!

Happy coding !

9
8
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8