WebSocket API
Truyền dữ liệu thời gian thực cho giao dịch quyền chọn trên Hypercall.
Hãy xem Tài liệu tham khảo WebSocket API tương tác để có trải nghiệm duyệt tốt hơn với các ví dụ trực tiếp và chi tiết schema.
Tải đặc tả AsyncAPI để sử dụng theo cách lập trình.
Các đối tượng thông điệp WebSocket có thể được bổ sung trường mới mà không thông báo trước. Client phải bỏ qua các trường không nhận diện được. Hypercall không xóa trường khỏi schema thông điệp hiện có.
Kết nối
Kết nối tới wss://HOST/ws:
Endpoint:
- Production:
wss://api.hypercall.xyz/ws - Local:
ws://localhost:3000/ws
Testnet tạm thời bị vô hiệu hóa cho đến khi Hypercall có thêm HYPE testnet.
Nén dữ liệu
/ws hỗ trợ permessage-deflate theo RFC 7692. Hãy bật tính năng này trong client để giảm băng thông dữ liệu thị trường: trên lưu lượng production đã ghi nhận, các frame được nén độc lập nhỏ hơn khoảng 45%, và các batch giá chỉ số nhỏ hơn khoảng 70%.
- Client của bạn đề xuất extension trong yêu cầu upgrade, ví dụ
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits. - Khi server chấp nhận, phản hồi
101mangSec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover. Khi đó mỗi thông điệp từ server được nén riêng, không dùng chung sliding window, và các thông điệp dưới vài trăm byte vẫn được gửi không nén. Thư viện của bạn sẽ tự giải nén một cách trong suốt. - Nếu phản hồi không có header
Sec-WebSocket-Extensions, mọi frame đều không nén. Tính năng nén được bật theo từng môi trường, vì vậy client phải xử lý được cả hai trường hợp; các thông điệp JSON giống hệt nhau trong cả hai trường hợp. Production hiện chưa chấp nhận extension này, nên các frame trên production hiện không được nén. - Client của bạn có thể nén dữ liệu gửi đi. Server giải nén mỗi thông điệp từ client tới tối đa 256 KiB và đóng kết nối nếu một thông điệp vượt quá giới hạn đó.
Trình duyệt tự động thương lượng extension. Hầu hết thư viện không cần thay đổi:
Python (websockets bật nén theo mặc định):
import websockets
async with websockets.connect("wss://api.hypercall.xyz/ws", compression="deflate") as ws:
...
Node.js (ws):
import WebSocket from "ws";
const ws = new WebSocket("wss://api.hypercall.xyz/ws", { perMessageDeflate: true });
Rust: WsClient của hypercall-client thương lượng permessage-deflate theo mặc định (xem Ví dụ: Rust Client). tungstenite và tokio-tungstenite thuần chưa hỗ trợ tính năng này, nên chúng kết nối không nén. Để dùng nén với socket riêng của bạn, hãy dùng một client có hỗ trợ, chẳng hạn yawc:
let url = "wss://api.hypercall.xyz/ws".parse()?;
let mut ws = yawc::WebSocket::connect(url)
.with_options(yawc::Options::default().with_low_latency_compression())
.await?;
Định danh ví
Để nhận dữ liệu trên các kênh cần xác thực (lệnh, khớp lệnh, danh mục), hãy định danh ví sau khi kết nối bằng cách gửi thông điệp Authenticate:
{"type": "Authenticate", "wallet": "0x1234..."}
Server phản hồi xác nhận:
{"type": "Authenticated", "wallet": "0x1234..."}
Sau khi nhận Authenticated, bạn có thể đăng ký các kênh cần xác thực. Nếu địa chỉ ví không hợp lệ, server phản hồi bằng thông điệp Error và kết nối vẫn được giữ mở.
Tham số truy vấn ?wallet= vẫn được hỗ trợ để tương thích ngược nhưng không còn được khuyến nghị và sẽ bị loại bỏ trong một bản phát hành tương lai. Hãy ưu tiên cách dùng thông điệp ở trên.
Duy trì kết nối
Server áp dụng cơ chế heartbeat WebSocket:
- Gửi frame điều khiển
Pingmỗi 20 giây - Chờ
Pongtương ứng trong vòng 60 giây - Đóng kết nối với mã đóng
1008và lý dopong timeoutnếu client ngừng phản hồi
Các triển khai WebSocket trên trình duyệt tự động xử lý ping/pong. Nhiều thư viện websocket Rust, bao gồm tungstenite và tokio-tungstenite, cũng tự xử lý ping/pong ở frame điều khiển. Hãy kiểm tra tài liệu thư viện client của bạn trước khi tự thêm xử lý Pong. Các triển khai tùy chỉnh hoặc socket thô phải trả lời frame Ping bằng Pong.
Khôi phục khi client tiêu thụ chậm
Server đóng kết nối /ws nếu kết nối đó không thể xả dữ liệu gửi đi trong ngưỡng an toàn đã cấu hình về số thông điệp, số byte đã mã hóa, tuổi hàng đợi hoặc thời gian ghi socket. Khi kết nối vẫn có thể nhận frame đóng, server dùng mã 1008 và một lý do JSON rút gọn:
{"error":"slow_consumer","class":"ordered_public","cause":"message_age","recovery":"snapshot_resubscribe"}
Các trường lý do gồm:
| Trường | Ý nghĩa |
|---|---|
class | Lớp phân phối có frame đã vượt ngưỡng an toàn. |
cause | message_limit, byte_limit, message_age hoặc write_timeout. |
recovery | Hành động bắt buộc tiếp theo, chẳng hạn resubscribe, snapshot_resubscribe, portfolio_refetch hoặc rest_reconcile. |
Sau bất kỳ lần ngắt kết nối nào, hãy kết nối lại, định danh ví lại khi cần, đăng ký lại và đối soát trạng thái hiện tại trước khi xử lý sự kiện mới. Các kênh công khai có thứ tự yêu cầu một snapshot mới. Các kênh sự kiện riêng tư yêu cầu đối soát qua REST có thẩm quyền vì chưa hỗ trợ phát lại theo cursor. Một kết nối bị treo hoàn toàn có thể kết thúc trước khi đọc được lý do đóng, vì vậy client cũng phải áp dụng quy trình khôi phục này khi kết nối đóng không sạch.
Hãy dùng các kết nối riêng cho dữ liệu thị trường công khai tần suất cao và cho lệnh cần xác thực hoặc luồng riêng tư. Lớp phân phối quyết định metric và hành vi khôi phục, nhưng các frame trên cùng một kết nối vẫn dùng chung một đường ghi socket có thứ tự. Do đó, một lần ghi công khai bị treo có thể làm chậm các frame riêng tư phía sau trên cùng kết nối cho đến khi hạn ghi khiến kết nối bị đóng.
Đăng ký kênh
Gửi một thông điệp JSON để đăng ký:
{"type": "Subscribe", "channel": "orderbook"}
Để hủy đăng ký:
{"type": "Unsubscribe", "channel": "orderbook"}
Bạn sẽ nhận được xác nhận:
{"type": "Subscribed", "channel": "orderbook"}
Lọc theo symbol
Các kênh order_updates và fills hỗ trợ bộ lọc symbols tùy chọn. Khi được cung cấp, server chỉ gửi các thông điệp có tài sản cơ sở khớp với một trong các symbol đã chỉ định.
{"type": "Subscribe", "channel": "order_updates", "symbols": ["BTC"]}
Chấp nhận cả tên tài sản cơ sở ("BTC") lẫn tên công cụ đầy đủ ("BTC-20260131-100000-C"). Để thêm symbol, hãy gửi thêm một Subscribe. Để xóa các symbol cụ thể:
{"type": "Unsubscribe", "channel": "order_updates", "symbols": ["BTC"]}
Khi không chỉ định symbols, mọi cập nhật cho ví của bạn đều được chuyển tiếp.
Các kênh công khai orderbook, trades, indicative_market_data và indicative_market_data_v2 cũng chấp nhận symbols, được so khớp với symbol công cụ chính xác (không phân biệt hoa thường), không phải tài sản cơ sở:
{"type": "Subscribe", "channel": "orderbook", "symbols": ["BTC-20260131-100000-C"]}
Không có symbols, các kênh này phân phối mọi công cụ.
Lọc chuỗi quyền chọn
Kênh options_chain hỗ trợ lọc theo symbol công cụ, ngày đáo hạn và loại quyền chọn:
{
"type": "Subscribe",
"channel": "options_chain",
"symbols": ["BTC-20260131-100000-C"],
"expiry": "2026-01-31",
"option_type": "call"
}
| Bộ lọc | Giá trị | Mặc định |
|---|---|---|
symbols | Mảng các symbol công cụ đầy đủ (ví dụ: ["BTC-20260131-100000-C"]) | Tất cả công cụ |
expiry | Chuỗi ngày "YYYY-MM-DD", so khớp với ngày lịch UTC của ngày đáo hạn từng công cụ | Tất cả ngày đáo hạn |
option_type | "call", "put", "both", hoặc bỏ trống để lấy cả hai | Cả hai |
Phân phối theo batch
indicative_market_data_v2 mang cùng các dòng dữ liệu như indicative_market_data, nhiều dòng mỗi frame:
{"type": "Subscribe", "channel": "indicative_market_data_v2", "symbols": ["BTC-20260131-100000-C"]}
Server xác nhận với một dấu hiệu batch:
{"type": "Subscribed", "channel": "indicative_market_data_v2", "batch": true}
Sau đó server giữ mỗi dòng tối đa một cửa sổ batch, mặc định 25 ms, và gửi các dòng được phát trong cửa sổ đó dưới dạng một frame IndicativeMarketDataBatch. Một batch cũng được gửi sớm khi đạt 256 dòng.
- Phát hiện hỗ trợ: chỉ một xác nhận có
"batch": truemới cho biết server thực hiện batch. Các server phát hành trước kênh này xác nhận bất kỳ tên kênh nào mà không có dấu hiệu đó rồi không gửi gì, còn server hiện tại trả lời kênh không xác định bằng lỗiunknown_channel. Trong cả hai trường hợp, hãy hủy đăng kýindicative_market_data_v2và đăng kýindicative_market_datatrên cùng kết nối. - Độ trễ: một dòng đến muộn hơn tối đa một cửa sổ so với trên
indicative_market_data. Trên lưu lượng production với cửa sổ mặc định, các dòng chờ trung bình 12 ms và không bao giờ quá 25 ms. Hãy dùng kênh v1 nếu bạn cần phản ứng với từng cập nhật báo giá trong vài mili giây. - Băng thông: riêng việc batch chỉ tiết kiệm khoảng 7% số byte. Mức tiết kiệm lớn đến khi kết hợp với
permessage-deflate: các batch đã nén nhỏ hơn khoảng 9,8 lần so với frame một dòng không nén cho một đăng ký không lọc, và nhỏ hơn khoảng 8,3 lần cho một chuỗi quyền chọn, so với khoảng 1,8 lần khi nén từng dòng riêng lẻ. - Thứ tự: các dòng trong
updatestheo thứ tự phát, và các batch đến theo thứ tự. Các dòng không bị gộp, nên một công cụ có thể xuất hiện nhiều lần trong một batch. Áp dụng các dòng theo thứ tự và bạn sẽ đạt cùng trạng thái như trên kênh v1. - Snapshot: snapshot tại thời điểm đăng ký cũng đến dưới dạng frame batch.
- Bộ lọc:
symbolshoạt động giống như trênindicative_market_data. Thu hẹp bộ lọc hoặc hủy đăng ký sẽ gửi trước các dòng đang chờ theo bộ lọc cũ, rồi mới gửi xác nhậnUnsubscribed, nên không có dòng nào bị mất hoặc trùng lặp. - Kênh độc lập: một kết nối có thể đăng ký cả hai kênh với các bộ lọc khác nhau.
indicative_market_datakhông thay đổi.
Các kênh khả dụng
| Kênh | Cần xác thực | Mô tả |
|---|---|---|
orderbook | Không | Cập nhật sổ lệnh L2 cho tất cả symbol |
trades | Không | Luồng giao dịch công khai |
market_updates | Không | Thay đổi niêm yết thị trường (tạo/xóa/đáo hạn) |
options_chain | Không | Cập nhật tăng dần của chuỗi quyền chọn (lọc được theo symbols, expiry, option_type) |
index_prices | Không | Giá giao ngay/giá chỉ số thời gian thực cho mọi tài sản cơ sở |
indicative_market_data | Không | Luồng của nhà cung cấp báo giá trong danh sách cho phép. Chưa mở rộng rãi |
indicative_market_data_v2 | Không | Cùng luồng trên dưới dạng frame batch. Xem Phân phối theo batch |
order_updates | Có | Thay đổi trạng thái lệnh của bạn (lọc được theo symbol) |
fills | Có | Các lần khớp lệnh của bạn (lọc được theo symbol) |
portfolio | Có | Cập nhật vị thế và số dư của bạn |
liquidation | Có | Thay đổi trạng thái thanh lý của bạn |
rfq | Có | Báo giá RFQ, cập nhật trạng thái và thông báo khớp lệnh |
experimental_order_updates, experimental_combo_fills | Có | Các kênh combo thử nghiệm. Xem API Combo thử nghiệm |
experimental_combo_trades | Không | Giao dịch combo công khai thử nghiệm |
Dữ liệu cuộc thi và bảng xếp hạng không được cung cấp bởi api.hypercall.xyz, cả qua WebSocket lẫn REST. Đăng ký các kênh đã ngừng competition hoặc competition_engagement sẽ trả về Error. Ứng dụng giao dịch đọc dữ liệu cuộc thi qua HTTP từ dịch vụ analytics tại https://api-ui.hypercall.xyz, ví dụ GET /v2/competitions, GET /v2/competitions/{id}, GET /v2/competitions/leaderboard và GET /v2/competitions/all-time/leaderboard.
Các loại thông điệp
Đặt lệnh (Cần xác thực)
Đặt lệnh qua đường lệnh WebSocket.
{
"type": "PlaceOrder",
"wallet": "0x1234...",
"symbol": "BTC-20260131-100000-C",
"side": "Buy",
"size": "1",
"price": "100",
"tif": "gtc",
"route": "book_only",
"client_id": "my-order-1",
"nonce": 1780000000000,
"signature": "0x..."
}
nonce ở trên chỉ mang tính minh họa. Hãy tạo nonce mới cho mỗi lệnh từ thời gian Unix hiện tại tính bằng mili giây, ví dụ Date.now() trong JavaScript. Một giá trị cố định được sao chép sẽ nằm ngoài khoảng chấp nhận và bị từ chối.
| Trường | Kiểu | Mô tả |
|---|---|---|
wallet | string | Địa chỉ ví sở hữu lệnh |
symbol | string | Symbol quyền chọn |
side | string | "Buy" hoặc "Sell" |
size | string | Quy mô hợp đồng, khớp chính xác với giá trị đã ký |
price | string | Giá giới hạn, khớp chính xác với giá trị đã ký |
tif | string | Time-in-force tùy chọn, mặc định "gtc" |
route | string | Dùng "book_only". Route bị bỏ trống vẫn được chấp nhận nhưng không còn được khuyến nghị, và hạn ngừng hỗ trợ đã qua. |
client_id | string | ID lệnh phía client, tùy chọn |
reduce_only | boolean | Tùy chọn, mặc định false. Lệnh reduce-only ký PlaceOrderReduceOnly và yêu cầu route tường minh |
mmp_enabled | boolean | Tùy chọn, mặc định false |
builder_code_address | string | Ví builder code, tùy chọn |
nonce | integer | Nonce ký bắt buộc: thời gian Unix hiện tại tính bằng mili giây. Giá trị phải nằm trong khoảng từ hai ngày trước đến một ngày sau thời điểm hiện tại. Mỗi nonce chỉ được chấp nhận một lần cho mỗi người ký, và lệnh REST và WebSocket dùng chung không gian nonce. Frame bị phát lại sẽ bị từ chối. |
signature | string | Chữ ký EIP-712 PlaceOrder |
Kết nối phải gửi Authenticate trước; nếu không, server trả lời {"type": "Error", "message": "Not authenticated"}. Người ký phải là wallet hoặc một agent đã được phê duyệt cho ví đó.
PlaceOrder qua WebSocket hiện được chuyển thẳng vào sổ lệnh. route="best_execution" và route="rfq_only" bị từ chối trên WebSocket vì đường này chưa chạy định tuyến RPI/RFQ. Hãy dùng POST /order cho best_execution.
Lệnh được chấp nhận sẽ được trả lời trên cùng kết nối bằng OrderResult:
{
"type": "OrderResult",
"order_id": 12345,
"status": "ACKED",
"symbol": "BTC-20260131-100000-C",
"side": "Buy",
"price": "100",
"size": "1"
}
reason được thêm vào khi lệnh không được chấp nhận. Các lỗi xác thực dữ liệu, chữ ký và giới hạn tốc độ được gửi dưới dạng Error có message bắt đầu bằng Order placement failed:. Các thay đổi trạng thái tiếp theo đến trên order_updates.
Cập nhật sổ lệnh
Snapshot/cập nhật sổ lệnh L2 cho một symbol.
{
"type": "OrderbookUpdate",
"symbol": "BTC-20260131-100000-C",
"option_token_address": "0x...",
"bids": [["95000.5", "10.5"], ["94999.0", "25.0"]],
"asks": [["95001.0", "8.0"], ["95002.5", "15.0"]],
"timestamp": 1737331200000
}
| Trường | Kiểu | Mô tả |
|---|---|---|
symbol | string | Symbol quyền chọn |
option_token_address | string? | Địa chỉ token quyền chọn on-chain, khi đã biết |
bids | array | Các mức giá mua dạng tuple [price, size], size tính bằng số hợp đồng dạng dễ đọc |
asks | array | Các mức giá bán dạng tuple [price, size], size tính bằng số hợp đồng dạng dễ đọc |
timestamp | integer | Unix timestamp (mili giây) |
Giao dịch
Sự kiện giao dịch công khai.
{
"type": "Trade",
"symbol": "BTC-20260131-100000-C",
"price": "0.0523",
"size": "5.0",
"side": "Buy",
"timestamp": 1737331200000
}
| Trường | Kiểu | Mô tả |
|---|---|---|
symbol | string | Symbol quyền chọn |
price | string | Giá giao dịch tính bằng USD |
size | string | Khối lượng giao dịch tính bằng số hợp đồng |
side | string | Phía chủ động (Buy hoặc Sell) |
timestamp | integer | Unix timestamp (mili giây) |
Khớp lệnh (Cần xác thực)
Thông báo khớp lệnh của bạn.
{
"type": "Fill",
"order_id": 12345,
"fill_id": 67890,
"symbol": "BTC-20260131-100000-C",
"side": "Buy",
"price": "0.0523",
"size": "5.0",
"timestamp": 1737331200000,
"wallet_address": "0x1234...abcd",
"fee": "0",
"trade_id": 99999,
"is_taker": true,
"builder_code_address": null,
"builder_code_fee": null,
"instrument_type": "option"
}
| Trường | Kiểu | Mô tả |
|---|---|---|
order_id | integer | ID lệnh của bạn |
fill_id | integer | ID khớp lệnh |
symbol | string | Symbol quyền chọn |
side | string | Phía của bạn trong giao dịch (Buy hoặc Sell) |
price | string | Giá khớp tính bằng USD |
size | string | Khối lượng khớp tính bằng số hợp đồng |
timestamp | integer | Unix timestamp (mili giây) |
wallet_address | string | Địa chỉ ví của bạn |
fee | string | Phí giao dịch đã tính. Trả về 0 trong thời gian phí sàn giai đoạn ra mắt bị tắt |
trade_id | integer | ID giao dịch duy nhất |
is_taker | boolean | Bạn có phải là taker hay không |
builder_code_address | string? | Ví builder code (nếu có) |
builder_code_fee | string? | Phí builder code. Trả về null trong thời gian phí sàn giai đoạn ra mắt bị tắt |
instrument_type | string | "option" |
Cập nhật danh mục (Cần xác thực)
Được gửi trên kênh portfolio cho vị thế, số dư, ký quỹ và Greeks. Khi đăng ký, server gửi snapshot Initial, sau đó là các cập nhật tăng dần.
type của mỗi frame là loại cập nhật của nó:
| Loại cập nhật | Các trường ngoài timestamp |
|---|---|
Initial | positions |
PositionUpdate | position |
BalanceUpdate | total_margin_used |
MarginUpdate | span_margin, margin_summary, margin_mode, total_margin_used, available_balance |
GreeksUpdate | per_leg, aggregate |
timestamp trên các frame portfolio tính bằng giây Unix, khác với timestamp tính bằng mili giây trên các kênh khác.
Ví dụ cập nhật Greeks:
{
"type": "GreeksUpdate",
"timestamp": 1737331200,
"per_leg": [
{
"symbol": "BTC-20260131-100000-C",
"quantity": "2.0",
"delta": 0.91,
"gamma": 0.003,
"theta": -0.12,
"vega": 0.44,
"iv": 0.63
}
],
"aggregate": {
"delta": 0.91,
"gamma": 0.003,
"theta": -0.12,
"vega": 0.44,
"iv": 0.63
}
}
Với danh mục trống, cập nhật Greeks dùng:
per_leg: []aggregate: null
Cập nhật lệnh (Cần xác thực)
Thông báo thay đổi trạng thái lệnh. Bao gồm cả cập nhật PARTIALLY_FILLED.
filled_size là khối lượng đã khớp cộng dồn qua các lần thực thi của lệnh,
không phải khối lượng của lần khớp gần nhất.
{
"type": "OrderUpdate",
"order_id": 12345,
"client_id": "my-order-1",
"request": {
"price": "0.0523",
"size": "10.0",
"symbol": "BTC-20260131-100000-C",
"side": "Buy",
"tif": "gtc"
},
"status": "PARTIALLY_FILLED",
"filled_size": "0.75",
"timestamp": 1767225600000,
"reason": null,
"wallet_address": "0x0000000000000000000000000000000000000001",
"instrument_type": "option"
}
status là một trong ACKED, OPEN, PARTIALLY_FILLED, FILLED, CANCELED hoặc REJECTED. client_id bị bỏ qua khi lệnh không có giá trị này. instrument_type là "option" hoặc "perp".
Cập nhật thị trường
Thay đổi niêm yết thị trường.
Thị trường được tạo:
{
"type": "MarketUpdate",
"action": "Created",
"symbol": "BTC-20260131-100000-C",
"strike": "100000",
"is_call": true,
"underlying": "BTC",
"expiry": 1738281600,
"timestamp": 1737331200000
}
Thị trường đáo hạn:
{
"type": "MarketUpdate",
"action": "Expired",
"symbol": "BTC-20260131-100000-C",
"strike": "100000",
"is_call": true,
"underlying": "BTC",
"expiry": 1738281600,
"timestamp": 1738281600000
}
action là Created, Expired, Deleted (chỉ mang symbol và timestamp), hoặc ComboCreated (xem API Combo thử nghiệm).
Cập nhật chuỗi quyền chọn
Được gửi trên options_chain khi một niêm yết hoặc đỉnh sổ lệnh của nó thay đổi. action là Upsert hoặc Remove.
{
"type": "OptionsChainUpdate",
"action": "Upsert",
"currency": "BTC",
"expiry": 1769846400,
"row": {
"strike": 100000.0,
"call": {
"symbol": "BTC-20260131-100000-C",
"bid_price_usd": 1520.0,
"ask_price_usd": 1580.0
}
},
"timestamp": 1737331200000
}
Một dòng Upsert mang một chân (call hoặc put) với các trường chân của snapshot chuỗi quyền chọn: symbol, option_token_address, giá mua và giá bán, IV, khối lượng tính bằng số hợp đồng và giá trị danh nghĩa USD, greeks_abs và greeks_cash (ví dụ ở trên đã được rút gọn). Các giá trị không có sẵn là null; chân không thuộc cập nhật sẽ bị bỏ qua. Một Remove mang currency, expiry, strike, option_type, symbol và timestamp khi một công cụ bị xóa, đáo hạn hoặc chuyển sang trạng thái chờ thanh toán. expiry tính bằng giây Unix.
Vị thế đáo hạn (Cần xác thực)
Được gửi trên kênh portfolio khi vị thế của bạn được thanh toán tại ngày đáo hạn.
{
"type": "PositionExpired",
"wallet_address": "0x1234...abcd",
"symbol": "BTC-20260131-100000-C",
"position_size": "10.0",
"settlement_price": "105000",
"settlement_value": "500.0",
"settlement_entry_price": "100.0",
"cost_basis": "1000.0",
"net_pnl": "-500.0",
"timestamp": 1738281600000
}
settlement_entry_price, cost_basis và net_pnl là null khi không có sẵn.
Thay đổi trạng thái thanh lý (Cần xác thực)
Được gửi trên kênh liquidation khi trạng thái thanh lý của tài khoản bạn thay đổi.
{
"type": "LiquidationStateChange",
"wallet_address": "0x1234...abcd",
"previous_state": "healthy",
"new_state": "pre_liquidation",
"liquidation_mode": "partial",
"margin_mode": "standard",
"equity": "10000.0",
"mm_required": "10500.0",
"maintenance_margin": "-500.0",
"shortfall": "500.0",
"partial_liquidation": { "...": "..." },
"full_liquidation": null,
"timestamp": 1737331200000
}
| Trường | Mô tả |
|---|---|
previous_state, new_state | healthy, pre_liquidation, in_liquidation hoặc liquidated |
liquidation_mode | partial, full, hoặc null khi không có quy trình thanh lý nào đang hoạt động |
margin_mode | standard hoặc portfolio |
equity | Vốn chủ sở hữu của tài khoản |
mm_required | Yêu cầu ký quỹ duy trì |
maintenance_margin | Vốn chủ sở hữu trừ đi yêu cầu ký quỹ duy trì |
shortfall | Số tiền tài khoản đang thiếu so với ký quỹ duy trì |
partial_liquidation | Tiến trình thanh lý một phần (thời điểm bắt đầu, vốn chủ sở hữu mục tiêu, hạn leo thang, các lệnh thanh lý đang hoạt động, tiền thưởng), hoặc null |
full_liquidation | Chi tiết đấu giá thanh lý toàn phần (ID đấu giá, thời điểm bắt đầu, ký quỹ cần thiết, và khi hoàn tất là bên thắng, tiền thưởng và giao dịch xử lý), hoặc null |
Xem Thanh lý để biết ý nghĩa của từng trạng thái.
Cập nhật giá chỉ số
Giá giao ngay/giá chỉ số theo batch cho mọi tài sản cơ sở.
{
"type": "IndexPriceUpdate",
"prices": [
{"underlying": "BTC", "price": "97250.50", "timestamp": 1737331200000},
{"underlying": "ETH", "price": "3200.00", "timestamp": 1737331199980},
{"underlying": "NVDA", "price": "182.40", "timestamp": 1737331199950}
],
"timestamp": 1737331199950
}
| Trường | Kiểu | Mô tả |
|---|---|---|
prices | array | Mảng các mục {underlying, price, timestamp} cho từng tài sản cơ sở được theo dõi |
prices[].underlying | string | Symbol tài sản cơ sở (ví dụ: "BTC", "ETH") |
prices[].price | string | Giá giao ngay/giá chỉ số hiện tại tính bằng USD |
prices[].timestamp | integer | Thời điểm quan sát tại nguồn cho tài sản cơ sở này, tính bằng mili giây Unix |
timestamp | integer | Thời điểm quan sát tại nguồn cũ nhất có trong prices, tính bằng mili giây Unix |
Dữ liệu thị trường tham khảo
Luồng của nhà cung cấp báo giá trong danh sách cho phép, với giá mua/giá bán tốt nhất tổng hợp từ các nhà cung cấp báo giá đã đăng ký. Kênh này chưa mở rộng rãi. Hãy dùng dữ liệu thị trường REST và các kênh lệnh/khớp lệnh/danh mục cần xác thực, trừ khi Hypercall đã bật luồng nhà cung cấp báo giá cho tích hợp của bạn.
{
"type": "IndicativeMarketData",
"instrument": "BTC-20260131-100000-C",
"best_bid": "0.0520",
"best_ask": "0.0530",
"indicative_bid_size": "50.0",
"indicative_ask_size": "25.0",
"num_providers": 3,
"published_at": 1737331200004,
"timestamp": 1737331200000
}
| Trường | Kiểu | Mô tả |
|---|---|---|
instrument | string | Symbol quyền chọn |
best_bid | string | Giá mua tổng hợp tốt nhất, tùy chọn |
best_ask | string | Giá bán tổng hợp tốt nhất, tùy chọn |
bid_iv | number | Biến động ngụ ý của giá mua tốt nhất, tùy chọn |
ask_iv | number | Biến động ngụ ý của giá bán tốt nhất, tùy chọn |
indicative_bid_size | string | Tổng khối lượng mua trên các nhà cung cấp, tùy chọn |
indicative_ask_size | string | Tổng khối lượng bán trên các nhà cung cấp, tùy chọn |
num_providers | integer | Số nhà cung cấp báo giá đang hoạt động |
rfq_provider_quotes | array | Báo giá theo từng nhà cung cấp, tùy chọn: wallet, bid_price, ask_price, max_bid_size, max_ask_size, updated_at |
published_at | integer | Thời điểm dòng này được phát theo đồng hồ API, mili giây Unix. Hãy đo tuổi của rfq_provider_quotes theo giá trị này, không theo đồng hồ cục bộ của bạn |
timestamp | integer | Thời điểm của báo giá nhà cung cấp gần nhất, mili giây Unix |
Batch dữ liệu thị trường tham khảo
Được gửi trên kênh indicative_market_data_v2 (xem Phân phối theo batch). Mỗi phần tử của updates có cùng các trường như thông điệp IndicativeMarketData, không có type.
{
"type": "IndicativeMarketDataBatch",
"flushed_at": 1737331200025,
"updates": [
{
"instrument": "BTC-20260131-100000-C",
"best_bid": "0.0520",
"best_ask": "0.0530",
"num_providers": 3,
"published_at": 1737331200004,
"timestamp": 1737331200000
},
{
"instrument": "BTC-20260131-105000-C",
"best_bid": "0.0310",
"best_ask": "0.0322",
"num_providers": 2,
"published_at": 1737331200004,
"timestamp": 1737331200001
}
]
}
| Trường | Kiểu | Mô tả |
|---|---|---|
flushed_at | integer | Thời điểm batch được gửi theo đồng hồ API, mili giây Unix. flushed_at - published_at là độ trễ batch của một dòng |
updates | array | Các dòng được phát trong cửa sổ, cũ nhất trước |
Báo giá RFQ (Cần xác thực)
Các báo giá nhận được để phản hồi yêu cầu RFQ bạn đã gửi.
{
"type": "RfqQuotes",
"rfq_id": "550e8400-e29b-41d4-a716-446655440000",
"quotes": [
{
"quote_id": "660e8400-e29b-41d4-a716-446655440001",
"net_premium": "52.30",
"expires_at": 1737331225000
}
],
"status": "quoted",
"taker_wallet": "0x1234...abcd"
}
Cập nhật trạng thái RFQ (Cần xác thực)
Thay đổi trạng thái của một RFQ bạn đã gửi.
{
"type": "RfqStatusUpdate",
"rfq_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "executed",
"taker_wallet": "0x1234...abcd"
}
Đồng bộ đồng hồ
Gửi ClockSync với một chuỗi nonce bất kỳ để nhận mẫu đồng hồ API trên cùng kết nối, ví dụ để ước lượng giới hạn độ trễ truyền tải:
{"type": "ClockSync", "nonce": "abc"}
{"type": "ClockSynced", "nonce": "abc", "server_at": 1737331200000}
server_at tính bằng mili giây Unix. Không cần xác thực.
Lỗi
Thông điệp lỗi từ server. Hãy so khớp theo code khi có, không theo message.
{
"type": "Error",
"message": "Unknown channel 'foobar'",
"code": "unknown_channel",
"channel": "foobar"
}
| Trường | Kiểu | Mô tả |
|---|---|---|
message | string | Mô tả dễ đọc |
code | string | Lý do ổn định, tùy chọn. unknown_channel: một Subscribe đã chỉ định kênh không tồn tại |
channel | string | Tùy chọn. Kênh mà Subscribe bị từ chối đã chỉ định |
Một Subscribe tới kênh không có trong Các kênh khả dụng sẽ được trả lời bằng lỗi unknown_channel, và không có đăng ký nào được tạo. Các server trước đây xác nhận mọi tên kênh rồi không gửi gì.
Các lỗi khác chỉ mang message. Ví dụ: Authentication required for this channel khi bạn đăng ký kênh cần xác thực trước khi gửi Authenticate, Not authenticated cho PlaceOrder trước Authenticate, và Invalid wallet address: ....
Xác thực
Các kênh cần xác thực yêu cầu một thông điệp định danh ví sau khi kết nối:
{"type": "Authenticate", "wallet": "0x1234567890abcdef..."}
Thông điệp trên các kênh cần xác thực được lọc để chỉ hiển thị dữ liệu cho ví của bạn. Kết nối WebSocket không yêu cầu chữ ký.
Ví dụ: Python Client
import asyncio
import websockets
import json
async def main():
uri = "wss://api.hypercall.xyz/ws"
async with websockets.connect(uri) as ws:
# Identify the wallet before subscribing to authenticated channels.
await ws.send(json.dumps({
"type": "Authenticate",
"wallet": "0xYourWallet"
}))
# Subscribe to orderbook
await ws.send(json.dumps({
"type": "Subscribe",
"channel": "orderbook"
}))
# Subscribe to fills for BTC only
await ws.send(json.dumps({
"type": "Subscribe",
"channel": "fills",
"symbols": ["BTC"]
}))
# Listen for messages
async for message in ws:
data = json.loads(message)
print(f"Received: {data['type']}")
asyncio.run(main())
Ví dụ: TypeScript Client
const ws = new WebSocket("wss://api.hypercall.xyz/ws");
ws.onopen = () => {
ws.send(JSON.stringify({ type: "Authenticate", wallet: "0xYourWallet" }));
// Subscribe to channels
ws.send(JSON.stringify({ type: "Subscribe", channel: "orderbook" }));
// Subscribe to order updates filtered to BTC
ws.send(JSON.stringify({
type: "Subscribe",
channel: "order_updates",
symbols: ["BTC"],
}));
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
console.log(`Received: ${msg.type}`);
if (msg.type === "OrderbookUpdate") {
console.log(`${msg.symbol}: ${msg.bids.length} bids, ${msg.asks.length} asks`);
}
};
Ví dụ: Rust Client
WsClient của crate hypercall-client tự định danh ví, khôi phục các đăng ký sau khi kết nối lại và trả lời ping từ server. Nó đề xuất nén permessage-deflate theo mặc định và quay về frame không nén khi server không chấp nhận, với cùng các thông điệp JSON trong cả hai trường hợp. Gọi with_permessage_deflate(false) để ngừng đề xuất nén.
use hypercall_client::WsClient;
#[tokio::main]
async fn main() -> hypercall_client::Result<()> {
let ws = WsClient::new();
ws.connect("https://api.hypercall.xyz", None).await?;
ws.subscribe(vec!["orderbook", "index_prices"]).await?;
if let Some(msg) = ws.wait_for_message(|_| true, 5_000).await {
println!("Received: {msg:?}");
}
Ok(())
}