CCXTを使って仮想通貨のトレードをしてみる(第4回):バックテストから本番運用へ

約45分で読めます by ぽんたぬき
CCXTを使って仮想通貨のトレードをしてみる(第4回):バックテストから本番運用へ

CCXTを使って仮想通貨のトレードをしてみる(第4回):バックテストから本番運用へ

⚠️ 注意:仮想通貨取引には大きなリスクが伴います。必ず余剰資金で行い、税務・法務についても最新の情報を確認し、必要に応じて専門家の助言を受けてください。


はじめに:CCXTライブトレードで学べること

バックテスト、うまくいったヨ!!✨ 「よっしゃ、これで儲かるぞ!!」って思った瞬間、本番に投入したら全然ダメだった……ってコト、あるよネ😭 僕もサ、第3回でせっかくリスク管理とバックテストを実装したのに、本番でボコボコにされちゃいましたヨ……(笑)ナンデかって言うとサ——そこに「バックテストと本番運用の深〜い溝」があったんだヨネ🎵

今回の第4回では、そのギャップを埋めて、バックテストで検証した戦略をCCXTライブトレードまで持っていくための全部入りガイドをお届けしちゃいますヨ!!🔥 具体的には——

  • バックテストと本番で起きる「見落としがちな落とし穴」
  • Binance Testnetを使ったサンドボックス検証
  • CCXT ProのWebSocketでリアルタイムCCXTライブトレード
  • asyncio(Pythonの非同期I/Oライブラリ)で複数ペアを並列管理
  • エラーハンドリングと自動リカバリ
  • Telegram通知システムの連携
  • AWS EC2でクラウド本番運用

……という盛りだくさんな内容デス!!🎉 ここまで第1〜3回を読んできたキミなら、絶対ついてこれるから!!😆

前提知識:Python基礎、CCXTを使って仮想通貨のトレードをしてみる第1〜3回の内容(インストール・注文・バックテスト)を理解していること。まだ読んでないヒトは過去記事をチェックしてネ♪


1. CCXTバックテストと本番ライブトレードの違い|見落としがちな落とし穴

1-1. バックテストが「完璧」でも本番CCXTライブトレードで崩れる理由

聞いて聞いて!!バックテストで月利30%叩き出した時サ、「コレはいける!!」って完全に浮かれてたんだヨネ😆 でも本番に投入した瞬間、利益がスルスルと消えていってサ……あの絶望感、ファミコンのカセット吹いても直らない時みたいだったヨ📟(笑)

バックテストが崩れる主な原因はコレ!!

スリッページ・約定遅延:スリッページとは、注文を出した価格と実際に約定した価格の差のコトデス!!バックテストでは「その価格で確実に約定した」前提で計算するんだケド、実際のマーケットでは注文を出した瞬間に価格が動いちゃうんだヨネ💦 特に流動性が低い時間帯や急騰・急落時はヤバい。

過学習(カーブフィッティング):これ、マジで罠なんですヨ!!過去データにパラメータを最適化しすぎると、そのデータにしか効かない戦略が出来上がっちゃうんだヨ😭 「過去には完璧だけど未来には役立たず」——これが一番怖い罠デス!! アウト・オブ・サンプル検証(学習に使っていない別期間のデータで戦略を評価するコト)でリスクを事前に確認するのが大事デス!!

手数料の見落とし:バックテストで手数料を正確にモデル化していないと、CCXTライブトレードの実際の利益が大幅に減るコトがあるんだヨネ💡 Binanceなら取引手数料0.1%でも、頻繁売買すれば積み重なるんだヨ!!

1-2. CCXTライブトレードで直面する新たな課題

APIレート制限とネットワーク障害:バックテストではHTTPエラーなんて考えなくていいけど、本番はネットワークが落ちる、取引所のAPIがタイムアウトする——そういうカオスが普通に起きるんだヨネ🔥 ある夜中、いいシグナルが出た瞬間にWi-Fiが落ちてサ、大チャンスを逃したコトがあったヨ……(笑)

残高管理のリアルタイム監視:バックテストでは残高を仮定できるケド、本番では「思ったより残高が減ってた」「証拠金維持率がギリギリ」ってコトが普通に起きるから、CCXTライブトレードではリアルタイム監視が超重要デス!!😭

1-3. 本番CCXTライブトレード移行前のチェックリスト

