Statistics
  • 현재 접속자 228 명
  • 오늘 방문자 973 명
  • 어제 방문자 3,367 명
  • 최대 방문자 11,031 명
  • 전체 방문자 1,113,404 명
  • 전체 회원수 76 명
  • 전체 게시물 2,691 개
  • 전체 댓글수 4 개
AI강의사이트

비트겟 RSI & MACD 자동매매 봇 - 비트겟(Bitget) API를 활용한 **자동매매 트레이딩 봇 (RSI & MACD 기반)**을 Python으로 구현하겠습니다.

작성자 정보

  • 작성자 bryanai
  • 작성일

컨텐츠 정보

  • 조회 607

본문

비트겟 RSI & MACD 자동매매 봇

비트겟(Bitget) API를 활용한 **자동매매 트레이딩 봇 (RSI & MACD 기반)**을 Python으로 구현하겠습니다.

비트겟(Bitget) API를 활용한 **자동매매 트레이딩 봇 (RSI & MACD 기반)**을 Python으로 구현하겠습니다.


기능 개요

  1. 비트겟 API에서 시세 데이터 가져오기 (캔들 데이터)
  2. RSI (Relative Strength Index) 계산
    • RSI가 30 이하일 때 매수 (과매도 상태)
    • RSI가 70 이상일 때 매도 (과매수 상태)
  3. MACD (Moving Average Convergence Divergence) 계산
    • MACD가 시그널선을 상향 돌파하면 매수
    • MACD가 시그널선을 하향 돌파하면 매도
  4. 자동 매매 실행 (비트겟 API를 통한 매수/매도 주문)
  5. 잔고 확인 및 로깅

코드: 비트겟 RSI & MACD 자동매매 봇

import requests
import time
import numpy as np
import pandas as pd
import talib
import hmac
import hashlib
import json

# === 비트겟 API 정보 (본인 API 키 입력) ===
API_KEY = "your_api_key"
API_SECRET = "your_api_secret"
BASE_URL = "https://api.bitget.com"

# === 설정 값 ===
SYMBOL = "BTCUSDT"  # BTC/USDT 거래쌍
TIMEFRAME = "1m"    # 캔들 주기 (1분)
TRADE_AMOUNT = 0.001  # 매매할 BTC 수량
RSI_OVERBOUGHT = 70  # RSI 과매수 기준
RSI_OVERSOLD = 30    # RSI 과매도 기준

# === 비트겟 시세 데이터 가져오기 ===
def get_candles(symbol, timeframe, limit=100):
    url = f"{BASE_URL}/api/v2/market/candles"
    params = {
        "symbol": symbol,
        "period": timeframe,
        "limit": limit
    }
    response = requests.get(url, params=params)
    if response.status_code == 200:
        return pd.DataFrame(response.json()["data"], columns=["timestamp", "open", "high", "low", "close", "volume"])
    else:
        print("캔들 데이터 조회 실패:", response.text)
        return None

# === RSI 계산 ===
def calculate_rsi(data, period=14):
    close_prices = data["close"].astype(float).values
    rsi = talib.RSI(close_prices, timeperiod=period)
    return rsi[-1]  # 가장 최신 RSI 값

# === MACD 계산 ===
def calculate_macd(data):
    close_prices = data["close"].astype(float).values
    macd, signal, hist = talib.MACD(close_prices, fastperiod=12, slowperiod=26, signalperiod=9)
    return macd[-1], signal[-1]  # 최신 MACD & 시그널 값

# === API 서명 생성 ===
def create_signature(method, endpoint, params=""):
    message = method + endpoint + params
    return hmac.new(API_SECRET.encode(), message.encode(), hashlib.sha256).hexdigest()

# === 매수 주문 실행 ===
def place_order(symbol, side, amount):
    endpoint = "/api/v2/spot/orders"
    url = BASE_URL + endpoint
    params = {
        "symbol": symbol,
        "side": side,
        "type": "market",
        "quantity": str(amount)
    }
    headers = {
        "X-BG-APIKEY": API_KEY,
        "X-BG-SIGNATURE": create_signature("POST", endpoint, json.dumps(params)),
        "Content-Type": "application/json"
    }
    response = requests.post(url, headers=headers, json=params)
    return response.json()

