บทนำ

การซื้อขายสัญญาซื้อขายล่วงหน้า (Futures) และออปชัน (Options) บน OKX ต้องการความเข้าใจเรื่องมาร์จิ้นอย่างลึกซึ้ง โดยเฉพาะเมื่อต้องการใช้โมเดล Portfolio Margin ที่ช่วยเพิ่มประสิทธิภาพการใช้เงินทุน บทความนี้จะพาคุณเจาะลึกการคำนวณมาร์จิ้นแบบทฤษฎีและปฏิบัติ พร้อมโค้ด Python ที่พร้อมใช้งานจริงในระดับ Production ในโลกการเงินเชิงปริมาณ การคำนวณมาร์จิ้นที่แม่นยำหมายถึงความสามารถในการเทรดที่มีประสิทธิภาพสูงสุด ผมเคยทำงานกับทีม Quant ที่ต้องประมวลผลพอร์ตหลายร้อยสัญญาในเวลาไม่กี่มิลลิวินาที ซึ่งต้องอาศัยทั้งความรู้ทางคณิตศาสตร์และการเขียนโค้ดที่ optimize อย่างดี

พื้นฐานการคำนวณมาร์จิ้น OKX

ประเภทมาร์จิ้นบน OKX

OKX รองรับโมเดลมาร์จิ้นสองแบบหลัก:

องค์ประกอบสำคัญของมาร์จิ้น


"""
OKX Margin Calculation Module
Author: HolySheep AI Quantitative Team
Version: 2.1.0
"""

from dataclasses import dataclass
from enum import Enum
from typing import Dict, List, Optional
import math

class PositionSide(Enum):
    LONG = "long"
    SHORT = "short"
    NET = "net"

class InstrumentType(Enum):
    FUTURES = "futures"      # สัญญาซื้อขายล่วงหน้า
    OPTIONS = "options"      # ออปชัน
    PERPETUAL = "perpetual"  # สัญญาไม่มีวันหมดอายุ

@dataclass
class ContractInfo:
    """ข้อมูลสัญญา"""
    symbol: str
    instrument_type: InstrumentType
    contract_size: float      # ขนาดสัญญา
    tick_size: float          # ขั้นตอนราคาขั้นต่ำ
    multiplier: float         # ตัวคูณ
    settlement_currency: str  # สกุลเงินชำระ
    max_leverage: int         # เลเวอเรจสูงสุด
    maintenance_margin_rate: float  # อัตรามาร์จิ้นรักษา

@dataclass  
class PositionData:
    """ข้อมูลตำแหน่ง"""
    symbol: str
    side: PositionSide
    quantity: float
    entry_price: float
    mark_price: float
    leverage: int

@dataclass
class MarginResult:
    """ผลลัพธ์การคำนวณมาร์จิ้น"""
    initial_margin: float           # มาร์จิ้นเริ่มต้น
    maintenance_margin: float       # มาร์จิ้นรักษา
    margin_ratio: float             # อัตราส่วนมาร์จิ้น
    leverage_used: float            # เลเวอเรจที่ใช้จริง
    liquidation_price: Optional[float] = None  # ราคาบังคับปิด

การคำนวณมาร์จิ้นสัญญาซื้อขายล่วงหน้า (Futures)

สำหรับสัญญาซื้อขายล่วงหน้าแบบ Linear Delivery บน OKX สูตรการคำนวณมาร์จิ้นมีดังนี้:

Initial Margin Formula


