Bot トレードロジック

仮想通貨botの開発記録#81(2024/7/27)「基本的な取引ロジックの雛形まとめ①」

2024年7月27日

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

Yodaka

今回は、5種類の基本的な取引ロジックの雛形をまとめました。

実際にbotで取引をしてみたいけれど、どんなコードを書いたら良いのか分からないという方の参考になると思います。

1.注文書き込みのアービトラージ

Yodaka

同一銘柄の異なる取引所間で生じる価格差を利用するタイプのbotです。

注文書き込みのアービトラージ(order book arbitrage)を行うためのPythonコードの雛形です。この戦略は、同一の仮想通貨や銘柄について、異なる取引所間の価格差を利用して利益を得るものです。以下の雛形は、2つの異なる取引所での価格を比較し、利益が出る場合に取引を行う基本的なロジックです。

まずは、必要なライブラリをインポートし、取引所のAPIクライアントを設定します。以下の例では、ccxt ライブラリを使って取引所にアクセスしますが、実際の取引所やAPIの仕様に応じて適宜変更が必要です。

import ccxt
import time

# 取引所のAPIキーとシークレットを設定
api_key = 'YOUR_API_KEY'
api_secret = 'YOUR_API_SECRET'

# 取引所クライアントの初期化
exchange1 = ccxt.binance({
    'apiKey': api_key,
    'secret': api_secret
})

exchange2 = ccxt.kraken({
    'apiKey': api_key,
    'secret': api_secret
})

# アービトラージを行う通貨ペアと閾値
symbol = 'BTC/USD'
threshold = 10  # 利益が出る最小価格差(USD)

def get_price(exchange, symbol):
    """指定された取引所と通貨ペアでの最新の価格情報を取得"""
    orderbook = exchange.fetch_order_book(symbol)
    bid_price = orderbook['bids'][0][0] if orderbook['bids'] else None
    ask_price = orderbook['asks'][0][0] if orderbook['asks'] else None
    return bid_price, ask_price

def arbitrage():
    """アービトラージの機会を探し、利益が出る場合に取引を実行"""
    while True:
        # 価格情報を取得
        bid_price1, ask_price1 = get_price(exchange1, symbol)
        bid_price2, ask_price2 = get_price(exchange2, symbol)

        if bid_price1 and ask_price2 and (bid_price1 - ask_price2 > threshold):
            print(f"Arbitrage opportunity: Buy at Exchange 2 at {ask_price2}, Sell at Exchange 1 at {bid_price1}")
            # ここに買い注文と売り注文の実行コードを記述

        if bid_price2 and ask_price1 and (bid_price2 - ask_price1 > threshold):
            print(f"Arbitrage opportunity: Buy at Exchange 1 at {ask_price1}, Sell at Exchange 2 at {bid_price2}")
            # ここに買い注文と売り注文の実行コードを記述

        time.sleep(5)  # APIのレート制限に注意

if __name__ == "__main__":
    arbitrage()

このコードは、定期的に2つの取引所の価格をチェックし、閾値を超える価格差がある場合に「アービトラージの機会」として報告します。実際に取引を行うためには、各取引所のAPIを通じて買い注文と売り注文を出す処理を追加する必要があります。

また、リアルタイムでの取引実行には、APIの呼び出し制限、注文の執行遅延、通信エラーなどの取り扱いも考慮してください。

2.【応用】取引所で扱う全ての銘柄を対象にする

Yodaka

上記のコードを応用して、より広い範囲でのアービトラージを行うタイプのbotを組んでみます。

異なる取引所で扱われている全ての銘柄に対してアービトラージを行うPythonコードの雛形です。このコードでは、取引所からサポートされている通貨ペアのリストを取得し、それぞれの通貨ペアに対して価格差を確認しアービトラージの機会を探します。

import ccxt
import time

# 取引所のAPIキーとシークレットを設定
api_key = 'YOUR_API_KEY'
api_secret = 'YOUR_API_SECRET'

# 取引所クライアントの初期化
exchange1 = ccxt.binance({
    'apiKey': api_key,
    'secret': api_secret
})

exchange2 = ccxt.kraken({
    'apiKey': api_key,
    'secret': api_secret
})

threshold = 10  # 利益が出る最小価格差(USD)

def get_price(exchange, symbol):
    """指定された取引所と通貨ペアでの最新の価格情報を取得"""
    try:
        orderbook = exchange.fetch_order_book(symbol)
        bid_price = orderbook['bids'][0][0] if orderbook['bids'] else None
        ask_price = orderbook['asks'][0][0] if orderbook['asks'] else None
        return bid_price, ask_price
    except Exception as e:
        print(f"Error fetching data for {symbol} on {exchange.id}: {e}")
        return None, None

def arbitrage(symbol):
    """特定の通貨ペアに対してアービトラージの機会を探し、利益が出る場合に取引を実行"""
    bid_price1, ask_price1 = get_price(exchange1, symbol)
    bid_price2, ask_price2 = get_price(exchange2, symbol)

    if bid_price1 and ask_price2 and (bid_price1 - ask_price2 > threshold):
        print(f"Arbitrage opportunity: Buy at {exchange2.id} at {ask_price2}, Sell at {exchange1.id} at {bid_price1}")

    if bid_price2 and ask_price1 and (bid_price2 - ask_price1 > threshold):
        print(f"Arbitrage opportunity: Buy at {exchange1.id} at {ask_price1}, Sell at {exchange2.id} at {bid_price2}")

