Bot トレードロジック 機械学習・データサイエンス

仮想通貨botの開発記録#108(2024/9/30)「機械学習を用いた価格予測botの開発②」

前回の記事に引き続き、今回も仮想通貨botの開発状況をまとめていきます。

今回は「機械学習を用いた価格予測botの雛形」を作成しました。

Yodaka

実装に向けて必要な部分を解説しながら、コード全体の理解を深めていきましょう。

解決したかったこと

・機械学習アルゴリズムの構造の理解

・機械学習アルゴリズムと注文執行アルゴリズムの統合

・実装に向けて必要な知識と経験の蓄積

価格予測のアルゴリズムの雛形

仮想通貨の価格予測アルゴリズムを構築するには、取引所からデータを取得し、そのデータをもとにマシンラーニングアルゴリズムを使って価格予測を行うことが基本となります。以下にその雛形となるコードを示します。

まずは、Pythonの仮想環境を整え、依存関係を管理するためにPoetryを使用します。次に、ccxtライブラリを使って取引所(例えばBinance)からビットコインの取引データを取得し、マシンラーニングで使用するための前処理を行い、最終的にscikit-learnTensorFlow/Kerasを使用して価格予測を行います。

関連
仮想通貨botの開発記録#109(2024/9/30)「機械学習ライブラリscikit-learnとTensorFlow/Keras」

続きを見る

必要なライブラリのインストール

Yodaka

まずは、Poetryで必要なライブラリをインストールします。

poetry add ccxt pandas scikit-learn tensorflow

取引データの取得

Yodaka

以下はccxtを使ってBinanceからビットコインの過去データを取得する例です。

import ccxt
import pandas as pd
from datetime import datetime, timedelta

# Binanceのインスタンスを作成
exchange = ccxt.binance()

# 現在の日付と過去1ヶ月の日付を指定
now = datetime.now()
since = now - timedelta(days=30)

# Binanceのビットコインのローソク足データを取得(1時間足)
ohlcv = exchange.fetch_ohlcv('BTC/USDT', timeframe='1h', since=int(since.timestamp() * 1000))

# データフレームに変換
df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')

print(df.head())

データの前処理

Yodaka

次に、このデータを機械学習に適した形式に変換します。

ここでは、価格の特徴量(open, high, low, close, volume)を使用して次の時間の価格を予測するモデルを構築します。

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# 特徴量とラベルの設定
X = df[['open', 'high', 'low', 'close', 'volume']].values
y = df['close'].shift(-1).fillna(df['close']).values  # 次の時間の価格をラベルに

# 訓練データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)

# データの標準化
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

価格予測のモデル構築

Yodaka

ここでは、簡単なニューラルネットワークモデルを使用します。

Kerasで構築し、次の時間のビットコイン価格を予測します。

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

# モデルの構築
model = Sequential([
    Dense(64, activation='relu', input_shape=(X_train_scaled.shape[1],)),
    Dense(32, activation='relu'),
    Dense(1)  # 次の時間の価格を予測
])

# モデルのコンパイル
model.compile(optimizer='adam', loss='mean_squared_error')

# モデルの訓練
history = model.fit(X_train_scaled, y_train, epochs=10, batch_size=32, validation_data=(X_test_scaled, y_test))

# テストデータで予測
predictions = model.predict(X_test_scaled)

# 予測結果の表示
print(predictions[:5])

補足

  • 上記のコードは非常にシンプルなモデルですが、価格予測を行うための基本的な流れを示しています。
  • 実際の取引戦略に応用する場合、より高度な特徴量の作成(テクニカル指標の追加など)や、モデルの精緻化(LSTMやGRUなどの時系列データに特化したモデル)を検討する必要があります。
  • 取引所のAPI制限やデータの品質も重要な要素なので、定期的にデータを更新し、最新のデータに基づいてモデルを訓練する必要があります。
Yodaka

この雛形を基に、取引ロジックに応じてカスタマイズしていくことができます。

売買注文アルゴリズムとの統合

Yodaka

価格予測アルゴリズムを売買注文執行アルゴリズムと組み合わせる場合、全体のコード設計は以下のような構造になります。

この設計では、価格予測を元に自動的に売買注文を出す部分を追加し、アルゴリズムの一連の流れを実現します。

全体のコード設計

  1. データ取得モジュール: 取引所からの価格データを取得し、前処理する。
  2. 価格予測モジュール: マシンラーニングモデルを使って価格の予測を行う。
  3. 注文執行モジュール: 予測結果に基づいて売買注文を実行する。
  4. リスク管理モジュール: 損失を限定するためのリスク管理(例えば、ストップロスやテイクプロフィット)を実装。
  5. バックテストモジュール(オプション): 過去のデータを用いてアルゴリズムのパフォーマンスを検証する。
  6. モニタリングモジュール: 稼働中のアルゴリズムを監視し、異常を検知する。

具体的なコード例

import ccxt
import pandas as pd
from datetime import datetime, timedelta
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
import time

