ทำไมต้องเก็บข้อมูล Hyperliquid History?

ถ้าคุณเทรดบน Hyperliquid หรือกำลังสร้างบอทเทรดอัตโนมัติ สิ่งสำคัญที่สุดคือต้องมี ข้อมูลประวัติราคา (Historical OHLCV) เพื่อทดสอบกลยุทธ์ย้อนหลัง (Backtest) ว่าสิ่งที่คุณวางแผนไว้มันใช้งานได้จริงหรือไม่ ในบทความนี้ผมจะอธิบาย 2 วิธีหลักในการดึงข้อมูล ได้แก่ พร้อมเปรียบเทียบเรื่อง ค่าใช้จ่าย ความเร็ว และ ความสมบูรณ์ของข้อมูล ว่าแบบไหนเหมาะกับคุณ

ข้อมูลประเภทไหนที่ต้องการ?

ก่อนจะเลือกวิธีเก็บ ต้องเข้าใจก่อนว่าข้อมูลบน Hyperliquid มีหลายระดับ สำหรับ Backtest ที่แม่นยำ คุณต้องการ Trades หรือ Orderbook ระดับละเอียดที่สุด

วิธีที่ 1: Tardis API (บริการสำเร็จรูป)

Tardis คืออะไร?

Tardis เป็น บริการให้เช่าข้อมูล ที่รวบรวม data จาก exchange หลายตัวไว้แล้ว คุณแค่เรียก API ก็ได้ข้อมูลมาเลย ไม่ต้องสร้างระบบเก็บเอง

ข้อดีของ Tardis

ข้อเสียของ Tardis

ตัวอย่างโค้ดเรียก Tardis API

import requests

ตัวอย่างเรียกข้อมูล trades จาก Tardis

url = "https://api.tardis.dev/v1/feeds" headers = {"Authorization": "Bearer YOUR_TARDIS_API_KEY"}

ดึงรายการ feeds ที่รองรับ

response = requests.get(url, headers=headers) print(response.json())
# ตัวอย่างเรียกข้อมูล OHLCV ของ Hyperliquid
import requests

ดึงข้อมูล candlestick 5 นาที

params = { "exchange": "hyperliquid", "symbol": "BTC-PERP", "timeframe": "5m", "from": "2026-04-01", "to": "2026-04-30" } response = requests.get( "https://api.tardis.dev/v1/historical/ohlcv", params=params, headers={"Authorization": "Bearer YOUR_TARDIS_API_KEY"} ) data = response.json() print(f"ได้ข้อมูล {len(data)} แท่งเทียน") for candle in data[:3]: print(candle)

วิธีที่ 2: สร้างระบบเก็บข้อมูลเอง (Self-Hosted Collector)

แนวคิด

แทนที่จะจ่ายเงินให้ Tardis คุณสามารถสร้าง โปรแกรม Python ให้ไปดึงข้อมูลจาก Hyperliquid API โดยตรง แล้วบันทึกลงฐานข้อมูล เช่น PostgreSQL หรือ MongoDB

ข้อดีของวิธีนี้

ข้อเสีย

ตัวอย่างโค้ดดึงข้อมูลจาก Hyperliquid โดยตรง

import requests
import json
import time
from datetime import datetime

ดึงข้อมูล trades จาก Hyperliquid API โดยตรง

BASE_URL = "https://api.hyperliquid.xyz" def get_trades(symbol="BTC-PERP", start_time=None, end_time=None): """ ดึงข้อมูล trades จาก Hyperliquid start_time และ end_time ในหน่วย milliseconds """ endpoint = f"{BASE_URL}/info" payload = { "type": " trades", "symbol": symbol, } if start_time: payload["startTime"] = start_time if end_time: payload["endTime"] = end_time response = requests.post(endpoint, json=payload) if response.status_code == 200: return response.json() else: print(f"Error: {response.status_code}") return None

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

start = int(datetime(2026, 4, 1).timestamp() * 1000) end = int(datetime(2026, 4, 2).timestamp() * 1000) trades = get_trades("BTC-PERP", start, end) print(f"ได้ trades: {len(trades) if trades else 0} รายการ")
# ระบบเก็บข้อมูล OHLCV อย่างต่อเนื่อง
import requests
import json
import time
import sqlite3
from datetime import datetime, timedelta

BASE_URL = "https://api.hyperliquid.xyz"

