비트겟 RSI & MACD 자동매매 봇 - 비트겟(Bitget) API를 활용한 **자동매매 트레이딩 봇 (RSI & MACD 기반)**을 Python으로 구현하겠습니다.
작성자 정보
- 작성자 bryanai
- 작성일
컨텐츠 정보
- 조회 607
본문
비트겟 RSI & MACD 자동매매 봇
비트겟(Bitget) API를 활용한 **자동매매 트레이딩 봇 (RSI & MACD 기반)**을 Python으로 구현하겠습니다.
비트겟(Bitget) API를 활용한 **자동매매 트레이딩 봇 (RSI & MACD 기반)**을 Python으로 구현하겠습니다.
기능 개요
- 비트겟 API에서 시세 데이터 가져오기 (캔들 데이터)
- RSI (Relative Strength Index) 계산
- RSI가 30 이하일 때 매수 (과매도 상태)
- RSI가 70 이상일 때 매도 (과매수 상태)
- MACD (Moving Average Convergence Divergence) 계산
- MACD가 시그널선을 상향 돌파하면 매수
- MACD가 시그널선을 하향 돌파하면 매도
- 자동 매매 실행 (비트겟 API를 통한 매수/매도 주문)
- 잔고 확인 및 로깅
코드: 비트겟 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()
코드 설명
- 캔들 데이터 가져오기
get_candles()
: 비트겟 API에서 1분봉 캔들 데이터를 가져옵니다.
- RSI 계산
calculate_rsi()
:TA-Lib
을 사용하여 RSI를 계산합니다.- RSI 30 이하이면 매수, 70 이상이면 매도
- MACD 계산
calculate_macd()
:TA-Lib
을 사용하여 MACD와 Signal 값을 계산합니다.- MACD가 Signal을 상향 돌파하면 매수, 하향 돌파하면 매도
- 자동매매 실행
trade()
: 1분마다 RSI와 MACD를 확인하여 자동으로 매매를 실행합니다.- 매매 시 API를 통해 시장가 주문을 실행합니다.
- 비트겟 API 호출
place_order()
: 시장가 주문 실행 (매수/매도)get_balance()
: 잔고 조회
실행 방법
- Python 라이브러리 설치
pip install requests numpy pandas ta-lib
⚠️
TA-Lib
은 설치가 어려울 수 있으므로, Windows 사용자는conda install -c conda-forge ta-lib
명령어를 사용할 수 있습니다.
-
API 키 설정
- 비트겟에서 API Key와 Secret을 발급받아 코드의
API_KEY
,API_SECRET
에 입력하세요.
- 비트겟에서 API Key와 Secret을 발급받아 코드의
-
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();
})();
관련자료
-
이전
-
다음