什麼是套利:10 分鐘做出你的第一個掃描器

套利課程第 1 課。認識套利的意思、價格落差為何存在,以及用十行 Python 寫出的掃描器,比較同一枚幣在兩間交易所的最佳買價和最佳賣價。

課程「套利:從零到自己的掃描器」第 1 課。你不需要交易經驗,只需要 Python 和十分鐘。

用鉛筆舉個例子

想像同一條街上有兩間店。A 店賣一雙運動鞋要 100 美元。B 店願意向任何人用 108 美元買同一雙鞋。你在 A 店買鞋,走二十公尺到 B 店賣掉,留下 8 美元。你沒有賭運動鞋會不會變得更受歡迎。你只需要發現兩個價格不一樣。

這就是套利:在便宜的地方買進某樣東西,同一時間在昂貴的地方賣出同樣的東西,保留中間的差額。

這句話有兩個重點:

  • 「同樣的東西」:兩間店的那雙運動鞋完全相同;
  • 「同一時間」:如果等一週,價格可能改變,價差也可能消失。

為什麼會有價差?

在加密貨幣交易所,每秒都有數千人和程式買賣 Bitcoin。每間交易所有自己的使用者群,所以各自的價格會有一點不同。新聞傳到各處的時間略有差異,資金在交易所之間移動也很慢。因此,同一枚幣在兩間交易所的價格幾乎相同,但很少完全一樣。

持續觀察這些價差並把它們消除的程式,正是價差維持很小的原因。今天你會做出這類程式的一個很小版本。

必須認識的兩個詞:買價與賣價

交易所會保留一份委託清單。想買的人會說自己願意用什麼價格買;想賣的人會說自己願意用什麼價格賣。

  • **買價(bid)**是此刻有人願意為這枚幣支付的最高價格。
  • **賣價(ask)**是此刻有人願意賣出這枚幣的最低價格。

如果你想立刻買進,就要付賣價。如果你想立刻賣出,就會收到買價。同一間交易所的賣價一定高於買價。兩者之間的距離叫做買賣價差,是交易本身內建的成本。

用數字看一個小例子:

買價(你在這裡賣)賣價(你在這裡買)
交易所 A100.00100.10
交易所 B100.30100.40

在 A 以它的賣價 100.10 買進。在 B 以它的買價 100.30 賣出。每枚幣的價差是 100.30 − 100.10 = 0.20。交易 1000 枚幣,手續費前就是 200。

現在反過來:在 B 以 100.40 買進,在 A 以 100.00 賣出。每枚幣會虧 0.40。因此,就算有價差,也只會出現在一個方向。

一行規則:

Gap = bid where you sell − ask where you buy.

如果價差是正數,就值得進一步看看。如果是零或負數,就沒有機會。

寫程式前的三個誠實提醒

  1. 手續費。每間交易所都會從每筆交易收取一小部分比例。價格 100 的 0.20 價差是 0.2%。如果兩邊手續費加起來也是 0.2%,利潤就是零。後面的課會仔細介紹手續費。
  2. 數量。最佳買價與最佳賣價只對少量的幣是真實可成交的。如果你想交易更多,就會「吃掉」後面價格較差的委託。第 9 和第 10 課會談這件事。
  3. 速度。等你看到價差時,別人可能已經把它消除了。第 11 課會談這件事。

今天的程式像一支溫度計:它顯示是否有價差,卻不表示你能不能靠它賺錢。

迷你掃描器

這個掃描器刻意採用直接做的版本:每間交易所一個請求、做一次減法、不計手續費、不看數量、沒有錯誤處理。它是最簡單可運作的東西,也會以後面課程將指出的方式出錯(第 4 課的手續費、第 9 課的委託簿深度、第 11 課的時間差)。先做這個簡單直接的版本,之後的每個修正才是在解決你已經看見的問題。

這支程式向兩間交易所詢問同一枚幣的最佳買價和最佳賣價,並印出兩個方向的價差。它只使用公開資料,不需要帳戶、API 金鑰或資金。