# === 잔고 조회 ===
def get_balance():
    endpoint = "/api/v2/spot/accounts"
    url = BASE_URL + endpoint
    headers = {
        "X-BG-APIKEY": API_KEY,
        "X-BG-SIGNATURE": create_signature("GET", endpoint)
    }
    response = requests.get(url, headers=headers)
    return response.json()

# === 자동매매 실행 ===
def trade():
    while True:
        print("\n 시세 데이터 조회 중...")
        data = get_candles(SYMBOL, TIMEFRAME)
        if data is None:
            time.sleep(60)
            continue

        # RSI & MACD 계산
        rsi = calculate_rsi(data)
        macd, signal = calculate_macd(data)

        print(f"RSI: {rsi:.2f}, MACD: {macd:.2f}, Signal: {signal:.2f}")

        # 매매 로직
        if rsi <= RSI_OVERSOLD and macd > signal:  # RSI 과매도 + MACD 골든크로스 → 매수
            print(" 매수 조건 충족! 매수 주문 실행 중...")
            response = place_order(SYMBOL, "buy", TRADE_AMOUNT)
            print(" 매수 결과:", response)

        elif rsi >= RSI_OVERBOUGHT and macd < signal:  # RSI 과매수 + MACD 데드크로스 → 매도
            print(" 매도 조건 충족! 매도 주문 실행 중...")
            response = place_order(SYMBOL, "sell", TRADE_AMOUNT)
            print(" 매도 결과:", response)

        # 1분 대기 후 반복
        time.sleep(60)

# === 자동매매 실행 ===
if __name__ == "__main__":
    trade()

코드 설명

  1. 캔들 데이터 가져오기
    • get_candles(): 비트겟 API에서 1분봉 캔들 데이터를 가져옵니다.
  2. RSI 계산
    • calculate_rsi(): TA-Lib을 사용하여 RSI를 계산합니다.
    • RSI 30 이하이면 매수, 70 이상이면 매도
  3. MACD 계산
    • calculate_macd(): TA-Lib을 사용하여 MACD와 Signal 값을 계산합니다.
    • MACD가 Signal을 상향 돌파하면 매수, 하향 돌파하면 매도
  4. 자동매매 실행
    • trade(): 1분마다 RSI와 MACD를 확인하여 자동으로 매매를 실행합니다.
    • 매매 시 API를 통해 시장가 주문을 실행합니다.
  5. 비트겟 API 호출
    • place_order(): 시장가 주문 실행 (매수/매도)
    • get_balance(): 잔고 조회

실행 방법

  1. Python 라이브러리 설치
pip install requests numpy pandas ta-lib

⚠️ TA-Lib은 설치가 어려울 수 있으므로, Windows 사용자는 conda install -c conda-forge ta-lib 명령어를 사용할 수 있습니다.

  1. API 키 설정

    • 비트겟에서 API Key와 Secret을 발급받아 코드의 API_KEY, API_SECRET에 입력하세요.
  2. Python 코드 실행

python bitget_bot.py

결론

이제 비트겟에서 RSI & MACD 기반 자동매매 봇이 실행됩니다.
이 코드는 1분마다 시세를 확인하고, 매수/매도 조건이 충족되면 자동으로 주문을 실행합니다.

개선할 점

  • 손절 및 익절 기능 추가 (예: -2% 손절, +5% 익절)
  • 로그 저장 및 백테스트 기능 추가
  • 거래량/유동성을 고려한 추가 필터링

추가 기능이 필요하면 알려주세요!


자바스크립트


// === Bitget API Info ===

const API_KEY = "your_api_key";

const API_SECRET = "your_api_secret";

const BASE_URL = "https://api.bitget.com";


// === Settings ===

const SYMBOL = "BTCUSDT"; // BTC/USDT trading pair

const TIMEFRAME = "1m"; // Candle interval (1 minute)

const TRADE_AMOUNT = 0.001; // Amount of BTC to trade

const RSI_OVERBOUGHT = 70; // RSI overbought threshold

const RSI_OVERSOLD = 30; // RSI oversold threshold


const fetch = require("node-fetch");

const crypto = require("crypto");


// === Fetch Candlestick Data ===

