ในโลกของการเทรดคริปโตผ่าน API หลายคนอาจเคยเจอสถานการณ์แบบนี้: คุณเขียนโค้ดระบบเทรดอัตโนมัติเสร็จสรรพ ทดสอบบน Spot API ได้ผลดีมาก พอนำไปใช้กับ Futures API จริงกลับเจอ 403 Forbidden หรือราคาที่ได้ไม่ตรงตามคาดเพราะ Funding Rate ที่คิดเข้ามา หรือบางที Margin Call มาโดยไม่ทันตั้งตัว

บทความนี้จะพาคุณเข้าใจความแตกต่างเชิงลึกระหว่าง Binance Spot API และ Futures API พร้อมตัวอย่างโค้ดที่ใช้งานได้จริง และข้อผิดพลาดยอดนิยมที่นักพัฒนาไทยมักเจอบ่อยที่สุด

ความแตกต่างพื้นฐานระหว่าง Spot และ Futures API

ก่อนจะลงลึกเรื่อง Technical Detail เรามาทำความเข้าใจ Concept พื้นฐานกันก่อน

Spot API ทำงานอย่างไร

Spot API ใช้สำหรับการซื้อขายเหรียญจริง (สินทรัพย์จริง) คุณต้องมีเหรียญในกระเป๋าเงินก่อนจึงจะซื้อได้ ราคาที่เห็นคือราคาจริงที่ตลาดกำหนด ไม่มี Leverage ไม่มี Funding Fee ไม่มี Liquidation

Futures API ทำงานอย่างไร

Futures API ใช้สำหรับสัญญา Bitcoin Futures ที่คุณไม่ได้ถือเหรียญจริง แต่เป็นสัญญาที่คุณจ่าย Margin เป็นหลักประกัน คุณสามารถใช้ Leverage ได้สูงถึง 125x ในบางสินทรัพย์ แต่ข้อเสียคือมีค่า Funding Rate ที่ต้องจ่ายทุก 8 ชั่วโมง และมีความเสี่ยง Liquidation หากราคาเคลื่อนไหวตรงข้ามกับทิศทางที่คุณเปิดออเดอร์

ตารางเปรียบเทียบ Spot API กับ Futures API

คุณสมบัติ Binance Spot API Binance Futures API
ประเภทสินทรัพย์ เหรียญจริง (BTC, ETH, BNB) สัญญา Futures (BTCUSD, ETHUSD)
Margin และ Leverage ไม่มี (ซื้อเต็มจำนวน) มี Leverage สูงสุด 125x
Funding Rate ไม่มี จ่าย/รับทุก 8 ชั่วโมง
Liquidation ไม่มี มี เมื่อ Margin ต่ำกว่า Maintenance
ความเสี่ยง จำกัดอยู่ที่จำนวนเงินที่มี สูญเสียมากกว่าเงินที่มีได้ (ในบางกรณี)
API Endpoint api.binance.com fapi.binance.com (Testnet: fapi-testnet.binance.com)
Order Book Depth สูงสุด 5,000 orders สูงสุด 5,000 orders
WebSocket Streams wss://stream.binance.com:9443 wss://fstream.binance.com

ตัวอย่างโค้ดการเชื่อมต่อ Spot API

สำหรับนักพัฒนาที่ต้องการเริ่มต้นเชื่อมต่อ Spot API นี่คือตัวอย่างโค้ด Python ที่ใช้งานได้จริง:

import requests
import time
import hmac
import hashlib