import json
import urllib.request

def get(url):
    with urllib.request.urlopen(url, timeout=10) as r:
        return json.load(r)

# 交易所 A:Binance,幣對 BTC / USDT
a = get("https://api.binance.com/api/v3/ticker/bookTicker?symbol=BTCUSDT")
a_bid, a_ask = float(a["bidPrice"]), float(a["askPrice"])

# 交易所 B:Kraken,同一枚幣
b = get("https://api.kraken.com/0/public/Ticker?pair=XBTUSDT")
b = next(iter(b["result"].values()))
b_bid, b_ask = float(b["b"][0]), float(b["a"][0])

print("A bid/ask:", a_bid, a_ask)
print("B bid/ask:", b_bid, b_ask)
print("buy A, sell B:", round(b_bid - a_ask, 2))
print("buy B, sell A:", round(a_bid - b_ask, 2))

把它存成 scanner.py,然後執行 python3 scanner.py。

應該看到什麼結果

你會看到四個價格和兩個數字。對兩間大型交易所的 Bitcoin 而言,這兩個數字通常都是負數或接近零。有時其中一個會是很小的正數。一次測試的買價和賣價,在一間交易所接近 75,782,在另一間接近 75,786,所以一個方向顯示 +3.89,另一個顯示 −4.00。正數的那個是 3.89 / 75,782 = 0.005%,遠低於大約 0.2% 的手續費。這很正常,也是最重要的一課:在流動性高的幣與交易所上,市場很有效率,足以支付手續費的大價差很少見,而且持續時間很短。

每隔一分鐘執行程式幾次,觀察兩個數字如何移動,記下你看到最大的那一個。

如果某個請求失敗,交易所可能封鎖了你的國家或網路。把它換成另一間提供公開價格端點的交易所,程式的架構不會改變。

讓 AI 代理人代替你打字

在這門課裡,你會和 Claude Code 或 Codex 這類 AI 代理人一起建立自己的套利機器人。代理人負責寫程式;你決定要做什麼,也檢查結果。檢查這件事不能交出去:代理人可能印出一個看來很有把握、其實錯誤的數字。

比較兩種為今天程式提出需求的方式。

一個模糊的要求:

幫我做一個套利掃描器。

代理人得猜所有事情:要用哪些交易所、哪一枚幣、「掃描器」要印出什麼、要不要計算手續費。它可能做出一個很大、你看不懂的東西。

一個明確說出需要內容的要求:

用 Python 寫 scanner.py,不要用額外函式庫。透過 Binance 與 Kraken 的公開 REST 端點取得 BTC/USDT 的最佳買價和最佳賣價。印出兩邊的報價,以及兩個方向的價差,計算方式是 bid_sell 減 ask_buy。不需要 API 金鑰,不要交易。程式保持在 40 行以內,把交易對放在檔案最上方。

有了這個要求,你可以自己檢查答案:每個方向的價差都必須是一個買價減一個賣價,也可以用計算機驗證。整門課都要保持這個習慣:要求一小段功能,執行它,手算一個數字,然後存下一個版本(git commit,或只複製一份檔案)。

你的練習

  1. 執行掃描器三次,每次記下四個價格和兩個價差。
  2. 把 BTCUSDT 和 XBTUSDT 改成兩間交易所都有上架的另一枚幣(例如 ETH)。價差比 Bitcoin 大還是小?交易較少的小型幣通常有更大的價差。想一想為什麼。
  3. 手算:把價差換成買入價的百分比,gap / ask * 100。和每間交易所 0.1%、合計 0.2% 的手續費比較。你的三次結果中,有任何一次高過這條線嗎?

接下來

今天你比較了兩個數字。真正的套利系統會對數千個交易對和許多交易所做同樣的事,接著仔細檢查最有希望的候選項目。第 2 課會介紹不同種類的套利,第 3 課會介紹每個系統都要經過的階段。