คุณเคยอยากวิเคราะห์ข้อมูลการซื้อขายจาก Bybit เพื่อใช้ในการเทรดหรือทำระบบเทรดอัตโนมัติไหมครับ? บทความนี้จะสอนคุณตั้งแต่เริ่มต้นว่าจะดึงข้อมูล Bybit Perpetual Futures Trades มาใช้งานได้อย่างไร โดยไม่ต้องมีความรู้เรื่องการเขียนโค้ดมาก่อนเลย
Bybit API คืออะไร
Bybit เป็นหนึ่งในตลาดซื้อขายคริปโตที่ใหญ่ที่สุดในโลก และทาง Bybit เปิดให้เราสามารถดึงข้อมูลต่าง ๆ ผ่านสิ่งที่เรียกว่า API ซึ่งย่อมาจาก Application Programming Interface เปรียบเสมือนประตูที่เชื่อมต่อระหว่างโปรแกรมของเรากับข้อมูลของ Bybit นั่นเองครับ
ข้อมูลที่เราจะดึงมาคืออะไร
- Trades (รายการซื้อขาย) - บันทึกทุกครั้งที่มีคนซื้อหรือขาย
- Perpetual Futures (สัญญา永续) - สัญญาซื้อขายล่วงหน้าที่ไม่มีวันหมดอายุ
- เราจะได้ข้อมูลอะไรบ้าง - ราคา ปริมาณ เวลา ฝั่งซื้อหรือขาย
เริ่มต้นใช้งาน Bybit API อย่างละเอียด
ขั้นตอนที่ 1: สร้าง API Key บน Bybit
ก่อนอื่นเราต้องไปสร้าง API Key บนเว็บไซต์ Bybit กันก่อนครับ ทำตามนี้เลย
- เข้าไปที่ bybit.com และทำการล็อกอิน
- ไปที่เมนู Account & Security (บัญชีและความปลอดภัย)
- เลือก API Management (การจัดการ API)
- กดปุ่ม Create new key (สร้าง Key ใหม่)
- ตั้งชื่อ API เช่น "Trading Bot"
- เลือก Read-Only เพราะเราแค่อ่านข้อมูลเท่านั้น
- เลือกช่อง Query spot/trade
- กด Submit และยืนยันอีเมล
สิ่งสำคัญ: คุณจะได้ API Key และ Secret Key มา ต้องเก็บไว้ให้ดีนะครับ อย่าให้ใครเห็น!
ขั้นตอนที่ 2: ติดตั้งโปรแกรมที่จำเป็น
สำหรับมือใหม่ ผมแนะนำให้ติดตั้ง Python ก่อนครับ
# ดาวน์โหลด Python ได้ที่ https://www.python.org/downloads/
เลือกเวอร์ชันล่าสุด (3.10 ขึ้นไป)
หลังติดตั้งเสร็จ เปิด Command Prompt หรือ Terminal แล้วพิมพ์
pip install requests pandas
ขั้นตอนที่ 3: เขียนโค้ดดึงข้อมูล Trades
มาถึงขั้นตอนสำคัญแล้วครับ เราจะเขียนโค้ด Python เพื่อดึงข้อมูลการซื้อขายจาก Bybit มาเก็บไว้ใช้งาน
import requests
import pandas as pd
import time
ตั้งค่าข้อมูล API ของคุณ
API_KEY = "YOUR_BYBIT_API_KEY"
API_SECRET = "YOUR_BYBIT_API_SECRET"
def get_bybit_trades(symbol="BTCUSDT", limit=100):
"""
ดึงข้อมูลรายการซื้อขายล่าสุดจาก Bybit
Parameters:
- symbol: ชื่อเหรียญ เช่น BTCUSDT, ETHUSDT
- limit: จำนวนรายการที่ต้องการ (สูงสุด 1000)
Returns:
- DataFrame ที่มีข้อมูล trade_id, price, qty, time, side
"""
url = "https://api.bybit.com/v5/market/recent-trade"
params = {
"category": "linear", # สำหรับ USDT Perpetual
"symbol": symbol, # คู่เทรด
"limit": limit # จำนวนข้อมูล
}
headers = {
"X-BAPI-API-KEY": API_KEY,
"X-BAPI-SIGN": API_SECRET,
"X-BAPI-SIGN-TYPE": "2"
}
response = requests.get(url, params=params, headers=headers)
if response.status_code == 200:
data = response.json()
if data["retCode"] == 0:
trades = data["result"]["list"]
# แปลงเป็น DataFrame สำหรับวิเคราะห์
df = pd.DataFrame(trades)
df["trade_time_ms"] = pd.to_numeric(df["tradeTime"])
df["trade_time"] = pd.to_datetime(df["trade_time_ms"], unit="ms")
df["price"] = pd.to_numeric(df["price"])
df["qty"] = pd.to_numeric(df["qty"])
print(f"✅ ดึงข้อมูลสำเร็จ: {len(df)} รายการ")
return df
else:
print(f"❌ ข้อผิดพลาด: {data['retMsg']}")
return None
else:
print(f"❌ HTTP Error: {response.status_code}")
return None
ทดสอบเรียกใช้งาน
if __name__ == "__main__":
# ดึงข้อมูล BTC ล่าสุด 100 รายการ
btc_trades = get_bybit_trades(symbol="BTCUSDT", limit=100)
if btc_trades is not None:
print("\n📊 ตัวอย่างข้อมูล 5 รายการแรก:")
print(btc_trades[["trade_time", "price", "qty", "side"]].head())
ขั้นตอนที่ 4: ดึงข้อมูลหลายเหรียญพร้อมกัน
import requests
import pandas as pd
from concurrent.futures import ThreadPoolExecutor
def get_multi_symbols_trades(symbols=["BTCUSDT", "ETHUSDT", "SOLUSDT"], limit=200):
"""
ดึงข้อมูลหลายเหรียญพร้อมกันอย่างรวดเร็ว
Parameters:
- symbols: รายชื่อเหรียญที่ต้องการ
- limit: จำนวนข้อมูลต่อเหรียญ
"""
all_trades = []
def fetch_single(symbol):
url = "https://api.bybit.com/v5/market/recent-trade"
params = {"category": "linear", "symbol": symbol, "limit": limit}
try:
response = requests.get(url, params=params, timeout=10)
data = response.json()
if data["retCode"] == 0:
trades = data["result"]["list"]
df = pd.DataFrame(trades)
df["symbol"] = symbol
return df
except Exception as e:
print(f"⚠️ ดึงข้อมูล {symbol} ล้มเหลว: {e}")
return None
# ใช้ ThreadPoolExecutor เพื่อดึงข้อมูลหลายเหรียญพร้อมกัน
with ThreadPoolExecutor(max_workers=5) as executor:
results = list(executor.map(fetch_single, symbols))
# รวมข้อมูลทั้งหมด
all_trades = [df for df in results if df is not None]
if all_trades:
combined_df = pd.concat(all_trades, ignore_index=True)
combined_df["trade_time"] = pd.to_datetime(
combined_df["tradeTime"], unit="ms"
)
combined_df["price"] = pd.to_numeric(combined_df["price"])
combined_df["qty"] = pd.to_numeric(combined_df["qty"])
# บันทึกเป็นไฟล์ CSV
combined_df.to_csv("bybit_trades.csv", index=False)
print(f"✅ บันทึกข้อมูลทั้งหมด {len(combined_df)} รายการ")
return combined_df
return None
ทดสอบดึงข้อมูล 3 เหรียญยอดนิยม
if __name__ == "__main__":
symbols = ["BTCUSDT", "ETHUSDT", "SOLUSDT"]
df = get_multi_symbols_trades(symbols=symbols, limit=200)
if df is not None:
print("\n📈 สรุปข้อมูล:")
print(df.groupby("symbol").agg({
"price": ["min", "max", "mean"],
"trade_time": "count"
}))
ขั้นตอนที่ 5: ตั้งเวลาดึงข้อมูลอัตโนมัติ
ถ้าคุณต้องการเก็บข้อมูลตลอดเวลา สามารถใช้โค้ดนี้ครับ
import requests
import pandas as pd
import time
from datetime import datetime
def continuous_data_collector(symbol="BTCUSDT", interval_seconds=60, duration_minutes=60):
"""
เก็บข้อมูลอย่างต่อเนื่องทุก X วินาที
Parameters:
- symbol: ชื่อเหรียญ
- interval_seconds: ดึงข้อมูลทุกกี่วินาที
- duration_minutes: เก็บข้อมูลนานกี่นาที
"""
all_data = []
start_time = time.time()
iterations = (duration_minutes * 60) // interval_seconds
print(f"🔄 เริ่มเก็บข้อมูล {symbol} ทุก {interval_seconds} วินาที")
print(f"⏱️ จะเก็บข้อมูลทั้งหมด {iterations} ครั้ง")
for i in range(iterations):
try:
# ดึงข้อมูล
url = "https://api.bybit.com/v5/market/recent-trade"
params = {"category": "linear", "symbol": symbol, "limit": 100}
response = requests.get(url, params=params, timeout=10)
data = response.json()
if data["retCode"] == 0:
trades = data["result"]["list"]
all_data.extend(trades)
now = datetime.now().strftime("%H:%M:%S")
print(f"[{now}] ครั้งที่ {i+1}/{iterations} - ดึงได้ {len(trades)} รายการ")
except Exception as e:
print(f"⚠️ ข้อผิดพลาด: {e}")
# รอตามเวลาที่กำหนด
if i < iterations - 1:
time.sleep(interval_seconds)
# บันทึกข้อมูลทั้งหมด
if all_data:
df = pd.DataFrame(all_data)
df = df.drop_duplicates(subset=["tradeId"]) # ลบรายการซ้ำ
df.to_csv(f"{symbol}_continuous.csv", index=False)
print(f"\n✅ เสร็จสิ้น! เก็บข้อมูลได้ {len(df)} รายการ")
return df
return None
ทดสอบเก็บข้อมูล 10 นาที ทุก 30 วินาที
if __name__ == "__main__":
continuous_data_collector(
symbol="BTCUSDT",
interval_seconds=30,
duration_minutes=10
)
ข้อมูลที่ได้จาก API มีอะไรบ้าง
เมื่อเราดึงข้อมูลมาสำเร็จ คุณจะได้ข้อมูลดังนี้ครับ
| ฟิลด์ | คำอธิบาย | ตัวอย่าง |
|---|---|---|
| tradeId | หมายเลขรายการซื้อขาย | 1234567890 |
| symbol | คู่เทรด | BTCUSDT |
| price | ราคาที่ซื้อขาย | 65432.50 |
| qty | ปริมาณที่ซื้อขาย | 0.015 |
| side | ฝั่งซื้อหรือขาย (Buy/Sell) | Buy |
| tradeTime | เวลาที่ซื้อขาย (millisecond) | 1746234567000 |
| isBuyerMaker | ผู้สร้างรายการเป็นฝั่งขายหรือไม่ | true/false |
ข้อผิดพลาดที่พบบ่อยและวิธีแก้ไข
ข้อผิดพลาดที่ 1: 10001 System Error หรือ IP ถูกบล็อก
อาการ: ได้รับข้อความ {"retCode": 10001, "retMsg": "system error"}
สาเหตุ: Bybit บล็อก IP ของคุณเนื่องจากเรียก API บ่อยเกินไป หรือ IP ถูกจำกัด
# วิธีแก้ไขที่ 1: เพิ่มการหน่วงเวลา
import time
import random
def safe_api_call_with_retry(url, params, max_retries=3):
"""
เรียก API อย่างปลอดภัยพร้อมระบบรอและลองใหม่
"""
for attempt in range(max_retries):
try:
# สุ่มหน่วงเวลา 1-3 วินาที เพื่อไม่ให้ถูกบล็อก
delay = random.uniform(1, 3)
print(f"⏳ รอ {delay:.2f} วินาที...")
time.sleep(delay)
response = requests.get(url, params=params, timeout=15)
if response.status_code == 200:
data = response.json()
if data["retCode"] == 0:
return data["result"]
elif "system error" in data["retMsg"].lower():
print(f"⚠️ ลองใหม่ครั้งที่ {attempt + 1}")
continue
else:
print(f"❌ ข้อผิดพลาด: {data['retMsg']}")
return None
except requests.exceptions.Timeout:
print(f"⚠️ Connection Timeout - ลองใหม่ครั้งที่ {attempt + 1}")
continue
except Exception as e:
print(f"❌ ข้อผิดพลาด: {e}")
return None
print("❌ ล้มเหลวหลังจากลองหลายครั้ง")
return None
วิธีแก้ไขที่ 2: ตรวจสอบ IP Whitelist
ไปที่ Bybit API Management และเพิ่ม IP ปัจจุบันของคุณใน whitelist
ข้อผิดพลาดที่ 2: 10002 Sign ไม่ถูกต้อง
อาการ: ได้รับข้อความ {"retCode": 10002, "retMsg": "sign error"}
สาเหตุ: การเซ็นต์คำขอไม่ถูกต้อง เกิดจาก API Key ผิด หรือวิธีการเซ็นต์ไม่ถูก
# สำหรับการอ่านข้อมูลสาธารณะ ไม่ต้องมี Signature!
ใช้โค้ดนี้แทน (ไม่ต้องส่ง API Key และ Secret)
import requests
def get_public_trades(symbol="BTCUSDT", limit=100):
"""
ดึงข้อมูลสาธารณะ ไม่ต้องล็อกอิน
⚠️ วิธีนี้เหมาะสำหรับอ่านข้อมูลเท่านั้น ไม่สามารถเทรดได้
"""
url = "https://api.bybit.com/v5/market/recent-trade"
params = {
"category": "linear",
"symbol": symbol,
"limit": limit
}
# ไม่ต้องส่ง headers ใด ๆ
response = requests.get(url, params=params)
if response.status_code == 200:
data = response.json()
if data["retCode"] == 0:
trades = data["result"]["list"]
print(f"✅ ดึงข้อมูลสาธารณะสำเร็จ: {len(trades)} รายการ")
return trades
else:
print(f"❌ ข้อผิดพลาด: {data['retMsg']}")
return None
ทดสอบ
trades = get_public_trades("BTCUSDT", 50)
if trades:
for trade in trades[:3]:
print(f"ราคา: {trade['price']}, ปริมาณ: {trade['qty']}, เวลา: {trade['tradeTime']}")
ข้อผิดพลาดที่ 3: Rate Limit - เรียก API เร็วเกินไป
อาการ: ได้รับข้อความ {"retCode": 10006, "retMsg": "too many request"}
สาเหตุ: Bybit จำกัดจำนวนคำขอต่อวินาที (rate limit)
import time
from collections import deque
from threading import Lock
class RateLimiter:
"""
ระบบจำกัดจำนวนคำขออัตโนมัติ
Bybit จำกัดที่ 100 คำขอต่อ 10 วินาทีสำหรับ Public API
และ 60 คำขอต่อ 10 วินาทีสำหรับ Private API
"""
def __init__(self, max_requests=100, time_window=10):
self.max_requests = max_requests
self.time_window = time_window
self.requests = deque()
self.lock = Lock()
def wait_if_needed(self):
"""รอจนกว่าจะสามารถส่งคำขอได้"""
with self.lock:
now = time.time()
# ลบคำขอที่เก่ากว่า time_window วินาที
while self.requests and self.requests[0] < now - self.time_window:
self.requests.popleft()
# ถ้าจำนวนคำขอเกิน limit ให้รอ
if len(self.requests) >= self.max_requests:
oldest = self.requests[0]
wait_time = oldest - (now - self.time_window) + 0.1
print(f"⏳ รอเนื่องจาก Rate Limit... {wait_time:.2f} วินาที")
time.sleep(wait_time)
return self.wait_if_needed()
# เพิ่มคำขอปัจจุบัน
self.requests.append(time.time())
return True
วิธีใช้งาน
limiter = RateLimiter(max_requests=100, time_window=10)
def rate_limited_request(url, params):
"""ส่งคำขอแบบมีระบบจำกัดอัตรา"""
limiter.wait_if_needed()
response = requests.get(url, params=params)
return response
ทดสอบ: ดึงข้อมูล 500 ครั้งโดยไม่ถูกบล็อก
for i in range(500):
result = rate_limited_request(
"https://api.bybit.com/v5/market/recent-trade",
{"category": "linear", "symbol": "BTCUSDT", "limit": 10}
)
print(f"ครั้งที่ {i+1}: {result.status_code}")
ข้อผิดพลาดที่ 4: Connection Error หรือ SSL Error
อาการ: ConnectionError หรือ SSLError
สาเหตุ: ปัญหาเครือข่าย หรือเวลาเครื่องไม่ตรง
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
def create_robust_session():
"""
สร้าง Session ที่มีความทนทานต่อข้อผิดพลาด
"""
session = requests.Session()
# ตั้งค่า Retry Strategy
retry_strategy = Retry(
total=5,
backoff_factor=1,
status_forcelist=[429, 500, 502, 503, 504],
)
# ตั้งค่า Adapter
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("https://", adapter)
session.mount("http://", adapter)
# ตั้งค่า Timeout
session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
})
return session
def safe_get_data(url, params, timeout=30):
"""
ดึงข้อมูลแบบปลอดภัยพร้อม Retry และ Timeout
"""
session = create_robust_session()
try:
print(f"📡 กำลังเรียก API: {url}")
response = session.get(url, params=params, timeout=timeout)
response.raise_for_status()
data = response.json()
if data["retCode"] == 0:
return data["result"]
else:
print(f"⚠️ API Error: {data['retMsg']}")
return None
except requests.exceptions.Timeout:
print("❌ Connection Timeout - เซิร์ฟเวอร์ตอบสนองช้า")
except requests.exceptions.ConnectionError:
print("❌ Connection Error - ตรวจสอบอินเทอร์เน็ตของคุณ")
except requests.exceptions.SSLError:
print("❌ SSL Error - อัปเดต certificates")
except Exception as e:
print(f"❌ ข้อผิดพลาดที่ไม่ทราบสาเหตุ: {e}")
return None
ทดสอบใช้งาน
result = safe_get_data(
"https://api.bybit.com/v5/market/recent-trade",
{"