สวัสดีครับ ผมเป็นนักพัฒนาอิสระที่รับงานเขียนบอทเทรด crypto ให้กับกองทุนขนาดเล็กในสิงคโปร์ เมื่อเดือนมกราคม 2025 ลูกค้าของผมส่งคำขอเดียวกันมาสามรายติด: "อยากได้ Market Making bot บน BTCUSDT perpetual ที่ทำกำไรได้จริงในช่วง sideways" ผมเคยใช้ข้อมูลจาก Binance API ตรงๆ มาก่อน แต่พบว่า rate limit แค่ 1,200 request ต่อนาที ไม่พอกับการ reconstruct order book ที่ละเอียดระดับมิลลิวินาที จนกระทั่งย้ายมาใช้ Tardis ซึ่งเก็บ raw L2 snapshot ทุก 100ms ของ Binance Futures ไว้ครบ บทความนี้คือขั้นตอนทั้งหมดที่ผมใช้ทำ backtest จริง รวมถึงการดึง HolySheep AI มาช่วย optimize parameter ที่ผมเคยเสียเวลาปรับเองนานหลายวัน

Tardis คืออะไร และทำไม L2 Snapshot ถึงสำคัญกับการทำ Market Making

Tardis เป็นบริการเก็บ market data แบบ historical ที่ครอบคลุม exchange หลักกว่า 40 แห่ง โดยเฉพาะ Binance Futures, Bybit และ OKX จุดเด่นคือเก็บข้อมูลดิบระดับ book_snapshot_25 และ incremental_L2 ไว้ในรูปแบบ CSV.gz ที่ดาวน์โหลดได้ทันที ทำให้เรา reconstruct order book ณ เวลาใดก็ได้ในอดีต ไม่ต้องเสียค่าเช่า co-location หรือรัน bot เก็บข้อมูลเอง

สำหรับ HFT market making ข้อมูล L2 ที่ละเอียดถึง tick มีความสำคัญมาก เพราะ fill probability ขึ้นอยู่กับความหนาแน่นของ order book ภายใน 5-10 bps จาก mid price ถ้าใช้แค่ OHLCV 1 นาที จะ overestimate Sharpe Ratio ไปอย่างน้อย 3 เท่า จากประสบการณ์ของผม การใช้ Tardis ทำให้ backtest ใกล้เคียงผล live trading มากที่สุดเท่าที่เคยทำมา

เตรียมสภาพแวดล้อมและดึงข้อมูล L2 จาก Tardis

ขั้นแรกสมัคร Tardis account ที่ tardis.dev แล้ว generate API key จากหน้า Dashboard จากนั้นติดตั้ง dependency แค่ 3 ตัว:

pip install requests pandas numpy
export TARDIS_API_KEY="lt-xxxxxxxxxxxxxxxxxxxx"
export HOLYSHEEP_API_KEY="YOUR_HOLYSHEEP_API_KEY"

โค้ดด้านล่างนี้ดึง L2 snapshot ของ BTCUSDT perpetual วันที่ 15 มกราคม 2025 ซึ่งเป็นช่วงที่ตลาด sideways พอดี เหมาะกับการทดสอบ market making strategy:

import os
import requests
import pandas as pd
from io import BytesIO

TARDIS_KEY = os.environ["TARDIS_API_KEY"]
BASE_URL = "https://datasets.tardis.dev/v1"

def fetch_l2_snapshot(exchange, symbol, data_type, date):
    """ดึงไฟล์ L2 snapshot ของวันที่ระบุ แล้วคืนค่าเป็น DataFrame"""
    url = f"{BASE_URL}/{exchange}/{data_type}/{symbol}/{date}.csv.gz"
    headers = {"Authorization": f"Bearer {TARDIS_KEY}"}
    resp = requests.get(url, headers=headers, timeout=60)
    resp.raise_for_status()
    df = pd.read_csv(BytesIO