class BinanceSpotAPI:
    def __init__(self, api_key, api_secret):
        self.api_key = api_key
        self.api_secret = api_secret
        self.base_url = "https://api.binance.com"
    
    def _generate_signature(self, params):
        """สร้าง HMAC SHA256 signature"""
        query_string = '&'.join([f"{k}={v}" for k, v in params.items()])
        signature = hmac.new(
            self.api_secret.encode('utf-8'),
            query_string.encode('utf-8'),
            hashlib.sha256
        ).hexdigest()
        return signature
    
    def get_account_balance(self):
        """ดึงยอดคงเหลือ Spot Account"""
        timestamp = int(time.time() * 1000)
        params = {
            'timestamp': timestamp,
            'recvWindow': 5000
        }
        params['signature'] = self._generate_signature(params)
        
        headers = {
            'X-MBX-APIKEY': self.api_key,
            'Content-Type': 'application/json'
        }
        
        response = requests.get(
            f"{self.base_url}/api/v3/account",
            params=params,
            headers=headers
        )
        
        if response.status_code == 200:
            return response.json()
        else:
            raise Exception(f"Error {response.status_code}: {response.text}")
    
    def place_order(self, symbol, side, order_type, quantity, price=None):
        """เปิดออเดอร์ซื้อ/ขาย"""
        timestamp = int(time.time() * 1000)
        params = {
            'symbol': symbol,
            'side': side,
            'type': order_type,
            'quantity': quantity,
            'timestamp': timestamp,
            'recvWindow': 5000
        }
        
        if price:
            params['price'] = price
            params['timeInForce'] = 'GTC'
        
        params['signature'] = self._generate_signature(params)
        
        headers = {
            'X-MBX-APIKEY': self.api_key
        }
        
        response = requests.post(
            f"{self.base_url}/api/v3/order",
            params=params,
            headers=headers
        )
        
        return response.json()

วิธีใช้งาน

api = BinanceSpotAPI( api_key='YOUR_SPOT_API_KEY', api_secret='YOUR_SPOT_API_SECRET' )

ดึงยอดคงเหลือ

balance = api.get_account_balance() print(f"ยอด USDT: {balance['balances'][0]['free']}")

ซื้อ BTC 0.001 ตัว ที่ราคา 50,000 USDT

order = api.place_order( symbol='BTCUSDT', side='BUY', order_type='LIMIT', quantity='0.001', price='50000' ) print(f"Order ID: {order['orderId']}")

ตัวอย่างโค้ดการเชื่อมต่อ Futures API

สำหรับ Futures API จะมีความแตกต่างที่สำคัญหลายจุด โดยเฉพาะเรื่อง Position Mode, Margin Type และ Leverage

import requests
import time
import hmac
import hashlib

