株の裁量トレードがストレスだったため、自動売買ツールを作ってみた

# 1. はじめに
株は、買って放置するものだと思っていましたが。。。実際に株を購入してみると、性格次第でしょうが、自分は、毎日の値動きが非常に気になりました。そして、２０２０年秋～２０２１年秋の１年間が、あまりに株価が上昇していたので、調子に乗って購入してたら、金利上昇懸念の下落につかまり、損切も出来ず、多大な含み損を抱えたまま、２０２２年３月現在に至っており、非常にストレスを感じています。もちろん、毎日値動きを追ってしまい、ストレスマッハ状態です；；；；
そこで、自分がたどり着いた結論は、ルールに従ったトレードを、自動でやる、ということでした。そして、ネットサーフィンしていくと、

1. GPIFのトレードを参考にすると、AI開発とかしなくても、株の値上がりだけでなく、トレードで多少は儲けることが出来る気がした。
1. AUカブコム証券だと、プログラミングさえ出来たら、個人で株の自動売買ツールが作成可能。
⇒AUカブコム証券のツール作成に必要な情報は、こちら。
　https://kabucom.github.io/kabusapi/ptal/index.html

ということが分かり、２０２２年正月休み中に自動売買ツールを作成し、実際に自動売買してみたところ、なかなか良いのではないかと思い、記事にしようと思いました。ちなみに、儲かっているかというと、２０２２年春時点では下落局面のため、含み損状態です；；；；ただ、自分の裁量トレードよりはマシという意味なので、ご了承ください。。。（３月１７日時点で含み益に転じました！！）もちろん、この記事を参考にしてトレードし、損失を出しても、責任は持ちません。また、自動売買ツールのコードも公開していますが、残念ながら、その動作も保証していません。

# 2. トレード戦術
トレード戦術は、GPIFのトレードを参考にしましたが、トレード手法を簡単に書くと、上がったら売る、下がったら買う、というものでした。ただ、

1. どのように売買するか
1. どのタイミングで売買するか

が問題となります。
前者は簡単で、例えば、

1. 日経ETFを５０％、日本国債を５０％に割合を設定
1. 日が経ち、日経ETFが５２％、日本国債が４８％になり、設定割合から４％のずれが発生
⇒４％は、（５２－５０）÷５０で計算
1. 日経ETFを２％分売り、日本国債を２％分買うことで、日経ETF５０％、日本国債５０％になるようなトレードをする

といった感じで、あらかじめ設定した比率を守るようにトレードします。ここで注意が必要なのは、上記例では、日経ETFと日本国債を選択しましたが、選択する銘柄としては、例え現時点で下がっても、将来的には元の値段に戻る可能性が高い銘柄を選択することです。そうすることにより、値動きの波を利益に変換することが可能となります。ただし、上記例で値段が元に戻ったとしても、１往復で０．１６％しか増加しないので、期待はしないでください。。。持ち続けるより、若干資産が増える程度です。
後者は、さすがに分からなかったため、以下のようにアルゴを作成しました。

1. 基本は、設定割合からのズレが、閾値（上記例の４％のこと）を超えたら、逆トレードを実行
⇒閾値超えた時点で、設定割合より低ければ買、設定割合より高ければ売
1. 閾値を超えた時点でのトレードが、前回と同じトレードであれば、そのトレードは一旦見送る。
⇒例えば、前回購入したにも関わらず、今回も購入判定となった場合は、購入しない。
1. 見送ったトレードは、株数の履歴を取っておき、極値と比較してリバウンド閾値を超えたら、トレードを実行
⇒リバウンド閾値を閾値の半分２％と仮定すると、例えば、日経ETFの売りを見送り、割合が６０％にまで到達したが、それが５９％に落ちたら、その時点でトレードを実行

トレードの見送りについては、株価というものは、一旦上昇、あるいは、下降トレンドが発生すると、それが継続することが多いため、毎回閾値超えでトレードしていると、値幅があまり取れず、勿体ないと考えたからです。

