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