class BinanceFuturesAPI:
    def __init__(self, api_key, api_secret):
        self.api_key = api_key
        self.api_secret = api_secret
        self.base_url = "https://fapi.binance.com"
    
    def _generate_signature(self, params):
        """สร้าง HMAC SHA256 signature สำหรับ Futures"""
        query_string = '&'.join([f"{k}={v}" for k, v in params.items()])
        signature = hmac.new(
            self.api_secret.encode('utf-8'),
            query_string.encode('utf-8'),
            hashlib.sha256
        ).hexdigest()
        return signature
    
    def set_leverage(self, symbol, leverage):
        """ตั้งค่า Leverage สำหรับ Symbol (จำเป็นต้องทำก่อนเปิดออเดอร์)"""
        timestamp = int(time.time() * 1000)
        params = {
            'symbol': symbol,
            'leverage': leverage,
            'timestamp': timestamp,
            'recvWindow': 5000
        }
        params['signature'] = self._generate_signature(params)
        
        headers = {'X-MBX-APIKEY': self.api_key}
        
        response = requests.post(
            f"{self.base_url}/fapi/v1/leverage",
            params=params,
            headers=headers
        )
        
        if response.status_code == 200:
            print(f"ตั้งค่า Leverage {leverage}x สำหรับ {symbol} สำเร็จ")
            return response.json()
        else:
            raise Exception(f"Set Leverage Error: {response.text}")
    
    def get_position_info(self, symbol=None):
        """ดึงข้อมูล Position ปัจจุบัน"""
        timestamp = int(time.time() * 1000)
        params = {
            'timestamp': timestamp,
            'recvWindow': 5000
        }
        
        if symbol:
            params['symbol'] = symbol
        
        params['signature'] = self._generate_signature(params)
        
        headers = {'X-MBX-APIKEY': self.api_key}
        
        response = requests.get(
            f"{self.base_url}/fapi/v2/positionRisk",
            params=params,
            headers=headers
        )
        
        return response.json()
    
    def place_futures_order(self, symbol, side, order_type, quantity, price=None, leverage=10):
        """เปิดออเดอร์ Futures"""
        # ตั้งค่า Leverage ก่อนเสมอ
        self.set_leverage(symbol, leverage)
        
        timestamp = int(time.time() * 1000)
        params = {
            'symbol': symbol,
            'side': side,
            'type': order_type,
            'quantity': quantity,
            'timestamp': timestamp,
            'recvWindow': 5000
        }
        
        if price:
            params['price'] = price
            params['timeInForce'] = 'GTC'
        
        params['signature'] = self._generate_signature(params)
        
        headers = {'X-MBX-APIKEY': self.api_key}
        
        response = requests.post(
            f"{self.base_url}/fapi/v1/order",
            params=params,
            headers=headers
        )
        
        return response.json()
    
    def get_funding_rate(self, symbol):
        """ดึง Funding Rate ปัจจุบัน (สำคัญมาก!)"""
        params = {'symbol': symbol}
        response = requests.get(
            f"{self.base_url}/fapi/v1/premiumIndex",
            params=params
        )
        data = response.json()
        
        return {
            'symbol': data['symbol'],
            'fundingRate': float(data['lastFundingRate']) * 100,
            'nextFundingTime': data['nextFundingTime']
        }

วิธีใช้งาน

futures = BinanceFuturesAPI( api_key='YOUR_FUTURES_API_KEY', api_secret='YOUR_FUTURES_API_SECRET' )

ตรวจสอบ Funding Rate ก่อนเปิดออเดอร์

funding = futures.get_funding_rate('BTCUSDT') print(f"Funding Rate ปัจจุบัน: {funding['fundingRate']}%") print(f"Next Funding: {funding['nextFundingTime']}")

เปิด Long Position BTC 0.01 ที่ Leverage 10x

order = futures.place_futures_order( symbol='BTCUSDT', side='BUY', order_type='LIMIT', quantity='0.01', price='50000', leverage=10 ) print(f"Position opened: {order['orderId']}")

ตรวจสอบ Position

positions = futures.get_position_info('BTCUSDT') for pos in positions: if float(pos['positionAmt']) != 0: print(f"Position: {pos['positionAmt']}, Entry: {pos['entryPrice']}")

ข้อผิดพลาดที่พบบ่อยและวิธีแก้ไข

กรณีที่ 1: Error 403 Forbidden หรือ API Key ไม่มีสิทธิ์

อาการ: ได้รับข้อผิดพลาด {"code":-2015,"msg":"Invalid API-key, IP, or permissions for action"}

สาเหตุ: API Key ที่สร้างมาไม่ได้ Enable สิทธิ์ที่จำเป็นสำหรับ Futures หรือ IP ที่เรียกใช้ไม่ได้อยู่ใน whitelist

วิธีแก้ไข:

# แก้ไขโดยสร้าง API Key ใหม่ที่ Enable สิทธิ์ครบถ้วน

ไปที่ Binance > API Management > Create New Key

ตรวจสอบสิทธิ์ของ API Key ที่ใช้

import requests def check_api_permissions(api_key, api_secret): """ตรวจสอบสิทธิ์ของ API Key""" timestamp = int(time.time() * 1000) params = { 'timestamp': timestamp, 'recvWindow': 5000 } # สำหรับ Spot spot_base = "https://api.binance.com" # สำหรับ Futures futures_base = "https://fapi.binance.com" # ตรวจสอบ Spot Account try: spot_response = requests.get( f"{spot_base}/api/v3/account", headers={'X-MBX-APIKEY': api_key}, params=params ) print(f"Spot Status: {spot_response.status_code}") except Exception as e: print(f"Spot Error: {e}") # ตรวจสอบ Futures Account try: futures_response = requests.get( f"{futures_base}/fapi/v2/account", headers={'X-MBX-APIKEY': api_key}, params=params ) print(f"Futures Status: {futures_response.status_code}") except Exception as e: print(f"Futures Error: {e}")