class FuturesMarginCalculator:
    """เครื่องคำนวณมาร์จิ้นสัญญาซื้อขายล่วงหน้า"""
    
    def __init__(self, contract_info: ContractInfo):
        self.contract = contract_info
    
    def calculate_initial_margin(
        self,
        position: PositionData,
        order_price: Optional[float] = None
    ) -> float:
        """
        คำนวณมาร์จิ้นเริ่มต้นสำหรับ Futures
        
        Formula: Initial Margin = Position Value × IM Rate
        โดย Position Value = Quantity × Price × Multiplier
        """
        # ใช้ mark price หรือ order price ที่เลือก
        price = order_price if order_price else position.mark_price
        
        # คำนวณมูลค่าตำแหน่ง
        position_value = (
            position.quantity * 
            price * 
            self.contract.multiplier
        )
        
        # คำนวณอัตรามาร์จิ้นเริ่มต้นจากเลเวอเรจ
        im_rate = 1.0 / position.leverage
        
        # ปรับด้วยค่า Safety Factor
        safety_factor = 1.1  # OKX ใช้ 10% safety buffer
        adjusted_im_rate = im_rate * safety_factor
        
        initial_margin = position_value * adjusted_im_rate
        
        return round(initial_margin, 8)
    
    def calculate_maintenance_margin(
        self,
        position: PositionData
    ) -> float:
        """
        คำนวณมาร์จิ้นรักษา
        
        Formula: Maintenance Margin = Position Value × MM Rate
        """
        position_value = (
            position.quantity * 
            position.mark_price * 
            self.contract.multiplier
        )
        
        # MM Rate ของ OKX อยู่ที่ประมาณ 50% ของ IM Rate
        mm_rate = self.contract.maintenance_margin_rate
        
        return round(position_value * mm_rate, 8)
    
    def calculate_liquidation_price(
        self,
        position: PositionData,
        is_long: bool = True
    ) -> float:
        """
        คำนวณราคาบังคับปิด (Liquidation Price)
        
        Formula สำหรับ Long Position:
        Liq Price = Entry Price × (1 - IM Rate + MM Rate)
        
        Formula สำหรับ Short Position:
        Liq Price = Entry Price × (1 + IM Rate - MM Rate)
        """
        im_rate = 1.0 / position.leverage
        mm_rate = self.contract.maintenance_margin_rate
        
        if is_long:
            # Long: ราคาลงมาถึงจุดนี้จะโดนบังคับปิด
            liq_price = position.entry_price * (
                1 - im_rate + mm_rate
            )
        else:
            # Short: ราคาขึ้นมาถึงจุดนี้จะโดนบังคับปิด
            liq_price = position.entry_price * (
                1 + im_rate - mm_rate
            )
        
        # ปรับให้เป็นทวีคูณของ tick_size
        liq_price = round(
            liq_price / self.contract.tick_size
        ) * self.contract.tick_size
        
        return liq_price
    
    def get_full_margin_analysis(
        self,
        position: PositionData
    ) -> MarginResult:
        """วิเคราะห์มาร์จิ้นแบบครบถ้วน"""
        
        is_long = position.side == PositionSide.LONG
        
        initial_margin = self.calculate_initial_margin(position)
        maintenance_margin = self.calculate_maintenance_margin(position)
        liq_price = self.calculate_liquidation_price(position, is_long)
        
        # คำนวณ margin ratio
        position_value = (
            position.quantity * 
            position.mark_price * 
            self.contract.multiplier
        )
        margin_ratio = (
            (initial_margin - maintenance_margin) / 
            position_value * 100
        ) if position_value > 0 else 0
        
        return MarginResult(
            initial_margin=initial_margin,
            maintenance_margin=maintenance_margin,
            margin_ratio=margin_ratio,
            leverage_used=position.leverage,
            liquidation_price=liq_price
        )

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

if __name__ == "__main__": # BTC-USDT Perpetual Contract btc_contract = ContractInfo( symbol="BTC-USDT-SWAP", instrument_type=InstrumentType.PERPETUAL, contract_size=0.0001, # BTC tick_size=0.1, # USDT multiplier=1, settlement_currency="USDT", max_leverage=125, maintenance_margin_rate=0.005 # 0.5% ) calculator = FuturesMarginCalculator(btc_contract) # ตำแหน่ง Long 1 BTC ที่ราคา 65,000 USDT btc_position = PositionData( symbol="BTC-USDT-SWAP", side=PositionSide.LONG, quantity=1.0, entry_price=65000.0, mark_price=65200.0, leverage=10 ) result = calculator.get_full_margin_analysis(btc_position) print(f"Initial Margin: {result.initial_margin:.2f} USDT") print(f"Maintenance Margin: {result.maintenance_margin:.2f} USDT") print(f"Liquidation Price: {result.liquidation_price:.1f} USDT")

การคำนวณมาร์จิ้นออปชัน

ออปชันมีความซับซ้อนมากกว่า Futures เนื่องจากมี Greek Letters และ Strike Price ที่ต้องพิจารณา

from scipy.stats import norm
from typing import Tuple

