Xây dựng bot tự động giao dịch trên sàn Binance với Python

2024-04-27 — QuantTrade

Xây dựng bot tự động giao dịch trên sàn Binance với Python

Giới thiệu

Bot giao dịch tự động là chương trình máy tính được thiết kế để tự động thực hiện các giao dịch trên thị trường tài chính dựa trên các thuật toán và chiến lược định sẵn. Với sự phát triển của công nghệ blockchain và các sàn giao dịch tiền điện tử như Binance, việc xây dựng các bot giao dịch tự động đã trở nên phổ biến và dễ tiếp cận hơn.

Bài viết này sẽ hướng dẫn bạn cách xây dựng một bot giao dịch tự động trên sàn Binance bằng ngôn ngữ lập trình Python.

Yêu cầu cơ bản

Trước khi bắt đầu, bạn cần chuẩn bị:

  1. Tài khoản Binance - Đăng ký tài khoản tại Binance.com
  2. API Key và Secret Key - Tạo từ tài khoản Binance của bạn
  3. Môi trường Python - Python 3.7+ và các thư viện cần thiết
  4. Kiến thức cơ bản về Python, API và thị trường tiền điện tử

Cài đặt thư viện cần thiết

pip install ccxt pandas numpy ta matplotlib websocket-client

Các thư viện chính sẽ được sử dụng:

  • ccxt: Thư viện giao dịch tiền điện tử hỗ trợ nhiều sàn, bao gồm Binance
  • pandas: Xử lý và phân tích dữ liệu
  • numpy: Tính toán số học
  • ta: Các chỉ báo phân tích kỹ thuật
  • matplotlib: Trực quan hóa dữ liệu
  • websocket-client: Kết nối websocket cho dữ liệu thời gian thực

Thiết lập kết nối với Binance API

import ccxt
import pandas as pd
import numpy as np
import time
from datetime import datetime
import config  # File chứa thông tin API key

# Khởi tạo kết nối với Binance
binance = ccxt.binance({
    'apiKey': config.API_KEY,
    'secret': config.API_SECRET,
    'enableRateLimit': True,
    'options': {
        'defaultType': 'future'  # Sử dụng future market, đổi thành 'spot' cho spot market
    }
})

# Kiểm tra kết nối
print(binance.fetch_balance())

Tạo file config.py để lưu trữ thông tin API:

API_KEY = 'your_api_key_here'
API_SECRET = 'your_api_secret_here'

Thu thập và xử lý dữ liệu thị trường

def fetch_ohlcv(symbol, timeframe, limit):
    """
    Lấy dữ liệu OHLCV (Open, High, Low, Close, Volume) từ Binance
    """
    ohlcv = binance.fetch_ohlcv(symbol, timeframe, limit=limit)
    df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
    df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
    return df

# Ví dụ: Lấy 100 nến gần nhất của BTC/USDT với khung thời gian 1 giờ
btc_usdt_data = fetch_ohlcv('BTC/USDT', '1h', 100)
print(btc_usdt_data.head())

Thêm chỉ báo phân tích kỹ thuật

def add_indicators(df):
    """
    Thêm các chỉ báo phân tích kỹ thuật vào DataFrame
    """
    # Thêm SMA (Simple Moving Average)
    df['sma20'] = df['close'].rolling(window=20).mean()
    df['sma50'] = df['close'].rolling(window=50).mean()
    
    # Thêm RSI (Relative Strength Index)
    delta = df['close'].diff()
    gain = delta.where(delta > 0, 0).rolling(window=14).mean()
    loss = -delta.where(delta < 0, 0).rolling(window=14).mean()
    rs = gain / loss
    df['rsi'] = 100 - (100 / (1 + rs))
    
    # Thêm MACD (Moving Average Convergence Divergence)
    ema12 = df['close'].ewm(span=12, adjust=False).mean()
    ema26 = df['close'].ewm(span=26, adjust=False).mean()
    df['macd'] = ema12 - ema26
    df['macd_signal'] = df['macd'].ewm(span=9, adjust=False).mean()
    df['macd_hist'] = df['macd'] - df['macd_signal']
    
    return df

# Áp dụng chỉ báo
btc_data_with_indicators = add_indicators(btc_usdt_data)

Xây dựng chiến lược giao dịch

def generate_signals(df):
    """
    Tạo tín hiệu giao dịch dựa trên chỉ báo
    """
    # Khởi tạo cột tín hiệu
    df['signal'] = 0
    
    # Chiến lược đơn giản: Giao cắt MA
    # Mua khi SMA20 cắt lên trên SMA50
    df.loc[(df['sma20'] > df['sma50']) & (df['sma20'].shift(1) <= df['sma50'].shift(1)), 'signal'] = 1
    
    # Bán khi SMA20 cắt xuống dưới SMA50
    df.loc[(df['sma20'] < df['sma50']) & (df['sma20'].shift(1) >= df['sma50'].shift(1)), 'signal'] = -1
    
    return df