หรือใช้วิธี Enable IP Whitelist ใน Binance Dashboard

ไปที่ API Management > Edit Restrictions

เลือก "Disable IP Restriction" ชั่วคราวเพื่อทดสอบ

หรือเพิ่ม IP ของ Server ที่รันโค้ดเข้าไปใน whitelist

สำหรับ Testnet ให้ใช้ API Key ที่สร้างจาก Testnet

TESTNET_API_KEY = 'YOUR_TESTNET_KEY' TESTNET_API_SECRET = 'YOUR_TESTNET_SECRET' TESTNET_BASE = "https://testnet.binancefuture.com"

กรณีที่ 2: ออเดอร์ถูก Reject ด้วย Error -5022 Insufficient Margin

อาการ: ได้รับข้อผิดพลาด {"code":-5022,"msg":"Margin is insufficient"} ทั้งที่มีเงินในบัญชี

สาเหตุ: กระเป๋าเงิน Spot และ Futures แยกกัน คุณต้องโอนเงินจาก Spot Wallet ไปยัง USDT-M Futures Wallet ก่อน

วิธีแก้ไข:

import requests
import time
import hmac
import hashlib

def transfer_to_futures(api_key, api_secret, asset='USDT', amount):
    """โอนเงินจาก Spot Wallet ไปยัง Futures Wallet"""
    
    timestamp = int(time.time() * 1000)
    params = {
        'asset': asset,
        'amount': amount,
        'type': 'MAIN_UMFUTURE',  # Spot to USDT-M Futures
        'timestamp': timestamp,
        'recvWindow': 5000
    }
    
    query_string = '&'.join([f"{k}={v}" for k, v in params.items()])
    signature = hmac.new(
        api_secret.encode('utf-8'),
        query_string.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    params['signature'] = signature
    
    headers = {'X-MBX-APIKEY': api_key}
    
    response = requests.post(
        "https://api.binance.com/sapi/v1/asset/transfer",
        params=params,
        headers=headers
    )
    
    if response.status_code == 200:
        result = response.json()
        print(f"โอนสำเร็จ! TranId: {result['tranId']}")
        return result
    else:
        print(f"Transfer Error: {response.text}")
        return None

def get_futures_balance(api_key, api_secret):
    """ดึงยอดคงเหลือใน Futures Wallet"""
    timestamp = int(time.time() * 1000)
    params = {
        'timestamp': timestamp,
        'recvWindow': 5000
    }
    
    query_string = '&'.join([f"{k}={v}" for k, v in params.items()])
    signature = hmac.new(
        api_secret.encode('utf-8'),
        query_string.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    params['signature'] = signature
    
    headers = {'X-MBX-APIKEY': api_key}
    
    response = requests.get(
        "https://fapi.binance.com/fapi/v2/balance",
        params=params,
        headers=headers
    )
    
    if response.status_code == 200:
        balances = response.json()
        for b in balances:
            if float(b['availableBalance']) > 0:
                print(f"{b['asset']}: Available = {b['availableBalance']}")
        return balances
    else:
        print(f"Balance Error: {response.text}")
        return None

วิธีใช้งาน

api_key = 'YOUR_API_KEY' api_secret = 'YOUR_API_SECRET'

1. โอนเงิน 100 USDT ไป Futures Wallet

transfer_result = transfer_to_futures(api_key, api_secret, 'USDT', '100')

2. ตรวจสอบยอดใน Futures

futures_balances = get_futures_balance(api_key, api_secret)

กรณีที่ 3: Liquidation โดนโดยไม่ได้ตั้ง Stop Loss

อาการ: Position ถูก Liquidate โดยไม่ทันตั้งตัว สูญเสียเงินทั้งหมดที่วางเป็น Margin

สาเหตุ: ไม่ได้ตั้ง Stop Loss หรือใช้ Leverage สูงเกินไป ไม่เข้าใจเรื่อง Liquidation Price

วิธีแก้ไข:

def calculate_liquidation_price(entry_price, leverage, position_side='LONG'):
    """คำนวณราคา Liquidation"""
    if position_side == 'LONG':
        # สำหรับ Long Position
        liq_price = entry_price * (1 - 1 / leverage)
    else:
        # สำหรับ Short Position
        liq_price = entry_price * (1 + 1 / leverage)
    
    return liq_price

def place_stop_loss_order(api_key, api_secret, symbol, position_side, 
                          quantity, stop_price, take_profit_price=None):
    """ตั้ง Stop Loss และ Take Profit พร้อมกัน"""
    
    timestamp = int(time.time() * 1000)
    
    # Stop Loss Order (Stop Market)
    sl_params = {
        'symbol': symbol,
        'side': 'SELL' if position_side == 'LONG' else 'BUY',
        'type': 'STOP_MARKET',
        'stopPrice': stop_price,
        'quantity': quantity,
        'reduceOnly': True,
        'timestamp': timestamp,
        'recvWindow': 5000
    }
    
    query_string = '&'.join([f"{k}={v}" for k, v in sl_params.items()])
    signature = hmac.new(
        api_secret.encode('utf-8'),
        query_string.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    sl_params['signature'] = signature
    
    headers = {'X-MBX-APIKEY': api_key}
    
    sl_response = requests.post(
        "https://fapi.binance.com/fapi/v1/order",
        params=sl_params,
        headers=headers
    )
    
    print(f"Stop Loss ตั้งสำเร็จ: {sl_response.json()}")
    
    # Take Profit Order (Take Profit Market)
    if take_profit_price:
        tp_params = {
            'symbol': symbol,
            'side': 'SELL' if position_side == 'LONG' else 'BUY',
            'type': 'TAKE_PROFIT_MARKET',
            'stopPrice': take_profit_price,
            'quantity': quantity,
            'reduceOnly': True,
            'timestamp': timestamp,
            'recvWindow': 5000
        }
        
        tp_query = '&'.join([f"{k}={v}" for k, v in tp_params.items()])
        tp_signature = hmac.new(
            api_secret.encode('utf-8'),
            tp_query.encode('utf-8'),
            hashlib.sha256
        ).hexdigest()
        tp_params['signature'] = tp_signature
        
        tp_response = requests.post(
            "https://fapi.binance.com/fapi/v1/order",
            params=tp_params,
            headers=headers
        )
        print(f"Take Profit ตั้งสำเร็จ: {tp_response.json()}")

ตัวอย่างการใช้งาน

entry_price = 50000 leverage = 10 position_size = '0.01' # 0.01 BTC position_side = 'LONG'

คำนวณ Liquidation Price

liq_price = calculate_liquidation_price(entry_price, leverage, position_side) print(f"ราคาเปิด: {entry_price}") print(f"Liquidation Price: {liq_price:.2f} (ต่ำกว่า {entry_price - liq_price:.2f} USDT)")

ตั้ง Stop Loss ที่ -2% จากราคาเปิด

stop_loss_price = entry_price * 0.98

ตั้ง Take Profit ที่ +5% จากราคาเปิด

take_profit_price = entry_price * 1.05 place_stop_loss_order( api_key='YOUR_KEY', api_secret='YOUR_SECRET', symbol='BTCUSDT', position_side=position_side, quantity=position_size, stop_price=stop_loss_price, take_profit_price=take_profit_price )

เหมาะกับใคร / ไม่เหมาะกับใคร

เหมาะกับการใช้ Spot API