APIリファレンス
リアルタイムのシグナルをご自身のシステムに組み込めます。APIは読み取り専用です:市場データを提供するだけで、注文を出したり取引所アカウントに触れたりすることはありません。VIP Quantに含まれます。ターミナルが初めての方は、まずドキュメントをご覧ください。
ベースURL:
https://api.arbitragex.io
認証
設定でキーを作成してください。キーは一度だけ表示され、ハッシュとしてのみ保存されるため、安全に保管し、ブラウザには絶対に置かないでください。紛失したキーは復元できません:無効化して新しいキーを作成してください。1ユーザーあたり最大5キーです。WebSocketのアップグレードを含むすべてのリクエストで、X-API-Keyヘッダーに含めて送信してください。
curl -H "X-API-Key: $ARBITRAGEX_KEY" https://api.arbitragex.io/v1/opportunities
import os, requests
rows = requests.get(
"https://api.arbitragex.io/v1/opportunities",
headers={"X-API-Key": os.environ["ARBITRAGEX_KEY"]},
timeout=5,
).json()["rows"]
for row in rows[:5]:
print(row["coin"], row["buy"]["venue"], row["sell"]["venue"], row["netUsd"]["1000"])const res = await fetch("https://api.arbitragex.io/v1/opportunities", {
headers: { "X-API-Key": process.env.ARBITRAGEX_KEY },
});
const { rows } = await res.json();
for (const row of rows.slice(0, 5)) {
console.log(row.coin, row.buy.venue, row.sell.venue, row.netUsd["1000"]);
}無効化したキーは数秒以内に使えなくなり、開いているソケットもその後すぐに閉じられます。キーはプランの終了とともに停止し、プランが復活すれば再び有効になります。
レート制限
各キーには個別の上限があり、既定では1分あたり120リクエスト(1分単位のウィンドウで計測)、さらに同時ソケット3つです。すべてのレスポンスで現在の状況がわかります:
X-RateLimit-Limit:ウィンドウあたりの許可リクエスト数。X-RateLimit-Remaining:このウィンドウの残りリクエスト数。X-RateLimit-Reset:ウィンドウ終了までの秒数。
リアルタイムの行にはWebSocketをおすすめします。変更を発生と同時にプッシュし、1つのソケットは開いた後は上限にカウントされません。
エラー
エラーはJSONです: { "error": "Rate limit reached." }
- 401:キーが誤っている、無効化されている、またはプランが終了しています。
- 405:APIはGETのみ受け付けます。
- 429:レート制限またはソケット上限に達しました。
Retry-Afterの秒数だけお待ちください。 - 503:現在キーを確認できません。しばらくしてから再試行してください。
OpenAPI
API全体は、固定のアドレスにある1つのOpenAPI 3.1ドキュメントに記述されています。Postman、Insomnia、Swagger UIにインポートしたり、型付きクライアントを生成したりできます。そこに含まれるすべてのエンドポイントには、以下のcurl、Python、JavaScriptの例が付いています。
https://arbitragex.io/openapi.json
# A typed client, for example: npx openapi-typescript https://arbitragex.io/openapi.json -o arbitragex.d.ts openapi-python-client generate --url https://arbitragex.io/openapi.json
エンドポイントリファレンス
OpenAPIドキュメントから生成した、すべてのRESTエンドポイントです。各例はキーをARBITRAGEX_KEY環境変数から読み取ります。
- /v1/opportunities Live opportunities
- /v1/listings New listings
- /v1/notices Exchange notices
- /v1/funding Funding rates
- /v1/funding/history Funding history
- /v1/premiums Regional premiums
- /v1/markets Volume and open interest
- /v1/fees Taker fees
- /v1/reliability Venue reliability
- /v1/spread/{id} A route's spread over time
- /v1/proof Proof Log
- /v1/events Prediction market routes
- /v1/events/proof Prediction market Proof Log
- /v1/events/markets Prediction market browser
- /v1/events/history A market's odds over time
- /v1/events/holders A Polymarket market's holders and big bets
get/v1/opportunitiesLive opportunities
Every route on the feed right now, as the plan sees it. Reading it often is fine; the stream is better past a few times a minute.
strategyquery: `all`, the default, or one trade type.
curl
curl -s -H "X-API-Key: $ARBITRAGEX_KEY" "https://api.arbitragex.io/v1/opportunities"
Python
import os
import requests
res = requests.get(
"https://api.arbitragex.io/v1/opportunities",
headers={"X-API-Key": os.environ["ARBITRAGEX_KEY"]},
timeout=10,
)
res.raise_for_status()
data = res.json()
for row in data["rows"][:5]:
print(row["coin"], row["buy"]["venue"], row["sell"]["venue"], row["netBps"])JavaScript
const res = await fetch("https://api.arbitragex.io/v1/opportunities", {
headers: { "X-API-Key": process.env.ARBITRAGEX_KEY },
});
if (!res.ok) throw new Error((await res.json()).error);
const data = await res.json();
for (const row of data.rows.slice(0, 5)) console.log(row.coin, row.buy.venue, row.sell.venue, row.netBps);get/v1/listingsNew listings
Markets first seen in the last 72 hours, newest first, and listings exchanges have announced but don't list yet.
curl
curl -s -H "X-API-Key: $ARBITRAGEX_KEY" "https://api.arbitragex.io/v1/listings"
Python
import os
import requests
res = requests.get(
"https://api.arbitragex.io/v1/listings",
headers={"X-API-Key": os.environ["ARBITRAGEX_KEY"]},
timeout=10,
)
res.raise_for_status()
data = res.json()
for row in data["rows"]:
print(row["venue"], row["kind"], row["coin"])JavaScript
const res = await fetch("https://api.arbitragex.io/v1/listings", {
headers: { "X-API-Key": process.env.ARBITRAGEX_KEY },
});
if (!res.ok) throw new Error((await res.json()).error);
const data = await res.json();
for (const row of data.rows) console.log(row.venue, row.kind, row.coin);get/v1/noticesExchange notices
Delistings, deposit and withdrawal suspensions, maintenance and announced listings still in effect, newest first. The same for every plan.
curl
curl -s -H "X-API-Key: $ARBITRAGEX_KEY" "https://api.arbitragex.io/v1/notices"
Python
import os
import requests
res = requests.get(
"https://api.arbitragex.io/v1/notices",
headers={"X-API-Key": os.environ["ARBITRAGEX_KEY"]},
timeout=10,
)
res.raise_for_status()
data = res.json()
for row in data["rows"]:
print(row["venue"], row["kind"], row["coins"], row["title"])JavaScript
const res = await fetch("https://api.arbitragex.io/v1/notices", {
headers: { "X-API-Key": process.env.ARBITRAGEX_KEY },
});
if (!res.ok) throw new Error((await res.json()).error);
const data = await res.json();
for (const row of data.rows) console.log(row.venue, row.kind, row.coins, row.title);get/v1/fundingFunding rates
Every perp's current funding rate, per interval and annualised.
curl
curl -s -H "X-API-Key: $ARBITRAGEX_KEY" "https://api.arbitragex.io/v1/funding"
Python
import os
import requests
res = requests.get(
"https://api.arbitragex.io/v1/funding",
headers={"X-API-Key": os.environ["ARBITRAGEX_KEY"]},
timeout=10,
)
res.raise_for_status()
data = res.json()
top = sorted(data["rows"], key=lambda r: -abs(r["aprPct"]))[:5]
for row in top:
print(row["coin"], row["venue"], row["aprPct"])JavaScript
const res = await fetch("https://api.arbitragex.io/v1/funding", {
headers: { "X-API-Key": process.env.ARBITRAGEX_KEY },
});
if (!res.ok) throw new Error((await res.json()).error);
const data = await res.json();
const top = [...data.rows].sort((a, b) => Math.abs(b.aprPct) - Math.abs(a.aprPct)).slice(0, 5);
for (const row of top) console.log(row.coin, row.venue, row.aprPct);get/v1/funding/historyFunding history
One coin's funding settlements over the last 30 days, oldest first. A gap is never filled in.
coinquery, 必須: The coin, in any case.
curl
curl -s -H "X-API-Key: $ARBITRAGEX_KEY" "https://api.arbitragex.io/v1/funding/history?coin=BTC"
Python
import os
import requests
res = requests.get(
"https://api.arbitragex.io/v1/funding/history?coin=BTC",
headers={"X-API-Key": os.environ["ARBITRAGEX_KEY"]},
timeout=10,
)
res.raise_for_status()
data = res.json()
for row in data["rows"]:
print(row["venue"], len(row["points"]), "settlements")JavaScript
const res = await fetch("https://api.arbitragex.io/v1/funding/history?coin=BTC", {
headers: { "X-API-Key": process.env.ARBITRAGEX_KEY },
});
if (!res.ok) throw new Error((await res.json()).error);
const data = await res.json();
for (const row of data.rows) console.log(row.venue, row.points.length, "settlements");get/v1/premiumsRegional premiums
Each coin's premium in each local currency over the middle USDT price on order book venues, priced through each venue's own USDT book, with each currency's index and its 24 hours of 5-minute means. With coin, that coin's rows only, each with its own 24 hours.
coinquery: One coin, in any case.
curl
curl -s -H "X-API-Key: $ARBITRAGEX_KEY" "https://api.arbitragex.io/v1/premiums"
Python
import os
import requests
res = requests.get(
"https://api.arbitragex.io/v1/premiums",
headers={"X-API-Key": os.environ["ARBITRAGEX_KEY"]},
timeout=10,
)
res.raise_for_status()
data = res.json()
for row in data["rows"][:5]:
print(row["coin"], row["fiat"], row["premiumBps"], row["verified"])JavaScript
const res = await fetch("https://api.arbitragex.io/v1/premiums", {
headers: { "X-API-Key": process.env.ARBITRAGEX_KEY },
});
if (!res.ok) throw new Error((await res.json()).error);
const data = await res.json();
for (const row of data.rows.slice(0, 5)) console.log(row.coin, row.fiat, row.premiumBps, row.verified);get/v1/marketsVolume and open interest
One row per market, busiest first, as arrays: [venue, kind, coin, symbol, volumeUsd, oiUsd]. Null where the venue publishes no figure.
curl
curl -s -H "X-API-Key: $ARBITRAGEX_KEY" "https://api.arbitragex.io/v1/markets"
Python
import os
import requests
res = requests.get(
"https://api.arbitragex.io/v1/markets",
headers={"X-API-Key": os.environ["ARBITRAGEX_KEY"]},
timeout=10,
)
res.raise_for_status()
data = res.json()
for venue, kind, coin, symbol, volume, oi in data["rows"][:5]:
print(venue, kind, symbol, volume, oi)JavaScript
const res = await fetch("https://api.arbitragex.io/v1/markets", {
headers: { "X-API-Key": process.env.ARBITRAGEX_KEY },
});
if (!res.ok) throw new Error((await res.json()).error);
const data = await res.json();
for (const [venue, kind, , symbol, volume, oi] of data.rows.slice(0, 5)) console.log(venue, kind, symbol, volume, oi);get/v1/feesTaker fees
Each venue's published base taker fee, the rate net figures are priced at. Re-price a route at your own fees with the formula on /docs/api#fees.
curl
curl -s -H "X-API-Key: $ARBITRAGEX_KEY" "https://api.arbitragex.io/v1/fees"
Python
import os
import requests
res = requests.get(
"https://api.arbitragex.io/v1/fees",
headers={"X-API-Key": os.environ["ARBITRAGEX_KEY"]},
timeout=10,
)
res.raise_for_status()
data = res.json()
for row in data["rows"]:
print(row["venue"], row["spotTakerBps"], row["perpTakerBps"])JavaScript
const res = await fetch("https://api.arbitragex.io/v1/fees", {
headers: { "X-API-Key": process.env.ARBITRAGEX_KEY },
});
if (!res.ok) throw new Error((await res.json()).error);
const data = await res.json();
for (const row of data.rows) console.log(row.venue, row.spotTakerBps, row.perpTakerBps);get/v1/reliabilityVenue reliability
Each venue's track record over the last 7 and 30 UTC days, from watched time only: uptime, outages, how fresh its prices were, the share of its routes that lasted 30 seconds, and wallet list changes. A figure with too little behind it is null, never a guess.
curl
curl -s -H "X-API-Key: $ARBITRAGEX_KEY" "https://api.arbitragex.io/v1/reliability"
Python
import os
import requests
res = requests.get(
"https://api.arbitragex.io/v1/reliability",
headers={"X-API-Key": os.environ["ARBITRAGEX_KEY"]},
timeout=10,
)
res.raise_for_status()
data = res.json()
for row in data["rows"][:5]:
print(row["venue"], row["online"], row["uptime7d"], row["heldShare30d"])JavaScript
const res = await fetch("https://api.arbitragex.io/v1/reliability", {
headers: { "X-API-Key": process.env.ARBITRAGEX_KEY },
});
if (!res.ok) throw new Error((await res.json()).error);
const data = await res.json();
for (const row of data.rows.slice(0, 5)) console.log(row.venue, row.online, row.uptime7d, row.heldShare30d);get/v1/spread/{id}A route's spread over time
Net bps over time for one route. Without a range, the latest row, up to 72 points. With `from` or `to`, every row in that stretch, at most 2,000 points, keeping the peaks.
idpath, 必須: A route id, URL-encoded.fromquery: Earliest point, unix ms.toquery: Latest point, unix ms.
curl
curl -s -H "X-API-Key: $ARBITRAGEX_KEY" "https://api.arbitragex.io/v1/spread/BTC%7CBinance%3Aspot%7COKX%3Aperp"
Python
import os
import requests
res = requests.get(
"https://api.arbitragex.io/v1/spread/BTC%7CBinance%3Aspot%7COKX%3Aperp",
headers={"X-API-Key": os.environ["ARBITRAGEX_KEY"]},
timeout=10,
)
res.raise_for_status()
data = res.json()
print(len(data["points"]), "points, peak", max((p["netBps"] for p in data["points"]), default=None))JavaScript
const res = await fetch("https://api.arbitragex.io/v1/spread/BTC%7CBinance%3Aspot%7COKX%3Aperp", {
headers: { "X-API-Key": process.env.ARBITRAGEX_KEY },
});
if (!res.ok) throw new Error((await res.json()).error);
const data = await res.json();
console.log(data.points.length, "points, peak", Math.max(...data.points.map((p) => p.netBps)));get/v1/proofProof Log
Closed opportunities that lasted at least 30 seconds, newest first, with a cursor for the next page.
limitquery: Rows per page, 50 by default, at most 500.fromquery: Earliest close, unix ms.toquery: Latest close, unix ms.coinquery: One coin, exact in any case.cursorquery: `next` from the previous page.
curl
curl -s -H "X-API-Key: $ARBITRAGEX_KEY" "https://api.arbitragex.io/v1/proof?limit=100"
Python
import os
import requests
res = requests.get(
"https://api.arbitragex.io/v1/proof?limit=100",
headers={"X-API-Key": os.environ["ARBITRAGEX_KEY"]},
timeout=10,
)
res.raise_for_status()
data = res.json()
for row in data["rows"][:5]:
print(row["coin"], row["buyVenue"], row["sellVenue"], row["peakNetBps"])
print("next page:", data["next"])JavaScript
const res = await fetch("https://api.arbitragex.io/v1/proof?limit=100", {
headers: { "X-API-Key": process.env.ARBITRAGEX_KEY },
});
if (!res.ok) throw new Error((await res.json()).error);
const data = await res.json();
for (const row of data.rows.slice(0, 5)) console.log(row.coin, row.buyVenue, row.sellVenue, row.peakNetBps);
console.log("next page:", data.next);get/v1/eventsPrediction market routes
Sets of contracts on Polymarket, Polymarket US and Kalshi that cost less after fees than the $1 they pay at settlement, best net first, as the plan sees them. Every `cross` route is Caution: each exchange settles by its own rules, attached in `rules`.
kindquery: `all`, the default, or one route kind.
curl
curl -s -H "X-API-Key: $ARBITRAGEX_KEY" "https://api.arbitragex.io/v1/events"
Python
import os
import requests
res = requests.get(
"https://api.arbitragex.io/v1/events",
headers={"X-API-Key": os.environ["ARBITRAGEX_KEY"]},
timeout=10,
)
res.raise_for_status()
data = res.json()
for row in data["rows"][:5]:
print(row["kind"], row["title"], row["netBps"], row["days"])JavaScript
const res = await fetch("https://api.arbitragex.io/v1/events", {
headers: { "X-API-Key": process.env.ARBITRAGEX_KEY },
});
if (!res.ok) throw new Error((await res.json()).error);
const data = await res.json();
for (const row of data.rows.slice(0, 5)) console.log(row.kind, row.title, row.netBps, row.days);get/v1/events/proofPrediction market Proof Log
Prediction market routes that ended after lasting at least 30 seconds, newest first, with a cursor for the next page. Kept a year.
limitquery: Rows per page, 50 by default, at most 500.fromquery: Earliest close, unix ms.toquery: Latest close, unix ms.kindquery: `all`, the default, or one route kind.cursorquery: `next` from the previous page.
curl
curl -s -H "X-API-Key: $ARBITRAGEX_KEY" "https://api.arbitragex.io/v1/events/proof?limit=100"
Python
import os
import requests
res = requests.get(
"https://api.arbitragex.io/v1/events/proof?limit=100",
headers={"X-API-Key": os.environ["ARBITRAGEX_KEY"]},
timeout=10,
)
res.raise_for_status()
data = res.json()
for row in data["rows"][:5]:
print(row["kind"], row["title"], row["venues"], row["peakNetBps"])
print("next page:", data["next"])JavaScript
const res = await fetch("https://api.arbitragex.io/v1/events/proof?limit=100", {
headers: { "X-API-Key": process.env.ARBITRAGEX_KEY },
});
if (!res.ok) throw new Error((await res.json()).error);
const data = await res.json();
for (const row of data.rows.slice(0, 5)) console.log(row.kind, row.title, row.venues, row.peakNetBps);
console.log("next page:", data.next);get/v1/events/marketsPrediction market browser
Every open market on Polymarket, Polymarket US and Kalshi, routes or not, joined into events so each venue's odds for the same outcome stand side by side. Odds are YES's probability, 0 to 1. With `group`, one event whole; with `markets`, the events holding those markets. Live on every plan.
qquery: Every word in the title, outcomes or questions. At most 100 characters.categoryquery: One category.venuequery: Events on this venue.daysquery: An outcome resolving within this many days.sortquery: `volume`, the default, `closing` or `movers`.limitquery: Rows per page, 25 by default, at most 50.cursorquery: `next` from the previous page.groupquery: One event's id, for all its outcomes.marketsquery: Up to 50 `<venue>|<market id>`, comma separated.
curl
curl -s -H "X-API-Key: $ARBITRAGEX_KEY" "https://api.arbitragex.io/v1/events/markets?category=crypto&sort=closing"
Python
import os
import requests
res = requests.get(
"https://api.arbitragex.io/v1/events/markets?category=crypto&sort=closing",
headers={"X-API-Key": os.environ["ARBITRAGEX_KEY"]},
timeout=10,
)
res.raise_for_status()
data = res.json()
for row in data["rows"][:5]:
print(row["title"], [(q["venue"], q["prob"]) for q in row["lines"][0]["quotes"]])JavaScript
const res = await fetch("https://api.arbitragex.io/v1/events/markets?category=crypto&sort=closing", {
headers: { "X-API-Key": process.env.ARBITRAGEX_KEY },
});
if (!res.ok) throw new Error((await res.json()).error);
const data = await res.json();
for (const row of data.rows.slice(0, 5)) console.log(row.title, row.lines[0].quotes.map((q) => [q.venue, q.prob]));get/v1/events/historyA market's odds over time
YES's probability over a day, week or month, oldest first: from the venue where it keeps a history, else sampled by us.
venuequery, 必須: The market's venue.marketquery, 必須: The market id, as in a quote's `marketId`.rangequery: `1d`, `1w` or `1m`.
curl
curl -s -H "X-API-Key: $ARBITRAGEX_KEY" "https://api.arbitragex.io/v1/events/history"
Python
import os
import requests
res = requests.get(
"https://api.arbitragex.io/v1/events/history",
headers={"X-API-Key": os.environ["ARBITRAGEX_KEY"]},
timeout=10,
)
res.raise_for_status()
data = res.json()
print(len(data["points"]), "points from", data["source"])JavaScript
const res = await fetch("https://api.arbitragex.io/v1/events/history", {
headers: { "X-API-Key": process.env.ARBITRAGEX_KEY },
});
if (!res.ok) throw new Error((await res.json()).error);
const data = await res.json();
console.log(data.points.length, "points from", data.source);get/v1/events/holdersA Polymarket market's holders and big bets
The top 10 holders of each outcome and the latest 20 bets of $1,000 or more, as Polymarket's public data states them.
marketquery, 必須: Polymarket's condition id.
curl
curl -s -H "X-API-Key: $ARBITRAGEX_KEY" "https://api.arbitragex.io/v1/events/holders"
Python
import os
import requests
res = requests.get(
"https://api.arbitragex.io/v1/events/holders",
headers={"X-API-Key": os.environ["ARBITRAGEX_KEY"]},
timeout=10,
)
res.raise_for_status()
data = res.json()
for h in data["holders"][:5]:
print(h["side"], h["name"] or h["address"], h["shares"])JavaScript
const res = await fetch("https://api.arbitragex.io/v1/events/holders", {
headers: { "X-API-Key": process.env.ARBITRAGEX_KEY },
});
if (!res.ok) throw new Error((await res.json()).error);
const data = await res.json();
for (const h of data.holders.slice(0, 5)) console.log(h.side, h.name ?? h.address, h.shares);機会
GET /v1/opportunitiesは、すべてのリアルタイムの行を純利益の高い順に返します。
{
"rows": [
{
"id": "BTC|Binance:spot|OKX:perp",
"coin": "BTC",
"strategy": "spot_perp",
"buy": { "venue": "Binance", "kind": "spot", "symbol": "BTCUSDT", "price": 68250.1,
"sizeUsd": 41200, "ageMs": 120, "fundingBps8h": null, "url": "https://..." },
"sell": { "venue": "OKX", "kind": "perp", "symbol": "BTC-USDT-SWAP", "price": 68310.4,
"sizeUsd": 38900, "ageMs": 240, "fundingBps8h": 1.2, "url": "https://..." },
"grossBps": 8.8,
"netBps": 2.1,
"netUsd": { "100": 0.2, "1000": 2.1, "10000": 19.4, "100000": null, "1000000": null },
"maxSizeUsd": 21400,
"exitBps": 6.2,
"transfer": "not_needed",
"network": null,
"status": "verified",
"reasons": [],
"firstSeenMs": 1793570209670,
"updatedMs": 1793570229670,
"spark": [2.0, 2.1]
}
],
"delayedMs": 0
}資金調達率
GET /v1/fundingは、すべての無期限の現在の資金調達率を返します。
{ "rows": [ { "coin": "BTC", "venue": "Binance", "symbol": "BTCUSDT", "ratePct": 0.01,
"hours": 8, "aprPct": 10.95, "nextFundingMs": 1793577600000 } ] }手数料
GET /v1/feesは、各取引所の公表テイカー手数料を約定ごとのbpsで返します。純利益は基本料率を使用します。サイズSでご自身の手数料による純利益を算出するには:
{ "rows": [ { "venue": "Binance", "spotTakerBps": 10, "perpTakerBps": 5 } ] }
fills = 1 if strategy == "spot" else 2 # a hedged route pays again to close
shift = fills * ((paid_buy - mine) + (paid_sell - mine) * (1 + grossBps / 10000))
net = netUsd[S] + S * shift / 10000スプレッド
GET /v1/spread/:idは、ルートの純スプレッドを返します。開いている間はリアルタイム、終了後は保存された値です。idはURLエンコードしてください。fromまたはtoをunixミリ秒で追加すると、その範囲で保存されたすべての履歴からルートを取得できます:最大2,000点、古い順、ピークを保持。
curl -H "X-API-Key: $ARBITRAGEX_KEY" \
"https://api.arbitragex.io/v1/spread/BTC%7CBinance%3Aspot%7COKX%3Aperp"
{ "points": [ { "t": 1793570209670, "netBps": 2.1 } ], "historyFromMs": 0 }Proof Log
GET /v1/proof?limit=50は、30秒以上続いた終了済みの機会を新しい順に返します。limitは最大500です。5分以内に再び現れたルートは最後の行を延長するため、行が先頭に戻ることがあります。
from、to:unixミリ秒で、行が終了した時刻に対して指定します。coin:1つのコイン。cursor:前のページのnextの値。最後のページではnextはnullです。
{ "rows": [ { "id": "BTC|Binance:spot|OKX:perp", "coin": "BTC", "strategy": "spot_perp",
"buyVenue": "Binance", "sellVenue": "OKX", "peakNetBps": 4.2, "maxSizeUsd": 21400,
"openNetBps": 3.8, "openSizeUsd": 18200, "closeNetBps": 1.1, "closeSizeUsd": 9600,
"status": "verified", "openedMs": 1793570209670, "closedMs": 1793570389670 } ],
"next": "1793570389670:48121", "historyFromMs": 0 }WebSocket
X-API-Keyヘッダーにキーを入れてwss://api.arbitragex.io/v1/streamに接続してください。まずすべての行のsnapshotを受け取り、その後最短250 ms間隔でバッチを受け取ります。約4秒以上遅れたクライアントは切断され、再接続時に新しいスナップショットを受け取ります。
import WebSocket from "ws";
const rows = new Map();
function connect() {
const socket = new WebSocket("wss://api.arbitragex.io/v1/stream", {
headers: { "X-API-Key": process.env.ARBITRAGEX_KEY },
});
socket.on("message", (data) => {
const message = JSON.parse(data);
if (message.type === "snapshot") {
rows.clear();
for (const row of message.rows) rows.set(row.id, row);
}
if (message.type === "upsert") for (const row of message.rows) rows.set(row.id, row);
if (message.type === "remove") for (const id of message.ids) rows.delete(id);
});
socket.on("close", () => setTimeout(connect, 1000));
}
connect();snapshot:{ type, rows, delayedMs }、常に最初。upsert:{ type, rows }、新規または変更された行、1バッチ最大400件。remove:{ type, ids }、消えた行。health:{ type, venues, medianLatencyMs }、5秒ごと。
型
strategy:spot、spot_perp、またはperp_perp。status:verifiedまたはcaution。理由はreasonsにわかりやすい言葉で入ります。transfer:open、unknown、またはnot_needed。netUsd:各サイズでの推定利益。nullは板が約定できないことを意味します。netBps:$1,000でのコスト差し引き後の値。$1,000で損失になる場合は、最も利益の出るサイズでの値。- 時刻はunixミリ秒です。価格はコイン1枚あたりのUSDTです。
純利益は推定値であり、約定ではありません。純利益の計算方法をご覧ください。自動化したものについては、お客様の責任となります。