本番に移る前に、必ずコレを確認しておいてヨ!!💡

  • ✅ 戦略パラメータを「アウト・オブ・サンプル」データで再検証した
  • ✅ 最大ドローダウン許容値を数値で決めた(例:初期資金の20%)
  • ✅ 緊急停止ルール(「ここまで来たらボット止める」)を明文化した
  • ✅ APIキーの出金権限をオフにした(これ忘れたら大変なコトになるヨ!!😭)
  • ✅ サンドボックス環境で少なくとも1週間以上テストした

2. CCXTサンドボックス環境構築|Binance Testnetで安全に検証する

2-1. Binance Testnetとは?CCXTペーパートレードの重要性

キミ、知ってた!?Binanceにはテスト用の環境があってサ、本物のお金を使わずにCCXTライブトレードを試せるんだヨ!!🎉 これが「Binance Testnet」ってやつデス♪

テストネットとメインネットの違いはカンタン——テストネットのお金は全部ニセモノ!!💡 だから何億円分の注文を出しても財布は痛まないし、バグで全滅しても「あ〜あ」で済むんだヨ😆 本番でやらかす前に、絶対ここで動作確認してほしいネ!!

僕さ、最初にサンドボックスをスキップして本番に直投したことあってサ、コードのバグで0.1BTCが一瞬で消えかけたコトがあったんだヨネ……あの時は手が震えたヨ😭 ギリギリAPIエラーで約定しなかったんだケド、ホントに冷や汗モノでした——やらかしちゃいましたヨ……😭

2-2. CCXTでBinance Testnetに接続するセットアップ手順

まず https://testnet.binance.vision/ でテストネット用APIキーを取得してネ♪ GitHubアカウントでログインするだけで発行できるヨ!!

コレ見てよ!!スゴくナイ!?✨ たった数行でTestnetに繋がっちゃうんだヨ!!

import ccxt

# ccxt.binance の future サンドボックスは廃止済み。
# 代わりに ccxt.binanceusdm(USD-M先物専用クラス)+ set_sandbox_mode を使用する。
exchange = ccxt.binanceusdm({
    'apiKey': 'YOUR_DEMO_API_KEY',
    'secret': 'YOUR_DEMO_SECRET',
    'enableRateLimit': True,  # 絶対に外さない!
})

# デモトレードモードを有効化(旧テストネット/サンドボックスの代替)
exchange.set_sandbox_mode(True)

# 接続確認
balance = exchange.fetch_balance()
print(balance['USDT'])

繋がった時サ、思わず「よっしゃ!!」って声出ちゃいましたヨ😆

enableRateLimit=True が必須な理由:これをオフにすると、CCXTがAPIを叩きまくってBanされるリスクがあるんだヨネ💦 取引所のAPIには1分あたりの呼び出し上限があってサ、超えたら一時的にアクセス遮断されちゃうんだヨ。enableRateLimit=True にしておくと、CCXTが自動で待機時間を計算してくれるから、絶対オンにしておいてネ!!

2-3. CCXTサンドボックスでの動作確認ポイント

テストネットでは必ずコレ全部を確認してネ♪ 確認モレがあると本番で泣くコトになるヨ!!😭

# 注文作成テスト
# binanceusdm では USDM無期限先物のシンボルは 'BTC/USDT:USDT' 形式を使用する
order = exchange.create_order(
    symbol='BTC/USDT:USDT',
    type='limit',
    side='buy',
    amount=0.001,
    price=50000
)
print(f"注文ID: {order['id']}")

# 注文キャンセルテスト
exchange.cancel_order(order['id'], 'BTC/USDT:USDT')

# 残高確認テスト
balance = exchange.fetch_balance()
print(f"USDT残高: {balance['USDT']['free']}")

# オープン注文一覧確認
open_orders = exchange.fetch_open_orders('BTC/USDT:USDT')
print(f"未約定注文数: {len(open_orders)}")

本番移行のタイミング判断基準:少なくとも「1週間連続でエラーなしに動いた」「想定通りの注文が想定通りに入っている」を確認してから移行してネ!!急ぎたい気持ちはわかるケド、ここで焦ると大変なコトになるヨ😭


3. CCXT ProのWebSocket移行|リアルタイムデータでCCXTライブトレード速度を上げる

3-1. RESTとWebSocketの違い|なぜCCXT Proへ移行するのか

ちょっと聞いてヨ……僕さ、RESTのポーリング方式でしばらく運用してたんだヨネ😭 WebSocket(サーバーとクライアントが双方向でリアルタイム通信できるプロトコルのコトデス!!)って最初ちょっと難しそうに見えたんだヨ。でもそのせいで、急騰シグナルに気づくのが2〜3秒遅れてサ、エントリーを何回も逃したんだヨネ……💦

