WebSocket API v1 명령줄 클라이언트 (Python)

최종 업데이트: 2025년 4월 1일

다음 Python 코드는 Kraken의 거래소 WebSocket API v1용 명령줄 API 클라이언트를 구현합니다. 이 코드는 독립형 API 클라이언트로 사용하거나 다른 인터프리터 또는 컴파일된 프로그래밍 언어(Bash, C++ 등)에서 호출할 수 있습니다.

WebSocket 네트워킹에는 표준 Python WebSocket 라이브러리(websocket-client)가 필요하지만, 다른 API 라이브러리/모듈은 필요하지 않습니다.

WebSocket API 명령줄 클라이언트는 krakenws.py로도 다운로드할 수 있습니다.

모든 공개 시장 데이터 피드(ticker, book, spread, ohlc, trade), 비공개 계정 관리 피드(openOrdersownTrades), 그리고 거래 엔드포인트(addOrder, cancelOrder, cancelAll)가 지원됩니다.

비공개 피드/엔드포인트의 경우, REST API GetWebSocketsToken 엔드포인트에서 토큰을 검색한 다음, 토큰 값을 WS_Token이라는 텍스트 파일(명령줄 API 클라이언트와 동일한 디렉터리/폴더에)에 복사/붙여넣기하여 WebSocket 인증 토큰을 제공해야 합니다.

사용법

  • krakenws.py feed/endpoint [parameters]

  • ./krakenws.py ticker XBT/USD ETH/EUR XDG/XBT

  • ./krakenws.py book ETH/USD 10

  • ./krakenws.py ohlc LTC/EUR XBT/USD 60

  • ./krakenws.py openOrders

  • ./krakenws.py ownTrades

  • ./krakenws.py addOrder pair=XBT/USD type=buy ordertype=market volume=0.002 leverage=5

  • ./krakenws.py cancelOrder txid=O6L3CW-FD5CZ-NE373X

WebSocket API v1 명령줄 클라이언트의 사용법은 다음과 같습니다.

Python 코드

#!/usr/bin/env python

# Kraken WebSocket API
#
# Usage: ./krakenws.py feed/endpoint [parameters]
# Example: ./krakenws.py ticker XBT/USD
# Example: ./krakenws.py spread XBT/USD XBT/EUR ETH/USD LTC/EUR
# Example: ./krakenws.py book XBT/USD XBT/EUR 10
# Example: ./krakenws.py openOrders
# Example: ./krakenws.py ownTrades
# Example: ./krakenws.py addOrder pair=XBT/EUR type=sell ordertype=limit price=7500 volume=0.125
# Example: ./krakenws.py cancelOrder txid=OADMSD-7AGC3-IMB46A,OD6VRE-HCSPM-CKORER
#
# For account management and trading, a valid WebSocket authentication token (from the REST API GetWebSocketsToken endpoint) must be provided in a plain text file named WS_Token.

import sys
import signal
from websocket import create_connection

def timeoutfunction(signalnumber, frame):
raise KeyboardInterrupt

signal.signal(signal.SIGALRM, timeoutfunction)

api_status = {"ping"}
api_public = {"trade", "book", "ticker", "spread", "ohlc"}
api_private = {"openOrders", "ownTrades", "balances"}
api_trading = {"addOrder", "editOrder", "cancelOrder", "cancelAll", "cancelAllOrdersAfter"}
api_domain_public = "wss://ws.kraken.com/"
api_domain_private = "wss://ws-auth.kraken.com/"
api_symbols = ""
api_number = 0

if len(sys.argv) < 2:
api_feed = "ping"
else:
api_feed = sys.argv[1]

