2026.9 には Kraken に関する4つの独立した不具合の修正が入りました。どれもコードを一度読んだだけで気づける種類のものではありません。それぞれが特定の条件下でしか現れません。接続時に誤ったエンドポイントを使ってしまう、リクエストの本文がマシンの外に一度も出ていかない、再接続が数百ミリ秒早すぎるタイミングで起きてしまう、といった具合です。4つとも修正済みですが、いずれも理解しておく価値があります。というのも、それぞれの失敗の様子が、まったく別の問題であるかのように見えるからです。
スポットクライアントが v2 エンドポイントに v1 を話していた問題
TsgcWSAPI_Kraken は v1 スキーマを組み立て、解析します。event、pair、subscription、subscriptionStatus、systemStatus です。このスキーマには理由があり、このコンポーネント上のすべての subscribe 呼び出しとすべてのイベントハンドラーは、それを前提として書かれています。ところが接続先のエンドポイントは、既定で Kraken の v2 WebSocket になっており、そちらはまったく異なるスキーマ、method、params、channel、type を話します。接続自体はエラーなく開きました。ただ、subscription の確認応答や status イベントが一つも生成されませんでした。サーバーが、クライアントが決して解析しない形で応答していたからです。
Kraken.Version は既定で 1 になり、コンポーネントは対応する v1 エンドポイントを選ぶようになりました。
uses
sgcWebSocket, sgcWebSocket_APIs;
var
oKraken: TsgcWSAPI_Kraken;
begin
oKraken := TsgcWSAPI_Kraken.Create(nil);
oKraken.Client := oClient;
// Version defaults to 1, matching the event/pair/subscription
// schema this component already builds and parses.
oKraken.Kraken.Version := 1;
oClient.Active := True;
oKraken.SubscribeTicker('XBT/USD');
end;
もしあなたのアプリケーションが、この古い、黙って誤っていた既定値に何らかの形で依存していたとしても、それはそもそも v1 イベントを一度も受信できていなかったということを意味するので、今日時点で維持すべき「動いているもの」は何もありません。Kraken.Version := 2 を明示的に設定すれば、これまでどおり v2 エンドポイントに接続され、RawMessages を有効にしたうえで OnKrakenData または OnMessage でペイロードを扱う形になります。意図的にそちらのスキーマ向けに開発している方のためのものです。
Futures の注文が GET として送信され、本文が破棄されていた問題
こちらはより静かで、より深刻な問題です。Kraken Futures REST クライアント上のすべてのプライベートリクエスト、つまり注文の送信、編集、キャンセル、送金、出金が、すべて HTTP の GET として送出されていました。署名済みのリクエスト本文は正しく組み立てられ、計算され、整形され、送信できる状態になっていましたが、そのまま破棄されていました。GET リクエストには本文を入れる場所がないからです。Kraken はパラメーターのない GET を受け取り、それを拒否するか無視していました。これらの呼び出しは一つとして機能していませんでした。
uses
sgcHTTP_API_Kraken;
var
oKraken: TsgcHTTP_API_Kraken_Futures_Rest;
oOrder: TsgcHTTPKrakenFuturesOrder;
begin
oKraken := TsgcHTTP_API_Kraken_Futures_Rest.Create(nil);
oKraken.KrakenOptions.ApiKey := 'your_api_key';
oKraken.KrakenOptions.ApiSecret := 'your_api_secret';
oOrder := TsgcHTTPKrakenFuturesOrder.Create;
try
oOrder.OrderType := kotfLMT;
oOrder.Symbol := 'PF_XBTUSD';
oOrder.Side := kosfBuy;
oOrder.Size := 1;
oOrder.LimitPrice := 30000;
// SendOrder now posts through DoHTTP_POST_PRIVATE, body included.
ShowMessage(oKraken.SendOrder(oOrder));
finally
oOrder.Free;
end;
end;
SendOrder、EditOrderByOrderId、EditOrderByCliOrderId、CancelOrderByOrderId、CancelOrderByCliOrderId、Transfer、WithdrawalToSpotWallet は、いずれもプライベート POST の経路を通るようになり、署名済みの本文が実際にリクエストへ添付されるようになりました。
再接続時にプライベートサブスクリプションが失われる問題
WatchDog が再接続し、ログにはきれいな再接続が記録され、そしてその時点から orders、balance、fills の各チャンネルが単純に消えてしまいます。エラーは何も出ません。ログにも何も残りません。再接続自体は成功していたので、見た目には完全に成功したように見えます。実際に起きていたのは、切断前に発行されていたプライベートサブスクリプションだけが、その後一度も再送されなかったということです。これは Kraken のスポットと Futures の両方に影響し、同じ修正で対応した他のいくつかの取引所クライアントにも影響していました。現在では、再接続後に公開マーケットデータのサブスクリプションをすでに復元している経路と同じ、標準の resubscribe replay の一部になっています。
Futures がセッションの認証完了前に resubscribe していた問題
これと密接に関連する、Kraken Futures 特有の不具合もありました。再接続後、有効なサブスクリプションの replay が、認証ハンドシェイクが実際に完了する前に実行されてしまうことがありました。subscribe リクエストは、Kraken がまだ認証していないセッション上で送出されるため、プライベートなものは拒否されますが、ここでもクライアント側には理由を示すものが何もありません。現在では、replay は認証が完了するのを待ってから resubscribe するようになりました。
アップグレード
4つの修正はすべてドロップインであり、移行が必要な API はありません。唯一注意すべき挙動の変化は、Kraken.Version の既定値が、これまでの実質的に機能していなかった値から 1 へ切り替わったことです。すでにコードで Version := 2 を明示的に設定している場合は、何も変わりません。
ご質問やフィードバック、移行のお手伝いが必要ですか?お問い合わせください — コードを書いた本人から返信が届きます。