# Áp dụng chiến lược
btc_data_with_signals = generate_signals(btc_data_with_indicators)

Thực hiện giao dịch

def execute_trade(symbol, side, amount, price=None):
    """
    Thực hiện lệnh giao dịch
    """
    try:
        if side == 'buy':
            order = binance.create_market_buy_order(symbol, amount)
        elif side == 'sell':
            order = binance.create_market_sell_order(symbol, amount)
        
        print(f"Đã {side} {amount} {symbol} thành công")
        return order
    except Exception as e:
        print(f"Lỗi khi thực hiện giao dịch: {e}")
        return None

def trading_bot(symbol, timeframe, amount, limit=100):
    """
    Bot giao dịch tự động
    """
    print(f"Bot giao dịch bắt đầu cho {symbol}")
    
    position = 0  # 0: không có vị thế, 1: đang mua, -1: đang bán
    
    while True:
        try:
            # Lấy dữ liệu mới nhất
            data = fetch_ohlcv(symbol, timeframe, limit)
            data = add_indicators(data)
            data = generate_signals(data)
            
            # Kiểm tra tín hiệu mới nhất
            current_signal = data['signal'].iloc[-1]
            
            # Thực hiện giao dịch nếu có tín hiệu và chưa có vị thế tương ứng
            if current_signal == 1 and position <= 0:
                execute_trade(symbol, 'buy', amount)
                position = 1
            elif current_signal == -1 and position >= 0:
                execute_trade(symbol, 'sell', amount)
                position = -1
            
            # Chờ một khoảng thời gian trước khi kiểm tra lại
            print(f"Đang chờ... Trạng thái vị thế: {position}")
            time.sleep(60)  # Kiểm tra mỗi phút
            
        except Exception as e:
            print(f"Lỗi: {e}")
            time.sleep(60)  # Tiếp tục chờ nếu có lỗi

Quản lý rủi ro

def calculate_position_size(account_balance, risk_per_trade, stop_loss_percent):
    """
    Tính toán kích thước vị thế dựa trên quản lý rủi ro
    """
    # Số tiền rủi ro cho mỗi giao dịch
    risk_amount = account_balance * (risk_per_trade / 100)
    
    # Kích thước vị thế dựa trên mức stop loss
    position_size = risk_amount / stop_loss_percent
    
    return position_size

def add_stop_loss_take_profit(symbol, order, stop_loss_percent, take_profit_percent):
    """
    Thêm lệnh stop loss và take profit
    """
    if order is None:
        return
    
    entry_price = float(order['price'])
    
    if order['side'] == 'buy':
        # Đặt stop loss dưới giá mua
        stop_price = entry_price * (1 - stop_loss_percent)
        binance.create_order(
            symbol,
            'stop_loss',
            'sell',
            order['amount'],
            None,
            {'stopPrice': stop_price}
        )
        
        # Đặt take profit trên giá mua
        take_profit_price = entry_price * (1 + take_profit_percent)
        binance.create_order(
            symbol,
            'take_profit',
            'sell',
            order['amount'],
            take_profit_price
        )
    
    elif order['side'] == 'sell':
        # Ngược lại cho lệnh bán
        stop_price = entry_price * (1 + stop_loss_percent)
        binance.create_order(
            symbol,
            'stop_loss',
            'buy',
            order['amount'],
            None,
            {'stopPrice': stop_price}
        )
        
        take_profit_price = entry_price * (1 - take_profit_percent)
        binance.create_order(
            symbol,
            'take_profit',
            'buy',
            order['amount'],
            take_profit_price
        )

Theo dõi hiệu suất

def calculate_performance(trades):
    """
    Tính toán hiệu suất của bot giao dịch
    """
    if not trades:
        return {
            'total_trades': 0,
            'win_rate': 0,
            'profit_factor': 0,
            'average_profit': 0
        }
    
    wins = [t for t in trades if t['profit'] > 0]
    losses = [t for t in trades if t['profit'] <= 0]
    
    total_profit = sum(t['profit'] for t in wins)
    total_loss = abs(sum(t['profit'] for t in losses))
    
    win_rate = len(wins) / len(trades) * 100
    profit_factor = total_profit / total_loss if total_loss > 0 else float('inf')
    average_profit = sum(t['profit'] for t in trades) / len(trades)
    
    return {
        'total_trades': len(trades),
        'win_rate': win_rate,
        'profit_factor': profit_factor,
        'average_profit': average_profit
    }