REST方式は「5秒ごとに価格を取りに行く」ポーリング方式だから、その間の価格変動に気づけないんだヨ!!それにAPIを叩くたびにレート制限のカウンターが増えていくからサ、頻繁に叩けば叩くほどBanリスクが高まっちゃうんだヨネ😅

WebSocketはサーバー側から「変化があったら教えてくれる」プッシュ型だから、レイテンシが劇的に下がってAPIレート問題も根本から解決できるんだヨ!!🔥 CCXTライブトレードにはWebSocketが欠かせないネ!!

3-2. CCXT Proのインストールと基本設定

コレでインストール完了デス!!すぐ使えるヨ!!✨

pip install "ccxt[pro]"

CCXT ProはCCXTのWebSocket拡張版でサ、基本的な使い方はほぼ同じだから安心してネ♪ ただし、一部の高度な機能は有料プランが必要なケースもあるから、公式ドキュメントで確認しておくとよいデス💡

3-3. CCXT Proで watch_ticker() / watch_ohlcv() を実装する

コレ見てよ!!スゴくナイ!?✨ asyncioと組み合わせるとこんなにスッキリ書けちゃうんだヨ!!

import ccxt.pro as ccxtpro
import asyncio

async def watch_price():
    exchange = ccxtpro.binance({'enableRateLimit': True})

    try:
        while True:
            # リアルタイムでティッカーを受信
            ticker = await exchange.watch_ticker('BTC/USDT')
            price = ticker['last']
            print(f"BTC/USDT 現在価格: {price}")

            # ここでシグナル判定ロジックを呼ぶ
            signal = check_signal(price)
            if signal == 'BUY':
                order = await exchange.create_order(
                    'BTC/USDT', 'market', 'buy', 0.001
                )
                print(f"買い注文執行: {order['id']}")
    finally:
        await exchange.close()

def check_signal(price):
    # ここに戦略ロジックを入れる
    return None

asyncio.run(watch_price())

リアルタイムで価格が流れてくるのサ、最初見た時はホントに感動しちゃったヨ!!🎵 「コレが本物のCCXTライブトレードだ!!」ってテンション上がりっぱなしだったネ!!😆

3-4. ATRベースのストップロスとCCXT Proの組み合わせ

第3回でやったATR(Average True Range=平均真の値幅のコト。相場のボラティリティ、つまり価格変動の激しさを数値化する指標デス!!)ベースのストップロス、覚えてるネ!?あれをCCXT Pro WebSocketと組み合わせるとこんな感じになるヨ!!🎵

コレ見てよ!!スゴくナイ!?✨ ATRが市場のボラティリティを読み取ってストップロス幅をリアルタイムに自動調整してくれるんだヨ!!

import ccxt.pro as ccxtpro
import asyncio
import pandas as pd
import numpy as np

def calculate_atr(ohlcv_data, period=14):
    """ATR(平均真のレンジ)を計算"""
    df = pd.DataFrame(
        ohlcv_data,
        columns=['timestamp', 'open', 'high', 'low', 'close', 'volume']
    )
    df['tr'] = np.maximum(
        df['high'] - df['low'],
        np.maximum(
            abs(df['high'] - df['close'].shift(1)),
            abs(df['low'] - df['close'].shift(1))
        )
    )
    return df['tr'].rolling(period).mean().iloc[-1]

async def live_trade_with_atr_stop():
    exchange = ccxtpro.binance({
        'apiKey': 'YOUR_API_KEY',
        'secret': 'YOUR_SECRET',
        'enableRateLimit': True,
    })
    exchange.set_sandbox_mode(True)  # テスト中は必ずサンドボックス!

    entry_price = None
    stop_loss_price = None

    try:
        while True:
            # OHLCVをリアルタイムで取得
            ohlcv = await exchange.watch_ohlcv('BTC/USDT', '1m')

            if len(ohlcv) >= 15:
                atr = calculate_atr(ohlcv[-50:])
                current_price = ohlcv[-1][4]  # 最新クローズ価格

                # エントリー済みの場合はストップロスチェック
                if entry_price is not None and stop_loss_price is not None:
                    if current_price <= stop_loss_price:
                        print(f"ストップロス発動!! {current_price} <= {stop_loss_price}")
                        order = await exchange.create_order(
                            'BTC/USDT', 'market', 'sell', 0.001
                        )
                        entry_price = None
                        stop_loss_price = None
    finally:
        await exchange.close()