def create_table():
    """สร้างตาราง SQLite สำหรับเก็บข้อมูล"""
    conn = sqlite3.connect('hyperliquid_data.db')
    cursor = conn.cursor()
    
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS ohlcv (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            symbol TEXT,
            timestamp INTEGER,
            open REAL,
            high REAL,
            low REAL,
            close REAL,
            volume REAL,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ''')
    conn.commit()
    return conn

def get_candles(symbol="BTC-PERP", interval="1h"):
    """ดึงข้อมูล OHLCV"""
    endpoint = f"{BASE_URL}/info"
    
    payload = {
        "type": "candleSnapshot",
        "req": {
            "coin": symbol.replace("-PERP", ""),
            "interval": interval
        }
    }
    
    response = requests.post(endpoint, json=payload)
    return response.json() if response.status_code == 200 else None

def save_to_database(conn, symbol, candles):
    """บันทึกข้อมูลลง SQLite"""
    cursor = conn.cursor()
    
    for candle in candles:
        cursor.execute('''
            INSERT OR REPLACE INTO ohlcv 
            (symbol, timestamp, open, high, low, close, volume)
            VALUES (?, ?, ?, ?, ?, ?, ?)
        ''', (
            symbol,
            candle['t'],  # timestamp
            candle['o'],  # open
            candle['h'],  # high
            candle['l'],  # low
            candle['c'],  # close
            candle['v']   # volume
        ))
    
    conn.commit()

รันระบบเก็บข้อมูล

conn = create_table() symbols = ["BTC-PERP", "ETH-PERP", "SOL-PERP"] print("เริ่มระบบเก็บข้อมูล...") for symbol in symbols: data = get_candles(symbol) if data and 'candles' in data: save_to_database(conn, symbol, data['candles']) print(f"✓ {symbol}: บันทึก {len(data['candles'])} แท่งเทียน") time.sleep(0.5) # รอคิว Rate Limit print("เสร็จสิ้นการเก็บข้อมูล")

เปรียบเทียบตาราง: Tardis vs Self-Hosted vs HolySheep AI

เกณฑ์เปรียบเทียบ Tardis API Self-Hosted (เก็บเอง) HolySheep AI
ค่าใช้จ่ายต่อเดือน $99 - $499 $5 - $20 (VPS + Storage) ประหยัด 85%+
Latency (ความหน่วง) 200-500ms 50-100ms <50ms
ความสมบูรณ์ของข้อมูล สูง มีตรวจสอบ ขึ้นกับโค้ดคุณ สูง มี QA
เวลาตั้งค่า 15 นาที 1-3 วัน 30 นาที
Rate Limit จำกัดตามแพ็กเกจ ขึ้นกับ Hyperliquid ไม่จำกัด
ต้องดูแล Server ไม่ ใช่ ต้องดูแล ไม่
รองรับ Exchange อื่น 30+ exchanges ต้องเขียนเพิ่ม หลายตัว

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

ข้อผิดพลาดที่ 1: Rate Limit Exceeded (เกินจำนวนคำขอ)

อาการ: ได้รับ error 429 หรือข้อความ "Too Many Requests"

สาเหตุ: เรียก API บ่อยเกินไป Hyperliquid จำกัด request ต่อวินาที

# วิธีแก้ไข: เพิ่ม delay ระหว่างคำขอ
import time
import requests

def safe_api_call(url, payload, max_retries=3):
    """เรียก API พร้อม retry และ delay"""
    for attempt in range(max_retries):
        try:
            response = requests.post(url, json=payload)
            
            if response.status_code == 429:
                # รอ 60 วินาทีแล้วลองใหม่
                print(f"Rate limited, รอ 60 วินาที...")
                time.sleep(60)
                continue
                
            return response
            
        except Exception as e:
            print(f"Error: {e}")
            time.sleep(5)
    
    return None

ใช้งาน

payload = {"type": " trades", "symbol": "BTC-PERP"} result = safe_api_call("https://api.hyperliquid.xyz/info", payload)

ข้อผิดพลาดที่ 2: ข้อมูลขาดหาย (Missing Data Gaps)

อาการ: ช่วงเวลาบางช่วงไม่มีข้อมูล ทำให้ Backtest ผิดพลาด

สาเหตุ: Server ล่ม, collector หยุดทำงาน หรือ network timeout

# วิธีแก้ไข: ตรวจสอบช่องว่างของข้อมูลและดึงใหม่
import sqlite3
from datetime import datetime, timedelta

def check_data_gaps(conn, symbol, timeframe_minutes=60):
    """ตรวจสอบช่องว่างในข้อมูล"""
    cursor = conn.cursor()
    
    cursor.execute('''
        SELECT timestamp FROM ohlcv 
        WHERE symbol = ? 
        ORDER BY timestamp ASC
    ''', (symbol,))
    
    timestamps = [row[0] for row in cursor.fetchall()]
    
    gaps = []
    expected_interval = timeframe_minutes * 60 * 1000  # milliseconds
    
    for i in range(1, len(timestamps)):
        diff = timestamps[i] - timestamps[i-1]
        if diff > expected_interval * 1.5:  # เกิน 150% ถือว่ามี gap
            gaps.append({
                'start': timestamps[i-1],
                'end': timestamps[i],
                'missing_minutes': (diff - expected_interval) / 60000
            })
    
    return gaps

def fill_gaps(conn, symbol, gaps):
    """เติมข้อมูลที่ขาดหาย"""
    for gap in gaps:
        print(f"กำลังดึงข้อมูลที่ขาด: {gap['missing_minutes']:.0f} นาที")
        
        # เรียก API เพื่อดึงข้อมูลในช่วงที่ขาด
        # (โค้ดดึงข้อมูลเหมือนตัวอย่างก่อนหน้า)
        pass

ตรวจสอบและเติมข้อมูล

conn = sqlite3.connect('hyperliquid_data.db') gaps = check_data_gaps(conn, 'BTC-PERP') print(f"พบช่องว่าง {len(gaps)} จุด") fill_gaps(conn, 'BTC-PERP', gaps)

ข้อผิดพลาดที่ 3: ข้อมูลซ้ำ (Duplicate Data)

อาการ: มีแถวข้อมูลซ้ำกันในฐานข้อมูล ทำให้ Backtest น้ำหนักมากเกินไป

สาเหตุ: Script รันซ้ำโดยไม่ได้ตรวจสอบก่อน หรือ API ส่งข้อมูลกลับมาซ้ำ

# วิธีแก้ไข: สร้าง Unique Constraint และลบข้อมูลซ้ำ
import sqlite3

def deduplicate_database(conn):
    """ลบข้อมูลซ้ำออกจากฐานข้อมูล"""
    cursor = conn.cursor()
    
    # สร้างตารางใหม่ที่ไม่มีข้อมูลซ้ำ
    cursor.execute('''
        CREATE TABLE ohlcv_unique AS
        SELECT DISTINCT symbol, timestamp, open, high, low, close, volume
        FROM ohlcv
        GROUP BY symbol, timestamp
    ''')
    
    # ลบตารางเดิม
    cursor.execute("DROP TABLE ohlcv")
    
    # เปลี่ยนชื่อตารางใหม่
    cursor.execute("ALTER TABLE ohlcv_unique RENAME TO ohlcv")
    
    # สร้าง index เพื่อความเร็ว
    cursor.execute('''
        CREATE INDEX IF NOT EXISTS idx_symbol_time 
        ON ohlcv(symbol, timestamp)
    ''')
    
    conn.commit()
    print("ลบข้อมูลซ้ำเรียบร้อยแล้ว")

ใช้งาน

conn = sqlite3.connect('hyperliquid_data.db') deduplicate_database(conn)

ข้อผิดพลาดที่ 4: Wrong Data Format (รูปแบบข้อมูลผิด)

อาการ: ข้อมูล timestamp ผิด, ตัวเลขมีทศนิยมผิด หรือ type mismatch

สาเหตุ: Hyperliquid ใช้หน่วยเวลาเป็น nanoseconds หรือ milliseconds ไม่ตรงกับที่คาด

# วิธีแก้ไข: ตรวจสอบและแปลง format ให้ถูกต้อง
from datetime import datetime

def parse_timestamp(ts):
    """แปลง timestamp ให้เป็น datetime ที่ถูกต้อง"""
    
    # Hyperliquid ใช้ milliseconds
    if ts > 1_000_000_000_000:  # มากกว่า 1 ล้านล้าน = nanoseconds
        ts = ts / 1_000_000  # แปลงเป็น milliseconds
    
    return datetime.fromtimestamp(ts / 1000)

def validate_candle(candle):
    """ตรวจสอบความถูกต้องของ candle"""
    errors = []
    
    # OHLC ต้อง > 0
    if candle.get('o', 0) <= 0:
        errors.append("Open price must be > 0")
    if candle.get('h', 0) <= 0:
        errors.append("High price must be > 0")
    if candle.get('l', 0) <= 0:
        errors.append("Low price must be > 0")
    if candle.get('c', 0) <= 0:
        errors.append("Close price must be > 0")
    
    # High ต้อง >= Open, Close, Low
    if candle.get('h', 0) < max(candle.get('o', 0), candle.get('c', 0)):
        errors.append("High must be >= Open and Close")
    
    # Low ต้อง <= Open, Close, High
    if candle.get('l', 0) > min(candle.get('o', 0), candle.get('c', 0)):
        errors.append("Low must be <= Open and Close")
    
    return errors

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

sample_candle = { 't': 1743523200000, # timestamp ms 'o': 94321.50, 'h': 94450.00, 'l': 94200.00, 'c': 94380.25, 'v': 1250.5 } dt = parse_timestamp(sample_candle['t']) print(f"วันที่: {dt}") # Output: 2026-04-01 00:00:00 errors = validate_candle(sample_candle) if errors: print(f"พบปัญหา: {errors}") else: print("ข้อมูลถูกต้อง")

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

วิธีการ ✓ เหมาะกับ ✗ ไม่เหมาะกับ
Tardis API
  • ต้องการข้อมูลหลาย exchange
  • มีงบประมาณสูง ($100+/เดือน)
  • ต้องการ start เร็ว ไม่มีเวลาเขียนโค้ด
  • ทีมมืออาชีพที่มี dev ops ดูแล
  • มือใหม่ที่มีงบจำกัด
  • ต้องการแค่ Hyperliquid
  • ต้องการประหยัดค่าใช้จ่าย
Self-Hosted