Submit Search
アルゴリズム取引のシステムを開発・運用してみて分かったこと
•
125 likes
•
79,112 views
Satoshi KOBAYASHI
Follow
趣味でアルゴリズム取引のシステムを開発・運用してみたことで得られた知見について、社内のテーマ自由な勉強会で発表しました。
Read less
Read more
1 of 75
More Related Content
アルゴリズム取引のシステムを開発・運用してみて分かったこと
1.
アルゴリズム取引のシステムを 開発・運用してみて分かったこと 2017/02/17 Satoshi KOBAYASHI (satoshi-k
at iij.ad.jp)
2.
目次 • 自己紹介 • 背景 •
システムの概要 • 遭遇した問題と得られた知見 • 最近の状況 • まとめ
3.
自己紹介
4.
誰? • 名前: 小林
智史 (Satoshi KOBAYASHI) • 所属: インターネットイニシアティブ (IIJ) • 職業: ソフトウェアエンジニア • 備考: 普段の業務は金融とは一切関わりがない
5.
元々、投資は好き • 普段の投資について • 堅実枠 •
海外ETFを使った長期分散投資 • 趣味枠 • 好きな (応援したい) 企業の株を銘柄買い
6.
ちなみに • 年齢が若いことは投資では有利に働きやすい • 長期間で時間分散できる •
時間分散?→ドル・コスト平均法など • 長期間に渡って複利が効く • 複利?→利益がさらに利益を生む仕組み • 損をしたときもダメージが少ない • 何故?→人的資本が多く残されている (定年まで長い)
7.
背景
8.
お金儲けについての研究 • 知識と技術を使ってお金儲けができないか? • 大学時代の研究室の先輩と二人三脚で研究 •
どちらも社会人なので余暇を利用 • データを駆使して市場に打ち勝つ • 今回作ったシステムはその一環で生まれた
9.
大学時代の研究室の先輩 • 名前: 加川
敏規 (Toshinori KAGAWA) • 所属: 情報通信研究機構 (NICT) • 職業: 研究者 ※博士(工学) • 備考: 先輩も投資が好き
10.
システムの概要
11.
どんなものを作ったか • ある金融資産を全自動で取引するシステム • 特定のアルゴリズムにもとづいて動作する •
24 時間 365 日休まず取引し続ける • アルゴリズムの基本 • 安く買って高く売る (商売と同じ) • 統計の考え方を用いている
12.
どのようにして作ったか • Python を使ってスクラッチで実装した •
最初ワークフローエンジンを使おうとした • Apache Airflow とか • 学習コストの高さ、クセの強さから断念 • その後は、ひたすら下回りから書いていった
13.
システム構成図 (概要) 情報収集 プログラム 取引用 プログラム レポート用 プログラム 取引所RDB (MySQL) トーク (Slack) 集計用 プログラム 取引所API ライブラリ 可視化 (Re:dash) 板の取得や注文など 何かあったときは Slack に通知する (自作部分) 定期実行 ユーティリ ティ 設定管理 ユーティリ ティ など…RDBの内容を グラフにする 各種データの集積所
14.
システム構成について • 役割ごとに細かくプロセスを分けた • ティッカー、板などの情報を取得する役 •
得られた色々なデータを処理して発注する役 • これは正解だった • 疎結合でデバッグしやすい
15.
用語の補足 • ティッカー? • 最後に成立した取引の情報 •
いくらで売られたか、買われたか • 板? • まだ成立していない取引の一覧 • いくらで売ります、買います
16.
サーバ • 某 VPS
上で稼働させている • OS: Ubuntu 16.04 LTS • CPU: 3C • RAM: 2GB • DB: MySQL 5.7
17.
遭遇した問題と得られた知見
18.
取引はいつか必ず失敗する …それも連続で
19.
取引が失敗する主な原因 • 外的要因 • 取引所のメンテナンス・障害など •
内的要因 • 自作した取引システムの障害 • 連携させている口座の残高不足など
20.
一旦失敗すると長引くことも • 一過性 (数分〜)
のものなら特に問題はない • Slack のログが汚れるだけ • 長期間 (数時間〜) に渡って失敗することも • 意外とよくある • 人間が介入しないと直らなかったり、とか
21.
取引が失敗するデメリット • 機会損失 • 失敗している間はお金儲けができない •
スプレッド分の損が連続して発生しうる • これが特にやばい
22.
何がヤバイのか • 複数注文の組み合わせで取引したいことがある • 組み合わせはトランザクション的に扱いたい •
つまり All or Nothing にしたい • もし失敗したときはロールバックさせる • 買った所で直後に売ることになる • あるいはその逆
23.
何か問題が? • 売値と買値はイコールではない • 必ず売値
< 買値の関係になっている • 高く買って安く売りたい人はいない • 両者の差額をスプレッドという • 単純に買って売るだけでも差額分を損する
24.
失敗し続けるのはまずい • 買って売っての繰り返し • スプレッド分を延々と損し続ける •
それも、数時間単位で!
25.
どう解決する? • 単位時間あたりの失敗数に上限を設ける • 閾値を超えて失敗すると、関連する注文を中止 •
これをペナルティーと名付けた • 復帰条件 • 一定期間が経過する • 人間が介入して状態を解除する
26.
取引手数料は最大の敵
27.
前述したスプレッドに関連 • 多くの取引所では取引自体に手数料がかかる • 一回の約定あたりでいくら、とか •
板に最初から上乗せされていることも • ギャンブルでいう「控除率」に相当する • 胴元の懐に入るお金という意味で同じ
28.
控除率の壁を超える必要あり • 超えられないと損し続けることに • HFT
的なことをすると特に問題になる • HFT?→高頻度取引 • 頑張って手数料ばっかり払い続ける
29.
どう解決する? • なるべく手数料の少ない取引所・商品を選ぶ • 最初、高いものを使って痛い目を見た •
アルゴリズムを改良して壁を超える • 壁を超える利益が得られそうかを計算する
30.
ティッカーの値段では 買えない
31.
ティッカーは単なる過去の実績 • 開発の初期において • ティッカーの情報を元に注文を入れていた •
想定と異なる約定が頻発した • 成行注文: 想定より高い・安い • 指値注文: 買えない・売れない
32.
得られた気づき • ティッカーだけを見ていてはいけない • 直近の取引で成立したというのに過ぎない •
市場は刻一刻と変化している • 過去の実績と今の市場は異なる • 約定した取引量も分からない
33.
どう解決する? • ティッカーの代わりに板の情報を使う • 板の情報は成立していない注文の一覧 •
今出ている注文を見て自分の注文を入れる • いくらで売買できそうかを計算する
34.
板の値段でなら買える! …と思った?
35.
想定外は減った、しかし… • 板の情報を使っても完璧ではない • 他の人も注文をバンバン入れている •
板は取得した直後に過去の情報となる • 想定外の約定は生じうる
36.
どう解決する? • 板を見てから注文までのディレイを減らす • 処理の最適化・高速化 •
「想定外」の取捨選択をする • 成行取引: 想定より高い・安いを許容する • 指値取引: 中途半端な約定に対処する
37.
中途半端な約定? • 商品が売買される単位はバラバラ • 「100
買う」という注文を指値で出したとする • その値段で 50 だけ買えた (約定) • 残りはいつまでたっても買えない • 上記のような状況が起こりうる • アルゴリズムが複雑化しがち
38.
ちなみに高速化では… • ボトルネックが自作システム以外にあること も • 取引所や途中経路が重いこともよくある •
注文が受理されるまで数秒かかるとか • その間クライアントがブロックする • 別のスレッドにして他の仕事させよう…
39.
買えなかった (´・ω・`) …いや、実は買えていた!
40.
取引に時間がかかるのは困る • 注文内容が市場の相場から乖離してしまう • 一定期間で
API 呼び出しをタイムアウトする • しかし取引所では処理が続いていることも • 「実は買え (売れ) てた!」がたまに起こる
41.
どう解決する? • システムが「実は」を直後に検出する • 検出後は失敗時のロールバックと同じ •
この「実は」の検出が意外と難しい • または問題が顕在化した時点で対処する • アルゴリズムによってはこれで済むことも
42.
その他の雑多な知見
43.
複利を活かすなら 口座情報を活用しよう
44.
取引量 • 何をいくつ売買するか • 口座情報を元に調整すると複利が効きやすい •
固定量だと人間が定期的に調整する必要あり
45.
余談 • ギャンブルで賭け金をいくらにすべきか? • 色々な手法が考案されている •
マーチンゲール法 (倍プッシュだ…) • ケリーの公式 ※ ここらへんの話は 『ツキの法則 -「賭け方」と「勝敗」の科学』 という本を読むと面白い
46.
貯めたデータを可視化しよう
47.
Re:dash • RDB のデータをグラフ化できる •
定期的に実行してモニタリングとか • 色んなデータの推移を見られるように
48.
注意点 • クエリによっては RDB
に負荷がかかる • 普段から結構メモリを食う • 以前は RAM 1GB のサーバで運用してた • ある日 OOM Killer が発動して大惨事に
49.
バックテストについて
50.
バックテスト? • 過去の履歴を使った検証 • 仮にあるアルゴリズムで運用していたら? •
機械学習系の知識は役に立ちそう • 教師信号への過学習で喜んでないかとか
51.
二つのフェーズ • 第一段階 • 上手くいくのか? •
アルゴリズム自体の検証 • 第二段階 • 利益を最大化するには? • ハイパーパラメータの調整
52.
しかし… • 高精度なバックテストは意外と難しい • 必要なデータが揃うとは限らない •
マーケットインパクトが読みづらい • このスライドにあるような幾多の落とし穴
53.
データが揃いづらい • 例 • ティッカーの値段では売買できない恐れ •
精度を上げるには板の情報もほしい • 一般には公開されていない場合が多い • 年単位のバックテストがしたいとき困る
54.
マーケットインパクトの評価 • 自分たちの取引が市場に与える影響 • 注文を入れた世界と入れなかった世界 •
金額が大きくなるほど影響が増す • アルゴリズムによってはこれを逆手に取る
55.
セキュリティについて 考えよう
56.
大前提 • それぞれ適切にセキュリティ対策を施す • サーバ:ファイアウォールとか •
取引所:二要素認証とか
57.
仮にサーバが乗っ取られたら? • 乗っ取られたときのことを考える • 嫌がらせ以上のことができないようにする •
外部に送金されたりするとまずい • 取引所によっては API 経由でできてしまう • 権限を適切に絞る
58.
問題が起きたとき 気付けるようにしよう
59.
開発の最初期 • 色んな問題が起こった • いつの間にか止まってた •
想定外の○○ • 気付けないと対処のしようがない • 気付けるようにすることが大事
60.
Slack への通知 • 何かあったときは
Bot が発言する • 取引の失敗とか例外とか何でも • スマホのアプリがおすすめ • 問題が起きたことに素早く気付ける
61.
運用やデバッグで REPL が活躍する
62.
REPL? • Read-eval-print loop •
対話型評価環境 • Python には組み込みで付属している • ちょっとしたスニペットを気軽に試せる
63.
運用やデバッグへの応用 • 何か問題が起こったときは REPL
に入る • 取引システムの API を手動で実行できる • デバッグに大活躍する • これがなかったらと思うと…
64.
スモールスタートしよう
65.
実装の面でのスモールスタート • 優先順位をつけて作れるところから • データ収集は最優先、取引部分は後回し •
データさえあれば取引はシミュレートできる • 実際にやってみると失敗も多い • 増改築しやすいように作る
66.
金額の面でのスモールスタート • 最初はシミュレーションから始めた • 実際には注文せず「もししていたら?」を分析する •
次のフェーズとして数週間は少額の取引をやってみた • 一取引あたり数百円規模 • 上手くいくことを確認しながら繰り返し増資 • 今ではひとつの取引で数十万円が動いている
67.
最近の状況
68.
Q: で、儲かってるの?
69.
A: 割りと
70.
どれくらい? • 半年間の実績: 投入資金が
1.3 倍になった • 内、金融資産の価格上昇由来: 82.7% • 仮に全てを買って放置していても増えた分 • 内、アルゴリズム取引由来: 17.3% • 取引することで増えた分 (こちらが重要)
71.
ある日の取引益 (24H) ※ 上記はチャンピオンデータではなく、 この資料を作っているときに、ふと取得したもの 長期間で見ると振動しながら 上昇トレンドを続ける ごく短期間で見ると マイナスに振れることもある このグラフでは、金融資産の 価格変動分を補正して除外している
72.
とはいえ • 一年だけ成績の良い金融商品はゴロゴロある • 継続して良い成績を残すことが重要 •
まだ本格稼働してから半年しか経っていな い
73.
今後も儲け続けられるか? • おそらく!ただし… • 全く同じ手法が通用する期間は限られるはず •
以下のどれか、あるいは組み合わせの影響 • 市場の傾向が大きく変化する • 壁を超えるのが困難なレベルで手数料が上がる • マーケットインパクトが大きくなる
74.
まとめ • アルゴリズム取引のシステムを作ってみた • 開発と運用を通して色々な知見が得られた •
楽しい! • ✌('ω'✌ )三✌('ω')✌三( ✌'ω')✌
75.
ありがとうございました