class BlackScholes:
    """Black-Scholes Model สำหรับคำนวณราคาออปชัน"""
    
    @staticmethod
    def calculate_d1_d2(
        S: float,      # Spot Price
        K: float,      # Strike Price  
        T: float,      # Time to Expiry (years)
        r: float,      # Risk-free rate
        sigma: float   # Volatility
    ) -> Tuple[float, float]:
        """คำนวณ d1 และ d2"""
        d1 = (
            math.log(S / K) + 
            (r + 0.5 * sigma ** 2) * T
        ) / (sigma * math.sqrt(T))
        
        d2 = d1 - sigma * math.sqrt(T)
        
        return d1, d2
    
    @staticmethod
    def call_price(
        S: float, K: float, T: float, r: float, sigma: float
    ) -> float:
        """คำนวณราคา Call Option"""
        if T <= 0:
            return max(S - K, 0)
            
        d1, d2 = BlackScholes.calculate_d1_d2(S, K, T, r, sigma)
        
        call = (
            S * norm.cdf(d1) - 
            K * math.exp(-r * T) * norm.cdf(d2)
        )
        
        return call
    
    @staticmethod
    def put_price(
        S: float, K: float, T: float, r: float, sigma: float
    ) -> float:
        """คำนวณราคา Put Option"""
        if T <= 0:
            return max(K - S, 0)
            
        d1, d2 = BlackScholes.calculate_d1_d2(S, K, T, r, sigma)
        
        put = (
            K * math.exp(-r * T) * norm.cdf(-d2) - 
            S * norm.cdf(-d1)
        )
        
        return put


class OptionsMarginCalculator:
    """เครื่องคำนวณมาร์จิ้นออปชันบน OKX"""
    
    def __init__(self, risk_free_rate: float = 0.05):
        self.r = risk_free_rate
        self.bs_model = BlackScholes()
    
    def calculate_option_premium(
        self,
        option_type: str,  # "call" หรือ "put"
        S: float,          # Spot Price
        K: float,          # Strike Price
        T: float,          # Time to Expiry (days)
        sigma: float        # Implied Volatility
    ) -> float:
        """คำนวณเบี้ยประกันออปชัน"""
        T_years = T / 365.0
        
        if option_type.lower() == "call":
            return self.bs_model.call_price(S, K, T_years, self.r, sigma)
        else:
            return self.bs_model.put_price(S, K, T_years, self.r, sigma)
    
    def calculate_options_initial_margin(
        self,
        position: PositionData,
        spot_price: float,
        iv: float,          # Implied Volatility
        days_to_expiry: int
    ) -> float:
        """
        คำนวณมาร์จิ้นเริ่มต้นสำหรับออปชัน
        
        OKX ใช้ Risk-Based Margin สำหรับออปชัน:
        1. Premium Margin = มูลค่าเบี้ยประกัน
        2. Margin สำหรับ Naked Position
        """
        # สกุลเงินที่ใช้ในโค้ดนี้คือ USDT ดังนั้นต้องใช้ USDT เป็นหลัก
        # ตรวจสอบว่าเป็น Long หรือ Short
        
        option_value = abs(position.quantity) * spot_price
        
        if position.side == PositionSide.LONG:
            # Long: จ่ายเฉพาะ Premium
            premium = self.calculate_option_premium(
                "call" if "CALL" in position.symbol else "put",
                spot_price,
                position.entry_price,  # ใช้เป็น Strike
                days_to_expiry,
                iv
            )
            return abs(position.quantity) * premium
        else:
            # Short: ต้องวางมาร์จิ้นเต็มจำนวน
            # คำนวณ Maximum Loss ที่อาจเกิดขึ้น
            
            # SPAN Margin (Standard Portfolio Analysis of Risk)
            # วิธีที่ OKX ใช้
            underlying_value = (
                abs(position.quantity) * 
                spot_price * 
                self.contract_multiplier
            )
            
            # คำนวณจาก delta และ scenario-based
            delta = self._calculate_delta(
                position, spot_price, iv, days_to_expiry
            )
            
            # Margin = Option Value + Potential Future Exposure
            margin = (
                underlying_value * abs(delta) * 0.15 +  # Delta margin
                underlying_value * 0.05                   # Safety buffer
            )
            
            return margin
    
    def _calculate_delta(
        self,
        position: PositionData,
        S: float,
        sigma: float,
        T: int
    ) -> float:
        """คำนวณ Delta ของออปชัน"""
        K = position.entry_price  # Strike Price
        T_years = T / 365.0
        
        d1, _ = BlackScholes.calculate_d1_d2(S, K, T_years, self.r, sigma)
        
        if "CALL" in position.symbol.upper():
            return norm.cdf(d1)
        else:
            return norm.cdf(d1) - 1
    
    def calculate_greeks(
        self,
        option_type: str,
        S: float,
        K: float,
        T: int,
        sigma: float
    ) -> Dict[str, float]:
        """คำนวณ Greek Letters ทั้งหมด"""
        T_years = T / 365.0
        d1, d2 = BlackScholes.calculate_d1_d2(S, K, T_years, self.r, sigma)
        
        if option_type.lower() == "call":
            delta = norm.cdf(d1)
            theta = self._calculate_theta_call(S, K, T_years, sigma)
        else:
            delta = norm.cdf(d1) - 1
            theta = self._calculate_theta_put(S, K, T_years, sigma)
        
        gamma = norm.pdf(d1) / (S * sigma * math.sqrt(T_years))
        vega = S * norm.pdf(d1) * math.sqrt(T_years) / 100  # Per 1% IV change
        
        return {
            "delta": delta,
            "gamma": gamma,
            "theta": theta,
            "vega": vega
        }
    
    def _calculate_theta_call(self, S, K, T, sigma) -> float:
        """คำนวณ Theta ของ Call"""
        d1, d2 = BlackScholes.calculate_d1_d2(S, K, T, self.r, sigma)
        term1 = -S * norm.pdf(d1) * sigma / (2 * math.sqrt(T))
        term2 = self.r * K * math.exp(-self.r * T) * norm.cdf(d2)
        return (term1 - term2) / 365
    
    def _calculate_theta_put(self, S, K, T, sigma) -> float:
        """คำนวณ Theta ของ Put"""
        d1, d2 = BlackScholes.calculate_d1_d2(S, K, T, self.r, sigma)
        term1 = -S * norm.pdf(d1) * sigma / (2 * math.sqrt(T))
        term2 = self.r * K * math.exp(-self.r * T) * norm.cdf(-d2)
        return (term1 + term2) / 365


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

