前回の記事に引き続き、今回も仮想通貨botの開発状況をまとめていきます。
今回は「Rust×Pythonで行うbot作り」のアイデアをまとめました。
新しいbotの開発ネタとして、記録を残しておきます。
どうせやることだし、先に買っておく。https://t.co/5PhQPzdNVL
— よだか(夜鷹/yodaka) (@yodakablog) February 8, 2025
Rustとは?
Rustは、高速性・安全性・並行性を兼ね備えたシステムプログラミング言語です。Mozillaが開発し、現在はRust財団が管理しています。
Rustの特徴
- メモリ安全性が高い
- 所有権システム(Ownership System) により、ガベージコレクションなしでメモリ管理を行う。
- 借用(Borrowing)とライフタイム(Lifetimes) により、メモリの不正アクセスを防ぐ。
- Nullポインタやデータ競合が発生しにくい 仕組みになっている。
- 高速な実行速度
- CやC++と同等のパフォーマンスを発揮。
- ゼロコスト抽象化 により、抽象度の高いコードでもオーバーヘッドがほぼゼロ。
- 安全な並行処理
- Fearless Concurrency(恐れない並行処理) を目指し、スレッド競合をコンパイル時に防ぐ。
std::sync
やtokio
などの強力な並列・非同期処理機能をサポート。
- エコシステムが充実
- パッケージマネージャー Cargo により、依存関係管理が簡単。
- 高性能なライブラリ(
serde
でシリアライズ、tokio
で非同期処理など)。
- WebAssembly(Wasm)との親和性
- RustでWebAssemblyを記述し、フロントエンド(Webブラウザ)でも高性能なアプリが動作可能。
- C言語との互換性
- FFI(Foreign Function Interface) を利用し、Cライブラリと簡単に連携できる。
Rustの用途
- システムプログラミング(OS、組み込みシステム)
- Webバックエンド(Actix、Rocketなどのフレームワーク)
- ブロックチェーン・仮想通貨(Solana、Parity Substrate)
- ゲーム開発(Bevy、Amethyst)
- 分散システム(TiKV、Vector)
- 機械学習(tch-rs、rust-ml)
RustとPythonの組み合わせ
RustはPythonと組み合わせて使うことも可能。たとえば:
- データストリーミングや高速な数値計算をRustで処理し、Pythonで機械学習モデルを実装
PyO3
やmaturin
を使って、RustでPythonの拡張モジュールを作成

私の自動取引botでも、Rustでデータストリーミングや価格計算を高速化し、Pythonで取引ロジックを実装するという形が活かせそうです。
📌 PythonとRustの棲み分け

