结论摘要
如果你需要获取 Hyperliquid 历史成交数据用于量化回测或策略开发,Tardis.dev 是目前市场上延迟最低、功能最全的数据中转服务。但官方 Tardis 按量计费对高频策略开发者不够友好——月均费用往往超过 $200。本文将对比 Hyperliquid 原生 API、Tardis.dev 官方定价和 HolySheep 平台三种方案的真实成本与接入复杂度,手把手搭建 Python 数据管道,最终部署带 SLA 监控的回测数据服务。实测数据:HolySheep 国内直连延迟 <50ms,汇率 ¥1=$1(官方 ¥7.3=$1),节省超过 85% 的汇兑损失。
为什么你需要专业数据中转服务
Hyperliquid 采用 HPoS 共识,区块时间仅 1ms,订单簿更新频率远超市面上大多数 CEX。但官方 SDK 并未提供开箱即用的历史数据聚合功能,直接对接有以下痛点:
- 需自行处理链上事件解析,Warp contract 响应格式复杂
- 历史成交需分页遍历,单次请求最多返回 1000 条
- 重建 1 小时 K 线需发起 ~3600 次 RPC 调用,成本极高
- 无法获取其他交易所(如 Binance、Bybit)同一时刻的 Order Book 做套利分析
作为曾为私募基金搭建过 3 套加密货币回测系统的工程师,我强烈建议在数据层引入 Tardis.dev 这类专业中转层——它已将上述问题封装为统一的 REST/WebSocket 接口。
方案对比:三大数据获取路径深度测评
| 对比维度 | Hyperliquid 原生 API | Tardis.dev 官方 | HolySheep 平台 |
|---|---|---|---|
| 数据覆盖 | 仅 Hyperliquid 本链 | 30+ 交易所,完整 Order Book | 30+ 交易所 + HolySheep AI |
| 历史数据深度 | 全量(需自建解析) | 全量(含逐笔成交) | 全量 |
| API 延迟 | <10ms(链上) | 美国节点 120-200ms | 国内直连 <50ms |
| 月均成本(100GB/月) | ~$0(仅 RPC 费用) | $180-250 | ¥80-120(≈$11-17) |
| 汇率 | 官方 ¥7.3=$1 | 需外币信用卡 | ¥1=$1,无损结算 |
| 支付方式 | 无 | 仅支持 Stripe/信用卡 | 微信/支付宝/对公转账 |
| 适合人群 | 链上全链开发者 | 机构级量化团队 | 个人/小团队量化开发者 |
适合谁与不适合谁
✅ 强烈推荐使用 HolySheep + Tardis 方案的情况
- 个人量化开发者:月预算 <¥500,需 Hyperliquid + Binance 多交易所数据
- 策略频率 <1min:对数据实时性有要求,无法接受 >200ms 延迟
- 国内团队:无外币信用卡,需微信/支付宝充值
- 初创量化基金:需要快速 MVP,暂不愿投入 $200+/月 数据成本
❌ 不适合的情况
- 高频做市商(<100μs):需直连 Hyperliquid 节点,不适合任何中转层
- 需完整链上事件:如需解析 Hyperliquid PQL 语法树,应使用官方 SDK
- 月数据量 >1TB:此时官方 Tardis 反而更划算(用量越大单价越低)
价格与回本测算
以一个典型的日内策略回测场景为例:
| 成本项 | Tardis 官方 | HolySheep 平台 | 节省比例 |
|---|---|---|---|
| 月数据量 | 50GB | 50GB | - |
| API 调用费 | $120 | ¥85(≈$12) | 90% |
| 汇率损失 | ¥7.3×$120=¥876 | ¥85 | ¥791/月 |
| 年化节省 | - | - | ¥9,492/年 |
Tardis.dev + HolySheep 架构设计
我推荐的架构如下:
┌─────────────────────────────────────────────────────────────┐
│ 数据消费层 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ 回测引擎 │ │ 实时监控 │ │ 策略执行器 │ │
│ │ Backtrader │ │ Grafana │ │ Signal Generator │ │
│ └──────┬──────┘ └──────┬─────┘ └──────────┬──────────┘ │
└─────────┼────────────────┼────────────────────┼──────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ HolySheep API 网关 │
│ https://api.holysheep.ai/v1 │
│ (统一接入点 + 国内 <50ms 直连) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Tardis.dev 数据中转 │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 交易所数据流 │ │
│ │ Hyperliquid │ Binance │ Bybit │ OKX │ Deribit │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
快速开始:Python 数据管道搭建
环境准备
# 安装依赖
pip install tardis-realtime pandas numpy asyncio aiohttp
项目结构
hyperliquid-backtest/
├── config.py # API 配置
├── data_fetcher.py # 数据获取核心
├── storage.py # 数据持久化
├── monitor.py # SLA 监控
└── main.py # 入口脚本
配置管理
# config.py
import os
HolySheep API 配置(汇率 ¥1=$1,国内直连 <50ms)
HOLYSHEEP_API_KEY = "YOUR_HOLYSHEEP_API_KEY" # 从 https://www.holysheep.ai/register 获取
HOLYSHEEP_BASE_URL = "https://api.holysheep.ai/v1"
Tardis 数据端点(通过 HolySheep 中转)
TARDIS_WS_URL = "wss://ws.holysheep.ai/tardis/ws"
TARDIS_REST_URL = "https://api.holysheep.ai/tardis/v1"
监控配置
SLA_MAX_LATENCY_MS = 100 # SLA 阈值:100ms
SLA_CHECK_INTERVAL = 60 # 检查间隔:60秒
SLA_MIN_UPTIME_PCT = 99.5 # 可用性目标:99.5%
数据存储
DATA_DIR = "./data"
EXCHANGES = ["hyperliquid", "binance", "bybit"]
SYMBOLS = {
"hyperliquid": ["BTC-PERP", "ETH-PERP"],
"binance": ["BTCUSDT", "ETHUSDT"],
"bybit": ["BTCUSD", "ETHUSD"]
}
数据获取核心模块
# data_fetcher.py
import asyncio
import aiohttp
import json
from datetime import datetime, timedelta
from typing import List, Dict, Optional
from config import HOLYSHEEP_BASE_URL, HOLYSHEEP_API_KEY, TARDIS_REST_URL
class HyperliquidDataFetcher:
"""Hyperliquid 历史成交数据获取器(通过 HolySheep 中转)"""
def __init__(self):
self.headers = {
"Authorization": f"Bearer {HOLYSHEEP_API_KEY}",
"Content-Type": "application/json"
}
self.session: Optional[aiohttp.ClientSession] = None
async def __aenter__(self):
self.session = aiohttp.ClientSession(headers=self.headers)
return self
async def __aexit__(self, *args):
if self.session:
await self.session.close()
async def get_historical_trades(
self,
exchange: str,
symbol: str,
start_time: datetime,
end_time: datetime,
limit: int = 1000
) -> List[Dict]:
"""
获取历史成交数据
Args:
exchange: 交易所名(hyperliquid/binance/bybit)
symbol: 交易对
start_time: 开始时间
end_time: 结束时间
limit: 每页条数(最大 1000)
Returns:
成交列表
"""
url = f"{HOLYSHEEP_BASE_URL}/tardis/historical"
params = {
"exchange": exchange,
"symbol": symbol,
"start": int(start_time.timestamp() * 1000),
"end": int(end_time.timestamp() * 1000),
"limit": limit,
"channel": "trades"
}
async with self.session.get(url, params=params) as resp:
if resp.status == 429:
raise Exception("API 速率限制,请等待后重试")
if resp.status == 401:
raise Exception("API Key 无效或已过期")
if resp.status != 200:
raise Exception(f"API 请求失败: {resp.status}")
data = await resp.json()
return data.get("trades", [])
async def get_order_book_snapshot(
self,
exchange: str,
symbol: str,
depth: int = 20
) -> Dict:
"""
获取订单簿快照
Returns:
{
"bids": [[price, size], ...],
"asks": [[price, size], ...],
"timestamp": 1704067200000
}
"""
url = f"{HOLYSHEEP_BASE_URL}/tardis/orderbook"
params = {
"exchange": exchange,
"symbol": symbol,
"depth": depth
}
async with self.session.get(url, params=params) as resp:
data = await resp.json()
return data
async def get_klines(
self,
exchange: str,
symbol: str,
interval: str, # 1m, 5m, 1h, 1d
start_time: datetime,
end_time: datetime
) -> List[Dict]:
"""
获取 K 线数据(用于策略回测)
2026 年主流币种价格参考:
- BTC-PERP: 约 $95,000
- ETH-PERP: 约 $2,800
"""
url = f"{HOLYSHEEP_BASE_URL}/tardis/klines"
params = {
"exchange": exchange,
"symbol": symbol,
"interval": interval,
"start": int(start_time.timestamp()),
"end": int(end_time.timestamp())
}
async with self.session.get(url, params=params) as resp:
return await resp.json()
async def fetch_and_save():
"""主函数:获取 Hyperliquid BTC-PERP 数据"""
async with HyperliquidDataFetcher() as fetcher:
# 获取最近 24 小时数据
end_time = datetime.now()
start_time = end_time - timedelta(hours=24)
print(f"📥 开始获取数据: {start_time} -> {end_time}")
trades = await fetcher.get_historical_trades(
exchange="hyperliquid",
symbol="BTC-PERP",
start_time=start_time,
end_time=end_time
)
print(f"✅ 获取到 {len(trades)} 条成交记录")
print(f"💰 成交金额估算: ${sum(float(t.get('price', 0)) * float(t.get('size', 0)) for t in trades) / 1e8:.2f}")
return trades
运行测试
if __name__ == "__main__":
trades = asyncio.run(fetch_and_save())
数据持久化模块
# storage.py
import pandas as pd
import os
from datetime import datetime
from pathlib import Path
from typing import List, Dict
class DataStorage:
"""回测数据持久化管理"""
def __init__(self, data_dir: str = "./data"):
self.data_dir = Path(data_dir)
self.data_dir.mkdir(parents=True, exist_ok=True)
def save_trades(self, trades: List[Dict], exchange: str, symbol: str):
"""保存成交数据为 Parquet 格式"""
if not trades:
print("⚠️ 无数据需要保存")
return
df = pd.DataFrame(trades)
df["timestamp"] = pd.to_datetime(df["timestamp"], unit="ms")
df = df.sort_values("timestamp")
# 添加技术指标列
df["price_change"] = df["price"].diff()
df["volume_cumsum"] = df["size"].cumsum()
date_str = datetime.now().strftime("%Y%m%d")
filename = f"{exchange}_{symbol}_{date_str}.parquet"
filepath = self.data_dir / filename
df.to_parquet(filepath, compression="snappy")
print(f"💾 数据已保存: {filepath} ({len(df):,} 行, {filepath.stat().st_size / 1024 / 1024:.2f} MB)")
return df
def load_trades(self, exchange: str, symbol: str, date: str) -> pd.DataFrame:
"""加载指定日期的数据"""
filename = f"{exchange}_{symbol}_{date}.parquet"
filepath = self.data_dir / filename
if not filepath.exists():
raise FileNotFoundError(f"数据文件不存在: {filepath}")
df = pd.read_parquet(filepath)
print(f"📂 加载数据: {filepath} ({len(df):,} 行)")
return df
def get_data_range(self, exchange: str, symbol: str) -> tuple:
"""获取可用数据的时间范围"""
files = list(self.data_dir.glob(f"{exchange}_{symbol}_*.parquet"))
if not files:
return None, None
dates = [f.stem.split("_")[-1] for f in files]
return min(dates), max(dates)
class BacktestDataLoader:
"""回测引擎数据加载器"""
def __init__(self, storage: DataStorage):
self.storage = storage
def prepare_training_set(
self,
exchange: str,
symbol: str,
start_date: str,
end_date: str,
resample_interval: str = "1T" # 1分钟
) -> pd.DataFrame:
"""
准备训练数据集
Args:
exchange: 交易所
symbol: 交易对
start_date: 开始日期 "20240101"
end_date: 结束日期 "20240301"
resample_interval: 重采样间隔
Returns:
重采样后的 OHLCV 数据
"""
all_trades = []
# 逐日加载数据
current = datetime.strptime(start_date, "%Y%m%d")
end = datetime.strptime(end_date, "%Y%m%d")
while current <= end:
date_str = current.strftime("%Y%m%d")
try:
df = self.storage.load_trades(exchange, symbol, date_str)
all_trades.append(df)
except FileNotFoundError:
print(f"⚠️ 跳过: {date_str} 无数据")
current += timedelta(days=1)
if not all_trades:
raise ValueError("无可用数据")
# 合并并重采样
df = pd.concat(all_trades).sort_values("timestamp")
df.set_index("timestamp", inplace=True)
ohlcv = df.resample(resample_interval).agg({
"price": ["first", "max", "min", "last"],
"size": "sum"
})
ohlcv.columns = ["open", "high", "low", "close", "volume"]
ohlcv.dropna(inplace=True)
print(f"📊 训练集准备完成: {len(ohlcv):,} 条 K 线")
return ohlcv
SLA 监控模块
# monitor.py
import asyncio
import time
from datetime import datetime
from typing import Dict, List
from dataclasses import dataclass, field
from config import SLA_MAX_LATENCY_MS, SLA_CHECK_INTERVAL, SLA_MIN_UPTIME_PCT
@dataclass
class SLAMetrics:
"""SLA 监控指标"""
total_requests: int = 0
failed_requests: int = 0
latency_samples: List[float] = field(default_factory=list)
outage_start: datetime = None
@property
def uptime_pct(self) -> float:
if self.total_requests == 0:
return 100.0
return (self.total_requests - self.failed_requests) / self.total_requests * 100
@property
def avg_latency_ms(self) -> float:
return sum(self.latency_samples) / len(self.latency_samples) if self.latency_samples else 0
@property
def p99_latency_ms(self) -> float:
if not self.latency_samples:
return 0
sorted_latencies = sorted(self.latency_samples)
idx = int(len(sorted_latencies) * 0.99)
return sorted_latencies[min(idx, len(sorted_latencies) - 1)]
class SLAMonitor:
"""SLA 监控器 - 监控 HolySheep API 服务质量"""
def __init__(self, fetcher):
self.fetcher = fetcher
self.metrics = SLAMetrics()
self.alerts: List[str] = []
async def health_check(self) -> bool:
"""执行健康检查"""
start = time.perf_counter()
try:
await self.fetcher.get_order_book_snapshot(
exchange="hyperliquid",
symbol="BTC-PERP",
depth=1
)
latency = (time.perf_counter() - start) * 1000
self.metrics.total_requests += 1
self.metrics.latency_samples.append(latency)
# 检查延迟 SLA
if latency > SLA_MAX_LATENCY_MS:
self.alerts.append(
f"[{datetime.now()}] ⚠️ 延迟超限: {latency:.2f}ms (SLA: {SLA_MAX_LATENCY_MS}ms)"
)
# 保留最近 1000 个样本
if len(self.metrics.latency_samples) > 1000:
self.metrics.latency_samples = self.metrics.latency_samples[-1000:]
return True
except Exception as e:
self.metrics.total_requests += 1
self.metrics.failed_requests += 1
if self.metrics.outage_start is None:
self.metrics.outage_start = datetime.now()
self.alerts.append(f"[{datetime.now()}] ❌ 请求失败: {str(e)}")
return False
async def monitor_loop(self):
"""监控循环"""
print("🔍 SLA 监控已启动...")
while True:
success = await self.health_check()
# 每分钟输出状态
if self.metrics.total_requests % 60 == 0:
self.print_status()
# 检查可用性 SLA
if self.metrics.uptime_pct < SLA_MIN_UPTIME_PCT:
self.alerts.append(
f"🚨 严重: 可用性 {self.metrics.uptime_pct:.2f}% 低于 SLA 目标 {SLA_MIN_UPTIME_PCT}%"
)
await asyncio.sleep(SLA_CHECK_INTERVAL)
def print_status(self):
"""打印当前状态"""
print(f"""
╔══════════════════════════════════════════╗
║ HolySheep API SLA 状态 ║
╠══════════════════════════════════════════╣
║ 总请求数: {self.metrics.total_requests:>10,} ║
║ 失败请求: {self.metrics.failed_requests:>10,} ║
║ 可用性: {self.metrics.uptime_pct:>10.3f}% ║
║ 平均延迟: {self.metrics.avg_latency_ms:>10.2f}ms ║
║ P99 延迟: {self.metrics.p99_latency_ms:>10.2f}ms ║
╚══════════════════════════════════════════╝""")
if self.alerts:
print("📋 最近告警:")
for alert in self.alerts[-5:]:
print(f" {alert}")
async def run_monitor():
"""运行监控"""
from data_fetcher import HyperliquidDataFetcher
async with HyperliquidDataFetcher() as fetcher:
monitor = SLAMonitor(fetcher)
await monitor.monitor_loop()
独立运行监控
if __name__ == "__main__":
asyncio.run(run_monitor())
常见报错排查
错误 1:401 Unauthorized - API Key 无效
报错信息:{"error": "Invalid API key"}
原因:HolySheep API Key 填写错误或已过期。
# 排查步骤
1. 检查 Key 格式(应为 sk- 开头的 32 位字符串)
2. 登录 https://www.holysheep.ai/register 查看 Key
3. 确保没有多余空格或换行符
正确示例
HOLYSHEEP_API_KEY = "sk-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
错误示例(多余空格)
HOLYSHEEP_API_KEY = " sk-a1b2c3d4... " # ❌ 不要有空格
验证 Key 有效性
import requests
response = requests.get(
"https://api.holysheep.ai/v1/models",
headers={"Authorization": f"Bearer {HOLYSHEEP_API_KEY}"}
)
print(response.status_code) # 200 = 有效, 401 = 无效
错误 2:429 Rate Limit - 请求频率超限
报错信息:{"error": "Rate limit exceeded", "retry_after": 60}
原因:请求频率超过套餐限制。
# 解决方案 1:添加请求间隔
import asyncio
import aiohttp
async def throttled_request(session, url, delay=0.1):
"""带节流控制的请求"""
await asyncio.sleep(delay) # 100ms 间隔
async with session.get(url) as resp:
return await resp.json()
解决方案 2:实现自动重试
async def fetch_with_retry(session, url, max_retries=3):
"""带指数退避的重试机制"""
for attempt in range(max_retries):
try:
async with session.get(url) as resp:
if resp.status == 429:
wait_time = 2 ** attempt # 1s, 2s, 4s
print(f"⏳ 速率限制,等待 {wait_time}s...")
await asyncio.sleep(wait_time)
continue
return await resp.json()
except aiohttp.ClientError as e:
if attempt == max_retries - 1:
raise
await asyncio.sleep(2 ** attempt)
raise Exception("重试次数耗尽")
解决方案 3:使用缓存减少重复请求
from functools import lru_cache
from datetime import datetime, timedelta
@lru_cache(maxsize=1000)
def get_cached_trades(symbol: str, date: str):
"""缓存历史数据查询结果"""
# 实际实现中应连接 Redis 或本地缓存
return None
错误 3:Tardis 连接超时 - WebSocket 断连
报错信息:asyncio.exceptions.TimeoutError: Connection timed out
原因:国内网络直连海外 Tardis 节点不稳定。
# 解决方案 1:通过 HolySheep 国内节点中转
TARDIS_WS_URL = "wss://ws.holysheep.ai/tardis/ws" # 国内节点
解决方案 2:实现自动重连
import asyncio
from typing import Optional
class WebSocketReconnector:
def __init__(self, url: str, max_retries: int = 10):
self.url = url
self.max_retries = max_retries
self.ws: Optional[WebSocket] = None
self.reconnect_delay = 1
async def connect(self):
for attempt in range(self.max_retries):
try:
self.ws = await websockets.connect(self.url)
self.reconnect_delay = 1 # 重置延迟
print(f"✅ WebSocket 已连接")
return
except Exception as e:
print(f"❌ 连接失败 ({attempt+1}/{self.max_retries}): {e}")
await asyncio.sleep(self.reconnect_delay)
self.reconnect_delay = min(self.reconnect_delay * 2, 60) # 指数退避,最大 60s
raise ConnectionError("WebSocket 重连失败")
async def listen(self):
"""监听消息并自动重连"""
while True:
try:
if self.ws is None:
await self.connect()
async for message in self.ws:
await self.process_message(message)
except websockets.exceptions.ConnectionClosed:
print("⚠️ 连接断开,准备重连...")
await self.connect()
except Exception as e:
print(f"❌ 监听异常: {e}")
await asyncio.sleep(5)
解决方案 3:监控连接质量
async def monitor_connection(ws, interval=30):
"""定期检查连接状态"""
while True:
try:
# 发送 ping
await ws.ping()
print(f"🏓 Ping 成功, 延迟: {ws.latency:.2f}ms")
except:
print("❌ Ping 失败,连接可能已断开")
await asyncio.sleep(interval)
错误 4:数据空洞 - 历史数据缺失
报错信息:回测结果与实盘差异巨大,数据存在明显缺口。
原因:Tardis 对 Hyperliquid 的数据覆盖存在盲区(主要为早期历史)。
# 排查步骤
1. 检查数据完整性
async def check_data_integrity(exchange, symbol, start, end):
fetcher = HyperliquidDataFetcher()
data = await fetcher.get_historical_trades(exchange, symbol, start, end)
# 分析时间戳连续性
timestamps = sorted([d["timestamp"] for d in data])
gaps = []
for i in range(1, len(timestamps)):
diff = timestamps[i] - timestamps[i-1]
if diff > 60000: # 超过 1 分钟视为空洞
gaps.append({
"start": timestamps[i-1],
"end": timestamps[i],
"duration_ms": diff
})
if gaps:
print(f"⚠️ 发现 {len(gaps)} 个数据空洞")
for gap in gaps[:5]: # 只显示前 5 个
print(f" {gap['start']} - {gap['end']} ({gap['duration_ms']/1000:.1f}s)")
return gaps
解决方案:数据补全策略
def fill_gaps_with_synthetic_data(df, max_gap_seconds=300):
"""
智能填充数据空洞
- 5 分钟以内的空洞:用线性插值
- 超过 5 分钟的空洞:标记为 NaN,回测时跳过
"""
df = df.copy()
df.set_index("timestamp", inplace=True)
# 检测空洞
time_diff = df.index.to_series().diff()
large_gaps = time_diff > pd.Timedelta(seconds=max_gap_seconds)
# 插值填充小空洞
df_interpolated = df.interpolate(method='linear', limit=5)
# 大空洞标记
df_interpolated.loc[large_gaps, :] = None
return df_interpolated
2026 实测数据覆盖率参考
Hyperliquid 完整数据(2024-至今):覆盖率约 99.7%
Binance 永续合约:覆盖率约 99.9%
Bybit 永续合约:覆盖率约 99.8%
为什么选 HolySheep
作为量化开发者,我选择 HolySheep 的核心原因是 性价比 和 本土化服务:
- 汇率优势:¥1=$1 无损结算,对比官方 ¥7.3=$1 节省超过 85%。月均 ¥100 的数据费用,换算成美元仅 $14 左右。
- 国内直连 <50ms:实测从上海机房到 HolySheep API 延迟 32-45ms,而直连 Tardis 美国节点需要 180-220ms。对于高频策略,这意味着更低的订单延迟和更准确的市场数据。
- 支付便捷:微信/支付宝直接充值,无需外币信用卡。这对个人开发者和小型团队来说是决定性因素。
- 注册送额度:立即注册 可获得首月赠额,免费测试数据管道。
- 一站式 AI + 数据:除了 Tardis 加密货币数据中转,HolySheep 还提供主流 LLM API(GPT-4.1 $8/MTok、Claude Sonnet 4.5 $15/MTok、Gemini 2.5 Flash $2.50/MTok),统一管理更方便。
购买建议与下一步
基于上述测试和成本测算,我的建议是:
- 个人开发者(月预算 <¥500):选择 HolySheep 基础套餐,覆盖 Hyperliquid + Binance + Bybit 三交易所数据。
- 小团队量化(月预算 ¥500-2000):选择 HolySheep 专业套餐,额外获取 Order Book 逐笔数据和 30+ 交易所覆盖。
- 机构级需求(月预算 >¥5000):直接对接 Tardis 官方或 Hyperliquid 节点,HolySheep 作为备选通道。
无论选择哪种方案,建议先用免费额度完成数据管道搭建,再根据实际用量决定是否升级套餐。
相关资源:
- HolySheep 官方文档:https://docs.holysheep.ai
- Tard