async function getCandles(symbol, timeframe, limit = 100) {

    const url = `${BASE_URL}/api/v2/market/candles?symbol=${symbol}&period=${timeframe}&limit=${limit}`;

    try {

        const response = await fetch(url);

        if (!response.ok) {

            console.error("Failed to fetch candle data:", response.statusText);

            return null;

        }

        const result = await response.json();

        return result.data.map(candle => ({

            timestamp: candle[0],

            open: parseFloat(candle[1]),

            high: parseFloat(candle[2]),

            low: parseFloat(candle[3]),

            close: parseFloat(candle[4]),

            volume: parseFloat(candle[5]),

        }));

    } catch (error) {

        console.error("Error fetching candle data:", error);

        return null;

    }

}


// === Calculate RSI ===

function calculateRSI(data, period = 14) {

    const closes = data.map(candle => candle.close);

    let gains = 0, losses = 0;


    for (let i = 1; i <= period; i++) {

        const change = closes[i] - closes[i - 1];

        if (change > 0) gains += change;

        else losses -= change;

    }


    const avgGain = gains / period;

    const avgLoss = losses / period;

    const rs = avgGain / avgLoss;

    const rsi = 100 - 100 / (1 + rs);


    return rsi;

}


// === Calculate MACD ===

function calculateMACD(data) {

    const closes = data.map(candle => candle.close);

    const ema12 = calculateEMA(closes, 12);

    const ema26 = calculateEMA(closes, 26);

    const macd = ema12.map((value, index) => value - ema26[index]);

    const signal = calculateEMA(macd, 9);


    return { macd: macd[macd.length - 1], signal: signal[signal.length - 1] };

}


function calculateEMA(data, period) {

    const multiplier = 2 / (period + 1);

    let ema = [data[0]];


    for (let i = 1; i < data.length; i++) {

        ema.push((data[i] - ema[i - 1]) * multiplier + ema[i - 1]);

    }


    return ema;

}


// === Create API Signature ===

function createSignature(method, endpoint, params = "") {

    const message = method + endpoint + params;

    return crypto.createHmac("sha256", API_SECRET).update(message).digest("hex");

}


// === Place Order ===

async function placeOrder(symbol, side, amount) {

    const endpoint = "/api/v2/spot/orders";

    const url = `${BASE_URL}${endpoint}`;

    const params = {

        symbol,

        side,

        type: "market",

        quantity: amount.toString()

    };


    const headers = {

        "X-BG-APIKEY": API_KEY,

        "X-BG-SIGNATURE": createSignature("POST", endpoint, JSON.stringify(params)),

        "Content-Type": "application/json"

    };


    try {

        const response = await fetch(url, {

            method: "POST",

            headers,

            body: JSON.stringify(params)

        });

        return await response.json();

    } catch (error) {

        console.error("Error placing order:", error);

        return null;

    }

}


// === Get Balance ===

async function getBalance() {

    const endpoint = "/api/v2/spot/accounts";

    const url = `${BASE_URL}${endpoint}`;

    const headers = {

        "X-BG-APIKEY": API_KEY,

        "X-BG-SIGNATURE": createSignature("GET", endpoint)

    };


    try {

        const response = await fetch(url, { method: "GET", headers });

        return await response.json();

    } catch (error) {

        console.error("Error fetching balance:", error);

        return null;

    }

}


// === Execute Trading ===

async function trade() {

    while (true) {

        console.log("\nFetching market data...");

        const data = await getCandles(SYMBOL, TIMEFRAME);


        if (!data) {

            await new Promise(resolve => setTimeout(resolve, 60000));

            continue;

        }


        const rsi = calculateRSI(data);

        const { macd, signal } = calculateMACD(data);


        console.log(`RSI: ${rsi.toFixed(2)}, MACD: ${macd.toFixed(2)}, Signal: ${signal.toFixed(2)}`);


        if (rsi <= RSI_OVERSOLD && macd > signal) {

            console.log("Buying condition met! Placing buy order...");

            const response = await placeOrder(SYMBOL, "buy", TRADE_AMOUNT);

            console.log("Buy order response:", response);

        } else if (rsi >= RSI_OVERBOUGHT && macd < signal) {

            console.log("Selling condition met! Placing sell order...");

            const response = await placeOrder(SYMBOL, "sell", TRADE_AMOUNT);

            console.log("Sell order response:", response);

        }


        await new Promise(resolve => setTimeout(resolve, 60000));

    }

}


// === Start Trading ===

(async () => {

    await trade();

})();

 

관련자료

댓글 0
등록된 댓글이 없습니다.
Notice
Member Rank