search
LoginSignup
1

posted at

updated at

【v9】auカブコム証券のkabuステーションREST APIで自前のリピート注文を作ってみる(設計、検証用実装編)

はじめに

過去記事は「auカブコム証券のkabuステーションREST APIに関する記事一覧」。

注文依頼を元に、状態確認、新規注文発注、注文約定確認、残高確認、返済注文発注、注文約定確認をループすることで、新規→返済→新規→返済を繰り返し実行することが可能となる。
トレイル注文のときは思いついたまま実装しても、ほぼ想定通りに動作したが、設計では気が付かないことが多々発生したので、方針だけ軽く設計してプロト実装で問題点を洗い出して解決しながら仕様を詰めていくことにする。

用語と永続化ファイル、設定ファイル

  • 注文依頼ファイル(OrderRequest):人間が用意したリピート注文の指示ファイル。MainEntryOrder_r3.cfg
  • 注文依頼状態管理ファイル(OrderRequestStatus):注文した新規注文番号を保存する。MainEntryOrder_r3.txt
  • 注文約定状態管理ファイル(OrderStatus):新規注文の状態を管理する。EntryOrdersLogic_r3.txt
  • 残高状態管理ファイル(PositionStatus):残高の状態を管理する。PositionsLogic_r3.txt
  • 返済注文管理ファイル(CloseOrders):返済注文の注文番号と対象となる残高の約定番号を紐づける。CloseOrdersLogic_r3.txt
  • 新規注文発注(EntryOrder):/sendorder/future API。
  • 注文約定照会(Orders):/orders API。
  • 残高照会(Positions):/positions API。
  • 返済注文発注(CloseOrder):/sendorder/future API。
  • 注文取消(CancelOrder):/cancelorder API。
  • APIパスワード(ApiPassword):事前に準備する設定ファイル。LockedAuthorizedToken.pwd。
  • 取引パスワード(TradePassword):事前に準備する設定ファイル。SendOrderConfig.pwd。

注文依頼ファイル(MainEntryOrder_r3.cfg)

注文依頼ファイルは人間が用意する。タブ区切りで2カラム。
keyはTreeMapのキーのため、ファイル内においてユニークな文字列となる。
価格(Price)、売買(Side)、数量(Qty)のみ指定し、銘柄コード等はツール内の設定項目とする。

No Name Description Example
1 key 新規注文のPrice,Side,Qtyをカンマ区切り 26000,L,2
2 value コマンド R

コマンドは以下のとおり。

No Name Description Example
1 Register/Resume 注文を新規登録する。停止していた注文を再開する。 R
2 Pause 停止状態で注文を新規登録する。決済後の次の注文を停止する。(すでに注文発注している場合は停止しない) P
3 Delete 未発注の注文依頼を削除する。発注済の注文を取り消す。(すでに残高が存在する場合は決済しないため、削除できない) D

注文依頼状態管理ファイル(MainEntryOrder_r3.txt)

注文依頼ファイル(MainEntryOrder_r3.cfg)を読み込み、MainEntryOrder_r3ツールが処理した状態を保存する。タブ区切りで2カラム。
keyは注文依頼ファイルと同じため、ファイル内においてユニークな文字列となる。
見やすいように、主キー(Price,Side,Qty)と異なり、ソートキー(Side,Price)で並び替える。

No Name Description Example
1 key 注文依頼ファイルのkey 26000,L,2
2 value コマンド状態と注文番号 O,1651050284644

コマンド状態は以下のとおり。

No Name Description Example
1 NotOrder 登録されて、まだ未発注 R
2 OrderAndRepeat Rコマンドで発注済。決済後に再発注する。 O,1651050284644
3 Pause 停止状態で登録 P
4 OrderAndPause Pコマンドで発注済。決済後に停止する。 P,1651050284644
5 Cancel Dコマンドで注文取消中 C,1651050284644

※未発注のkeyに対して、Dコマンドを指定すると、レコードが物理削除される。

注文約定状態管理ファイル(EntryOrdersLogic_r3.txt)

MainEntryOrder_r3ツールが、注文発注、注文取消を実行し、注文約定照会APIの状態を反映する。タブ区切りで9カラム。
主キーはjavaのミリ秒単位のシステム時刻を使用する。衝突した場合はユニークとなるように+1ミリ秒を繰り返す。
2カラム目に注文番号があるが、あくまでAPIが管理する注文は、新規注文と決済注文は別のため、新規注文の注文番号を主キーとすると、約定して数日経過すると削除されてしまうため、決済が完了するまで維持できるように独自のユニークキーを採番する。