if __name__ == "__main__": calc = OptionsMarginCalculator(risk_free_rate=0.05) # BTC Call Option Strike 70,000 greeks = calc.calculate_greeks( option_type="call", S=65000, # Spot Price K=70000, # Strike T=30, # 30 วัน sigma=0.80 # 80% IV ) print("Greek Letters:") for name, value in greeks.items(): print(f" {name.upper()}: {value:.6f}") # คำนวณเบี้ยประกัน premium = calc.calculate_option_premium( "call", 65000, 70000, 30, 0.80 ) print(f"\nCall Premium: {premium:.2f} USDT")

Portfolio Margin: การคำนวณมาร์จิ้นแบบรวมพอร์ต

Portfolio Margin เป็นโมเดลขั้นสูงที่คำนวณมาร์จิ้นจากความเสี่ยงรวมของพอร์ต แทนที่จะคำนวณแยกทีละสัญญา

import numpy as np
from typing import List
import requests
import json

class PortfolioMarginCalculator:
    """
    Portfolio Margin Calculator สำหรับ OKX
    รวม Futures และ Options เข้าด้วยกัน
    
    ใช้ HolySheep AI สำหรับการวิเคราะห์ความเสี่ยงขั้นสูง
    """
    
    def __init__(
        self,
        holysheep_api_key: str,
        correlation_matrix: Optional[np.ndarray] = None
    ):
        self.api_key = holysheep_api_key
        self.base_url = "https://api.holysheep.ai/v1"
        self.correlation_matrix = correlation_matrix
    
    def analyze_portfolio_risk_with_ai(
        self,
        positions: List[PositionData],
        market_data: Dict
    ) -> Dict:
        """
        ใช้ AI วิเคราะห์ความเสี่ยงพอร์ตแบบละเอียด
        
        ผ่าน HolySheep API ที่รองรับ:
        - ความหน่วงต่ำ (<50ms)
        - ราคาถูกกว่า OpenAI 85%+ (อัตรา ¥1=$1)
        """
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        # สร้าง prompt สำหรับวิเคราะห์ความเสี่ยง
        prompt = f"""
        วิเคราะห์ความเสี่ยงของ Portfolio ที่ประกอบด้วย:
        
        Positions:
        {json.dumps([{
            'symbol': p.symbol,
            'side': p.side.value,
            'quantity': p.quantity,
            'mark_price': p.mark_price,
            'leverage': p.leverage
        } for p in positions], indent=2)}
        
        Market Data:
        {json.dumps(market_data, indent=2)}
        
        กรุณาวิเคราะห์:
        1. Value at Risk (VaR) ที่ระดับ 95% และ 99%
        2. Maximum Drawdown ที่อาจเกิดขึ้น
        3. คำแนะนำการปรับสมดุลพอร์ต
        4. ระดับความเสี่ยงโดยรวม (Low/Medium/High/Critical)
        """
        
        payload = {
            "model": "gpt-4.1",  # เหมาะสำหรับงานวิเคราะห์เชิงปริมาณ
            "messages": [
                {
                    "role": "system",
                    "content": "คุณเป็นนักวิเคราะห์ความเสี่ยงทางการเงินผู้เชี่ยวชาญ"
                },
                {
                    "role": "user", 
                    "content": prompt
                }
            ],
            "temperature": 0.3,  # ความแม่นยำสูง
            "max_tokens": 2000
        }
        
        try:
            response = requests.post(
                f"{self.base_url}/chat/completions",
                headers=headers,
                json=payload,
                timeout=5  # HolySheep ตอบสนอง <50ms
            )
            response.raise_for_status()
            result = response.json()
            
            return {
                "status": "success",
                "analysis": result['choices'][0]['message']['content'],
                "usage": result.get('usage', {})
            }
        except requests.exceptions.RequestException as e:
            return {
                "status": "error",
                "message": str(e)
            }
    
    def calculate_portfolio_margin(
        self,
        futures_positions: List[PositionData],
        options_positions: List[PositionData],
        futures_calculator: FuturesMarginCalculator,
        options_calculator: OptionsMarginCalculator,
        confidence_level: float = 0.99
    ) -> Dict:
        """
        คำนวณมาร์จิ้นพอร์ตแบบครบวงจร
        
        ใช้ Method:
        1. Position-Level Margin
        2. Offsetting Margin Credit (สำหรับ Hedge)
        3. VaR-based Margin
        """
        
        # Step 1: คำนวณมาร์จิ้นระดับตำแหน่ง
        futures_margin = sum(
            futures_calculator.calculate_initial_margin(p)
            for p in futures_positions
        )
        
        options_margin = sum(
            options_calculator.calculate_initial_margin(p)
            for p in options_positions
        )
        
        # Step 2: คำนวณ Margin Offset (Hedge Benefit)
        offset_credit = self._calculate_hedge_credit(
            futures_positions,
            options_positions
        )
        
        # Step 3: VaR-based Final Margin
        var_margin = self._calculate_var_margin(
            futures_positions,
            options_positions,
            confidence_level
        )
        
        # Final: ใช้ค่าสูงสุดระหว่าง VaR และ Position-based
        final_margin = max(var_margin, futures_margin + options_margin)
        
        # หัก Margin Offset
        final_margin = max(0, final_margin - offset_credit)
        
        return {
            "futures_margin": futures_margin,
            "options_margin": options_margin,
            "offset_credit": offset_credit,
            "var_margin": var_margin,
            "final_portfolio_margin": final_margin,
            "margin_efficiency": (
                (futures_margin + options_margin - final_margin) / 
                (futures_margin + options_margin) * 100
            ) if (futures_margin + options_margin) > 0 else 0
        }
    
    def _calculate_hedge_credit(
        self,
        futures: List[PositionData],
        options: List[PositionData]
    ) -> float:
        """
        คำนวณ Margin Offset จากการ Hedge
        
        Futures Long + Put Option = Protective Put
        Futures Short + Call Option = Covered Call
        ลด Margin ลงได้ 30-50%
        """
        credit = 0.0
        
        # ตรวจสอบ Delta Neutral
        total_delta = 0.0
        for pos in futures:
            # Futures delta = position size * multiplier
            delta = pos.quantity if pos.side == PositionSide.LONG else -pos.quantity
            total_delta += delta
        
        for pos in options:
            # Options delta ต้องคำนวณจาก Greeks
            # สมมติ delta = 0.5 สำหรับ ATM
            opt_delta = 0.5 * pos.quantity
            total_delta += opt_delta
        
        # ถ้าใกล้เคียง Delta Neutral = Hedge ดี
        if abs(total_delta) < 0.1:  # Threshold 10%
            # Offset credit 40%
            credit = (
                abs(sum(
                    p.quantity * p.mark_price 
                    for p in futures
                )) * 0.4
            )
        
        return credit
    
    def _calculate_var_margin(
        self,
        futures: List[PositionData],
        options: List[PositionData],
        confidence: float
    ) -> float:
        """
        คำนวณ Value at Risk-based Margin
        
        VaR = Position × σ × Z-score
        """
        z_scores = {0.95: 1.645, 0.99: 2.326, 0.999: 3.090}
        z = z_scores.get(confidence, 2.326)
        
        # ความผันผวนประจำวัน (สมมติ 2% สำหรับ BTC)
        daily_vol = 0.02
        
        # คำนวณ VaR จากมูลค่าพอร์ตรวม
        total_value = 0.0
        
        for pos in futures:
            value = pos.quantity * pos.mark_price
            total_value += value
        
        for pos in options:
            # Options