【シストレ開発#5】システムトレードの状態遷移について考えてみよう!

いきなりコーディングする前にちゃんと設計しましょう!たっきん(Twitter)です!

前回までにざっくりとでしたがシストレ・アプリケーションのアーキテクチャ設計まで完了させることができました。

システム開発は設計が命!たっきん(Twitter)です! ROS2を使ったOANDA-APIのインターフェース周りの作成もある程度完成してき...

なので今回からは、各ノードの作りこみを始めていきたいと思います。

下位のモジュールである「pricing_streamer」、「order_service」ノードの実装はほぼ完了してますので、上位モジュールの「order_manager」の作りこみをぼちぼち始めていこうと思います。

<シストレ・アーキテクチャ ver.0.2>

さて、この「order_manager」ノードの役割ですが、注文の発行と注文状態の管理機能を持たせようと思っています。

現段階で僕が考えている注文仕様を以下のように定義しました。

<注文仕様>

  • 新規注文の種類は成行指値逆指値の3つのみとする
  • 新規注文時に必ずセットでOCOの決済注文を出す
  • 新規注文、決済注文時に有効期間をセットで出すことも可
  • 有効期間を過ぎた場合、強制的に手仕舞いする

上記の仕様を満足した上で、新規注文の発行からトレード完了まで、考えられるシーケンス・パターンは以下の5つになります。

■パターン1

Start
 ↓
新規注文発行(成行) & OCO決済注文発行
 ↓
OCO決済注文約定
 ↓
End

■パターン2

Start
 ↓
新規注文発行(成行) & OCO決済注文発行
 ↓
OCO決済注文未約定 & 有効期間を過ぎる
 ↓
手仕舞い(ポジション決済)
 ↓
End

■パターン3

Start
 ↓
新規注文発行(指値 or 逆指値)
 ↓
新規注文約定(指値 or 逆指値) & OCO決済注文発行
 ↓
OCO決済注文約定
 ↓
End

■パターン4

Start
 ↓
新規注文発行(指値 or 逆指値)
 ↓
新規注文未約定(指値 or 逆指値) & 有効期間を過ぎる
 ↓
新規注文キャンセル
 ↓
End

■パターン5

Start
 ↓
新規注文発行(指値 or 逆指値)
 ↓
新規注文約定(指値 or 逆指値) & OCO決済注文発行
 ↓
OCO決済注文未約定 & 有効期間を過ぎる
 ↓
手仕舞い(ポジション決済)
 ↓
End

これをいきなりコーディングしてもよかったのですが、僕のスキルだとスパゲッティ・コードになり兼ねないので、ちゃんと設計してから作ろうと思います(笑)。

Sponsored Link

状態遷移設計

上のパターン1から5までのシーケンスを見ると状態が逐次切り替わっているのがわかりますが、一部である状態時の処理を共通化できそうなところもいくつかありますね!

(例えばパターン1とパターン3にあるような「OCO決済注文約定」などは共通化できそう!)

なので今回は状態遷移設計を使うことで意外とシンプルな設計になるんじゃないかと思い、さっそく状態遷移表を考えてみました。

作成した状態遷移表は左側の「状態」と、右側の「遷移」で構成されています。
このへんをざっくり説明していきますね!

<状態>

「状態」欄には以下の3つを定義しています。

名称 意味
State ID 状態を一意に示すID
状態名 状態の名称
処理 処理内容を記述
Enrty:
・その状態に遷移したタイミングで実行される処理
Do:
・その状態にいる間実行される処理
Exit:
・その状態から出るタイミングで実行される処理

<遷移>

「遷移」欄には以下の3つを定義しています。

名称 意味
遷移条件 状態遷移するための条件
条件アクション 遷移条件を満たし、状態遷移する前に実行される処理
遷移先 遷移先のState ID

ちなみに、遷移条件の判定優先度は、「If → elif(2) → elif(3) → ・・・」の順に小さくなっていきます。

完成した状態遷移表を基に状態遷移図も描いてみました。

■状態遷移図(order_manager)

別に状態遷移図は書かなくても状態遷移表だけでコーディングは可能ですが、状態遷移図を使うと直感的に理解できるため、状態遷移表の記述ミスや抜け漏れ防止につながります。

コーディング

上記の状態遷移表を基に実際にコーディングを行いました。

ソースコードはGitHubで公開していますが、コードの細かい解説まではしませんので興味ある方は自力でトレースしてください。

ヒントを出すなら、コード上で実際に状態遷移関連の処理を行っている個所はOrderManagerクラス内の__update_stateメソッドになります。

さいごに

今回は状態遷移を使った設計にトライしてみました。

僕の経験上、システムのロジックを考えるときに複雑なロジックになりそうなときは状態遷移を使って考えるようにしています。

というのも、状態遷移を使わずにロジックを考えることもできますが、その代償として仕様変更に対し貧弱になる場合が多いと感じています。

よくありがちなのが、仕様変更を加えたことにより既存のロジックが正常に動かなくなる場合ですね。

こうなると最悪最初から設計のやり直しになる場合もあるので厄介です。

最初の内は状態遷移設計に慣れない部分もあって苦労するかもしれませんが、この考え方で設計ができるようになるとシステム・エンジニアとして1ランクアップすることができますので習得しておいても損はないと思いますよ!(^^)

それではまた!

Sponsored Link