asyncio.run(live_trade_with_atr_stop())

ATRが自動でストップロスを調整してくれるの、マジで便利なんだヨ!!😆 ボラティリティが高い時は広めに、低い時は狭めに——市場の状況に合わせて動いてくれるんだヨネ🎵


4. CCXT複数通貨ペアの並列管理|asyncioでCCXTライブトレードを効率化する

4-1. 複数ペア並列管理の設計思想

キミ、1つのペアだけ監視するのはちょっともったいなくナイ!?😆 BTC/USDTが動かない時でも、ETH/USDTやSOL/USDTが動いてたりするから、複数ペアを同時に監視することでチャンスを逃さないんだヨ!!🔥

ただし、複数ペアを管理するとなると、残高の分散や注文枠の競合に気をつけないといけないんだヨネ💡 例えば「BTC買いシグナル」と「ETH買いシグナル」が同時に出た時、残高が足りなくてどっちかが失敗する——なんてコトが起きるんだヨ😭 ここはちゃんと設計が必要デス!!

そういえばサ、最近近所のコンビニに深夜立ち寄ったらレジが無人になってたんだヨネ😆 「コレもある種の並列処理だナァ」とか思いながらチキン買って帰って、asyncioのコードを書き直してたら夜が明けてたヨ……(笑)そんな話はどうでもいいネ!!コードを見ていこうヨ!!

4-2. asyncio + fetch_tickers() によるCCXTバッチ取得

コレ見てよ!!スゴくナイ!?✨ API呼び出しを1回にまとめちゃえるんだヨ!!

import ccxt.pro as ccxtpro
import asyncio

async def fetch_multiple_pairs(exchange, symbols):
    """複数ペアのティッカーをバッチ取得(API呼び出し1回!)"""
    tickers = await exchange.fetch_tickers(symbols)
    return tickers

async def main():
    exchange = ccxtpro.binance({'enableRateLimit': True})
    exchange.set_sandbox_mode(True)

    symbols = ['BTC/USDT', 'ETH/USDT', 'SOL/USDT', 'BNB/USDT']

    try:
        tickers = await fetch_multiple_pairs(exchange, symbols)
        for symbol, ticker in tickers.items():
            print(f"{symbol}: 現在価格={ticker['last']}, 24h変化率={ticker['percentage']:.2f}%")
    finally:
        await exchange.close()

asyncio.run(main())

1回のAPI呼び出しで全ペアのデータが取れちゃうの、超効率的だヨネ!!🎉 レート制限の節約にもなるし、CCXTライブトレードの安定性がグッと上がるんだヨ!!

4-3. asyncio.gather() でCCXTライブトレードを真の並列実行にする

バッチ取得は1回のAPIコールで済むケド、各ペアのシグナル判定を真の並列で動かしたい時はコレだヨ!!✨

コレ見てよ!!スゴくナイ!?✨ asyncio.gather() を使うと複数のコルーチンが本当に同時に走るんだヨ!!

import ccxt.pro as ccxtpro
import asyncio

async def watch_single_pair(exchange, symbol, semaphore):
    """1ペアを監視するコルーチン"""
    while True:
        ticker = await exchange.watch_ticker(symbol)
        current_price = ticker['last']

        signal = check_signal(symbol, current_price)

        if signal == 'BUY':
            # セマフォで同時注文数を制御(複数ペアの残高競合を防ぐ)
            async with semaphore:
                order = await exchange.create_order(
                    symbol, 'market', 'buy', 0.001
                )
                print(f"[{symbol}] 買い注文: {order['id']}")

def check_signal(symbol, price):
    # ここに各ペアの戦略ロジックを実装
    return None

async def run_multi_pair_bot():
    exchange = ccxtpro.binance({
        'apiKey': 'YOUR_API_KEY',
        'secret': 'YOUR_SECRET',
        'enableRateLimit': True,
    })
    exchange.set_sandbox_mode(True)

    symbols = ['BTC/USDT', 'ETH/USDT', 'SOL/USDT', 'BNB/USDT']

    # セマフォで同時に実行できる注文数を2件に制限
    semaphore = asyncio.Semaphore(2)

    try:
        # 全ペアを並列で監視開始!!
        await asyncio.gather(
            *[watch_single_pair(exchange, symbol, semaphore) for symbol in symbols]
        )
    finally:
        await exchange.close()

