ผมเคยเจอสถานการณ์ที่ทำให้หัวใจหยุดเต้นชั่วขณะ — กำลังนั่งทำงานอยู่ดีๆ สัญญาณ Bitcoin ที่ถือครองพลิกกลับทันที แต่กลับไม่ได้รับการแจ้งเตือนจากระบบ สุดท้ายขาดทุนไปเกือบ 15% ภายในเวลาไม่ถึงชั่วโมง นี่คือจุดเริ่มต้นที่ทำให้ผมพัฒนาระบบ OKX Perpetual API Auto-Monitor ขึ้นมา และบทความนี้จะเป็นคู่มือฉบับสมบูรณ์ให้คุณสร้างระบบเตือนภัยที่คุ้มค่าที่สุดในปี 2026
ทำไมต้องมีระบบตรวจสอบอัตโนมัติ
การเทรดสัญญาไม่มีวันหมดอายุ (Perpetual Futures) มีความเสี่ยงสูงกว่าการเทรด Spot หลายเท่า เนื่องจากมี leverage และ liquidation ที่อาจเกิดขึ้นได้ทันที หากคุณถือสถานะข้ามคืนโดยไม่มีระบบเตือน คุณอาจตื่นมาเจอว่าเหรียญที่ถือถูก liquidate ไปแล้วโดยสมบูรณ์
ระบบตรวจสอบอัตโนมัติช่วยให้คุณ:
- ติดตามสถานะทุกวินาทีโดยไม่ต้องนั่งเฝ้าหน้าจอ
- รับการแจ้งเตือนทันทีเมื่อราคาเข้าใกล้ระดับ liquidation
- วิเคราะห์ความเสี่ยงของทั้งพอร์ตแบบครอบคลุม
- ตั้งค่า stop-loss และ take-profit อัตโนมัติ
พื้นฐาน OKX Perpetual API
ก่อนจะเริ่มเขียนโค้ด คุณต้องเตรียมข้อมูลดังนี้:
- API Key จาก OKX (ต้องมีสิทธิ์ Trade และ Read)
- Passphrase ที่ตั้งไว้ตอนสร้าง API
- Secret Key สำหรับ signing request
- InstType สำหรับสัญญาไม่มีวันหมดอายุคือ
SWAP
โครงสร้างโค้ด Python สำหรับตรวจสอบสถานะ
นี่คือโค้ดหลักสำหรับดึงข้อมูลตำแหน่งและคำนวณความเสี่ยง ผมใช้ HolySheep AI สำหรับวิเคราะห์ข้อมูลเพิ่มเติมด้วย AI
import requests
import time
import hmac
import hashlib
from datetime import datetime
from typing import List, Dict
class OKXPositionMonitor:
def __init__(self, api_key: str, secret_key: str, passphrase: str, passphrase_enc: bool = True):
self.api_key = api_key
self.secret_key = secret_key
self.passphrase = passphrase
self.passphrase_enc = passphrase_enc
self.base_url = "https://www.okx.com"
def _sign(self, timestamp: str, method: str, path: str, body: str = "") -> str:
"""สร้าง HMAC signature สำหรับ OKX API"""
message = timestamp + method + path + body
mac = hmac.new(
self.secret_key.encode('utf-8'),
message.encode('utf-8'),
hashlib.sha256
)
return mac.hexdigest()
def _get_headers(self, method: str, path: str, body: str = "") -> Dict[str, str]:
"""สร้าง headers พร้อม signature"""
timestamp = datetime.utcnow().isoformat() + 'Z'
sign = self._sign(timestamp, method, path, body)
headers = {
'OK-ACCESS-KEY': self.api_key,
'OK-ACCESS-SIGN': sign,
'OK-ACCESS-TIMESTAMP': timestamp,
'OK-ACCESS-PASSPHRASE': self.passphrase,
'Content-Type': 'application/json'
}
return headers
def get_positions(self, inst_id: str = None) -> List[Dict]:
"""ดึงข้อมูลตำแหน่งที่เปิดอยู่ทั้งหมด"""
path = "/api/v5/account/positions"
params = {}
if inst_id:
params['instId'] = inst_id
headers = self._get_headers("GET", path)
response = requests.get(
f"{self.base_url}{path}",
headers=headers,
params=params
)
if response.status_code == 200:
data = response.json()
if data.get('code') == '0':
return data.get('data', [])
else:
raise Exception(f"API Error: {data.get('msg')}")
else:
raise Exception(f"HTTP Error: {response.status_code}")
def get_position_risk(self, position: Dict) -> Dict:
"""คำนวณความเสี่ยงของแต่ละตำแหน่ง"""
notional_value = float(position.get('notionalUsd', 0))
margin = float(position.get('margin', 0))
liquidation_price = float(position.get('liqPx', 0))
mark_price = float(position.get('last', 0))
leverage = float(position.get('lever', 1))
# คำนวณระยะห่างจากราคา liquidation
if liquidation_price > 0 and mark_price > 0:
if 'long' in position.get('posSide', '').lower():
distance_pct = ((mark_price - liquidation_price) / mark_price) * 100
else:
distance_pct = ((liquidation_price - mark_price) / mark_price) * 100
else:
distance_pct = 999
# คำนวณ unrealized PnL
upl = float(position.get('upl', 0))
upl_ratio = (upl / margin * 100) if margin > 0 else 0
return {
'instId': position.get('instId'),
'posSide': position.get('posSide'),
'notionalValue': notional_value,
'margin': margin,
'leverage': leverage,
'liquidationPrice': liquidation_price,
'markPrice': mark_price,
'liquidationDistancePct': distance_pct,
'unrealizedPnL': upl,
'unrealizedPnLRatio': upl_ratio,
'riskLevel': 'HIGH' if distance_pct < 5 else ('MEDIUM' if distance_pct < 15 else 'LOW')
}
ตัวอย่างการใช้งาน
monitor = OKXPositionMonitor(
api_key="YOUR_OKX_API_KEY",
secret_key="YOUR_OKX_SECRET_KEY",
passphrase="YOUR_API_PASSPHRASE"
)
try:
positions = monitor.get_positions()
for pos in positions:
risk = monitor.get_position_risk(pos)
print(f"{risk['instId']} | Risk: {risk['riskLevel']} | Distance: {risk['liquidationDistancePct']:.2f}%")
except Exception as e:
print(f"Error: {e}")
ระบบแจ้งเตือนอัตโนมัติด้วย AI
เมื่อได้ข้อมูลความเสี่ยงแล้ว ขั้นตอนต่อไปคือการส่งการแจ้งเตือน ผมแนะนำให้ใช้ HolySheep AI เพื่อวิเคราะห์และสร้างข้อความแจ้งเตือนที่ฉลาดกว่าแค่ข้อความธรรมดา ด้วยความเร็วตอบสนองน้อยกว่า 50ms และราคาที่ประหยัดกว่า 85%
import requests
import json
class RiskAlertSystem:
def __init__(self, holysheep_api_key: str):
self.base_url = "https://api.holysheep.ai/v1"
self.api_key = holysheep_api_key
def analyze_and_alert(self, position_risks: list) -> dict:
"""วิเคราะห์ความเสี่ยงด้วย AI และสร้างข้อความแจ้งเตือน"""
# สร้าง prompt สำหรับวิเคราะห์
high_risk = [p for p in position_risks if p['riskLevel'] == 'HIGH']
medium_risk = [p for p in position_risks if p['riskLevel'] == 'MEDIUM']
prompt = f"""คุณเป็นผู้เชี่ยวชาญด้านความเสี่ยง cryptocurrency
จากข้อมูลตำแหน่งที่มีความเสี่ยงสูง:
{json.dumps(high_risk, indent=2)}
และความเสี่ยงปานกลาง:
{json.dumps(medium_risk, indent=2)}
จง:
1. วิเคราะห์สถานการณ์โดยรวมของพอร์ต
2. เสนอการดำเนินการที่ควรทำทันที
3. สร้างข้อความแจ้งเตือนฉุกเฉินหากจำเป็น
ตอบกลับเป็น JSON รูปแบบ:
{{"analysis": "...", "urgency": "HIGH|MEDIUM|LOW", "actions": ["..."], "alert_message": "..."}}"""
try:
response = requests.post(
f"{self.base_url}/chat/completions",
headers={
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
},
json={
"model": "gpt-4.1",
"messages": [{"role": "user", "content": prompt}],
"temperature": 0.3,
"max_tokens": 500
},
timeout=5
)
if response.status_code == 200:
result = response.json()
ai_response = result['choices'][0]['message']['content']
return json.loads(ai_response)
else:
return {"error": f"API Error: {response.status_code}"}
except requests.exceptions.Timeout:
return {"error": "Timeout - AI service did not respond"}
except Exception as e:
return {"error": str(e)}
def send_telegram_alert(self, message: str, bot_token: str, chat_id: str):
"""ส่งการแจ้งเตือนผ่าน Telegram"""
url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
payload = {
"chat_id": chat_id,
"text": message,
"parse_mode": "HTML"
}
response = requests.post(url, json=payload)
return response.json()
def send_email_alert(self, subject: str, body: str, smtp_config: dict):
"""ส่งการแจ้งเตือนทาง Email"""
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
msg = MIMEMultipart()
msg['From'] = smtp_config['sender']
msg['To'] = smtp_config['receiver']
msg['Subject'] = subject
msg.attach(MIMEText(body, 'html'))
with smtplib.SMTP(smtp_config['host'], smtp_config['port']) as server:
server.starttls()
server.login(smtp_config['username'], smtp_config['password'])
server.send_message(msg)
ตัวอย่างการใช้งานระบบแจ้งเตือน
alert_system = RiskAlertSystem(holysheep_api_key="YOUR_HOLYSHEEP_API_KEY")
วิเคราะห์ความเสี่ยง
risks = [monitor.get_position_risk(pos) for pos in positions]
analysis = alert_system.analyze_and_alert(risks)
if analysis.get('urgency') == 'HIGH':
# ส่งการแจ้งเตือนฉุกเฉิน
alert_system.send_telegram_alert(
message=f"🚨 CRITICAL ALERT\n\n{analysis.get('alert_message')}",
bot_token="YOUR_TELEGRAM_BOT_TOKEN",
chat_id="YOUR_CHAT_ID"
)
การตั้งค่า WebSocket สำหรับ Real-time Monitoring
การใช้ REST API อย่างเดียวอาจมีความล่าช้า ผมแนะนำให้ใช้ WebSocket สำหรับการติดตามแบบ real-time
import websocket
import json
import threading
import time
class OKXWebSocketMonitor:
def __init__(self, api_key: str, secret_key: str, passphrase: str):
self.api_key = api_key
self.secret_key = secret_key
self.passphrase = passphrase
self.ws = None
self.running = False
self.callbacks = []
def _generate_signature(self, channel: str, timestamp: str) -> str:
"""สร้าง signature สำหรับ WebSocket auth"""
message = timestamp + "GET" + f"/ws/{channel}"
mac = hmac.new(
self.secret_key.encode('utf-8'),
message.encode('utf-8'),
hashlib.sha256
)
return mac.hexdigest()
def on_message(self, ws, message):
"""จัดการเมื่อได้รับข้อความใหม่"""
data = json.loads(message)
if data.get('event') == 'error':
print(f"WebSocket Error: {data.get('msg')}")
return
# ประมวลผลข้อมูลตำแหน่ง
if 'data' in data and data.get('arg', {}).get('channel') == 'positions':
for position in data['data']:
for callback in self.callbacks:
callback(position)
def on_error(self, ws, error):
"""จัดการข้อผิดพลาด WebSocket"""
print(f"WebSocket Error: {error}")
def on_close(self, ws, close_status_code, close_msg):
"""จัดการเมื่อ WebSocket ปิด"""
print(f"WebSocket closed: {close_status_code} - {close_msg}")
if self.running:
# พยายามเชื่อมต่อใหม่
time.sleep(5)
self.connect()
def on_open(self, ws):
"""จัดการเมื่อ WebSocket เปิด"""
# ส่งคำสั่ง subscribe
subscribe_msg = {
"op": "subscribe",
"args": [{
"channel": "positions",
"instType": "SWAP",
"uly": "BTC-USDT"
}]
}
ws.send(json.dumps(subscribe_msg))
def add_callback(self, callback):
"""เพิ่มฟังก์ชัน callback สำหรับประมวลผลข้อมูล"""
self.callbacks.append(callback)
def connect(self):
"""เชื่อมต่อ WebSocket"""
self.running = True
ws_url = "wss://ws.okx.com:8443/ws/v5/private"
self.ws = websocket.WebSocketApp(
ws_url,
on_message=self.on_message,
on_error=self.on_error,
on_close=self.on_close,
on_open=self.on_open
)
thread = threading.Thread(target=self.ws.run_forever)
thread.daemon = True
thread.start()
def disconnect(self):
"""ยกเลิกการเชื่อมต่อ"""
self.running = False
if self.ws:
self.ws.close()
ตัวอย่างการใช้งาน
def position_alert(position):
"""ฟังก์ชันแจ้งเตือนเมื่อมีการเปลี่ยนแปลง"""
notional = float(position.get('notionalUsd', 0))
if notional > 10000: # ถ้ามูลค่าเกิน $10,000
print(f"⚠️ Large Position: {position.get('instId')} = ${notional:.2f}")
monitor_ws = OKXWebSocketMonitor(
api_key="YOUR_OKX_API_KEY",
secret_key="YOUR_OKX_SECRET_KEY",
passphrase="YOUR_API_PASSPHRASE"
)
monitor_ws.add_callback(position_alert)
monitor_ws.connect()
ข้อผิดพลาดที่พบบ่อยและวิธีแก้ไข
1. Error 401 Unauthorized - Signature ไม่ถูกต้อง
สาเหตุ: ปัญหานี้เกิดจากการ sign ข้อมูลผิดวิธี ซึ่งผมเจอบ่อยมากตอนเริ่มพัฒนา
# ❌ วิธีที่ผิด - timestamp format ไม่ถูกต้อง
def _sign_wrong(self, timestamp, method, path, body):
message = timestamp + method + path + body
# ...
✅ วิธีที่ถูกต้อง
def _sign_correct(self, timestamp, method, path, body=""):
"""
OKX ต้องการ format: timestamp + method + path + body
โดย timestamp ต้องเป็น ISO 8601 format พร้อม 'Z'
"""
message = f"{timestamp}{method}{path}{body}"
mac = hmac.new(
self.secret_key.encode('utf-8'),
message.encode('utf-8'),
hashlib.sha256
)
return mac.hexdigest()
ตรวจสอบ timestamp format
import datetime
correct_timestamp = datetime.datetime.utcnow().isoformat() + 'Z'
print(f"Correct format: {correct_timestamp}")
2. WebSocket Connection Timeout - pong not received
สาเหตุ: การเชื่อมต่อ WebSocket หมดเวลาหรือถูกตัดการเชื่อมต่อ
# ❌ ไม่มีการจัดการ reconnect
def connect_once(self):
self.ws = websocket.WebSocketApp(url)
self.ws.run_forever() # ถ้าหลุดจะไม่เชื่อมต่อใหม่
✅ วิธีที่ถูกต้อง - พร้อม auto-reconnect
class WebSocketWithReconnect:
def __init__(self, url, max_retries=5, retry_delay=5):
self.url = url
self.max_retries = max_retries
self.retry_delay = retry_delay
self.ws = None
def connect(self):
retry_count = 0
while retry_count < self.max_retries:
try:
self.ws = websocket.WebSocketApp(
self.url,
on_ping=self.on_ping,
on_pong=self.on_pong
)
self.ws.run_forever(ping_interval=20) # ping ทุก 20 วินาที
except Exception as e:
retry_count += 1
print(f"Connection failed: {e}. Retry {retry_count}/{self.max_retries}")
time.sleep(self.retry_delay * retry_count) # exponential backoff
def on_ping(self, ws, data):
ws.send(data, opcode=websocket.Opcode.PONG)
def on_pong(self, ws, data):
print("Pong received - connection alive")
3. Position Data Not Found - ดึงข้อมูลไม่ได้
สาเหตุ: API parameter ไม่ถูกต้องหรือไม่มี instId
# ❌ วิธีที่ผิด - instId ไม่ตรง format
positions = monitor.get_positions(inst_id="BTC-USDT") # ผิด format
✅ วิธีที่ถูกต้อง - ตรวจสอบ format
def get_positions_fixed(self, inst_id: str = None) -> List[Dict]:
"""
OKX Perpetual format: BTC-USDT-SWAP (ไม่ใช่ BTC-USDT)
"""
path = "/api/v5/account/positions"
params = {}
if inst_id:
# แปลง format อัตโนมัติถ้าจำเป็น
if "-SWAP" not in inst_id and "USDT" in inst_id:
inst_id = f"{inst_id}-SWAP"
params['instId'] = inst_id
# หรือใช้ instType เพื่อดึงทั้งหมด
# params['instType'] = 'SWAP'
headers = self._get_headers("GET", path)
response = requests.get(f"{self.base_url}{path}", headers=headers, params=params)
return response.json().get('data', [])
4. Liquidation Price Returns 0 - ราคา liquidation ไม่ถูกต้อง
สาเหตุ: margin mode หรือ position mode ไม่ตรงกับที่คาดหวัง
# ✅ วิธีที่ถูกต้อง - ดึงข้อมูลราคาจากหลาย endpoint
def get_liquidation_price(self, inst_id: str, pos_side: str) -> float:
"""
ลองหาข้อมูลจากหลาย endpoint
"""
# วิธีที่ 1: จาก positions endpoint
positions = self.get_positions(inst_id=inst_id)
for pos in positions:
if pos.get('posSide') == pos_side:
liq_px = float(pos.get('liqPx', 0))
if liq_px > 0:
return liq_px
# วิธีที่ 2: จาก position tier (สำหรับ isolated margin)
path = f"/api/v5/account/position-tiers"
params = {
'instId': inst_id,
'tier': '1',
'instType': 'SWAP'
}
response = requests.get(f"{self.base_url}{path}", params=params)
data = response.json()
if data.get('code') == '0' and data.get('data'):
tier_data = data['data'][0]
if pos_side.upper() == 'LONG':
return float(tier_data.get('liqPx', 0))
else:
return float(tier_data.get('liqPx', 0))
return 0.0
การตั้งค่า TradingView Webhook สำหรับ Auto-Close
หากต้องการปิดสถานะอัตโนมัติเมื่อถึงเงื่อนไข สามารถใช้ร่วมกับ TradingView Alert ได้
from flask import Flask, request
import threading
app = Flask(__name__)
position_monitor = OKXPositionMonitor(API_KEY, SECRET_KEY, PASSPHRASE)
@app.route('/webhook', methods=['POST'])
def webhook():
"""รับ webhook จาก TradingView"""
data = request.json
if data.get('action') == 'close_all':
# ปิดสถานะทั้งหมด
close_all_positions()
elif data.get('action') == 'close_position':
inst_id = data.get('inst_id')
close_position(inst_id)
return {"status": "success"}
def close_position(inst_id: str):
"""ปิดสถานะเฉพาะเหรียญ"""
path = "/api/v5/trade/order"
body = {
"instId": inst_id,
"tdMode": "cross",
"side": "sell", # หรือ buy ขึ้นอยู่กับ position side
"ordType": "market",
"sz": "0" # sz=0 หมายถึงปิดสถานะทั้งหมด
}
# ส่งคำสั่ง close
def close_all_positions():
"""ปิดสถานะทั้งหมด"""
positions = position_monitor.get_positions()
for pos in positions:
close_position(pos.get('instId'))
if __name__ == '__main__':
# รัน Flask server
app.run(host='0.0.0.0', port=5000)
เหมาะกับใคร / ไม่เหมาะกับใคร
| เหมาะกับ | ไม่เหมาะกับ |
|---|---|
| นักเทรดที่ถือสถานะข้ามคืน (Swing Trader) | ผู้ที่ไม่มีประสบการณ์ API มาก่อนเลย |
| นักเทรดที่ใช้ Bot หรือ EA แบบอัตโนมัติ | ผู้ที่ถือสถานะเพียงไม่กี่นาที (Scalper) |
| Portfolio Manager ที่ดูแลหลายพอร์ต | ผู้ที่มีงบประมาณจำกัดมาก (ควรเริ่มจาก Manual) |
| นักเทรดที่ต้องการความปลอดภัยสูงสุด | ผู้ที่ไม่มีความเข้าใจเ
แหล่งข้อมูลที่เกี่ยวข้องบทความที่เกี่ยวข้อง🔥 ลอง HolySheep AIเกตเวย์ AI API โดยตรง รองรับ Claude, GPT-5, Gemini, DeepSeek — หนึ่งคีย์ ไม่ต้อง VPN |