PythonとRustを組み合わせて仮想通貨の自動取引botを作る場合、それぞれの特性を活かして適切な棲み分けをすることが重要です。以下のような役割分担が考えられます。
機能 | Rustで実装 | Pythonで実装 |
---|---|---|
データ取得・ストリーミング | 高速なWebSocket処理 (tokio ) | 簡易なAPIアクセス (requests / websockets ) |
データ前処理 | 高速フィルタリング・集計 (polars ) | Pandasでデータ解析 |
価格予測 | 数値計算 (ndarray , nalgebra ) | 機械学習 (scikit-learn , PyTorch ) |
取引戦略の実装 | シンプルな戦略のバックテスト (backtest-rs ) | 複雑なMLモデルの適用 |
注文管理・リスク管理 | 低レイテンシな注文処理 (reqwest , serde ) | ロジックの組み合わせ (ccxt ) |
ログ管理・監視 | 効率的なロギング (tracing , log ) | 視覚化 (matplotlib , dash ) |
バックテスト | 高速なシミュレーション | 柔軟な分析 |
🌟 各モジュールの具体的な設計
1️⃣ データ取得・ストリーミング
- Rust:
- 高速WebSocket接続(
tokio-tungstenite
) - マルチスレッドで並行処理
serde
を使ったJSONパース
- 高速WebSocket接続(
- Python:
ccxt
を使ってスポットデータ取得(低頻度)- 過去データのロード・解析
2️⃣ データ処理・特徴量エンジニアリング
- Rust:
polars
やndarray
を使って超高速データ処理- 並列処理でリアルタイムフィルタリング
- Python:
pandas
でデータ解析- 時系列データの特徴量エンジニアリング
3️⃣ 価格予測
- Rust:
ndarray
,tch-rs (PyTorch for Rust)
を使って数値計算- 簡単な統計手法(移動平均、ボリンジャーバンド)
- Python:
scikit-learn
,tensorflow
,PyTorch
を使って機械学習モデルを構築- LSTM, Transformer, DQN などを利用
4️⃣ 取引戦略
- Rust:
- シンプルなロジック(スプレッドトレード、マーケットメイキング)
- 低レイテンシなアルゴリズム
- Python:
- 複雑なアルゴリズム(リスク制御、アービトラージ)
- MLを用いた動的戦略変更
5️⃣ 注文処理
- Rust:
- API通信の最適化 (
reqwest
) - 非同期注文 (
tokio
) - 超低レイテンシな発注
- API通信の最適化 (
- Python:
ccxt
でマルチ取引所対応- デバッグしやすい発注ロジック
6️⃣ ログ管理・監視
- Rust:
tracing
を使って軽量ログ記録- バイナリログフォーマット(パフォーマンス重視)
- Python:
matplotlib
,dash
で視覚化- Slack, Discord, Telegram へのアラート送信
🚀 RustとPythonの統合方法
1. PyO3
を使う
RustでPythonのモジュールを作成し、PythonからRustの関数を呼び出す方法。
メリット:Rustの高速性をPythonに統合できる。
例
use pyo3::prelude::*; #[pyfunction] fn add(a: i32, b: i32) -> i32 { a + b } #[pymodule] fn my_rust_module(py: Python, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(add, m)?)?; Ok(()) }
Pythonで利用:
import my_rust_module print(my_rust_module.add(3, 4)) # 7
2. FFI (cbindgen
) を使う
Rustで共有ライブラリ (.so
, .dll
) を作成し、Pythonから ctypes
や cffi
で呼び出す。
メリット:さらに低レベルな最適化が可能。
3. maturin
でPythonパッケージを作る
RustをPythonのネイティブ拡張としてビルドし、PyPIパッケージとして配布可能。
📌 まとめ
役割 | Rust | Python |
---|---|---|
データ取得 | WebSocketでリアルタイム処理 | API経由でデータ取得 |
データ処理 | 高速処理 (polars ) | 柔軟な解析 (pandas ) |
価格予測 | 数値計算 (ndarray ) | MLモデル (PyTorch ) |
戦略実装 | 低レイテンシ戦略 | 高度なロジック |
注文処理 | 高速APIリクエスト (reqwest ) | ccxt を活用 |
ログ管理 | tracing で軽量記録 | matplotlib で視覚化 |
Pythonの強み
- 柔軟な開発
- 豊富な機械学習ライブラリ
Rustの強み
- 高速処理
- 低レイテンシな通信
- 安全な並行処理
→ Rustでリアルタイム処理 & 取引API、PythonでMLとデータ解析 という棲み分けが最適!

この構成で開発を進めると、Pythonの機械学習の柔軟性 と Rustの低レイテンシ高速処理 の両方を活かせます。
実装の例
PythonとRustを組み合わせた仮想通貨自動取引botの設計について、リアルタイムデータ取得(Rust)→ ML戦略処理(Python)→ 取引実行(Rust) という流れで、実際のコード例を交えながら説明します。
🚀 RustでWebSocketデータ取得(リアルタイム)
Rustの tokio
を使って、仮想通貨取引所(Bybitなど)からリアルタイムのWebSocketデータを取得します。
📌 Rust(データ取得用)
src/main.rs
use tokio_tungstenite::connect_async; use tokio::stream::StreamExt; use serde_json::Value; #[tokio::main] async fn main() { let url = "wss://stream.bybit.com/realtime"; let (ws_stream, _) = connect_async(url).await.expect("Failed to connect"); let (_, mut read) = ws_stream.split(); println!("Connected to WebSocket!"); while let Some(msg) = read.next().await { if let Ok(msg) = msg { let text = msg.to_text().unwrap(); let json: Value = serde_json::from_str(text).unwrap(); println!("Received: {:?}", json); } } }
🔹 Rustのポイント
tokio_tungstenite
を使って非同期でWebSocket接続serde_json
で受信データをJSONとして解析- 受信データをリアルタイムで表示(取引所APIによってフォーマットを調整)
📌 Pythonで価格予測モデル
Rustで取得したデータをPythonに渡し、LSTM(長短期記憶ネットワーク)を使った価格予測を行います。
📌 Python(機械学習モデル)
ml_model.py
import numpy as np import torch import torch.nn as nn import torch.optim as optim # LSTMモデル定義 class LSTMPredictor(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(LSTMPredictor, self).__init__() self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True) self.fc = nn.Linear(hidden_size, output_size) def forward(self, x): _, (h_n, _) = self.lstm(x) out = self.fc(h_n[-1]) return out # モデルロード def load_model(): model = LSTMPredictor(1, 50, 1) model.load_state_dict(torch.load("lstm_model.pth")) model.eval() return model # 予測関数 def predict_price(model, data): data = torch.tensor(data, dtype=torch.float32).unsqueeze(0).unsqueeze(2) with torch.no_grad(): prediction = model(data).item() return prediction
🔹 Pythonのポイント
- PyTorchでLSTMモデルを定義
- 保存済みの学習済みモデルをロード
- WebSocketで受け取った価格データを使って予測
🚀 RustとPythonの連携
Rustで取得したデータをPythonのMLモデルに渡し、予測結果をRustに返します。
これには PyO3
を使用します。
📌 RustからPythonの予測関数を呼び出す
src/lib.rs
use pyo3::prelude::*; use pyo3::types::IntoPyDict; fn predict_price(price_data: Vec<f32>) -> f32 { let gil = Python::acquire_gil(); let py = gil.python(); let model_module = PyModule::import(py, "ml_model").expect("Failed to import Python module"); let model = model_module.call_function0("load_model").expect("Failed to load model"); let price = price_data.clone().into_py(py); let result = model_module.call_function1("predict_price", (model, price)) .expect("Failed to predict price"); result.extract::<f32>().unwrap() }
🔹 RustとPythonの連携のポイント
PyO3
を使ってPythonをRustから呼び出す- Rustで取得した価格データをPythonのMLモデルに渡す
- Pythonから予測値を取得し、Rust側で処理する
📌 Rustで取引注文の実行
予測結果に基づき、RustでBybit APIを使って取引を行います。
src/trade.rs
use reqwest::Client; use serde_json::json; async fn place_order(api_key: &str, secret_key: &str, side: &str, qty: f64, price: f64) -> Result<(), reqwest::Error> { let url = "https://api.bybit.com/v2/private/order/create"; let params = json!({ "api_key": api_key, "side": side, "symbol": "BTCUSDT", "order_type": "Limit", "qty": qty, "price": price, "time_in_force": "GoodTillCancel" }); let client = Client::new(); let response = client.post(url) .json(¶ms) .send() .await?; println!("Order response: {:?}", response.text().await?); Ok(()) }
🔹 Rustの取引処理のポイント
reqwest
を使ってBybit APIにHTTPリクエストを送信- APIキーとシークレットキー を使って認証
- 予測価格に基づき注文を発注(売買ロジックは後で追加可能)
🔗 RustとPythonの統合フロー
- Rust (
tokio
) でリアルタイム価格データを取得 - Rust (
PyO3
) で Python の ML モデル (predict_price
) を呼び出し、予測価格を取得 - 予測価格をもとに、Rust (
reqwest
) で取引注文を実行 - 結果をログに記録し、次の取引機会を待つ
🚀 まとめ
機能 | Rust | Python |
---|---|---|
リアルタイムデータ取得 | tokio + serde_json | ccxt (バックアップ用) |
データ処理 | polars | pandas |
価格予測 | なし(Rustでも可能) | PyTorch の LSTM モデル |
取引実行 | reqwest でBybit APIへ発注 | なし |
ログ管理 | tracing | matplotlib で可視化 |

この設計で、Rustの超高速処理とPythonの柔軟な機械学習 を最大限に活かすことができます。
しかし、これだけで終わらせるのは面白くないので、もう一工夫してみましょう。
より堅牢なコード

ロジックをさらに改善し、効率的な取引戦略 と パフォーマンスの向上 を図ります。
🛠 改善ポイント
- リアルタイムデータ処理の効率化
- RustでWebSocketを非同期ストリーミング処理
- データのバッファリング で過去データを一定期間保持(時間足データの作成)
- 価格変動率やボラティリティを計算
- 価格予測モデルの最適化
- 過去N件の価格をベクトルとして入力し、LSTMで予測
- 価格予測の信頼度スコアを導入し、エントリー判断を最適化
- 取引戦略の強化
- 注文執行ロジックを改善(指値注文 + 成行注文の組み合わせ)
- ポジションサイズの動的調整(資金管理)
- 取引履歴を記録し、トレード評価を自動化
🚀 改善後のコード
1️⃣ Rustでリアルタイムデータ処理
過去のデータを一定数保持し、価格変動率を計算できるようにします。
📌 Rust(データバッファ付きWebSocket処理)
src/main.rs
use tokio_tungstenite::connect_async; use tokio::sync::mpsc; use tokio::task; use tokio::time::{sleep, Duration}; use serde_json::Value; use std::collections::VecDeque; const BUFFER_SIZE: usize = 100; // 過去100件の価格を保持 #[tokio::main] async fn main() { let url = "wss://stream.bybit.com/realtime"; let (ws_stream, _) = connect_async(url).await.expect("Failed to connect"); let (_, mut read) = ws_stream.split(); let mut price_buffer: VecDeque<f64> = VecDeque::with_capacity(BUFFER_SIZE); while let Some(msg) = read.next().await { if let Ok(msg) = msg { let text = msg.to_text().unwrap(); let json: Value = serde_json::from_str(text).unwrap(); if let Some(price) = json["price"].as_f64() { if price_buffer.len() == BUFFER_SIZE { price_buffer.pop_front(); // 古いデータを削除 } price_buffer.push_back(price); // ボラティリティ計算 if price_buffer.len() > 10 { let volatility = calculate_volatility(&price_buffer); println!("Current Price: {}, Volatility: {:.4}", price, volatility); } } } } } // ボラティリティ計算(標準偏差) fn calculate_volatility(data: &VecDeque<f64>) -> f64 { let mean = data.iter().sum::<f64>() / data.len() as f64; let variance = data.iter().map(|x| (x - mean).powi(2)).sum::<f64>() / data.len() as f64; variance.sqrt() }
🔹 改善点
- 価格データをバッファリング → 過去の価格を保持し、傾向分析可能
- ボラティリティ計算 → 価格の変動率を分析し、リスク評価に利用
2️⃣ Pythonで価格予測(信頼度スコア付き)
予測モデルの信頼度スコアを計算し、取引判断を強化します。
📌 Python(価格予測モデル)
ml_model.py
import numpy as np import torch import torch.nn as nn import torch.optim as optim # LSTMモデル定義 class LSTMPredictor(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(LSTMPredictor, self).__init__() self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True) self.fc = nn.Linear(hidden_size, output_size) def forward(self, x): _, (h_n, _) = self.lstm(x) out = self.fc(h_n[-1]) return out # モデルロード def load_model(): model = LSTMPredictor(1, 50, 1) model.load_state_dict(torch.load("lstm_model.pth")) model.eval() return model # 予測と信頼度スコアの計算 def predict_price(model, data): data = torch.tensor(data, dtype=torch.float32).unsqueeze(0).unsqueeze(2) with torch.no_grad(): prediction = model(data).item() confidence = np.std(data.numpy()) # 標準偏差を信頼度スコアとして使用 return prediction, confidence
🔹 改善点
- 信頼度スコア を導入(ボラティリティが高いと信頼度を下げる)
- モデルの柔軟性向上(データを正規化して入力)
3️⃣ Rustで取引注文(動的ポジション管理)
価格変動と信頼度スコアを考慮し、注文量を調整する。
📌 Rust(リスク管理を考慮した発注)
src/trade.rs
use reqwest::Client; use serde_json::json; // 注文実行 async fn place_order(api_key: &str, secret_key: &str, side: &str, qty: f64, price: f64, confidence: f64) -> Result<(), reqwest::Error> { let url = "https://api.bybit.com/v2/private/order/create"; // 信頼度スコアに基づいてポジションサイズを調整 let adjusted_qty = if confidence < 0.01 { qty * 0.5 // 信頼度が低い場合はポジションを減らす } else { qty }; let params = json!({ "api_key": api_key, "side": side, "symbol": "BTCUSDT", "order_type": "Limit", "qty": adjusted_qty, "price": price, "time_in_force": "GoodTillCancel" }); let client = Client::new(); let response = client.post(url) .json(¶ms) .send() .await?; println!("Order response: {:?}", response.text().await?); Ok(()) }
🔹 改善点
- 信頼度スコアに応じて注文量を調整
- リスク管理を強化(不確実な相場では取引量を減らす)
🚀 改善後の全体フロー
- Rust (
tokio
) でリアルタイムデータ取得(過去データをバッファリング) - 価格変動率(ボラティリティ)を計算
- Rust (
PyO3
) で Python の ML モデルを呼び出し、価格予測 + 信頼度スコアを取得 - Rust (
reqwest
) で APIを呼び出し、信頼度に応じたポジションサイズで注文 - 取引結果を記録し、次の取引戦略にフィードバック
🎯 最適化のメリット
改善点 | 効果 |
---|---|
データのバッファリング | 過去の価格変動を分析しやすくなる |
ボラティリティ計算 | 相場の安定性を評価可能 |
信頼度スコア導入 | 取引の精度向上 |
リスク管理の強化 | 価格変動が大きいときはポジションを減らす |

この改良で、より堅牢な自動取引ボット になります! 🚀
まとめ
今回、初めてRustを使ったbot開発にチャレンジしてみました。
高速実行が可能なプログラミング言語として採用したRustでしたが、実際に調べて使ってみると、多くの使用方法があることにも気がつきました。
今後の仮想通貨bot開発をより広く展開していくためにも、Rustの習得を進めていきます。
参考にしている本
メインの開発とは別だが、これは今月の宿題。余力があるうちに次のことを進めておく。 pic.twitter.com/JyT01C7n24
— よだか(夜鷹/yodaka) (@yodakablog) February 10, 2025