if api_feed in api_status:
api_domain = api_domain_public
api_data = '{"event":"%(feed)s"}' % {"feed":api_feed}
signal.alarm(3)
elif api_feed in api_public:
if len(sys.argv) < 3:
print("Usage: %s feed/endpoint [parameters]" % sys.argv[0])
print("Example: %s ticker XBT/USD" % sys.argv[0])
sys.exit(1)
for count in range(2, len(sys.argv)):
if sys.argv[count].isdecimal() == True:
api_number = int(sys.argv[count])
else:
if len(api_symbols) == 0:
api_symbols += sys.argv[count].upper()
else:
api_symbols += '","' + sys.argv[count].upper()
if api_feed == 'book':
api_data = '{"event":"subscribe", "subscription":{"name":"%(feed)s", "depth":%(depth)d}, "pair":["%(symbols)s"]}' % {"feed":api_feed, "symbols":api_symbols, "depth":api_number if api_number != 0 else 10}
elif api_feed == 'ohlc':
api_data = '{"event":"subscribe", "subscription":{"name":"%(feed)s", "interval":%(interval)d}, "pair":["%(symbols)s"]}' % {"feed":api_feed, "symbols":api_symbols, "interval":api_number if api_number != 0 else 1}
else:
api_data = '{"event":"subscribe", "subscription":{"name":"%(feed)s"}, "pair":["%(symbols)s"]}' % {"feed":api_feed, "symbols":api_symbols}
api_domain = api_domain_public
elif api_feed in api_private:
api_domain = api_domain_private
try:
api_token = open("WS_Token").read().strip()
except:
print("WebSocket authentication token missing (WS_Token)")
sys.exit(1)
if len(sys.argv) >= 3:
if api_feed == 'openOrders':
api_data = '{"event":"subscribe", "subscription":{"name":"%(feed)s", "ratecounter":%(ratecounter)s, "token":"%(token)s"}}' % {"feed":api_feed, "ratecounter":sys.argv[2].split('=')[1], "token":api_token}
elif api_feed == 'ownTrades':
api_data = '{"event":"subscribe", "subscription":{"name":"%(feed)s", "snapshot":%(snapshot)s, "token":"%(token)s"}}' % {"feed":api_feed, "snapshot":sys.argv[2].split('=')[1], "token":api_token}
else:
api_data = '{"event":"subscribe", "subscription":{"name":"%(feed)s", "token":"%(token)s"}}' % {"feed":api_feed, "token":api_token}
else:
api_data = '{"event":"subscribe", "subscription":{"name":"%(feed)s", "token":"%(token)s"}}' % {"feed":api_feed, "token":api_token}
elif api_feed in api_trading:
api_domain = api_domain_private
try:
api_token = open("WS_Token").read().strip()
except:
print("WebSocket authentication token missing (WS_Token)")
sys.exit(1)
api_data = '{"event":"%(feed)s", "token":"%(token)s"' % {"feed":api_feed, "token":api_token}
for count in range(2, len(sys.argv)):
if sys.argv[count].split('=')[0] == 'txid':
api_data = api_data + ', "%(name)s":["%(value)s"]' % {"name":sys.argv[count].split('=')[0], "value":sys.argv[count].split('=')[1].replace(',', '","')}
elif sys.argv[count].split('=')[0] == 'reqid':
api_data = api_data + ', "%(name)s":%(value)s' % {"name":sys.argv[count].split('=')[0], "value":sys.argv[count].split('=')[1]}
elif sys.argv[count].split('=')[0] == 'timeout':
api_data = api_data + ', "%(name)s":%(value)s' % {"name":sys.argv[count].split('=')[0], "value":sys.argv[count].split('=')[1]}
else:
api_data = api_data + ', "%(name)s":"%(value)s"' % {"name":sys.argv[count].split('=')[0], "value":sys.argv[count].split('=')[1]}
api_data = api_data + '}'
signal.alarm(3)
else:
print("Usage: %s feed/endpoint [parameters]" % sys.argv[0])
print("Example: %s ticker XBT/USD" % sys.argv[0])
sys.exit(1)

try:
ws = create_connection(api_domain)
print("WebSocket -> Client: %s" % ws.recv())
except Exception as error:
print("WebSocket connection failed (%s)" % error)
sys.exit(1)

try:
print("Client -> WebSocket: %s" % api_data)
ws.send(api_data)
print("WebSocket -> Client: %s" % ws.recv())
except Exception as error:
print("WebSocket subscription/request failed (%s)" % error)
ws.close()
sys.exit(1)

while True:
try:
print("WebSocket -> Client: %s" % ws.recv())
except KeyboardInterrupt:
ws.close()
sys.exit(0)
except Exception as error:
print("WebSocket messages failed (%s)" % error)
sys.exit(1)

sys.exit(1)

더 많은 도움이 필요하신가요?