def run_arbitrage():
    """全ての通貨ペアでアービトラージ機会を探す"""
    symbols = list(set(exchange1.symbols) & set(exchange2.symbols))
    print(f"Common symbols: {symbols}")

    while True:
        for symbol in symbols:
            arbitrage(symbol)
        time.sleep(10)  # APIのレート制限に注意

if __name__ == "__main__":
    run_arbitrage()

このコードは、exchange1exchange2 の両取引所で共通の通貨ペアを見つけ出し、それぞれの通貨ペアに対してアービトラージの可能性を周期的にチェックします。このスクリプトを実際に運用する際には、各取引所のAPI呼び出し制限に注意し、エラーハンドリングを適切に行う必要があります。

また、実際にプログラムで注文を行う場合は、ccxtライブラリの create_order メソッドを使用して、購入および売却の注文を実装する必要があります。その際は、APIキーとシークレットの設定が求められます。

3.時間面の価格変動を捉える

Yodaka

一定時間における価格変動のパターンを捉え、売買するタイミングを見計らうタイプのbotです。

一定時間における価格変動のパターンを捉えて売買するタイミングを見計らうトレーディングボットを作成するには、価格データの時間系列分析を行い、適切な売買ポイントを判定するロジックが必要です。

以下はPythonとccxtライブラリを使用してこの戦略を実装する基本的な雛形です。この例では、移動平均を用いてトレーディングシグナルを生成します。

必要なライブラリのインポート

import ccxt
import pandas as pd
import time
from datetime import datetime

取引所の設定と初期化

exchange = ccxt.binance({
    'apiKey': 'YOUR_API_KEY',
    'secret': 'YOUR_API_SECRET'
})
symbol = 'BTC/USD'
timeframe = '1m'  # 1分足のデータ

データ取得とシグナル生成の関数