# 3. トレード戦略
この章は、自動売買ツールの作成には無関係な情報ですが、実際に運用する上では必要な情報だと思われるため、記載します。

銘柄、比率、閾値を決めると、２章に記載のルールをプログラミングし、自動でトレード出来ますが、銘柄選択、比率設定、閾値については、自分で考える必要があります。また、この設定も、１回決めたら変更しなくて良いものでもなく、例えば、株価が暴落した時には、安全資産である国債や現金の比率を下げ、株の比率を上げて、リスクを取る等の戦略をしたほうが、さらに資産が増える可能性が高いと思われます。もちろん、その後は長期間掛けて比率を元に戻し、次の暴落に備える必要はありますが。。。とりあえず、今回作成したプログラムは、デフォルトとして、以下の設定にしました。

1. 米国７－１０年国債（１６５６）、比率２０％、閾値１．２％
⇒リスクが低いと言われている株、配当も多少有り。
1. 日本高配当株（１４７８）、比率２０％、閾値１．５％
⇒日本投資は、あまり株価上昇が期待出来ないので、配当金を出している企業を選択。
1. SP500（１６５５）、比率２０％、閾値１．５％
⇒大人気だと思われる米国株。
1. 米国リート（１６５９）、比率１０％、閾値１．５％
⇒インフレ対策と高配当目的で、これを選択。
1. ゴールド（１５４０）、比率１０％、閾値２．０％
⇒インフレ対策的で、これを選択。
1. NASDAQに連動してそうな銘柄（２５２２）、比率１０％、閾値２．０％
⇒大人気だと思われるナスダック銘柄がメイン。日本株も多少入っている。自分が嫌いな中国株が若干入っているが、少量なので、気にしないことにした。。。
1. 現金、比率１０％
⇒暴落や上昇局面で株購入出来るように、若干残しておく。

後から設定を変更できるようにツールを作成しているので、自分で戦略を考えて設定してください。逆相関関係（一方が上がると、一方が下がるイメージ）や、相関関係が低い株を選択すると、利益につながりやすいはずです。ただし、逆相関するからと言って、インバース系の株を選択するのは止めたほうが良いと思われます。数年期間でチャートを確認したら分かりますが、株価が元に戻らないからです。ブル系はインバース系よりマシですが、それも、止めたほうが良いと思います。
閾値は、変動が激しい銘柄ほど、大きめに設定しておきました。SP500やナスダックを買うだけで良いという意見もあるため、どのように投資するかは、個人で考えてください。自分の意見としては、ある程度分散は必要だと思っていますが。。。実際、自分は上記よりも分散しています。また、選択する銘柄は、自動売買に投入できる資金が少ない場合は、粒度の問題があり、１単元が安いETFが良いと思われます。
ちなみに、閾値については、変動の激しさが状況によって変化するため、株価の履歴を記録しておき、２０日程度の１シグマを計算して、その割合を閾値にするようにすれば良いと思われますが、今回は、そこまで作っていません。

# 4. 実際のツール作成
## 4-1. ツール同士の相関図
![AUカブコムツール概要.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629725/cf3b33d5-0ea5-0fee-1186-4500bd5592a9.jpeg)
上記は、AUカブコムから提供されるツールと、個人開発ツールの関係を、簡単に示したものです。
https://kabucom.github.io/kabusapi/reference/index.html
ツール間の通信仕様は、上記を参照してください。また、今回はC#を選択してツールを作成しましたが、様々な言語で開発出来るよう、サンプルプログラムもあります。一旦kabuステーションを通してトレードする構成にしているのは、個人作成の自動売買ツールの誤動作等で、AUカブコムサーバーに負荷が掛かるのを防ぐ目的があると予想されます。他にも、一度に大量の発注が出来ないようなアサーションが、kabuステーション側に入っています。

