見出し画像

スイングトレード型botの損切問題① ~これまでの経緯~

botをつくり始めて1年9か月が経ちました。
最近になってちょこちょこと勝てるようになったこと、そしてこの間のbot開発をとおしていろいろと知見も得ましたので、今年を締めくくるにあたって久しぶりにポエムを投稿します。

前回のポエムからやったことが多く個々に書く気力もないため、今回はスイングトレード型botにおける損切問題を主題にまとめていこうかと。
(注:書いていたら長くなったのでまさかの3部編成の予定です)

まだまだ若葉マークを外せない初心者の戯言です。過ちや誤認識も多分に含まれていると思われますので、悪しからずご了承を。

あと前回も言ったことですが、私はゴリゴリガチガチにカーブフィッティングさせることにやりがいを見出しています。私のbot自体が相場の変動につねに過剰にフィッティングさせ続けたいという思想でつくっています。

「これカーブフィッティングじゃん(笑)」という励ましは私への誉め言葉です。その叱咤激励を受けてさらにカーブフィッティングに励んでまいります。

恥ずかしがることはありません。公言してしまえば、なにも恐れることはありませんよ。逆にこそっとフィッティングさせて、中途半端な成績のチャートになってしまう方がフィッティング職人としては恥ずかしい事態です。やるなら徹底的にカーブフィッティングさせたほうが清々しくていいですね! 


1.botのタイプ


最初に、私がつくっているbotのことを述べておきます。

【Botタイプ】 スイングトレード型(値動きの上下をとりにいく平凡なbot)
【タ―ゲット】 BTC ※BUY/SELL 両方向
【使用時間足】 5sec、1min
【botの特徴/特性】
①     エントリー初期条件:ストキャス BUY:< 25 / SELL :>75 ※毎次可変
②     獲得損益に応じてエントリー条件へのフィードバックあり。
③     エントリー指値位置も獲得損益に応じて可変。 
④     イグジット位置は可変。どの位置でイグジットするかは値動き次第。
⑤     獲得損益に応じてロジック自体の転換/切替/無効あり..
⑥     損切設定 : 最終ロスカット:±5% ほか検討中 ※後述

スイングトレードを狙っているわけではなく、いろいろ作っていて最終的にたどり着いた・・・というか自分が戦えそうなフィールドが結局これだったという次第です。

botを作り始めた当初から、相場にゴリゴリに追従させたカーブフィッティング指向のモデルをつくっており、いまもその流れを踏襲しています。
特徴として、おそらく自動売買を志す人ならみんな大好きテクニカル指標をふつうに使ってエントリーします。

なお、いろいろ試した結論として正直この条件はなんでもいいかなと。
ストキャスでも移動平均でも、ボリンジャーバンドでも、それこそ価格が何ポイント動いたとか、ある程度エントリー頻度が稼げる条件でいて、かつ調整代があればつかえます。条件によってbotの挙動は大きく変わるので、そのへんの好みかなと。

初期条件をもとに売買を繰り返しながら、しきい値や指値の位置を微調整して動いてくれるので、使い続ければそれらしく収まるところに収まって動き続けてくれます。

なので、買い優勢のときは売りエントリー側のしきい値を厳しくして制限する、値幅のとれそうなときは指値位置をちょっと遠くにしてみるとか、そういう微調整をしながら動き続けます。

そして、発動回数は少なめですが自動でロジックそのものを切り替える機能も相変わらず入れています。この機能を有効につかうには、使用ロジックが調子悪くなるタイミングで、高頻度で損失を連続で叩いて一気に切り替える必要があるため、うまくいく時といかない時があるのが課題です。

とりあえずbotの説明としてはこんな感じで、次に、これまでにやったことをざくっと時系列順にまとめました。



2.これまでにやったこと

