15
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

仮想通貨botterAdvent Calendar 2024

Day 9

クラウド上のサーバーレスのbotを支えるサービス

Posted at

これは、仮想通貨botter Advent Calendar 2024 シリーズ2 9日目の記事です。

今までこんな感じのことをやっている人間です。

Python歴: 6年
仮想通貨トレード歴: 7年
クラウド利用歴: 7年
Botter歴: 2024年3月時点で 0年!

「おいおい、そのスキルセットがあるのにまだ裁量トレードで消耗してるの?」
そんな煽りが脳内を駆け巡り、ついに私もBotterデビューを決意しました。

すでに有名なbotter先輩方が、Botterの秘伝や構成例を公開されているのを参考にしましたが、難しい界隈用語に初見殺されてちんぷんかんぷん。。
また、探し方が悪いからなのかニッチだからなのか、MLや売買ロジックの外側の部分、特にマイクロサービスを中心に構成するとしたらどうするのか、という例が多くないと感じています。
「なら、とりあえず1つでも公開してみるか」と動き始めた次第です。

職業柄、クラウドITインフラエンジニアなので、クラウドサービスの特性を活かした構成は経験しています。でもこれで、この構成でつよつよBotが作れるわけじゃないので、そこの誤解はナシで!お願いします。

「DEX Bot?なにそれ美味しいの?(旨味はあるんだろうけれど)」という状態なので、CEX Botです。あとエッジ狙いとか適正レートへの貢献とかじゃなくて、低頻度botです。
まずは自分がやりたいように形にすることが重要ですよね!

どのクラウドサービスで動かすのか

普段はAWS使いですが、どうせなら AWS, Azure, GoogleCloud の3大クラウド全部盛りでBotを動かしてみます。

クラウド環境でBotを動かすサービスは主に3つ考えられます。

  • IaaS (仮想マシン) 上に直接構築:
    自由度が高くOSレベルで何でもできる。独自のスケジューラーや通知システムを作りやすい。手間もコストもそれなり。
  • Dockerコンテナ によるデプロイ:
    ローカル環境で作業したコンテナをそのままクラウドにデプロイできる。「ローカルで動いたのにクラウドでコケる」問題を回避できるのがデカい。
  • FaaS (Function as a Service) によるサーバーレス構成:
    低コストで安い。 Botのプログラムを関数単位でデプロイ可能。 そして安い。 コードに集中できる。 そして安い。

低コストで始めるならFaaS一択でしょう。
「え?コスト?そんなのBotの利益で吹き飛ばせるだろ」
とツッコミが来そうですが、少しでも安く抑えられるのはメリットです。

3大クラウドのFaaSはこれです。

  • AWS:AWS Lambda
  • Azure:Azure Functions
  • Google Cloud:Cloud Run functions

今回はFaaS+周辺のサーバーレスサービス(イベントトリガー、ストレージなど)と連携した構成で進めてみます。

どういうbotか

今回作ったのは、特定の通貨ペア(例:BTC/USDT)で、売買シグナルを拾って自動エントリーする、量産型初心者向けBotです。
以下の4つの機能をモジュール化して実装しています。

  • ローソク足データを記録する機能
  • 売買シグナルを基にトレードする機能
  • MLによるパラメーター最適化機能
  • データ参照用Web機能

全体構成図

上述した全ての機能を1枚で表した全体構成図です。

まずは、特定のクラウド事業者に限定しない形で図にしています。

crypto-botter-serverless-Common.png

各クラウド事業者の共通項の表現をしようとすると、なんだかぼやけてしまいますね。
イメージしにくいので、AWSの場合で示してみます。

crypto-botter-serverless-AWS.png

これで分かりやすくなったでしょうか。

  • タイマー →  Amazon EventBridge
  • ワークフロー →  Step Functions
  • オブジェクトストレージ →  Amazon S3
  • セキュアデータ保管 →  Systems Manager Parameter Store
  • Key-Value DB →  Amazon DynamoDB
  • メッセージ通知 →  Amazon Simple Notification Service (SNS)
  • CDN →  Amazon CloudFront

設計のポイントがいくつかありますが、その中でも 関数の粒度データの配置 は大事ですので、この2点にフォーカスします。

関数の粒度

1つの関数に機能を詰め込みすぎると、実行時間オーバーのリスクがあったり、コードのメンテナンス性が悪化したりします。かといって細かく分けすぎると、パフォーマンスのオーバーヘッドや、関数間の連携のロジックが逆に複雑化するなどの懸念も。