asyncio.run(run_multi_pair_bot())

asyncio.Semaphore のポイントも解説するヨ!!💡 セマフォは「同時に使えるリソースの数を制限する仕組み」デス。Semaphore(2) にすることで「同時注文は最大2件まで」と制限できるんだヨネ。これをやっておかないと、4ペア全部で同時に買いシグナルが出た時に、残高不足でエラーが連発しちゃうんだヨ😭

4-4. ポジション管理と残高チェックの組み込み

複数ペアを並列で動かす以上、ポジション管理は絶対に必要デス!!🔥 同じペアでダブルエントリーしたり、残高ゼロで注文しようとしたりするバグは、複数ペアCCXTライブトレードで一番やりがちなやらかしデス……😭

コレ見てよ!!スゴくナイ!?✨ ポジション状態をdictで管理するシンプルな実装だヨ!!

import ccxt.pro as ccxtpro
import asyncio

class MultiPairBot:
    def __init__(self, exchange, symbols, budget_per_pair=100):
        self.exchange = exchange
        self.symbols = symbols
        self.budget_per_pair = budget_per_pair  # 1ペアあたりの予算(USDT)
        self.positions = {symbol: None for symbol in symbols}  # ポジション管理
        self.semaphore = asyncio.Semaphore(2)

    async def get_available_budget(self):
        """利用可能残高を取得"""
        balance = await self.exchange.fetch_balance()
        return balance['USDT']['free']

    async def watch_and_trade(self, symbol):
        """1ペアの監視+トレードループ"""
        while True:
            ticker = await self.exchange.watch_ticker(symbol)
            price = ticker['last']

            # ポジションなし → エントリー判断
            if self.positions[symbol] is None:
                signal = self.check_entry_signal(symbol, price)
                if signal == 'BUY':
                    budget = await self.get_available_budget()
                    if budget >= self.budget_per_pair:
                        async with self.semaphore:
                            amount = self.budget_per_pair / price
                            order = await self.exchange.create_order(
                                symbol, 'market', 'buy', amount
                            )
                            self.positions[symbol] = {
                                'entry_price': price,
                                'amount': amount,
                                'order_id': order['id']
                            }
                            print(f"[{symbol}] エントリー: {price} USDT")

            # ポジションあり → 決済判断
            else:
                pos = self.positions[symbol]
                if self.check_exit_signal(symbol, price, pos['entry_price']):
                    async with self.semaphore:
                        order = await self.exchange.create_order(
                            symbol, 'market', 'sell', pos['amount']
                        )
                        pnl = (price - pos['entry_price']) * pos['amount']
                        print(f"[{symbol}] 決済: {price} USDT | PnL: {pnl:.2f} USDT")
                        self.positions[symbol] = None

    def check_entry_signal(self, symbol, price):
        # エントリー判断ロジック(ここに戦略を実装)
        return None

    def check_exit_signal(self, symbol, price, entry_price):
        # 決済判断ロジック(例:2%利益確定 or 1%損切り)
        return_rate = (price - entry_price) / entry_price
        return return_rate >= 0.02 or return_rate <= -0.01

    async def run(self):
        try:
            await asyncio.gather(
                *[self.watch_and_trade(symbol) for symbol in self.symbols]
            )
        finally:
            await self.exchange.close()

コレでポジションの重複エントリーも残高不足エラーも防げるんだヨ!!😆 クラスにまとめると後でTelegramとかエラーハンドリングを追加しやすくなるし、コードもスッキリするんだヨネ🎵


5. CCXTライブトレードのエラーハンドリング|自動リカバリで安定稼働させる

5-1. CCXTライブトレードで頻出するエラーの種類と対処法

本番CCXTライブトレードで一番怖いのは「エラーでボットが黙って止まる」コトデス!!🔥 特に夜中に勝手に落ちてて、朝起きたら「え、ずっと動いてなかったの!!😱」ってなるアレ——僕も何回やったかわかんないヨ(笑)

CCXTライブトレードで頻出するエラーはコレ!!💡

エラー種別 原因 対処法
NetworkError ネットワーク一時断 指数バックオフでリトライ
RateLimitExceeded API呼び出し過多 enableRateLimit=True+スリープ
InsufficientFunds 残高不足 注文前に残高チェック
OrderNotFound 注文が存在しない 冪等性のある処理で再試行
ExchangeNotAvailable 取引所メンテ 長めの待機後にリトライ