def log_trade(trade_history, symbol, side, amount, entry_price, exit_price, profit):
    """
    Ghi lại thông tin giao dịch
    """
    trade = {
        'timestamp': datetime.now(),
        'symbol': symbol,
        'side': side,
        'amount': amount,
        'entry_price': entry_price,
        'exit_price': exit_price,
        'profit': profit
    }
    
    trade_history.append(trade)
    
    # Cập nhật hiệu suất
    performance = calculate_performance(trade_history)
    print(f"Hiệu suất hiện tại: Win rate {performance['win_rate']:.2f}%, Profit factor: {performance['profit_factor']:.2f}")
    
    return trade_history

Khởi chạy bot

def main():
    # Cấu hình
    symbol = 'BTC/USDT'
    timeframe = '1h'
    risk_percent = 1  # Rủi ro 1% tài khoản mỗi giao dịch
    stop_loss_percent = 0.02  # Stop loss 2%
    take_profit_percent = 0.04  # Take profit 4%
    
    # Lấy số dư tài khoản
    balance = binance.fetch_balance()
    usdt_balance = balance['total']['USDT']
    
    # Tính toán kích thước vị thế
    position_size = calculate_position_size(usdt_balance, risk_percent, stop_loss_percent)
    
    # Chuyển đổi position size từ USDT sang lượng BTC tương đương
    ticker = binance.fetch_ticker(symbol)
    current_price = ticker['last']
    btc_amount = position_size / current_price
    
    # Khởi chạy bot
    trading_bot(symbol, timeframe, btc_amount)

if __name__ == "__main__":
    main()

Nâng cao: Bot giao dịch với Websocket

Để có khả năng phản ứng nhanh hơn với thị trường, bạn có thể sử dụng kết nối Websocket để nhận dữ liệu thời gian thực:

import websocket
import json
import threading

def on_message(ws, message):
    """
    Xử lý tin nhắn từ Websocket
    """
    data = json.loads(message)
    
    # Xử lý dữ liệu kline
    if 'k' in data:
        kline = data['k']
        is_closed = kline['x']
        
        if is_closed:
            symbol = data['s']
            close_price = float(kline['c'])
            print(f"Nến đóng cửa mới cho {symbol}: {close_price}")
            
            # Thực hiện phân tích và giao dịch
            # ...

def on_error(ws, error):
    print(f"Lỗi: {error}")

def on_close(ws, close_status_code, close_msg):
    print("Kết nối Websocket đã đóng")

def on_open(ws):
    print("Kết nối Websocket đã được thiết lập")
    
    # Đăng ký kênh kline/candlestick cho BTC/USDT
    subscribe_message = {
        "method": "SUBSCRIBE",
        "params": [
            "btcusdt@kline_1h"  # BTC/USDT với khung thời gian 1 giờ
        ],
        "id": 1
    }
    ws.send(json.dumps(subscribe_message))

def start_websocket():
    # Kết nối tới Binance Websocket
    socket_url = "wss://stream.binance.com:9443/ws"
    ws = websocket.WebSocketApp(socket_url,
                               on_open=on_open,
                               on_message=on_message,
                               on_error=on_error,
                               on_close=on_close)
    ws.run_forever()

# Chạy websocket trong một thread riêng
websocket_thread = threading.Thread(target=start_websocket)
websocket_thread.daemon = True
websocket_thread.start()

Lưu ý quan trọng

  1. Kiểm tra kỹ chiến lược trước khi chạy trên tài khoản thật. Sử dụng môi trường testnet hoặc backtesting.
  2. Bảo mật API key là vô cùng quan trọng. Không bao giờ chia sẻ hoặc để lộ các khóa API.
  3. Quản lý rủi ro phải luôn được ưu tiên. Không giao dịch quá 1-2% tài khoản cho mỗi lệnh.
  4. Theo dõi thường xuyên hiệu suất của bot và điều chỉnh khi cần thiết.
  5. Lưu ý về chi phí giao dịch như phí giao dịch và slippage có thể ảnh hưởng đến lợi nhuận.

Kết luận

Xây dựng bot giao dịch trên Binance với Python mang lại nhiều lợi ích như loại bỏ cảm xúc trong giao dịch, giao dịch 24/7 và thực hiện chiến lược một cách nhất quán. Tuy nhiên, bot không phải là công cụ "kiếm tiền tự động" mà đòi hỏi kiến thức, kinh nghiệm và liên tục điều chỉnh để đạt hiệu quả tốt.

Việc xây dựng bot giao dịch là một quá trình liên tục học hỏi và cải tiến. Hãy bắt đầu với những chiến lược đơn giản, kiểm tra kỹ lưỡng, và dần dần phát triển những thuật toán phức tạp hơn khi bạn tích lũy được kinh nghiệm.

← Xem tất cả bài viết · Trang chủ