Posted at

Quantopianの基本的な使い方とアルゴリズム例


Quantopianとは

日本のSmartTrade社が提供するサービスQuantXと似た米国のサービス。

Quantopianでは、QuantXと同様に、無料で、金融取引のアルゴリズムの作成、シミュレーションを行うことができる。相違点としては、QuantopianではQuantXではできないショートの取引や、先物の取引ができるなど、Quantopianの方が機能が幅広いことが挙げられる。


実際にQuantopianを使ってみる


まず、Quantopianのページにアクセスし、アカウントを作成する必要がある。

スクリーンショット 2019-01-31 21.22.02.png

上の画像の赤で囲った部分からアカウント作成を行うことができます。


次に実際にアルゴリズムを作成してみたい

ドキュメントは英語で書かれていて少し難解です。(https://www.quantopian.com/help)

以下、僕が理解したことを書いていきたいと思います。実際にアルゴリズム作成の画面で解説していきたいと思います。

スクリーンショット 2019-01-31 21.27.27.png

上記の画面のAlgorithmというところからアルゴリズム作成画面に移ることができます。

それから

スクリーンショット 2019-01-31 21.29.25.png

上記のNewAlgorithmというところからアルゴリズム作成画面に移ることができます。

そうするとデフォルトでテンプレートが貼ってあります。

ここを理解するとあとは、オリジナルにいじることで、一定程度アルゴリズムを作ることができます。


テンプレートのアルゴリズム


template.py

"""

This is a template algorithm on Quantopian for you to adapt and fill in.
"""

import quantopian.algorithm as algo
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.filters import QTradableStocksUS

def initialize(context):
"""
Called once at the start of the algorithm.
"""

# Rebalance every day, 1 hour after market open.
algo.schedule_function(
rebalance,
algo.date_rules.every_day(),
algo.time_rules.market_open(hours=1),
)

# Record tracking variables at the end of each day.
algo.schedule_function(
record_vars,
algo.date_rules.every_day(),
algo.time_rules.market_close(),
)

# Create our dynamic stock selector.
algo.attach_pipeline(make_pipeline(), 'pipeline')

def make_pipeline():
"""
A function to create our dynamic stock selector (pipeline). Documentation
on pipeline can be found here:
https://www.quantopian.com/help#pipeline-title
"""

# Base universe set to the QTradableStocksUS
base_universe = QTradableStocksUS()

# Factor of yesterday's close price.
yesterday_close = USEquityPricing.close.latest

pipe = Pipeline(
columns={
'close': yesterday_close,
},
screen=base_universe
)
return pipe

def before_trading_start(context, data):
"""
Called every day before market open.
"""

context.output = algo.pipeline_output('pipeline')

# These are the securities that we are interested in trading each day.
context.security_list = context.output.index

def rebalance(context, data):
"""
Execute orders according to our schedule_function() timing.
"""

pass

def record_vars(context, data):
"""
Plot variables at the end of each day.
"""

pass

def handle_data(context, data):
"""
Called every minute.
"""

pass



第一段落


template1.py

import quantopian.algorithm as algo

from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.filters import QTradableStocksUS

最初の4行は、Quantopianが提供しているデータ解析ツールやデータセットをimportしています。

1行目アルゴリズムAPI(注文の実行や、スケジュール、変数の管理ができる)

2行目Pipeline API(データの解析ツール、例えば出来高が上位3%の株の抽出などができるツール)

3行目米国株のデータセット

4行目米国株のうち流動性が低くて取引が難しいものなどをとりのぞいたデータです。


第二段落


template2.py

def initialize(context):

"""
Called once at the start of the algorithm.
"""

# Rebalance every day, 1 hour after market open.
algo.schedule_function(
rebalance,
algo.date_rules.every_day(),
algo.time_rules.market_open(hours=1),
)

# Record tracking variables at the end of each day.
algo.schedule_function(
record_vars,
algo.date_rules.every_day(),
algo.time_rules.market_close(),
)

# Create our dynamic stock selector.
algo.attach_pipeline(make_pipeline(), 'pipeline')


initialize()は、アルゴリズムの開始時に動く関数です。

ここでは、不変のパラメータの定義や、アルゴリズムがどのような頻度で動くのかの定義データ分析ツールであるPipelineの適用などを行います。

algo.schedule_function()では、第一引数で定義した関数が動く頻度の定義(第一引数で定義した関数はのちほど定義する)

algo.attach_pipeline()ではpipelineの適用とその名前の定義が行われています。


第三段落


template5.py

def make_pipeline():

"""
A function to create our dynamic stock selector (pipeline). Documentation
on pipeline can be found here:
https://www.quantopian.com/help#pipeline-title
"""

# Base universe set to the QTradableStocksUS
base_universe = QTradableStocksUS()

# Factor of yesterday's close price.
yesterday_close = USEquityPricing.close.latest

pipe = Pipeline(
columns={
'close': yesterday_close,
},
screen=base_universe
)
return pipe


make_pipeline()は、その名の通りPipelineを作る関数です。

ここでは前日の終値を第一段落でimportしたUSEquityPricingから取り出してPipelineのデータとし、第一段落でimportしたQTradeableStockUSをスクリーニングの基準としていましす。

ちなみに、この関数は第一段落でpipelineと名付けられています。


第四段落


template4.py

def before_trading_start(context, data):

"""
Called every day before market open.
"""

context.output = algo.pipeline_output('pipeline')

# These are the securities that we are interested in trading each day.
context.security_list = context.output.index


before_trading_start(context, data)毎日呼び出される関数で、引数はcontextとdataをとります。

そしてこの関数内では、前述のデータ解析ツールであるPipelineの出力や、それに基づいて選定した銘柄をcontext.__という形でcontextオブジェクト**に追加していきます。


第五段落


template5.py

def rebalance(context, data):

"""
Execute orders according to our schedule_function() timing.
"""

pass

ここでは、第二段落algo.schedule_function()の第一引数となっていた関数を定義します。

通常この部分がアルゴリズムの核となる部分で、銘柄の注文の条件注文のアルゴリズムを書き込みます。


第六段落


template6.py

def record_vars(context, data):

"""
Plot variables at the end of each day.
"""

pass

ここでも第五段落と同様に、第二段落algo.schedule_function()の第一引数となっていた関数を定義します。

ただ、こちらは第五段落とは異なり、記録を残すものです。

具体的にはrecord()関数を使って、保持している現金取引に消費した現金第二段落のalgo.schedule_function()で定義した頻度で記録します。


第七段落


template7.py

def handle_data(context, data):

"""
Called every minute.
"""

pass

handle_data(context, data)毎分ベースで呼び出される関数で、第四段落のbefore_tradig_start(context, data)毎分版です。


実際にアルゴリズムを作ってみる

ボリンジャーバンドの実装は簡単なので、ボリンジャーバンドを作ってみたいと思います。

そもそも、ボリンジャーバンドとは、平均値から、kシグマ区間内に収まる確率を用いて、取引する手法です。たとえば、±2シグマ区間に収まる確率は約95%です。今回は、±2シグマ区間を用いたアルゴリズムを作ります。

コード例は以下です。


example1.py

import quantopian.algorithm as algo

from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.filters import QTradableStocksUS

def initialize(context):

# Schedule Rebalance function
algo.schedule_function(
rebalance,
algo.date_rules.every_day(),
algo.time_rules.market_open(hours=1),
)

# Record tracking variables at the end of each day.
algo.schedule_function(
record_vars,
algo.date_rules.every_day(),
algo.time_rules.market_close(),
)

# Create our dynamic stock selector.
algo.attach_pipeline(make_pipeline(), 'pipeline')

def make_pipeline():
"""
A function to create our dynamic stock selector (pipeline). Documentation
on pipeline can be found here:
https://www.quantopian.com/help#pipeline-title
"""

# Base universe set to the QTradableStocksUS
base_universe = QTradableStocksUS()

# Factor of yesterday's close price.
yesterday_close = USEquityPricing.close.latest

pipe = Pipeline(
columns={
'close': yesterday_close,
},
screen=base_universe
)
return pipe

def before_trading_start(context, data):
"""
Called every day before market open.
"""

context.output = algo.pipeline_output('pipeline')

# These are the securities that we are interested in trading each day.
context.security_list = context.output.index

def rebalance(context, data):
"""
Execute orders according to our schedule_function() timing.
"""

current_price=data.current(context.security_list,'price')
history=data.history(context.security_list,'price',21,'1d')
sigma=history[:-1].std()
mean=history[:-1].mean()
uband_1=mean+sigma
upband_2=mean+(sigma*2)
lband_1=mean-sigma
lband_2=mean-(sigma*2)
ratio1=current_price/upband_2
ratio2=lband_2/current_price

short_secs=ratio2.index[ratio2>=1.05]
long_secs=ratio1.index[ratio1>=1.05]

log.info("This week's longs:"+",".join([long_.symbol for long_ in long_secs]))
log.info("This week's shorts:"+",".join([short_.symbol for short_ in short_secs]))
for security in context.security_list:
if data.can_trade(security):
if ratio2[security]>=1.05:
order_target_percent(security,1.0)
if ratio1[security] >=1.05:
order_target_percent(security,0.0)

def record_vars(context, data):
"""
Plot variables at the end of each day.
"""

record(cash=context.portfolio.cash)

def handle_data(context, data):
"""
Called every minute.
"""

pass


上記のコードはとても簡単なもので、テンプレートの第五段落ボリンジャーバンドのアルゴリズムを書き込んだだけのものです。もうひとついじった部分は、第六段落で、ポートフォーリオに残っいる現金の記録を残すようにしています。


このアルゴリズムの要約

データ解析ツールであるPipelineはテンプレートのままいじっていないので、流動性が低いなど取引の難しい銘柄を除いた銘柄のデータセットを、context.securituy_listにしている。

第五段落で、シグマ区間を計算し、対2シグマ区間で前日終値が1.05倍以上であるものを売り、対-2シグマ区間で前日終値が1.05の逆数倍以下のものを買いにしています。最後に第六段落で、ポートフォーリオに残っている現金の記録を残しています。


まとめ

このように、テンプレートの各段落の役割を理解できれば、少しいじるだけで簡単なプログラムを作ることができます。Pipelineの用い方と、アルゴリズムの主要取引関数オリジナリティが生み出せるのではないでしょうか。僕も頑張ってみたいと思います‼️‼️

以上です、ご購読ありがとうございました〜〜〜〜〜〜〜〜‼️