# Binanceのインスタンス
exchange = ccxt.binance({
    'apiKey': 'YOUR_API_KEY',
    'secret': 'YOUR_SECRET_KEY',
})

# データ取得モジュール
def fetch_data():
    now = datetime.now()
    since = now - timedelta(days=30)
    ohlcv = exchange.fetch_ohlcv('BTC/USDT', timeframe='1h', since=int(since.timestamp() * 1000))
    df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
    df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
    return df

# モデル構築モジュール
def build_model(input_shape):
    model = Sequential([
        Dense(64, activation='relu', input_shape=input_shape),
        Dense(32, activation='relu'),
        Dense(1)  # 価格予測
    ])
    model.compile(optimizer='adam', loss='mean_squared_error')
    return model

# 注文執行モジュール
def place_order(signal, amount):
    if signal == 'buy':
        order = exchange.create_market_buy_order('BTC/USDT', amount)
        print("買い注文が執行されました。")
    elif signal == 'sell':
        order = exchange.create_market_sell_order('BTC/USDT', amount)
        print("売り注文が執行されました。")
    return order

# リスク管理モジュール
def risk_management(position, stop_loss, take_profit, current_price):
    if position == 'long' and (current_price <= stop_loss or current_price >= take_profit):
        place_order('sell', 0.001)  # ポジション解消
        return 'sell'
    elif position == 'short' and (current_price >= stop_loss or current_price <= take_profit):
        place_order('buy', 0.001)  # ポジション解消
        return 'buy'
    return None

# メインロジック
def main():
    df = fetch_data()
    
    # 特徴量とラベル
    X = df[['open', 'high', 'low', 'close', 'volume']].values
    y = df['close'].shift(-1).fillna(df['close']).values
    
    # 訓練・テストデータ分割
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)
    
    # データの標準化
    scaler = StandardScaler()
    X_train_scaled = scaler.fit_transform(X_train)
    X_test_scaled = scaler.transform(X_test)
    
    # モデルの構築
    model = build_model((X_train_scaled.shape[1],))
    model.fit(X_train_scaled, y_train, epochs=10, batch_size=32, validation_data=(X_test_scaled, y_test))
    
    # 現在のポジションとリスク管理設定
    position = None
    stop_loss = None
    take_profit = None

    # 自動取引ループ
    while True:
        # 最新のデータを取得
        df = fetch_data()
        current_price = df['close'].iloc[-1]
        
        # 予測
        X_live = scaler.transform(df[['open', 'high', 'low', 'close', 'volume']].values[-1].reshape(1, -1))
        predicted_price = model.predict(X_live)[0][0]
        
        # 売買ロジック
        if predicted_price > current_price and position != 'long':
            place_order('buy', 0.001)
            position = 'long'
            stop_loss = current_price * 0.98
            take_profit = current_price * 1.02
        
        elif predicted_price < current_price and position != 'short':
            place_order('sell', 0.001)
            position = 'short'
            stop_loss = current_price * 1.02
            take_profit = current_price * 0.98

        # リスク管理チェック
        risk_management(position, stop_loss, take_profit, current_price)
        
        # 5分ごとに更新
        time.sleep(300)

if __name__ == "__main__":
    main()

各モジュールの説明

  1. データ取得モジュール: 取引所から直近の価格データを取得して、ローソク足形式で保存します。リアルタイムのデータ更新を考慮し、定期的に取得します。
  2. モデル構築モジュール: ニューラルネットワークを使って価格予測モデルを構築します。訓練データで学習し、新しいデータが入るたびに予測を行います。
  3. 注文執行モジュール: 予測結果に基づいて売買注文を実行します。Binance APIを利用して市場注文(Market Order)を行います。
  4. リスク管理モジュール: ポジションがある場合、ストップロスやテイクプロフィットの条件に達したかをチェックし、必要に応じてポジションを解消します。
  5. 自動取引ループ: 価格予測、売買注文の執行、リスク管理の処理を定期的に繰り返します。例えば、5分ごとに更新される価格データを使い、予測と取引を行います。

考慮すべきポイント

  • 注文のスリッページ: 実際の取引では、注文が市場に出た際に価格が変動する可能性があります。これを考慮した戦略を組み込む必要があります。
  • APIのレートリミット: 取引所によってはAPIの呼び出し回数に制限があるため、取引頻度をコントロールする必要があります。
  • バックテスト: リアルトレードを行う前に、過去データを使って戦略のパフォーマンスを検証することが重要です。
Yodaka

この設計を基に、アルゴリズムの改善やカスタマイズが可能です。

ここからは、取引ロジックやリスク管理の精度を上げるために、戦略に応じて追加機能を実装することになります。

まとめ

今回は「機械学習を用いた価格予測botの雛形」についてまとめました。

Yodaka

このコードを動かしながらMLbotの大まかな構造を理解して、強いbot作りを進めていきます。

今後もこの調子で、開発の状況を発信していきます。

-Bot, トレードロジック, 機械学習・データサイエンス