投資自動化のために鞘取りシステムをつくる
#開発 #投資 #備忘 #モデリング #golang #mongodb #TDD #テスト駆動開発
モデリングの知識が何もない状態で始め、なんか違うなーっていうことで捨てたのが下記にあります
【アーカイブ】投資自動化のために鞘取りシステムをつくる
システム概要
端的に言うと投資を自動化するシステム。
鞘取りというのは複数の銘柄の動きの差で利ザヤを狙う手法で、例えば日経225指数に連動する銘柄とTOPIX指数に連動する銘柄に対して買いと売りを出しておいて、2つの銘柄の価格離れると儲かって、2つの銘柄の価格が近づくと損をするという形にする。
日経225指数とTOPIX指数はどちらも日本株の価格から作られる指数なので、極端に離れた動きはしないことが期待されている。
今回は指数に連動するETF商品での鞘取りを狙う。
対象とするのは、カブコムで手数料無料のETF。
銘柄一覧(フリーETF)|フリーETF|商品・サービス|株のことならネット証券会社【auカブコム】
※ 手数料が無料なだけで、信用取引にはほんの少しだけコストがかかります
手数料無料なので短期売買し放題。
開発手順
モデリング
脳内で済ますか、何かしらUMLみたいなので書き出すか、オレオレモデリングで済ますかは未定
出来れば全部ここに残したいので、オレオレモデリングにしちゃうかも
モデリング → コーディング を徹底したい
開発
新規注文
戦略管理
注文管理
約定確認
ポジション管理
返済注文
戦略管理
注文管理
どんなモデリングをするかを考える
シナリオを書いてそこからモデリングしていくのは変わらないけど、何を意識するかを先にはっきりさせておく。
かなり不純な動機であることは把握してるけど、ディレクトリ構成を変えたくないから構成に意味を持たせる。
ディレクトリ構成が先にあって、そこに明確な責務を持たせて何をモデル化するかを意識する。
とはいえ、Clean Architectureとかを意識して作ったディレクトリ構成やから、ある程度責務の分離をしやすい形にはなってるはず。
エンティティ: domain/entity
実体があったりなかったり
とりあえず一意に定まるものに使う = 固有名詞
固有名詞の反対は普通名詞
普通名詞がヒト、固有名詞がツチナガ(僕のこと
リポジトリ: domain/repository
永続化を責務としてる
永続化自体はrepositoryではなく、もっと外のinfraで行なう
interfaceで永続化に必要な関数の定義をして、実装はinfra、DIでドメイン層にいれる
つまりビジネスロジックの外側にあるものとのやり取りになる
利便性のために永続化と関係ないものをrepositoryに置くこともある
例えば現在時刻はサービスの中にあるとテストがしんどくなるから外に永続化されてる体にしたい
サービス: domain/service
エンティティの振る舞い
エンティティにはデータをやり取りするアクターもやり取りされるデータも入っているから、サービス間の依存は発生するかもやけどできるだけ発生させない
とにかく再利用可能なものにする
ユースケース: usecase
ドメイン層のやりくりで課題を解決するレイヤー
解決したい問題はここに出ることになる
システムの大まかな動きを書いた時の動きはここに表現されて、大まかな動きで書ききれない細かいのがサービスに出てくるはず
たぶん再利用しない
シナリオの洗い出し
モデリングするためのシナリオを書き出します。
このあとこのシナリオをもとにモデリングし、モデリングされた情報をもとに設計に入っていき実装に進むことを考えたら、ここで抜け漏れがあるとこの後に大きな問題が発生するかもしれない。
ってことでなるべく抜け漏れなくしっかりと書こうと思う。
抜け漏れがあってもモデリングとかで気付けることを期待はしてるけど。
シナリオ
ユーザーは、普段は証券会社のWebページから手動で注文を出している。注文を出すかどうかは脳内でのシミュレーションや、Excel等のツールをつかったテクニカル指標を用いた手法でしている。注文を出すべきだなーと判断したところで証券会社の画面で対象の銘柄を選択し、所持金と相談しながら期待にあった枚数だけ売買注文を行なう。また、保有している銘柄である程度の利益が出たり、損失が出たり、これから損失が出そうだなーというときには、これも証券会社の画面にはいり、決済すべき注文を選んで決済注文を出す。
今回、売買手法のうち計算だけで注文を出すかを決めている戦略を自動化することを考えている。
具体的には、同じ指標に追随するような動きをするETFの銘柄2つを選んで鞘取りを行なう戦略である。
2つの銘柄の価格が普段より近いなーというときにはこれから離れていくことを期待して、高い方を買い、安い方を売っておく。そしてその2つの銘柄の価格が普段より離れたなーというときにはこれから近づいていくことを期待して、高い方を売り、安い方を買っておく。そうして2つの銘柄の価格差で利ザヤを狙う。
さらにカブコムなどの証券会社にはフリーETFという銘柄があり、売買手数料が無料なものがある。※無料なのは手数料だけで、保管料や信用で必要な証拠金などは別途必要である。
2つの銘柄が近づいている、離れているという判断を行なう例として、2つの銘柄の価格差が平均を上回っているか下回っているか、標準偏差を上回っているか下回っているか、移動平均の短期と長期が上回っているか下回っているかなどがある。
これらの戦略に則り、その時点で売買すべきかを計算し、売買すべきだと判断されたら買いと売りの注文をセットにして証券会社に行う。そして証券会社から注文の一覧を取得することで約定していることを確認し、次は決済すべきかを計算し、決済すべきだと判断されたら保有中の銘柄を決済する注文を出す。
このようにして、システムで自動的に売買を行い、利益を得たいと考えている。
シナリオからモデリング
エンティティの候補
まずはエンティティの候補を洗い出す。基本的には名詞か動名詞かなーと思う。
ユーザー、証券会社、注文、手法、判断、銘柄、所持金、売買注文、保有している銘柄、利益、損失、決済、決済注文、売買手法、計算、指標、ETF、銘柄、鞘取り、戦略、価格、高い方、買う、安い方、売る、価格差、利ザヤ、カブコム、フリーETF、売買手数料、保管料、証拠金、価格差の平均、標準偏差、移動平均短期、移動平均長期、注文のセット、約定、システム、注文の一覧
後から知ったけど、シナリオの5W1Hにアンダーバーを引くのもいいみたい。
この時点では同じものを指していたり、あるエンティティの一属性を意味していたりするけど、何も気にせず出していく。
あとからまとめたりすればいいだけであって、洗い出すのを辞める理由はない。
エンティティの候補をまとめながら分類していく
同じ意味のものとか、あるエンティティの一部とか、そういうものをまとめてしまう。
ユーザ
所持金
証券会社
カブコム
注文
売買注文
決済(決済注文)
買う
売る
戦略(手法、売買手法、鞘取り)
判断
計算
高い方
買う
安い方
売る
価格差
価格差の平均
標準偏差
移動平均短期
移動平均中期
銘柄
ETF
フリーETF
価格
売買手数料
保管料
証拠金
指標
保有している銘柄
売買損益
利益
損失
利ザヤ
注文のセット
約定
注文の一覧
システム
どんな処理にするとかは考えず、カテゴライズしてみた。
あと複数の場所に含まれそうなのは複数の場所にカテゴライズしてる。
分からないのはとりあえずトップレベル。そんな感じ。
これをエンティティの属性とかは抜きで関係だけ作ってみた。
https://gyazo.com/78f97ecc6522c4a944b27382bed3086b
システムの外が横線より上、システムの中が横線より下
上から下に時系列で流れてる
って感じで意識した。
diagrams.netってのを使ってみたんやけど、楽ではないなーって印象
他のを使ったことないから分からんし、PlantUML書くのに比べたら楽やと思うけど。
draw.ioって名前で記事になってたりするし、何が正しいのかは知らない。
そういえば、取引可能日と取引可能時間のシナリオ忘れてたなー。ってここでなった場合、どうすればいいんやろう。
って思っても結局はシナリオに追記して、エンティティの洗い出しに追加して、モデリングに追加するしかないか。
この辺がめんどくさいところやんなー。自然言語から自動でモデリングしてくれる時代にはやくなってくれー。
さきにEntityをソースにしてからそれをもとに図を作るのは?
図って修正するのがまー大変っすよね。
ってことで、変更が容易でかつどうせやらないといえかにソースから関係を作るのって無理なのかってお話。
Entityだけで関連を出すのは難しい気もするから、もうちょっと何か考えないといけないけど、たぶんそういうツールはいっぱいあると思う
コードからモデリングしたものを出して、そのモデルが意図したものと一致してるかっていうのを確認できないか試したい。
https://gyazo.com/482a3efc0b897b9d65937b635561f87b
entityだけ用意しただけやとそりゃそうやわな。関係性なんかみえへんよなー。
enumとか含めて、色んな属性をつけた。
https://gyazo.com/1a2b5554330e31e52d1372348cd55780
Entity間の関係は見えないままやのに、色んなenumが登場して一気に見づらさがああああああああ
同じenumを見てる構造体は同じタイミングで使われるのかなーとか分かるのはまあ悪くない。
バックエンドの興味的にはどのタイミングでどのデータをどこから取ってきてどこに入れるかみたいなのが見れたらいいなーと感じる。
その辺はサービスか、ユースケースの実装をすれば出てくるんかなぁ?
なんか、結局シナリオから登場人物洗い出すところでモデリング止めちゃってる気がする。
ここらでまた立ち止まる
投資のシステムってぱっと見は大きくないけど、水面下でやってることが多くて制約が多いので設計をしっかり作りこむというのが難しいんですよね。
設計をあいまいにしたまま、実装にうつる方法がないかを検討したい。
ってことで今テスト駆動開発をみてる。
テスト駆動開発では、設計をふんわりして、すぐにテストを書き出すことに入る。んで、テストを作って、それをパスする実装を作る。
これがある程度複雑な開発に向ている方法なのではないかと感じてたりする。ってことで調べてる。
テスト駆動開発の始め方についておべんきょ
要件からTODOを書き出して、実装できるところからやっていくことで、詳細設計を先延ばしにしたいというもの。
どんどんモデリングから離れていってる気がするけど、やってみないと分からない!!!
テスト駆動のTODOリストを作る
何で管理するかちょっと悩んだけど、gitのissueを使おうと思う。
メインで使ってるのがGitLabなので、GitLabで。一応カンバンがあるからカンバンでやっていく。
ラベルはOpen、ToDo、Red、Green、Refactor、Closeにしとく。無駄かもやけど、一応。
とりあえず大雑把なタスクに分ける。
https://gyazo.com/ea39c2ba744b0d361799c03544959bd8
この大雑把なタスクの中身がどんなのか想像しながらさらにTODOを追加していく。
と、32個まで増えた。
https://gyazo.com/a1a3ea89b171b2e7e8717bba086f7902
たぶん同じ処理をするタスクもあると思うけど、それは今は考慮しない。
これまでissueでは不具合とか大きなタスクの管理しかしてこなかったからこんなに同時にissueが立ってるの初めて。
ラベルはOpen、ToDo、Red、Green、Refactor、Closeにしとく。
って書いたけど、ToDoの後にDoingを追加しておく。
ぼっちプロジェクトやから関係ないけど、一応何を作業中なのか自分で把握するために。
https://gyazo.com/311c4b0c0b33530e10332075e80c3eac
ってことで、早速一つに対してテスト駆動開発をやってみる。
テスト駆動開発の中でも設計に関係しそうなToDoリスト洗い出しは残すけど、実際にどんな作業をしたかはこの記事には残さない。
たぶんコミットログがgitに残るし大丈夫。
証券会社との契約がうまく進まなくていったん中断
残念なことに、証券会社などとの契約がうまくすすまなかったのでいったん中断
#2020/06/14週 #2020/06/21週
更新履歴
#2020/06/19 書き始め