5-2. 指数バックオフ付きリトライの実装

コレ見てよ!!スゴくナイ!?✨ 失敗しても自動で賢くリトライしてくれるんだヨ!!

import ccxt
import asyncio

async def safe_create_order(exchange, symbol, order_type, side, amount, max_retries=3):
    """エラーハンドリング付き注文作成(指数バックオフ)"""
    for attempt in range(max_retries):
        try:
            order = await exchange.create_order(symbol, order_type, side, amount)
            return order

        except ccxt.NetworkError as e:
            wait = 2 ** attempt  # 1秒 → 2秒 → 4秒と倍増
            print(f"ネットワークエラー(試行{attempt + 1}/{max_retries}): {e}")
            print(f"{wait}秒後にリトライ……")
            await asyncio.sleep(wait)

        except ccxt.RateLimitExceeded as e:
            wait = 10 * (attempt + 1)
            print(f"レートリミット超過: {e}{wait}秒待機")
            await asyncio.sleep(wait)

        except ccxt.InsufficientFunds as e:
            print(f"残高不足で注文キャンセル: {e}")
            return None  # リトライ不要

        except ccxt.BaseError as e:
            print(f"予期せぬCCXTエラー: {e}")
            if attempt == max_retries - 1:
                raise  # 最大試行回数を超えたら例外を再スロー
            await asyncio.sleep(2 ** attempt)

    return None

指数バックオフとは:リトライのたびに待機時間を指数的に増やす戦略のコトデス!!💡 1回目は1秒、2回目は2秒、3回目は4秒……と増やすことで、サーバー側の負荷を下げながら回復を待てるんだヨネ!!CCXTライブトレードの安定稼働にはコレが欠かせないデス!!

5-3. 緊急停止(サーキットブレーカー)機能

ある程度の損失が出たら自動でボットを止める「サーキットブレーカー」も大事デス!!🔥 これがないと、バグや暴落で一気に資金が飛ぶコトがあるんだヨ……やらかしちゃいましたヨ……😭

コレ見てよ!!スゴくナイ!?✨ 設定した損失率を超えたら自動停止するクラスだヨ!!

class CircuitBreaker:
    def __init__(self, initial_balance, max_drawdown_pct=0.10):
        """
        initial_balance: 初期残高(USDT)
        max_drawdown_pct: 許容最大ドローダウン率(デフォルト10%)
        """
        self.initial_balance = initial_balance
        self.max_drawdown_pct = max_drawdown_pct
        self.is_tripped = False

    def check(self, current_balance):
        """現在残高をチェックして、許容範囲を超えたら停止フラグを立てる"""
        drawdown = (self.initial_balance - current_balance) / self.initial_balance
        if drawdown >= self.max_drawdown_pct:
            self.is_tripped = True
            print(
                f"サーキットブレーカー発動!! "
                f"ドローダウン {drawdown:.1%} が上限 {self.max_drawdown_pct:.1%} を超過"
            )
        return not self.is_tripped

ドローダウンとは、残高の最高値からの下落幅のコトデス!!💡 サーキットブレーカーを組み込んでおくと、「夜中に気づいたら全滅してた」ってコトを防げるんだヨ!!🛡️ 許容ラインは事前によ〜く考えておいてネ😆


6. TelegramとCCXTライブトレードの連携|注文通知を自動化する

6-1. Telegram Botを5分で作る手順

CCXTライブトレードの注文が入ったら「スマホに通知が来る」、これ最高じゃナイ!!😆 仕事中でも外出中でも、ボットの状態がリアルタイムでわかるんだヨ!!🔥

Telegram Botの作成はカンタン!!💡

  1. TelegramでBotFatherを検索して /newbot を実行
  2. ボット名とユーザーネームを設定
  3. 発行されたAPIトークンをメモ
  4. 自分のBotにメッセージを送ってからAPIで getUpdates を叩いて chat_id を取得

コレ見てよ!!スゴくナイ!?✨ chat_idの取得はこれだけデス!!

import requests

BOT_TOKEN = 'YOUR_BOT_TOKEN'

url = f'https://api.telegram.org/bot{BOT_TOKEN}/getUpdates'
response = requests.get(url)
data = response.json()

# messages の中に chat.id が入ってるヨ
for result in data['result']:
    print(f"chat_id: {result['message']['chat']['id']}")

6-2. CCXTライブトレードの注文通知コードを実装する

