本日、QuantXの新エンジン maron-0.1.0 のβ版をリリースしましたのでお知らせします。主な変更点は次の通りです。
- 空売り対応機能を追加
- 指値注文の拡張
- 日計り注文方式を追加
- シグナル生成関数の仕様変更
- positionsオブジェクトの仕様変更
- 各種ライブラリを更新
空売り対応機能
QuantXのエンジンが空売りに対応しました。一部のETF銘柄ではインバース型の銘柄が存在しており間接的に空売りのような取引が可能でしたが、今回の対応で全個別銘柄に拡張されます。
空売り対応されたことで、市場全体が下げ相場であるときも利益を出す取引が可能となったり、マーケットニュートラルな運用を実現することが可能となり、様々な収益機会を狙うことが可能となります。
アルゴリズムの実装においては、保有株数が0のときに、売却(負の購入)を行うと空売り扱いとなります。
保有するポジション数を超える反対注文は、いわゆるドテン注文として扱われ、次のような挙動となります。
100株を保有しているときに、-200株の注文を行うと、100株の売却と100株の空売りを行い、最終的には、-100株のポジションとなります。
一般的に証券会社毎に空売り可能銘柄は異なりますが、QuantXにおいてはすべての銘柄で空売りが有効となっています。開発者におきましては、そのような仕様を想定した上で組入銘柄を選定いただければと思います。
指値注文の拡張
QuantXでは、指値に対応していましたが、逆指値と引け指値に対応しました。
指値とは、ザラ場において指定された価格以上/以下であるときに執行される取引条件です。購入と売却で挙動が異なり、指定価格よりも有利な価格であるときに執行されます。(maron-0.0.5より対応しています)
逆指値とは、指値とは逆の挙動で、指定価格よりも不利な価格であるときに執行されます。逆指値をうまく利用することで、リスクをコントロールすることが可能です。アルゴリズムの実装においては、order_typeとして、maron.OrderType.STOP_LIMIT を指定します。
引け指値とは、指値/逆指値が執行されなかったときに、引け時に有効となる取引条件です。引け指値は、引け価格において指値/逆指値の条件を指定することが可能です。指値で取引が行われなかった時に、より緩い条件を指定することで、機会損失を最小限に抑えることを可能にします。
アルゴリズムの実装においては、注文時にlimit_price_on_close/stop_limit_price_on_closeで価格を指定します。order_typeが、OrderType.LIMITかOrderType.STOP_LIMITのときのみ指定可能です。
# 指値130円以下のときに購入する # 執行されなかったとき(130円以下にならなかったとき)は、 # 引け値が150円以下である場合には購入する sec = ctx.getSecurity(sym) sec.order(1 * sec.unit(), order_type=maron.OrderType.LIMIT, limit_price=130, limit_price_on_close=150, comment="entry")
QuantXでは、翌営業日のシグナルを生成するため、執行までにタイムラグが存在します。市場の予測不可能な値動きに対応するためにも、指値/逆指値注文を用いて、執行価格に制限を設けることをおすすめします。
日計り注文方式に対応
QuantXのシグナルは、翌営業日に注文し、翌々営業日以降にポジションを解消する等の注文を行う前提の仕組みとなっています。今回新たに対応した日計り方式では、
- 翌営業日の寄りでEntry
- 翌営業日の引けでExit
を可能とします。つまり、翌営業日中に取引が完結し、日をまたいで銘柄を保有しないため、突発的なイベントによる価格変動リスクを最小限に抑えることが可能な注文方式です。
アルゴリズムの実装において日計り注文を利用するには、order_typeとして、OrderType.DAY_TRADE を指定します。注文実行時の数量で正を指定すると寄りで購入、引けで売却を行い、2つの注文が記録されます。数量として負の値を指定すると、寄りで売却(空売り)、引けで購入を行います。
# 翌営業日に1単位の日計り取引を行う sec = ctx.getSecurity(symbol) sec.order(1 * sec.unit(), order_type=maron.OrderType.DAY_TRADE, comment="日計り")
シグナル生成関数の仕様変更
シグナル生成関数の仕様が変更されました。
以前のバージョンでは、価格データとして pandas.Panel が引数として渡されましたが、maron-0.1.0以降では、dict となります。dictの中身は、configure()で指定したchannels毎にデータがセットされて渡されてきます。
channels毎の値の仕様は次の通りです。
jp.stock.daily
営業日毎の価格データが、pandas.DataFrame で渡されます。indexは、(date, symbol) となっています。上場廃止や価格がつかなかった銘柄の価格は、NaN となります。
例: close_price_adjの pandas.DataFrame を取得する方法
def _signal_emitter(datas): # 0.0.5までの取得方法 # cp = datas["close_price_adj"] # 新しい方法 daily = datas["jp.stock.daily"] cp = daily["close_price_adj"].unstack(level="symbol")
positionsオブジェクトの仕様変更
ctx.portfolio.positions は組入銘柄に関する保有状況を提供します。dict型でkeyはstringでsymbol(‘jp.stock.xxxx’)、値はdictで次の値を持ちます。
- amount
保有数量 - avg_entry_price
平均エントリ価格を表します。 - returns
現時点でのreturnを表します。 - max_returns
max returnを表します。 - holding_period
銘柄保有営業日数を表します。注文が約定した日を1とし、保有数が0になるまで1ずつ増えます。
銘柄を保有していない場合も、ctx.portfolio.positions[symbol] は、amount=0のdictを保持します。
各種ライブラリの更新
各種ライブラリのメジャーバージョンアップを行っています。特に Pandasのバージョンアップにより、pandas.Panel が利用できなくなっていますのでご注意ください。各ライブラリ毎の詳細なバージョン等はドキュメントを参照ください。
制限事項
現在はβ版となっており、挙動に問題がある可能性や、仕様変更が発生する可能性があります。
アルゴジェネレーターはmaron-0.1.0に対応しておりません。対応完了まで、もうしばらくお待ちいただけますようお願いいたします。
0.1.0で作成したアルゴリズムの販売は、正式版がリリースされた後に可能になりますので、もうしばらくお待ち下さい。