―2022.12~2023.11の経過ー

  • 特定期間で過剰最適化させたロジックーパラメータを多数格納した可変型 bot化 ⇒ 時間経過にしたがい成績悪化。相場に追従できない。×

  • 上記ロジックーパラメータの選択判断に機械学習導入。MLbot化 ⇒ 学習後、ある特定のロジックーパラメータしか選択しなくなる。失敗 ×

  • botを稼働させながらの新規パラメータの作成機能/オートチューニング機能検討 ⇒ バックテストと実損益の乖離が発覚する。×

  • 仮想取引と実売買の乖離-執行価格の位置について調査。⇒ 指値ほか、成行でもある程度狙ったところをとりにいける知見を得る。 〇

  • 不利な指値エントリー問題-指値位置の相場への追従調査 ⇒ 指値位置の最適化のために、フィードバック機能追加。成功 〇

  • 運動方程式を用いたポジション管理の検討 ⇒ バックテスト上では過去最高成績のモデルが完成するも、実際にはエントリー時の約定が追いつかず成績ふるわない △

  • 執行速度の研究、鍛錬のためにmmbotへ挑戦 ⇒ しばらく動かしながら作りこんでいたがbitflyerのSFDが発動し、検証できなくなったので断念 △

  • mmbotの副産物としてbotの高速化[1min ⇒ 5sec]を行う、⇒ 5sec対応のbotに全面改装 これが後々かなり効いてくることに 成功 〇

  • 強化学習にも手を出す。 ⇒ 簡易的な学習機能の試作。これが後々のフィードバック機能の改善につながる 〇

  • 短期間で大量の試行を繰り返し行う。 ⇒ botのバグ、API処理の非効率箇所を修正したことでbotの安定性向上 〇

  • エントリー/イグジット位置ほかbot挙動の視覚化 ⇒ これまで気づかなかったbotの不具合箇所が洗い出される 〇

  • 数秒間隔での短期スキャ型botの試行 ⇒ 短期間でコツコツ安定して稼ぐように。が、DDの影響大きい △

  • 実働botへのバックテスト機能移管/統一 ⇒ bot改良の効率が大幅に向上+バックテストと実損益の乖離縮小 〇

  • 相場への追従性向上のため、ロジック、パラメータへのフィードバック機能実装 ⇒ botの成績大幅に向上。放置してもそれなりに相場へ食らいつくようになる 〇

  • 夢のお告げにしたがい、これまで増改築を繰り返していたbotの不要箇所を削除 ⇒ 見違えるほど好成績のbotに 〇

  • 11月頭から連戦連勝だったが、数回の急騰/急落で相変わらず大ダメージ ⇒ 損切りの難しさを痛感、対策検討中 (←今ここ)

長くなりましたが以上です。
ほかにも細かなことをいろいろやっていますが、おおむねこの流れでbotの改良を細々と続けてきました。
自分にとってのターニングポイントになったところを次項で3点補足します。



3.ターニングポイントになったこと


①     MLbot/mmbot、強化学習にも手を出してはいた。


成果は上がらなかったもののMLbot、mmbotにも手を出し一応動かしてもみました。おかげで得られた知見は多く、副産物的にbotの構成を見直すことができたのは大きな成果物でした。(いまはML機能を無効にしています)

そして、MLbot化した流れで強化学習にも手を出しましたが、これがかなり自分の考え方を変えてくれたと思います。

それまでにも、固定ロジックではなくフィードバックは必要だなということは感じていましたが、強化学習の本に書いてあった、「報酬」という概念は新鮮でした。

機械屋さんの頭だと、あくまで制御量という無機質な意味合いで扱っていたのでこういう考え方もあるんだなとかなり衝撃を受けました。

こちらの本でいろいろ学ばせていただきました。
完全な強化学習型のbotは作れていませんが、強化学習の概念を参考にしたおかげで実態に即したフィードバック機能の実装につながったような気はします。


②     バックテスト機能の統合


わりと初期の段階からバックテスト結果と実損益が乖離しているな、とは感じていました。とはいえ、巷の情報からすれば「バックテストと実際のトレードとは乖離するもの」という前提で、その乖離の縮小について述べられている記事を見かけました。

なので、「まあ、そんなものかな? なんか乖離大きいきがするけど・・・」ぐらいの間隔で、執行価格のずれだとか、約定頻度の差異だとかを埋める作業を続けていました。

そんなこんなで改善を続けていましたが、あるとき、バックテスト上では大きなマイナスなのに、実損益が大幅プラスという今までとは逆の傾向が出現するようになりました。今年の9月くらいだったと思います。

それまでは、バックテストでプラスなのに、実際はマイナスというケースばかりだったので、これはおかしいと気づきました。

一般的にどういう形態でバックテストをするのが正解か不明ですが、私は従来からバックテストと実働botは分けていました。実働botに余計な機能は不要だろうという考えからです。ですが、おそらくバックテストと実働botの間でなにか差異が生じているだろうということで、思い切ってバックテスト機能を実働botに統合してみました。

やるまではめんどくさいだろうなーと抵抗感がありましたが、冷静に考えたらオンタイムで引っ張て来ている価格データの部分に、過去のデータをぶち込んで、売買関連のやりとりを制限するだけだったので、簡単に統合できたのが盲点でした。(もっと早くやっておけばよかった)

すると、それまでのバックテストとはがらりと変わり、実損益とそれほど乖離していない結果が出力されるようになったわけです。

ちなみに、それまでのバックテストと実働botでなにが違っていたのか、という点ですがこれはまだはっきり分かっていません。成績には影響しないだろうと変更しなかった細かい箇所というのが多数あるため、おそらくそれらの何かが乖離の主原因だったと考察しています。

なにが正解か分かりませんが、私にとってはバックテストを別に組んでいたことで誤った検証結果に基づいて検証を続けてしまっていた。これが反省点です。

③     結膜炎と夢のお告げ


ここからは非科学的な話ですが、ここ最近での最大のブレイクスルーのきっかけでしたので一応書いておきます。変な話なのでスルーください。

