Trang này được dịch tự động. Bản gốc tiếng Anh là phiên bản chính thức. Đọc bằng tiếng Anh →
Chuyển đến nội dung chính

WebSocket API

Truyền dữ liệu thời gian thực cho giao dịch quyền chọn trên Hypercall.

Tài liệu tham khảo tương tác

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.

Đặc tả máy đọc được

Tải đặc tả AsyncAPI để sử dụng theo cách lập trình.

Mở rộng schema theo hướng bổ sung

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
Trạng thái testnet

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 101 mang Sec-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ở.

Không còn khuyến nghị: Xác thực qua tham số truy vấn

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 Ping mỗi 20 giây
  • Chờ Pong tương ứng trong vòng 60 giây
  • Đóng kết nối với mã đóng 1008 và lý do pong timeout nế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
classLớp phân phối có frame đã vượt ngưỡng an toàn.
causemessage_limit, byte_limit, message_age hoặc write_timeout.
recoveryHà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ọcGiá trịMặc định
symbolsMảng các symbol công cụ đầy đủ (ví dụ: ["BTC-20260131-100000-C"])Tất cả công cụ
expiryChuỗ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ả haiCả 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": true mớ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ỗi unknown_channel. Trong cả hai trường hợp, hãy hủy đăng ký indicative_market_data_v2 và đăng ký indicative_market_data trê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 updates theo 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: symbols hoạt động giống như trên indicative_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ận Unsubscribed, 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_data không thay đổi.

Các kênh khả dụng​

KênhCần xác thựcMô tả
orderbookKhôngCập nhật sổ lệnh L2 cho tất cả symbol
tradesKhôngLuồng giao dịch công khai
market_updatesKhôngThay đổi niêm yết thị trường (tạo/xóa/đáo hạn)
options_chainKhôngCập nhật tăng dần của chuỗi quyền chọn (lọc được theo symbols, expiry, option_type)
index_pricesKhôngGiá giao ngay/giá chỉ số thời gian thực cho mọi tài sản cơ sở
indicative_market_dataKhôngLuồ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_v2KhôngCùng luồng trên dưới dạng frame batch. Xem Phân phối theo batch
order_updatesCóThay đổi trạng thái lệnh của bạn (lọc được theo symbol)
fillsCóCác lần khớp lệnh của bạn (lọc được theo symbol)
portfolioCóCập nhật vị thế và số dư của bạn
liquidationCóThay đổi trạng thái thanh lý của bạn
rfqCó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_fillsCóCác kênh combo thử nghiệm. Xem API Combo thử nghiệm
experimental_combo_tradesKhôngGiao 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ườngKiểuMô tả
walletstringĐịa chỉ ví sở hữu lệnh
symbolstringSymbol quyền chọn
sidestring"Buy" hoặc "Sell"
sizestringQuy mô hợp đồng, khớp chính xác với giá trị đã ký
pricestringGiá giới hạn, khớp chính xác với giá trị đã ký
tifstringTime-in-force tùy chọn, mặc định "gtc"
routestringDù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_idstringID lệnh phía client, tùy chọn
reduce_onlybooleanTùy chọn, mặc định false. Lệnh reduce-only ký PlaceOrderReduceOnly và yêu cầu route tường minh
mmp_enabledbooleanTùy chọn, mặc định false
builder_code_addressstringVí builder code, tùy chọn
nonceintegerNonce 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.
signaturestringChữ 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ườngKiểuMô tả
symbolstringSymbol quyền chọn
option_token_addressstring?Địa chỉ token quyền chọn on-chain, khi đã biết
bidsarrayCác mức giá mua dạng tuple [price, size], size tính bằng số hợp đồng dạng dễ đọc
asksarrayCác mức giá bán dạng tuple [price, size], size tính bằng số hợp đồng dạng dễ đọc
timestampintegerUnix 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ườngKiểuMô tả
symbolstringSymbol quyền chọn
pricestringGiá giao dịch tính bằng USD
sizestringKhối lượng giao dịch tính bằng số hợp đồng
sidestringPhía chủ động (Buy hoặc Sell)
timestampintegerUnix 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ườngKiểuMô tả
order_idintegerID lệnh của bạn
fill_idintegerID khớp lệnh
symbolstringSymbol quyền chọn
sidestringPhía của bạn trong giao dịch (Buy hoặc Sell)
pricestringGiá khớp tính bằng USD
sizestringKhối lượng khớp tính bằng số hợp đồng
timestampintegerUnix timestamp (mili giây)
wallet_addressstringĐịa chỉ ví của bạn
feestringPhí 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_idintegerID giao dịch duy nhất
is_takerbooleanBạn có phải là taker hay không
builder_code_addressstring?Ví builder code (nếu có)
builder_code_feestring?Phí builder code. Trả về null trong thời gian phí sàn giai đoạn ra mắt bị tắt
instrument_typestring"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ậtCác trường ngoài timestamp
Initialpositions
PositionUpdateposition
BalanceUpdatetotal_margin_used
MarginUpdatespan_margin, margin_summary, margin_mode, total_margin_used, available_balance
GreeksUpdateper_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ườngMô tả
previous_state, new_statehealthy, pre_liquidation, in_liquidation hoặc liquidated
liquidation_modepartial, full, hoặc null khi không có quy trình thanh lý nào đang hoạt động
margin_modestandard hoặc portfolio
equityVốn chủ sở hữu của tài khoản
mm_requiredYêu cầu ký quỹ duy trì
maintenance_marginVốn chủ sở hữu trừ đi yêu cầu ký quỹ duy trì
shortfallSố tiền tài khoản đang thiếu so với ký quỹ duy trì
partial_liquidationTiế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_liquidationChi 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ườngKiểuMô tả
pricesarrayMảng các mục {underlying, price, timestamp} cho từng tài sản cơ sở được theo dõi
prices[].underlyingstringSymbol tài sản cơ sở (ví dụ: "BTC", "ETH")
prices[].pricestringGiá giao ngay/giá chỉ số hiện tại tính bằng USD
prices[].timestampintegerThờ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
timestampintegerThờ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ườngKiểuMô tả
instrumentstringSymbol quyền chọn
best_bidstringGiá mua tổng hợp tốt nhất, tùy chọn
best_askstringGiá bán tổng hợp tốt nhất, tùy chọn
bid_ivnumberBiến động ngụ ý của giá mua tốt nhất, tùy chọn
ask_ivnumberBiến động ngụ ý của giá bán tốt nhất, tùy chọn
indicative_bid_sizestringTổng khối lượng mua trên các nhà cung cấp, tùy chọn
indicative_ask_sizestringTổng khối lượng bán trên các nhà cung cấp, tùy chọn
num_providersintegerSố nhà cung cấp báo giá đang hoạt động
rfq_provider_quotesarrayBá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_atintegerThờ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
timestampintegerThờ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ườngKiểuMô tả
flushed_atintegerThờ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
updatesarrayCá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ườngKiểuMô tả
messagestringMô tả dễ đọc
codestringLý do ổn định, tùy chọn. unknown_channel: một Subscribe đã chỉ định kênh không tồn tại
channelstringTù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(())
}