## 4-2. 自動売買ツールの場所
https://github.com/EmVerif/AutoTradeToolLimited
上記にコードを公開しました。ただ、最初に書いた通り、動作保証していないので、そのまま動かす場合は、自己責任で実行してください。コードのみの公開であり、実行体は個人で生成してください。
4-1章に記載の関係図の通り、このC#プログラムだけでは自動売買はできません。AUカブコムとの契約、kabuステーションのダウンロードは、別途必要となります。

以下は、使用する上での注意点です。

1. ツール動作させながら、スマフォ等からトレードすると、金額や株数管理が正しく動作しません。排他制御が出来ないためです。
⇒自分は、ツールを停止させてから、スマフォでトレードします。
1. ツールで自動売買している銘柄を、スマフォ等からトレードすると、金額や株数管理が正しく動作しません。
1. kabuステーションの仕様だと思われますが、kabuステーションは毎日立ち上げ直す必要があります。

## 4-3. 自動売買ツールのGUI
![自動売買ツールのGUI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629725/e6798f49-ff7c-3aac-ff64-8556c7cb10c4.jpeg)
GUIは上記を参照してください。銘柄を削除する場合は、銘柄を右クリックすれば出てくるはずです。短期投資用のタブは、自信が全くないトレードなので、公開プログラムからは削除しました。簡単に書くと、VWAPを基準に先物を自動売買する機能です。

## 4-4. 自動売買ツールの構成概略
### 4-4-1. モデル階層の概略
![自動売買ツール、モデル階層.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629725/b1573d22-e011-1943-1169-b7381d9c64ac.jpeg)
モデル階層は上図の構成になっており、
1. 銘柄毎にAutoRebalanceSymbolMクラスをインスタンス化し、そこで、銘柄コードや持ち株数など、銘柄毎の情報を管理
1. AutoRebalanceTopMクラスは１個だけインスタンス化しており、そこで、時価総額など、全体の情報を管理
1. Communicationクラスは１個だけインスタンス化しており、そこで、kabuステーションとの通信を実行

上記の通りです。ビューや、ビューモデルの階層は、ツールの表示やボタン操作に関係することなので、記載は省略します。

### 4-4-2. Communication
https://github.com/kabucom/kabusapi/releases/tag/C%23-v1.1.0
基本は、上記サンプルプログラムとほぼ同じですが、売買用メソッドは複数の通信を組み合わせて作っています。これは、この自動売買アルゴの特性上、ある程度のリアルタイムなトレードと、ある程度の正確な売買が必要ですが、

1. リアルタイム性を優先し、成り行き売買をすると、約定値段のバラつきが大きくなり、比率管理で誤差が生じやすい
1. 正確性を優先し、指値売買すると、トレード成立に時間が掛かる

という問題があるため、以下の購入メソッドのように、成り行き売買ではなく指値売買をするが、指定枚数の約定をしなくても、一定時間後にトレードをキャンセルし、その後約定枚数を確認するように売買シーケンスを組んでいます。売却メソッドは、購入メソッドとほぼ同じシーケンスのため、実際のプログラムを参照してください。
```c#
        public static void Buy(string inSymbol, Decimal inPrice, Decimal inQty, out Decimal outBuyNum, out Decimal outPrevCash, out Decimal outPostCash)
        {
            lock (_CommLock)
            {
                // 購入前のキャッシュ取得
                outPrevCash = GetCash();

                // 購入要求
                （省略）

                // 0.5秒後にキャンセル（0.2秒はその前に待っているため、引く。）
                （省略）

                // キャッシュの変化チェック
                outPostCash = GetCash();
                Boolean finFlag;
                do
                {
                    outBuyNum = GetContractNum(orderId, out finFlag);
                }
                while (!finFlag);
                if (outBuyNum != 0)
                {
                    // トレード成立した場合は、現金値が変化するまでポーリングする。
                    Decimal diffCash = outPrevCash - outPostCash;
                    Decimal diffCashMax = outBuyNum * inPrice * 1.01M;
                    Decimal diffCashMin = outBuyNum * inPrice * 0.9M;
                    Int32 loopCnt = 0;

                    while ((diffCash > diffCashMax) || (diffCash < diffCashMin))
                    {
                        loopCnt++;
                        if (loopCnt >= 100)
                        {
                            throw new Exception("想定外エラー：購入後の現金取得失敗。");
                        }
                        outPostCash = GetCash();
                        diffCash = outPrevCash - outPostCash;
                    }
                }
            }
        }
```
ここで、「キャッシュの変化チェック」というところで、キャッシュ値が変化するまでループさせています。これは、通信ログを確認すると、キャッシュ情報取得する通信が、どうもAUカブコムサーバーに直接確認しているのではなく、kabuステーション内部にcacheされた情報を取得しているだけであるようで、タイムラグが生じているからです。改善要求を出していますが、たぶん、改善には時間が掛かるので、キャッシュ値の変化の妥当性を確認することで、売買トレードを完結させています。