今回の例では、主要な処理を5つの関数に分けています。

  1. update-price-dataset: ローソク足データの更新
  2. signal: シグナルの生成
  3. position-control: ポジション管理と注文処理の呼び出し
  4. order: 注文処理
  5. update-params: パラメータの最適化

一旦はこの単位で作成していますが、複数の取引所間の注文があるなら order をさらに細分化するのが良さげ。機械学習を強化するなら update-params を細分化するのもありです。

データの配置

データの扱いをナメると痛い目を見るのがBot界隈です。「APIキー漏洩で資産蒸発」なんて話も聞きます。今回は以下の構成でデータを管理しています。

  • シークレットデータ保管: 注文APIキーを保管
  • Key-Valueデータベース(NoSQL DB): 学習済みパラメーターを保管
  • オブジェクトストレージ: ローソク足データやポジション状態データを保管

ポジション状態データは、静的Webサイトホスティングで外部から参照したいので、オブジェクトストレージに置いてます。ローソク足データは、Key-Valueデータベースの方が良いのかも。

動作1 ローソク足データを記録する機能

crypto-botter-serverless-flow1_cu.png

赤枠の部分を説明します。
ローソク足データを記録する機能です。いわゆる自炊です。

  1. タイマートリガーで定期的にワークフローを呼び出します。1分足、5分足などに応じたインターバルで実行します。
  2. ワークフローには、3つの関数 update-price-datasetsignalposition-control を順に登録しています。
  3. 関数#1 update-price-dataset
    取引所のPublic APIから最新価格データを取得します。オブジェクトストレージ(バケット/BLOB)に格納されているロウソク足のデータを読み込み、最新の値を追記して、再びオブジェクトストレージに保管します。
  4. オブジェクトストレージに格納するファイルは、バックテスト用に扱いやすい形で整えます。

動作2 売買シグナルを基にトレードする機能

crypto-botter-serverless-flow2_cu.png

赤枠部分を説明します。(動作1の赤枠とは囲んだ位置が違います)
ここがトレードの本番の機能。シグナルに基づいてポジションを操作します。

  1. 関数#2 signal
    売買ロジックの中核。機械学習で最適化されたパラメータを活用し、ローソク足データを分析します。
    出力されるシグナルは、5種類です。
    • BB (強い買いシグナル)
    • B (買いシグナル)
    • Y (シグナル無し)
    • S (売りシグナル)
    • SS (強い売りシグナル)
  2. 関数#3 position-control
    現在のポジション(例: 保有中のロング・ショート量)と最新のシグナルを元にオーダーを決定します。
    この部分は、シグナル Y なら全力ロングに対する75%を超過する量を決済、等のように、ポジションサイズ調整アルゴリズムに依存するため、戦略の優劣を左右します。
    ワークフローのサービスでは、関数#2 の出力データを 関数#3 の入力データとして渡すことができるので、5種類のシグナルのうち1つを渡しています。
  3. 関数#4 order
    最終的に取引所のPrivate APIを叩き、注文を実行します。この関数は position-control 関数内から直接APIで実行しています。

取引所にもよりますが、例えば 5 ETH のショートポジションの状態で 8 ETH を購入する場合、5 ETH のショート決済と、3 ETH のロング購入の2回API実行が必要になったりします。そのためorder関数は、ワークフローで定義しておらず、関数#3 position-control のコードから呼び出すようにしています。
注文用のPrivate APIキーは、安全のためシークレット保管のサービスを利用します。
注文結果は、Slackやメール通知サービスでリアルタイムにレポートします。

動作3 MLによるパラメーター最適化機能

crypto-botter-serverless-flow3_cu.png

Botの肝となる、機械学習(ML)によるパラメータチューニングを自動化した機能です。これが戦略の成否を大きく左右します。

  1. もう1つのタイマートリガーです。機械学習を頻繁に回すと過学習や無駄なリソース消費に繋がります。
    そのため、週足単位の更新頻度(例: 毎週日曜深夜)に設定しました。
  2. 関数#5 update-params
    機械学習を用いて、戦略ロジックに用いるパラメーターを最適化します。パラメーターとは、例えば移動平均の期間 m, n やRSI閾値などです。学習済みの結果はKey-Value DBに書き込み、リアルタイム戦略で利用します。

注意点として、クラウドFaaSの実行時間には上限があります。(例: AWS Lambdaなら最大15分)その値を超えないように学習時間を調整しました。