コレ見てよ!!スゴくナイ!?✨ CCXTライブトレードの注文が入った瞬間にスマホへ通知が飛ぶんだヨ!!

import requests
import asyncio

class TelegramNotifier:
    def __init__(self, bot_token, chat_id):
        self.bot_token = bot_token
        self.chat_id = chat_id
        self.base_url = f'https://api.telegram.org/bot{bot_token}/sendMessage'

    async def send(self, message):
        """非同期でTelegram通知を送信"""
        payload = {
            'chat_id': self.chat_id,
            'text': message,
            'parse_mode': 'HTML'
        }
        try:
            loop = asyncio.get_event_loop()
            await loop.run_in_executor(
                None,
                lambda: requests.post(self.base_url, data=payload, timeout=10)
            )
        except Exception as e:
            print(f"Telegram通知エラー(CCXTライブトレードは継続): {e}")

async def notify_order(notifier, symbol, side, price, amount):
    msg = (
        f"<b>【CCXTライブトレード注文通知】</b>\n"
        f"通貨ペア: {symbol}\n"
        f"方向: {side.upper()}\n"
        f"価格: {price:.2f} USDT\n"
        f"数量: {amount:.4f}\n"
        f"約定金額: {price * amount:.2f} USDT"
    )
    await notifier.send(msg)

スマホにピコン!って通知が来た時の嬉しさサ、最初は毎回スクショしてたヨ!!😆 「僕のボットが稼いでる!!」って感じがしてテンション爆上がりだったヨネ🎵 今は慣れちゃったケド、やっぱり通知来ると嬉しいんだヨ!!


7. AWS EC2でCCXTライブトレードをクラウド本番運用する

7-1. なぜローカルPCじゃダメなのか

「自分のPCで動かせばいいじゃん!!」って思うキミ、気持ちはわかるヨ😆 でもサ——PCを落としたらCCXTライブトレードのボットも止まるし、家のインターネットが落ちたらやっぱり止まるし、PCがスリープしても止まるんだヨ!!🔥 CCXTライブトレードは24時間365日動き続けてナンボだからサ、クラウドに乗せるのがベストなんだヨネ💡

AWS EC2なら月1,000〜2,000円程度のt3.microインスタンスで十分動くから、コスパも悪くないデス!!✨

7-2. EC2インスタンスのセットアップと環境構築

まずAWSコンソールでEC2インスタンスを立ち上げてネ♪ 設定はコレで十分デス!!

  • AMI:Ubuntu Server 22.04 LTS(無料枠対象)
  • インスタンスタイプ:t3.micro(1〜4ペア程度のCCXTライブトレードなら十分)
  • セキュリティグループ:SSHポート(22)のみ自分のIPに開放

コレ見てよ!!スゴくナイ!?✨ SSHで繋いだらこれだけで環境が整うんだヨ!!

# SSHでEC2に接続したら、まず環境を整えるヨ!!
sudo apt update && sudo apt upgrade -y
sudo apt install python3-pip python3-venv git -y

# プロジェクトディレクトリを作成
mkdir ~/ccxt_bot && cd ~/ccxt_bot

# 仮想環境を作成・有効化
python3 -m venv venv
source venv/bin/activate

# 必要なライブラリをインストール
pip install "ccxt[pro]" pandas numpy requests python-dotenv

7-3. systemdで24時間常駐化する

コレ見てよ!!スゴくナイ!?✨ systemdに登録するとサーバーが再起動しても自動でCCXTライブトレードボットが立ち上がるんだヨ!!

sudo nano /etc/systemd/system/ccxt_bot.service
[Unit]
Description=CCXT Live Trade Bot
After=network.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/ccxt_bot
ExecStart=/home/ubuntu/ccxt_bot/venv/bin/python main.py
Restart=always
RestartSec=10
EnvironmentFile=/home/ubuntu/ccxt_bot/.env

[Install]
WantedBy=multi-user.target
# サービスを有効化して起動!!
sudo systemctl daemon-reload
sudo systemctl enable ccxt_bot
sudo systemctl start ccxt_bot

# 動作確認
sudo systemctl status ccxt_bot
sudo journalctl -u ccxt_bot -f  # ログをリアルタイムで確認

.env ファイルで秘密情報を管理するのも絶対に忘れずに!!💡 APIキーをコードに直書きするのはNGデス!!

# .env ファイルの例
BINANCE_API_KEY=your_api_key_here
BINANCE_SECRET=your_secret_here
TELEGRAM_BOT_TOKEN=your_telegram_token
TELEGRAM_CHAT_ID=your_chat_id