### 4-4-3. AutoRebalanceSymbolM
銘柄毎の情報管理をしており、ここで、指定された比率から計算される値段と銘柄時価の差を計算し、ズレが閾値を超えたら、そのズレを修正するトレードを実行しています。
```c#
        public void Rebalance()
        {
            RebalancePreprocess();
            if (!_BoardInfo.TradeEnableFlag)
            {
                return;
            }
            if (AdjustFlag)
            {
                // キャッシュの増減や、割合変更による調整売買
                // ここで発生した売買は、PrevTradeに反映させない。
                AdjustTrade();
            }
            else
            {
                // 通常リバランス動作
                RebalanceNormal();
                VirtualCurrentRatio = CurrentRatio;
            }
        }
```
ズレを修正するトレードをリバランスと呼んでおり、上記メソッドのRebalanceNormal()内で実行しています。また、資金を追加削減したり、比率を変更すると、株数を調整する必要が出てきますが、その調整をAdjustTrade()で実行しています。その調整とは、VirtualCurrentRatioに資金や比率変更前の比率を記憶しておき、変更直後のトレードは、比率がVirtualCurrentRatioに近づけるようにトレードし、リバランスアルゴの影響がなるべく発生しないようにしています。

他にも、

1. 2章に記載のリバウンド判定
1. リバランス後、設定比率と実際比率のズレが大きくならない工夫
   1. 半分ずつトレードを実行
   1. スプレッドが広い場合にトレードを停止

と、細かい点は存在しますが、うまく記事を書く自信はないので、省略します。気が向いたら追加していきます。。。

# 5. まとめ
今回は、単純な自動売買を紹介しました。ただ、この単純なトレードであっても、自分の裁量だとほぼ出来ないトレードをしており、しかも、それで少量であっても利益を上げているので、自分にとっては、自動売買が非常に有効に思えました。例えば。。。

1. 下落局面で、含み損を抱えてしまっていても、下落幅の小さい株を売り、下落幅の大きい株を買う
1. 上昇局面で、一度売った株を、高い値段で買い戻す

上記のようなトレードであっても、自動売買であれば、ルールに従って実行してくれます。株トレードを初めてから、ルールを守ってトレードするのが重要なのに、難しいということを思い知らされましたが、自動売買ツールを使いルールを守らせることで、心が軽くなった気分です。もちろん、感情コントロールが完璧で、ルールを守るのが可能な人には不要なツールでしょうが、上記のような心当たりがある人で、プログラミング出来る人は、自動売買にチャレンジしてはいかがでしょうか。また、さらに上級者であれば、金利、チャート分析、ニュースサイトの文字解析をしたトレードを組むことが可能かもしれませんので、チャレンジしてはいかがでしょうか。

これで、自動売買が流行り、他人の貯金が少しでも市場に流れてくれたら、株価が上がって、自分が儲かｒ。。。善意で記事を書いています！！！！