Forex API
メジャー、マイナー、エキゾチックを含む 50+ の通貨ペアに Tick レベルの相場情報を提供します。
1 つの WebSocket・REST API で、Tick レベルの Forex、Crypto、Stock、Commodity、Index データを配信します。営業担当との通話なしで、数秒で無料キーを取得できます。
| シンボル | 資産クラス | 価格 | 直近変動 |
|---|---|---|---|
| EUR/USD 外国為替ユーロ / 米ドル | 外国為替 | - | - |
| BTC/USDT 暗号資産ビットコイン | 暗号資産 | - | - |
| ETH/USDT 暗号資産イーサリアム | 暗号資産 | - | - |
| AAPL 株式Apple Inc. | 株式 | - | - |
| XAU/USD コモディティ金スポット | コモディティ | - | - |
| USD/JPY 外国為替米ドル / 円 | 外国為替 | - | - |
| NVDA 株式NVIDIA Corp. | 株式 | - | - |
| SPX 指数S&P 500 指数 | 指数 | - | - |
AllTick がカバーするすべての市場を、同じ統一 REST と WebSocket インターフェースから利用できます。
メジャー、マイナー、エキゾチックを含む 50+ の通貨ペアに Tick レベルの相場情報を提供します。
リアルタイムの現物・デリバティブデータを、1 つの配信に正規化します。
米国、香港、中国本土市場の株式について、約定と相場情報を提供します。
貴金属とエネルギーのリアルタイム価格を提供します。
主要なグローバル指数のベンチマーク値と構成銘柄を提供します。
AllTick の各市場について、対応範囲、レイテンシー、データ種別を比較します。
製品を見るAllTick と一般的な従来型市場データベンダーを比較します。
| 機能 | AllTick | 一般的な従来型ベンダー |
|---|---|---|
| WebSocket レイテンシー中央値 | 約 150ms | 400–800ms |
| 1 つの API に含まれる資産クラス | 5(FX、Crypto、Stock、Commodities、Indices) | 1–2 |
| 稼働率 SLA | 99.95% | 99.5% またはなし |
| 無料枠 | あり — API キーを即時発行 | 営業担当との通話が必要 |
| WebSocket ストリーミング | ネイティブ | ポーリング / 制限あり |
WebSocket に接続し、あらゆる市場の任意のシンボルを購読できます。
# AllTick realtime financial data API
# forex crypto stock commodities indices
import asyncio, json, uuid
import websockets
subscribe = {
"cmd_id": 22004,
"seq_id": 1,
"trace": str(uuid.uuid4()),
"data": {"symbol_list": [{"code": "EURUSD"}]},
}
heartbeat = {"cmd_id": 22000, "seq_id": 1, "trace": "heartbeat", "data": {}}
async def stream():
uri = "wss://quote.alltick.co/quote-b-ws-api?token=YOUR_API_KEY"
async with websockets.connect(uri) as socket:
await socket.send(json.dumps(subscribe))
async def keep_alive():
while True:
await asyncio.sleep(10)
await socket.send(json.dumps(heartbeat))
asyncio.create_task(keep_alive())
async for message in socket:
print(json.loads(message))
asyncio.run(stream())Crypto の対応範囲を広げながら、市場データコストを 60% 削減。
“AllTick への移行により、3 社のベンダーを 1 つの WebSocket 配信に統合し、取引アプリを 1 四半期早くリリースできました。”導入事例を読む
200ms 未満の相場情報更新で 4 万人の同時接続ユーザーに対応。
“99.95% SLA と安定したレイテンシーは、当社のリテールブローカーがグローバル展開するためにまさに必要なものでした。”導入事例を読む
5 資産クラスにわたる 12 年分の Tick データをバックテスト。
“1 つの正規化 API から履歴データとリアルタイムデータを取得でき、数週間分のデータエンジニアリング作業が不要になりました。”導入事例を読む
市場データエンジニアリング、ストリーミング API、低遅延金融アプリケーション構築に関する実践的な記事です。
注文マッチングエンジンは、あらゆる取引システムの中核を担う存在です。マッチングアルゴリズム、データ管理、通信インターフェースなど、いくつかの主要なコンポーネントから構成されています。その主な役割は、市場参加者の売買注文をマッチングし、取引を実行し、取引記録を生成することです。毎日膨大な流動性が金融市場を通じて移動していますが、このプロセスを効率的に実行するのが注文マッチングエンジンです。
注文マッチングエンジンがなければ、取引プラットフォーム(FX、商品、株式、CFDなど資産の種類を問わず)は実際の取引を成立させることができません。実際、取引システム内の他のすべてのモジュールは、注文マッチングエンジンを支えるために存在すると言っても過言ではありません。
注文マッチングという概念は、19世紀に遡ります。当時の取引はオープンアウトクライ方式によって手動で行われていました。ニューヨーク証券取引所(NYSE)のような取引所では、トレーダーたちが取引フロアで「買い」「売り」と大声で叫びながら注文を出し、取引を成立させていました。これは当時としては効果的な方法でした。
その後、電子技術の進歩により、市場は徐々に自動化されたシステムへと移行していきました。1971年には、NASDAQが世界初の電子注文マッチングエンジンを導入し、人ではなくコンピューターが取引の実行を担うようになりました。この革新により、スピード・効率性・拡張性が飛躍的に向上し、現代の電子取引の基盤が築かれました。
ステップ説明1. 注文の受信トレーダーは取引プラットフォームを通じて、価格・数量・注文の種類(成行または指値)などの詳細を含む売買注文を提出します。2. 注文のキュー化マッチングエンジンは、事前に定められたルール(通常は価格優先・次に時間優先)に従って注文をキューに並べます。3. 注文のマッチングエンジンは板情報をスキャンし、マッチする相手を探します。買い注文の価格が売り注文の価格以上であれば、取引が成立します。4. 取引の確認マッチングが成立すると、エンジンは取引を確認し、双方と清算システムに通知を送信します。
注文板(オーダーブック)は、注文マッチングエンジンにとって重要な構成要素であり、現在のすべての指値注文を追跡します。
注文板を適切に管理することは、市場の流動性を維持し、価格発見プロセスを支える上で不可欠です。市場状況の変化に応じて、注文板はリアルタイムで更新されなければなりません。
成行注文(マーケットオーダー)
指値注文(リミットオーダー)
以下は、現在の市場で広く使用されている3つの代表的な注文マッチングアルゴリズムと、それぞれの簡単な実装例です。
1. 価格・時間優先方式(FIFO)
これは現代の市場で最も一般的に使用されているアルゴリズムです。注文はまず価格によって優先順位が決まり(より有利な価格が先)、同一価格の場合は時間順(早く出された注文が先)で処理されます。
例:
→ 売り注文が500円で来た場合、注文Aが優先的にマッチングされます。
import heapq
class Order:
def __init__(self, order_id, order_type, price, quantity):
self.order_id = order_id
self.order_type = order_type # 'buy' or 'sell'
self.price = price
self.quantity = quantity
self.timestamp = None
def __lt__(self, other):
if self.order_type == 'buy':
# For buy orders, higher prices have priority; if prices are equal, earlier orders have priority
return (self.price, -self.timestamp) > (other.price, -other.timestamp)
else:
# For sell orders, lower prices have priority; if prices are equal, earlier orders have priority
return (self.price, self.timestamp) < (other.price, other.timestamp)
class OrderBook:
def __init__(self):
self.buy_orders = [] # Max-heap for buy orders (negative prices for max-heap)
self.sell_orders = [] # Min-heap for sell orders
self.timestamp_counter = 0
def add_order(self, order):
order.timestamp = self.timestamp_counter
self.timestamp_counter += 1
if order.order_type == 'buy':
heapq.heappush(self.buy_orders, order)
else:
heapq.heappush(self.sell_orders, order)
def match_orders(self):
matches = []
while self.buy_orders and self.sell_orders:
highest_buy_order = self.buy_orders[0]
lowest_sell_order = self.sell_orders[0]
if highest_buy_order.price >= lowest_sell_order.price:
quantity_to_trade = min(highest_buy_order.quantity, lowest_sell_order.quantity)
matches.append((highest_buy_order.order_id, lowest_sell_order.order_id, quantity_to_trade))
highest_buy_order.quantity -= quantity_to_trade
lowest_sell_order.quantity -= quantity_to_trade
if highest_buy_order.quantity == 0:
heapq.heappop(self.buy_orders)
if lowest_sell_order.quantity == 0:
heapq.heappop(self.sell_orders)
else:
break
return matches
# Example usage
order_book = OrderBook()
# Add some buy and sell orders
order_book.add_order(Order(1, 'buy', 101, 10))
order_book.add_order(Order(2, 'buy', 102, 5))
order_book.add_order(Order(3, 'sell', 100, 8))
order_book.add_order(Order(4, 'sell', 99, 10))
# Match orders
matches = order_book.match_orders()
for match in matches:
print(f"Matched Buy Order {match[0]} with Sell Order {match[1]} for {match[2]} units")
2. プロラタ(比例配分)方式
同一価格帯に複数の注文がある場合、注文サイズに応じて比例的にマッチングが行われます。より大きな注文には、より多くの数量が割り当てられます。この方式は先物取引所などでよく採用されています。
例:
→ 売り注文が500株 @ 1000円で出された場合、注文Aに150株、注文Bに350株が割り当てられます。
import heapq
from collections import defaultdict
class Order:
def __init__(self, order_id, order_type, price, quantity):
self.order_id = order_id
self.order_type = order_type # 'buy' or 'sell'
self.price = price
self.quantity = quantity
self.timestamp = None
class OrderBook:
def __init__(self):
self.buy_orders = defaultdict(list) # Buy orders grouped by price
self.sell_orders = defaultdict(list) # Sell orders grouped by price
self.timestamp_counter = 0
def add_order(self, order):
order.timestamp = self.timestamp_counter
self.timestamp_counter += 1
if order.order_type == 'buy':
self.buy_orders[order.price].append(order)
else:
self.sell_orders[order.price].append(order)
def match_orders(self):
matches = []
# Sort buy and sell prices
buy_prices = sorted(self.buy_orders.keys(), reverse=True)
sell_prices = sorted(self.sell_orders.keys())
while buy_prices and sell_prices:
highest_buy_price = buy_prices[0]
lowest_sell_price = sell_prices[0]
if highest_buy_price >= lowest_sell_price:
buy_orders_at_price = self.buy_orders[highest_buy_price]
sell_orders_at_price = self.sell_orders[lowest_sell_price]
# Calculate total buy and sell quantities at this price
total_buy_quantity = sum(order.quantity for order in buy_orders_at_price)
total_sell_quantity = sum(order.quantity for order in sell_orders_at_price)
# Determine the amount to trade based on the smaller side
quantity_to_trade = min(total_buy_quantity, total_sell_quantity)
# Pro-rata allocation for buy and sell orders
for order in buy_orders_at_price:
proportion = order.quantity / total_buy_quantity
traded_quantity = quantity_to_trade * proportion
matches.append((order.order_id, lowest_sell_price, traded_quantity))
order.quantity -= traded_quantity
for order in sell_orders_at_price:
proportion = order.quantity / total_sell_quantity traded_quantity = quantity_to_trade * proportion matches.append((order.order_id, highest_buy_price, traded_quantity)) order.quantity -= traded_quantity # Remove fully matched orders self.buy_orders[highest_buy_price] = [o for o in buy_orders_at_price if o.quantity > 0] self.sell_orders[lowest_sell_price] = [o for o in sell_orders_at_price if o.quantity > 0] if not self.buy_orders[highest_buy_price]: del self.buy_orders[highest_buy_price] buy_prices.pop(0) if not self.sell_orders[lowest_sell_price]: del self.sell_orders[lowest_sell_price] sell_prices.pop(0) else: break return matches# Example usageorder_book = OrderBook()# Add some buy and sell ordersorder_book.add_order(Order(1, 'buy', 100, 10))order_book.add_order(Order(2, 'buy', 100, 20))order_book.add_order(Order(3, 'sell', 100, 15))order_book.add_order(Order(4, 'sell', 100, 5))# Match ordersmatches = order_book.match_orders()for match in matches: print(f"Order {match[0]} matched at price {match[1]} for {match[2]:.2f} units")
3. ハイブリッド方式
価格・時間優先方式とプロラタ方式を組み合わせたアルゴリズムです。市場構造や参加者の行動に応じて、エンジンがマッチングロジックを動的に調整します。柔軟かつ公平性の高いソリューションを提供する目的で設計されています。
例:
import heapq
from collections import defaultdict
class Order:
def __init__(self, order_id, order_type, price, quantity):
self.order_id = order_id
self.order_type = order_type # 'buy' or 'sell'
self.price = price
self.quantity = quantity
self.timestamp = None
def __lt__(self, other):
return self.timestamp < other.timestamp
class OrderBook:
def __init__(self):
self.buy_orders = defaultdict(list) # Buy orders grouped by price
self.sell_orders = defaultdict(list) # Sell orders grouped by price
self.timestamp_counter = 0
def add_order(self, order):
order.timestamp = self.timestamp_counter
self.timestamp_counter += 1
if order.order_type == 'buy':
heapq.heappush(self.buy_orders[order.price], order)
else:
heapq.heappush(self.sell_orders[order.price], order)
def match_orders(self):
matches = []
# Sort buy and sell prices
buy_prices = sorted(self.buy_orders.keys(), reverse=True)
sell_prices = sorted(self.sell_orders.keys())
while buy_prices and sell_prices:
highest_buy_price = buy_prices[0]
lowest_sell_price = sell_prices[0]
if highest_buy_price >= lowest_sell_price:
buy_orders_at_price = self.buy_orders[highest_buy_price]
sell_orders_at_price = self.sell_orders[lowest_sell_price]
# Calculate total buy and sell quantities at this price
total_buy_quantity = sum(order.quantity for order in buy_orders_at_price)
total_sell_quantity = sum(order.quantity for order in sell_orders_at_price)
# Determine the amount to trade based on the smaller side
quantity_to_trade = min(total_buy_quantity, total_sell_quantity)
# Priority based matching and then pro-rata allocation
while quantity_to_trade > 0 and buy_orders_at_price and sell_orders_at_price:
buy_order = buy_orders_at_price[0]
sell_order = sell_orders_at_price[0]
if buy_order.quantity <= sell_order.quantity:
matches.append((buy_order.order_id, sell_order.order_id, buy_order.quantity)) sell_order.quantity -= buy_order.quantity quantity_to_trade -= buy_order.quantity heapq.heappop(buy_orders_at_price) if sell_order.quantity == 0: heapq.heappop(sell_orders_at_price) else: matches.append((buy_order.order_id, sell_order.order_id, sell_order.quantity)) buy_order.quantity -= sell_order.quantity quantity_to_trade -= sell_order.quantity heapq.heappop(sell_orders_at_price) if buy_order.quantity == 0: heapq.heappop(buy_orders_at_price) # Remove empty price levels if not buy_orders_at_price: del self.buy_orders[highest_buy_price] buy_prices.pop(0) if not sell_orders_at_price: del self.sell_orders[lowest_sell_price] sell_prices.pop(0) else: break return matches# Example usageorder_book = OrderBook()# Add some buy and sell ordersorder_book.add_order(Order(1, 'buy', 100, 15))order_book.add_order(Order(2, 'buy', 100, 25))order_book.add_order(Order(3, 'sell', 100, 30))order_book.add_order(Order(4, 'sell', 100, 10))# Match ordersmatches = order_book.match_orders()for match in matches: print(f"Buy Order {match[0]} matched with Sell Order {match[1]} for {match[2]:.2f} units")