No Name Description Example
1 uniqId ユニークID 1650768994290
2 orderId 注文約定照会APIの注文番号(ID) 20220424A02N86121532
3 state 注文約定照会APIの状態(State)を元に独自拡張 97
4 price 注文約定照会APIの値段(Price) 26000
5 orderQty 注文約定照会APIの発注数量(OrderQty) 2
6 side 注文約定照会APIの売買区分(Side) 2
7 createDate 作成日時(currentTimeMillis値)と文字列形式 1650768994291(2022/04/24 11:56:34.291)
8 updateDate 更新日時(currentTimeMillis値)と文字列形式 1650863709620(2022/04/25 14:15:09.620)
9 executionIds 注文約定照会APIの約定番号(ExecutionID)と値段(Price)と数量(Qty)の配列をカンマ区切り E20220422000Y5:27445x2

stateはAPIが定義済の1-5の前後を拡張している。

No Name Description Example
1 STATE_NOT_ORDER 登録済、未発注。コマンド状態がRまたはP。 -1
2 STATE_UNKNOWN 発注済、注文ステータス不明。発注後にまだ注文約定照会APIを呼んでいない。 0
3 STATE_WAIT API:待機(発注待機) 1
4 STATE_SEND_ORDER API:処理中(発注送信中) 2
5 STATE_ORDER API:処理済(発注済・訂正済) 3
6 STATE_SEND_CANCEL API:訂正取消送信中 4
7 STATE_FINISH API:終了(発注エラー・取消済・全約定・失効・期限切れ) 5
8 STATE_CANCEL キャンセル済。API:終了の状態で、executionIdsが空の場合。 6
9 STATE_CLOSE 返済済。API:終了の状態で、executionIdsの残高が存在しない場合。 7
10 STATE_FINISH_DELETE 削除済(終了)。API:終了で残高が存在する状態で、新規注文照会から削除された。 95
11 STATE_CANCEL_DELETE 削除済(キャンセル)。キャンセル済の状態で、新規注文照会から削除された。 96
12 STATE_CLOSE_DELETE 削除済(返済)。返済済の状態で、新規注文照会から削除された。 97

残高状態管理ファイル(PositionsLogic_r3.txt)

11番目の記事のトレイル幅の動的拡張した際の建玉情報ファイルをそのままr3にリネームする。カラム定義に変更なし。

No Name Description Example
1 code 残高照会APIの銘柄コード(Symbol) 167060019
2 name 残高照会APIの銘柄名(SymbolName) 日経225mini 22/06
3 price(qty) 残高照会APIの値段(Price)と残数量(LeavesQty)、拘束数量(HoldQty)の集計 28000(2-0)
4 side 残高照会APIの売買区分(Side)。1(S):売、2(L):買。 1(S)
5 curPrice 残高照会APIの現在値(CurrentPrice) 27675
6 profitHigh 含み益の最大値 325
7 profitLow 含み損の最小値 -10
8 triggerPrice トリガー価格 27700
9 createDate 作成日時(currentTimeMillis値)と文字列形式 1649136073840(2022/04/05 14:21:13.840)
10 updateDate 更新日時(currentTimeMillis値)と文字列形式 1649136073841(2022/04/05 14:21:13.841)
11 executionIds 残高照会APIの約定番号(ExecutionID)と残数量(LeavesQty)、拘束数量(HoldQty)の配列をカンマ区切り E2022040601ZS8(1-0),E2022040603BWT(1-0)

返済注文管理ファイル(CloseOrdersLogic_r3.txt)

9番目の記事の注文情報管理ファイルをそのままr3にリネームする。カラム定義に変更なし。

No Name Description Example
1 OrderID 注文約定照会APIの注文番号(OrderID) 20220415A02N79601157
2 ExecutionID 残高照会APIの約定番号(ExecutionID)。手作業の発注で、不明な場合は"?"。 E2022041501B96

APIパスワード(LockedAuthorizedToken.pwd)

6番目の記事のAPIパスワードファイルをそのまま使う。ファイル名に変更なし。1行のみのファイル。

No Name Description Example
1 ApiPassword 認証APIのAPIパスワード XXXX

取引パスワード(SendOrderConfig.pwd)

8番目の記事の注文パスワードファイルをそのまま使う。ファイル名に変更なし。1行のみのファイル。

No Name Description Example
1 TradePassword 注文発注/注文取消APIの注文パスワード XXXX

javaクラス

パッケージv9に新規クラスを作成する。既存のクラスはr3にリネームして移動する。
入出力ファイル名もカラム定義の変更有無に関わらず常にr3にリネームするが、APIパスワードと取引パスワードは移行が面倒なので、ファイル名を変えない。