動作4 データ参照用Web機能

crypto-botter-serverless-flow4_cu.png

スマホやPCから、Botの稼働状況を確認できるWeb UIを提供します。
外出先でスマホからサクッと確認できるのが、この機能のメリットです。
CDNを使わずとも実装可能です。
AWSの場合は、AWS Amplifyを使うと、CDN+静的Webサイトホスティングをワンストップで構築することもできます。

Webは参照だけを実装しましtが、中断・再開・ロジックの切替、などの更新機能を実装すれば、より便利になるでしょう。

Azureの場合

crypto-botter-serverless-Azure.png

こちらはAzureで実装した場合のアーキテクチャ例です。

  • タイマー →  アプリのタイマートリガー機能
  • ワークフロー →  ロジックアプリ(logic apps)
  • オブジェクトストレージ →  Blob Storage
  • セキュアデータ保管 →  Key Vault
  • Key-Value DB →  Cosmos DB
  • メッセージ通知 →  関数アプリからSlackのWebHookやSendgrid
  • CDN →  Cloud CDN

構築時に、Azure Functions周りの権限エラーが多発したため、それに何度も泣かされ心が折れそうになりました。
その結果、正直なところ今回の構成は部分的にしか完成しておらず、フル実装の実績はありません。ただ、理論上は正しく動作するはずです(たぶん!)。

Google Cloudの場合

crypto-botter-serverless-GoogleCloud.png

こちらはGoogle Cloudを使った構成例です。

  • タイマー →  Cloud Scheduler
  • ワークフロー →  Workflow
  • オブジェクトストレージ →  Cloud Storage
  • セキュアデータ保管 →  Secret Manager
  • Key-Value DB →  Firestore
  • メッセージ通知 →  Pub/Sub
  • CDN →  Cloud CDN

こちらもまだ途中までの実装のみで、本格運用まで持っていっていませんが、パーツ単位では動作するので、おそらくこの構成で動作するはずです(きっと!)。

比較してみた感想

AWSが一番構築しやすい印象でした。(普段から使い慣れているからというのが大きい。)
AWSは特に以下の点が良かったです。

  • デプロイ爆速:
    AWS Lambdaは、関数の再デプロイが10秒もかかりません。「コード修正→即反映」のスムーズさは最高です。Azureはデプロイが劇遅なので、もう少し早いといいなぁ。。
  • 失敗率の低さ:
    AWSでは、クラウド基盤側の原因で関数実行が失敗することは、何カ月回しても0回。この安定感はさすがクラウド界のレジェンドという感じです。
  • IPの信頼性:
    関数から取引所APIへのアクセスで、AWSでは特に問題なかったですが、Google Cloudではいくつかの取引所でリクエストが弾かれました。IPの信頼性か。。

Google Cloudには、Cloud Runコンテナをという強みもありますし、AzureにはAzureの利点もあります。
視点を変えて各クラウドの特徴をもう少し生かすと、評価も変わるかもしれません。

利益は出たのか

「ガチホ(HODL)勢にはぜひ勝ちたい!」 と強くライバル心を燃やして、HODLに勝つためのML戦略をバックテストして初期パラメータを決めて、実践投入しました。

2024/4/10から2024/11/30までの結果は、、、

比較 2024/4/10時点 2024/11/30時点 増加率
HODLだった場合 1BTC=70612 USD 1BTC=90716 USD 28.47%
botの運用結果 USD評価額 100 (とする) USD評価額 107.66 7.66%

なんと、HODLにぼろ負けじゃないか・・・ビギナーでも勝ったよって記事にしたかったのに、残念!!まあそんなにうまくいくわけないよね。
利益出ているんだし、いいか。

おわりに

この構成例を見て、
「俺もBotterデビューして爆益になるぞ!」
と思って邁進してくれるとうれしいです。
・・・
・・・嘘です。そんなこと思っていません。
自己責任 の一言に尽きます。この沼は甘くないし、爆益の裏には爆損が潜む世界です。でも、それでも挑戦してみたいと思うなら、どうぞご勝手に一緒に進んでいきましょう。

シンプルな低頻度botならこんな構成になるよね、なにをダラダラと書いてあるんだこの記事は
って突っ込まれる内容になってないだろうか。
まあいいか。

もう少し本腰を入れて、まともなbotを作れるよう、情報をキャッチアップして取り組もうかな。

15
8
0

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
  3. You can use dark theme
What you can do with signing up
15
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?