def fetch_data(symbol, timeframe):
    """指定されたシンボルと時間枠で価格データを取得する"""
    bars = exchange.fetch_ohlcv(symbol, timeframe, limit=100)
    df = pd.DataFrame(bars, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
    df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
    return df

def calculate_signals(df):
    """移動平均を計算し、売買シグナルを生成する"""
    df['MA20'] = df['close'].rolling(window=20).mean()
    df['MA50'] = df['close'].rolling(window=50).mean()
    df['Signal'] = 0
    df['Signal'][df['MA20'] > df['MA50']] = 1
    df['Signal'][df['MA20'] < df['MA50']] = -1
    df['Position'] = df['Signal'].diff()
    return df

ボットのメイン実行関数

def run_bot():
    """ボットの実行ループ"""
    while True:
        df = fetch_data(symbol, timeframe)
        df = calculate_signals(df)

        # 最新のシグナルをチェック
        latest_position = df.iloc[-1]['Position']
        if latest_position > 0:
            print(f"{datetime.now()} - Buy signal")
            # 購入ロジック
        elif latest_position < 0:
            print(f"{datetime.now()} - Sell signal")
            # 売却ロジック

        time.sleep(60)  # ループのスリープ時間を1分に設定

if __name__ == '__main__':
    run_bot()

このスクリプトは、1分足の価格データを使用して移動平均線のクロスオーバーに基づいたトレーディングシグナルを生成します。移動平均線の長短がクロスする点を売買のシグナルとして利用し、相場のトレンド変化を捉えます。

実際の取引を行うためには、売買ロジック部分に具体的な取引コード(例:exchange.create_order(symbol, 'market', 'buy', amount))を追加する必要があります。また、取引所のAPI呼び出し制限、取引のスリッページ、手数料などを考慮することが重要です。

4.逆張り売買

Yodaka

トレンドの転換点を見計らい、売買のタイミングを捉えるタイプのbotです。

逆張り売買戦略を実行するボットを組むには、市場のトレンドが転換するポイントを正確に見極めるアルゴリズムが必要です。以下の例では、Pythonとccxtライブラリを使用し、相対力指数(RSI)を利用して市場の過買いや過売りの状況を検出し、それをトレンド転換のサインとして逆張りの取引シグナルを生成するボットの基本的な構造を示します。

必要なライブラリのインポート

import ccxt
import pandas as pd
import numpy as np
import time
from datetime import datetime

取引所の設定と初期化

exchange = ccxt.binance({
    'apiKey': 'YOUR_API_KEY',
    'secret': 'YOUR_API_SECRET'
})
symbol = 'BTC/USD'
timeframe = '5m'  # 5分足のデータ

データ取得とシグナル生成の関数

def fetch_data(symbol, timeframe):
    """指定されたシンボルと時間枠で価格データを取得する"""
    bars = exchange.fetch_ohlcv(symbol, timeframe, limit=100)
    df = pd.DataFrame(bars, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
    df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
    return df

def calculate_rsi(df, window=14):
    """RSIを計算する"""
    delta = df['close'].diff()
    gain = (delta.where(delta > 0, 0)).rolling(window=window).mean()
    loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean()

    rs = gain / loss
    rsi = 100 - (100 / (1 + rs))
    df['RSI'] = rsi
    return df

def generate_signals(df):
    """逆張りのシグナルを生成する"""
    df = calculate_rsi(df)
    df['Signal'] = 0
    df['Signal'][df['RSI'] > 70] = -1  # RSIが70を超えたら売り
    df['Signal'][df['RSI'] < 30] = 1   # RSIが30を下回ったら買い
    df['Position'] = df['Signal'].diff()
    return df

ボットのメイン実行関数

def run_bot():
    """ボットの実行ループ"""
    while True:
        df = fetch_data(symbol, timeframe)
        df = generate_signals(df)

        # 最新のシグナルをチェック
        latest_position = df.iloc[-1]['Position']
        if latest_position > 0:
            print(f"{datetime.now()} - Buy signal")
            # 購入ロジック
        elif latest_position < 0:
            print(f"{datetime.now()} - Sell signal")
            # 売却ロジック

        time.sleep(300)  # ループのスリープ時間を5分に設定

if __name__ == '__main__':
    run_bot()

このスクリプトでは、RSIインジケーターを用いて市場の過熱(過買いまたは過売り)状態を検出し、それをトレンド転換の可能性が高いサインとして利用しています。RSIが70を超えると売り、30を下回ると買うシグナルを出します。

実際の取引を行うためには、具体的な購入および売却の命令を追加する必要があります。また、実際に運用する際は市場の状況によりパラメータの調整が必要ですし、取引のスリッページ、手数料、その他の実用的な要素を考慮することが重要です。

5.ニュース対応の売買

Yodaka

重要ニュースが発表された際の短期的な価格変動に対応するタイプのbotです。

ニュース対応の売買戦略を実行するボットを構築するには、リアルタイムのニュースデータの取得とそのデータを解析してトレードするロジックが必要です。このタイプのボットは、ニュース発表の影響を市場価格に即座に反映させるため、高速なデータ処理と迅速な実行が求められます。

ここでは、ニュースデータを模擬的に扱う簡単な例を示し、実際のニュースフィードとの接続方法と基本的なトレードロジックを組み合わせたプログラムを紹介します。Pythonを使用し、ccxt ライブラリで市場データを取得し、独自のニュースフィードを模擬する関数を作成します。

必要なライブラリのインポート

import ccxt
import time
from datetime import datetime
import random

取引所の設定と初期化

exchange = ccxt.binance({
    'apiKey': 'YOUR_API_KEY',
    'secret': 'YOUR_API_SECRET'
})
symbol = 'BTC/USD'

ニュースフィードの模擬

def get_news():
    """ニュースイベントをランダムに生成する(実際のニュースAPIに置き換える)"""
    events = ['positive', 'negative', 'neutral']
    news_event = random.choice(events)
    return news_event

トレードロジック

def trade_on_news(news_event):
    """ニュースイベントに基づいてトレードを実行する"""
    if news_event == 'positive':
        print(f"{datetime.now()} - Positive news released, buying {symbol}")
        # ここで購入ロジックを実装
    elif news_event == 'negative':
        print(f"{datetime.now()} - Negative news released, selling {symbol}")
        # ここで売却ロジックを実装
    else:
        print(f"{datetime.now()} - No significant news, no action taken")

ボットのメイン実行関数

def run_bot():
    """ボットの実行ループ"""
    while True:
        news_event = get_news()
        trade_on_news(news_event)
        time.sleep(60)  # ニュースのチェック頻度(秒)

if __name__ == '__main__':
    run_bot()

このコードは、ニュースイベントに基づいて市場での売買を行うための基本的なフレームワークを提供します。実際のニュースAPIを使用する場合は、get_news() 関数を実際のニュースデータをリアルタイムで取得するロジックに置き換える必要があります。また、トレードの実行部分には、注文をプレースするための具体的なAPI呼び出しを追加する必要があります。

実際の運用では、ニュースの重要度を評価するためのさらに洗練された分析手法や、市場の反応をより正確に予測するための機械学習モデルを組み込むことも考慮すると良いでしょう。また、スリッページや取引手数料といった市場実行の現実的な要素を考慮することも重要です。

まとめ

今回は、基本的な取引ロジックを実行するbotの雛形を5種類まとめました。

普段、裁量で行なっているトレードをbotのロジックに落とし込む過程で学べることが数多くあると思います。

人間が行なっていることを可能な限り言語化して、コードに変換していくというプロセス自体は非常に根気のいる作業ですが、一度組み上げて仕舞えば、様々な形態に応用することもできます。

また、人間が感覚で理解・判断していることを高速で迷いなく行うことができる点がbotの優位性でもあるため、これらの戦略がどういう場で有効に働くのかを検証していくことが大事です。

また、botを作って運用すること自体がより強いbotの存在を判断する材料にもなります。

Yodaka

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

-Bot, トレードロジック