10月末ぐらいから、ちょっと重い結膜炎に罹りました。ウイルス性らしく今も後遺症に苦しんでいます。ちょうどこの結膜炎がピークだったときの夜、あまりの目の痛さにうなされながらなんともいえない状態で布団のなかでもだえていた夜のことです。

どういう話だったかは忘れましたが、夢の中に変なおっさんが現れ「余計なものは捨てよ」というお告げがありました。

(なんか二人で町の中を歩いていて、壁を蹴って飛んでいたような、場面がコロコロかわるような夢でした。壁を蹴ろうとしていたときだったかに、そんなことを言われました。変なおっさんやったことは確か。え? あなたもおっさんでしょって? まあ、ようはおっさん二人が仲良く散歩しとったということで)

夜中に目が覚めたとき、そのお告げのことが印象に残り、とりあえず寝直しましたが起きてからもやはり気になりました。(変な胸騒ぎ。おっと、動機ではないですよ)

そこで、目は痛いものの夢のお告げにしたがって、botの余計だと思われる箇所を消していきました。

もう使わないけど残しておいた関数、もう使わなくなったtalibで生成したテクニカル指標、ML化したときに増設した試験用の処理式、データフレームなどなど。

削ってみると、けっこういらないものだらけだったようで、かなりさっぱりしました。とりあえずちゃんと動くかな? ということで長めのデータをつかってバックテストをかけ、しばらく離れましたが、驚いたのは、バックテスト結果をみたときです。

このときの衝撃は久方ぶりにまさに肩が震えるというか、1回その場を離れてもう一度ディスプレイを見直したというか、とにかく驚きました。

それがこれ。↓↓

先ほど述べたようにバックテストを実働botに統合し、ある程度実損益に近い結果が出るようになったことを確認していたので、バックテストの結果が“これ”ということは、おそらく実損益でもそうなるんだろうという確信がありました。

そこで、とくに確認もせずにそのままの勢いでトレードモードに切り替え、放流したわけです。その結果がこんな感じでした。↓↓

霧が晴れるがごとく、これまで追い求めていたものについにたどり着いた瞬間でした。(目は痛いけど)

この理由についてですが、夢云々の話は置いとくとしても、こちらについてはその原因が判明しています。

それは、最終ロスカット用につかっていたATRの値の取り方でした。
最初、私のbotはプログラムとしての挙動に自信がなかったので、15分足で構築していました。ATRも15分足ベースで作成したものをつかっていたわけです。

それが、慣れにしたがって15分→5分→1分→30秒→15秒→5秒とbotの監視期間を刻むなかでそれに基づいて算出される、ATRの値も実際はかなり小さい値になっていたのに気づきませんでした。

さらに災いしたのは、初期に開発につかっていた価格データ自体が、btcにかなりの値動きのあった時期のデータだったため、必然的に毎次のATRも数値が大きかった時期でした。

そのときの環境に準じて入れたATRベースのロスカット条件を変えずにずっと継承し続けていたため、直近は5sec termで生成した小さめのATRがこの条件式に入っていたわけです。そのためかなりのタイミングでロスカットしてしまう動きになっていました。

「なんかストップロスしすぎじゃね?」と思ったこともあったように思いますが、「まあ、損切りも重要だしね」とさして問題意識ももたずに放置していたように思います。少なくともロスカット部分に注目したことはありませんでした。

この条件式も狙って消したかというとじつはそうでもなく、「削除、削除、削除・・・」と結膜炎の目で探すなかで、たまたまほかの損切り条件と一緒に消してしまったことで気づきました。
(ロスカットまで消すつもりはありませんでした)

なお、当然ロスカットまで消した覚えはなかったので、なにを消したらこんなに成績が上がったのかを探すのに、また四苦八苦して元のコードとにらめっこして間違い探ししたという感じです。(目が痛いのに)

整然とトラブルシュートして成果が上がるのが理想ですが、残念ながら私のケースでは、変な夢のお告げに導かれたこと+結膜炎で目が痛かったことによるヒューマンエラーにより、今まで気づかなかったコードの誤りに気付いたという流れです。

たまたまに、たまたまを重ねた出来事が功を奏した結果ですので、あまり褒められたものではないでしょう。というか、多分諸々の間違いに早く気づけていたらもっと早く成績をあげれていたのに。後悔ばかりです。

とりあえずロスカットの条件は、見直して入れ直しました。

いろいろやりすぎて話が発散してしまいますが、とりあえずそれなりに動くbotが出来たというのが結論です。そのうえで一つの教訓として、損切りが効きすぎると、ロジックの良さが損なわれるというのはやはりあるな、ということを図らずも気付きました。

直近では、それなりに勝ちつつも数回のDDで大ダメージを受ける問題に再びぶち当たっています。

このあたりの自分の考えと対策案については次の記事で書きたいと思います。長くなってしまいましたが、とりあえず直近までの経過と言うことで。

 
 
 

 


この記事が気に入ったらサポートをしてみませんか?