No Name Description API Logic
1 CloseOrdersLogic_r3 返済注文を管理する orders,sendorder,cancelorder なし
2 EntryOrdersLogic_r3 新規注文を管理する orders,sendorder,cancelorder PositionsLogic_r3
3 LockedAuthorizedToken_r3 認証TOKENをファイルロック管理する apisoftlimit,token なし
4 MainEntryOrder_r3 新規注文ツール board(※1) BoardLogic_r3(※1),EntryOrdersLogic_r3,PositionsLogic_r3
5 MainStopLossOrder_r3 ストップロス注文ツール なし CloseOrdersLogic_r3,PositionsLogic_r3
6 MainTrailOrder_r3 トレイル注文ツール positions(※2) CloseOrdersLogic_r3,PositionsLogic_r3
7 PositionsLogic_r3 建玉情報を管理する positions なし
8 SendOrderConfig_r3 注文発注に関する設定情報を管理する なし なし

※1 建玉がないときでも、価格を取得したい。将来、チャートデータ収集の際にLogicクラスを作ったときに委譲する。→後日、リファクタリング①で修正済
※2 指定した銘柄の残高を取得したい。本来ならばPositionsLogic_r3に用意してあるべき。→後日、リファクタリング②で修正済

埋め込み定数

手元環境はglobal.cfgに設定しているが、公開ソースはソースコード埋め込み。

No Name Description Example Tool
1 SYMBOL 銘柄コード(Symbol) 167060019 MainEntryOrder_r3
2 SYMBOL_NAME 銘柄名(SymbolName) 日経225mini 22/06 MainEntryOrder_r3
3 EXPIRE_DAY 有効期限(ExpireDay) 20220513 MainEntryOrder_r3
4 SKIP_PRICE_DELTA_CEIL スキップする天井の値幅(curPrice-basePrice)。注文が26500Lで現在価格が26600円以上のとき発注しない。 100 MainEntryOrder_r3
5 SKIP_PRICE_DELTA_FLOOR スキップする床の値幅(curPrice-basePrice)。注文が26500Lで現在価格が26400円以下のとき発注しない。 -100 MainEntryOrder_r3
6 STOP_LOSS_PRICE_RANGE ストップロス注文時の建玉の価格からの値幅 1000 MainStopLossOrder_r3

※スキップする値幅の説明は、買建(L)の場合。売建(S)は符号を反転する。
SKIP_PRICE_DELTA_CEILは、大きい数字でも問題は起きない。注文一覧に約定確率の低い注文が並ぶので、価格が近づいたときに発注するように遅延させる。
SKIP_PRICE_DELTA_FLOORは、小さい数字にすると、ストップロス注文が約定した後に、1000円下の価格帯で新規注文が約定することになる。特にコマンドをR→Pに変更し忘れた際に、突然かけ離れた注文が約定することになる。注文依頼当初と比べて、有利な注文なので、常に一定数の数量をキープしたい場合は、無効となる設定にする。

運用環境

参考までに。
jenkinsを準備し、毎分(* * * * *)のタスクと、10分ごと(H/10 * * * *)のタスクを用意し、それぞれバッチファイルを起動する。
毎分実行バッチファイルは、MainTrailOrder_r3とMainEntryOrder_r3を実行する。
10分ごと実行バッチファイルは、MainStopLossOrder_r3を実行する。

クラス内に曜日判定を指定していないので、休業日はjenkinsを起動しないか、タスクを無効にする。
このため、休業日でも、日中と夜間の時間帯での注文発注のテストが可能。

さらに手元環境では、新規注文発注とトレイル発注(新規・変更)の際のメール本文をファイルに保存し、バッチファイルからファイル有無を判定して、curlコマンドでsendmailしている。

その他、ログファイルのローテーションを別ツールで用意し、日時で実行している。

追記:コマンドの状態遷移図の手書きメモ

裏紙に書いたけど、なんかイマイチ。
上部の注文前と、下部の注文後を分けた方がいいかも。
実際には、返済注文約定後に、次の新規注文発注の際に、O,XXXからO,YYYと注文番号が変わる。

PXL_20220429_092319922

追記:stateの状態遷移図の手書きメモ

さらに裏紙に書いたけど、orders/positions APIを呼びまくっているな。抽象化したラッパーAPIが欲しいところ。
state=6,7,96,97となったときに、返済まで完了/中止しているので、実際は物理削除してもよい。
state=95は新規注文はもう削除されて、建玉が残っている塩漬け状態。消すと、注文依頼との紐づけがなくなるので、もう完了したと判断して、次の新規注文が入る。

PXL_20220429_094630907

追記:リファクタリング

  • ①create BoardLogic.getCurPrice()
  • ②getPosition() move from MainTrailOrder_r3 to PositionsLogic_r3

追記:ソースをarchiveブランチへ移動

最新版に移行し、もう使われることはないので、アーカイブする。

githubソース

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
1