.env は必ず .gitignore に追加してネ!!Githubに上げたら一瞬で不正アクセスされるヨ😭 ——これ、本当にやらかしちゃいましたヨ……😭 APIキーを即無効化して事なきを得たけど、マジで心臓止まるかと思ったデス!!

7-4. ログ管理と監視のポイント

本番CCXTライブトレードでは、ログが命綱デス!!🔥 何かあった時にログがないと「なんで損した!!?」が全くわからないんだヨネ……😭

コレ見てよ!!スゴくナイ!?✨ Pythonの標準loggingで十分な体制が作れるんだヨ!!

import logging
import os
from datetime import datetime

def setup_logger(name='ccxt_bot', log_dir='logs'):
    """ファイルとコンソール両方に出力するロガーを設定"""
    os.makedirs(log_dir, exist_ok=True)

    log_file = os.path.join(
        log_dir, f"{datetime.now().strftime('%Y%m%d')}.log"
    )

    logger = logging.getLogger(name)
    logger.setLevel(logging.INFO)

    file_handler = logging.FileHandler(log_file, encoding='utf-8')
    file_handler.setLevel(logging.INFO)

    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)

    formatter = logging.Formatter(
        '%(asctime)s [%(levelname)s] %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S'
    )
    file_handler.setFormatter(formatter)
    console_handler.setFormatter(formatter)

    if not logger.handlers:
        logger.addHandler(file_handler)
        logger.addHandler(console_handler)

    return logger

logger = setup_logger()
logger.info("CCXTライブトレードボット起動!!")
logger.warning("残高が低下しています")
logger.error("APIエラーが発生しました")

ログはできれば注文のたびに記録するようにしてネ!!💡 注文ID、シンボル、価格、数量、PnL——この5つは最低限残しておくと、後でパフォーマンス分析ができてめちゃくちゃ役立つんだヨ!!😆


まとめ|CCXTライブトレード第4回をふりかえる

ヤッタネ!!🎉 今回はかなり盛りだくさんな内容だったヨネ!!ざっとふりかえると——

セクション やったコト
1. バックテストと本番の違い スリッページ・過学習・手数料の落とし穴を整理
2. Binance Testnet set_sandbox_mode(True) で安全な検証環境を構築
3. CCXT Pro WebSocket watch_ticker() / watch_ohlcv() でリアルタイムCCXTライブトレード
4. asyncio並列管理 asyncio.gather() + セマフォで複数ペアを同時監視
5. エラーハンドリング 指数バックオフ+サーキットブレーカーで安定稼働
6. Telegram通知 注文が入るたびにスマホへプッシュ通知
7. AWS EC2本番運用 systemdで24時間常駐化+ログ管理

キミ、よくここまでついてきてくれたヨ!!😆 第1〜3回でCCXTの基礎→注文→バックテストをやってきてサ、今回でついにCCXTライブトレードの本番運用まで辿り着いたんだヨ!!🔥

最後に一番大事なコトを言っておくヨ!!💡 どんなに優れたシステムを作っても、市場は常に変化するんだヨネ。CCXTライブトレードを本番に乗せた後も、定期的にパフォーマンスを確認して、戦略を見直し続けるのが大事デス!!ボットを作って終わりじゃなくてサ、それがスタートラインなんだヨ!!😆

🙏 免責事項:本記事は教育目的での情報提供です。特定の投資を推奨するものではありません。仮想通貨取引は元本割れリスクがあります。最終的な投資判断はご自身でお願いします。

関連記事

CCXTを使って仮想通貨のトレードをしてみる(第3回):リスク管理とバックテストの完全ガイド
投資・トレード

CCXTを使って仮想通貨のトレードをしてみる(第3回):リスク管理とバックテストの完全ガイド

CCXTを使った仮想通貨トレードボット第3回。バックテストの実装方法からシャープレシオ・最大ドローダウンなどの評価指標、リスク管理の実践まで初心者にもわかりやすく解説します。

CCXTを使って仮想通貨のトレードをしてみる(第2回):注文実行と基本戦略の実装
投資・トレード

CCXTを使って仮想通貨のトレードをしてみる(第2回):注文実行と基本戦略の実装

CCXTを使った仮想通貨の自動売買・注文実行を解説。成行注文・指値注文の実装方法、サンドボックスでの安全な練習方法、レートリミット対策まで初心者向けにPythonコードで丁寧に説明します。

コメント

0/2000