API나 웹소켓을 다룰 때 주문, 계좌 정보와 같이
개인정보에 해당하는 내용을 다룰땐 API키가 필요합니다.
API키 발급 방법은 바이낸스 API키 발급 참조
import requests
import asyncio
import websockets
import json
with open("D:/코인/binance key.txt") as f:
lines = f.readlines()
api_key = lines[0].strip()
secret_key = lines[1].strip()
headers = {
"X-MBX-APIKEY": api_key,
}
FUTURES_STREAM_END_POINT_1 = "wss://fstream.binance.com"
BINANCE_FUTURES_END_POINT = "https://fapi.binance.com/fapi/v1/listenKey"
def create_futures_listen_key():
response = requests.post(url=BINANCE_FUTURES_END_POINT, headers=headers)
return response.json()['listenKey']
listen_key = create_futures_listen_key()
async def UserDataStream():
uri = f"{FUTURES_STREAM_END_POINT_1}/ws/{listen_key}"
async with websockets.connect(uri) as websocket:
try:
while True:
data = json.loads(await websocket.recv())
print(data)
except asyncio.CancelledError:
print("UserDataStream 작업이 취소되었습니다.")
except Exception as e:
print(f"UserDataStream 예외가 발생했습니다: {e}")
finally:
print("UserDataStream 웹소켓 연결을 종료합니다.")
await websocket.close()
async def ping_listen_key():
while True:
await asyncio.sleep(1800) # 30분 간격으로 ping 전송
response = requests.put(url=BINANCE_FUTURES_END_POINT, headers=headers)
if response.status_code == 200:
print('Ping sent successfully')
else:
print('Failed to send ping')
async def main():
tasks = [
asyncio.ensure_future(UserDataStream()),
asyncio.ensure_future(ping_listen_key())
]
try:
await asyncio.gather(*tasks)
except asyncio.CancelledError:
print("메인 작업이 취소되었습니다.")
for task in tasks:
task.cancel()
await asyncio.gather(*tasks, return_exceptions=True)
except Exception as e:
print(f"예외가 발생했습니다: {e}")
finally:
print("메인 작업이 종료되었습니다.")
if __name__ == '__main__':
try:
asyncio.run(main())
except KeyboardInterrupt:
print("프로그램을 종료합니다.")
참조.
Python을 사용한 스트리밍 바이낸스 주문 업데이트 | by 쿠쿠 카밀 | 코인몽크스 | 보통 (medium.com)
User Data Streams – Binance API Documentation (binance-docs.github.io)
공식 설명에도 나와있듯이 60분이 지나면 연결이 자동 종료됩니다.
그래서 ping_listen_ket()함수에서 1800초(30분)에 한번씩
재연결을 하도록 설계되어 있습니다.
주문을 넣을 때 해당 웹소켓으로 전달받는 데이터입니다.
{"e":"ORDER_TRADE_UPDATE", #이벤트 타입
"T":1686517295922, # 시간
"E":1686517295926, # 이벤트 시간
"o":{"s":"ETHUSDT", # 종목
"S":"BUY", # 주문 타입
"o":"LIMIT", # 지정가. 시장가는 MARKET
"q":"0.020", # 주문 수량
"p":"1700", # 주문 가격
"ap":"0", # 해당 주문이 체결된 평균 가격. 전체 포지션의 평단가가 아님
"x":"NEW", # 주문 유형, NEW는 새 주문 입력, TRADE는 주문 체결
"X":"NEW", # 주문 상태, NEW는 새 주문 입력, FILLED는 체결 완료
"i":8389765602604928560, # 주문 id
"ps":"LONG", # 포지션 방향
...
'rp': '-0.05000000' # 실현손익. 포지션 정리 주문 외엔 기본적으로 0
}}
위의 데이터에서 주로 사용하는 것은 's', 'q', 'p' 입니다.
어떤 코인을 몇개씩, 얼마에 주문 넣었는지 알 수 있습니다.
( data['o']['s'], data['o']['q'], data['o']['p'] )
포지션 정리 주문을 넣을 때 실현손익은 'rp' 입니다.
( data['o']['rp'] )
선물은 롱, 숏 양방향입니다.
Long, Buy는 롱 포지션 진입.
Long, Sell은 롱 포지션 정리.
Short, Sell은 숏 포지션 진입.
Short, buy는 숏 포지션 정리.
데이터들은 전부 문자열 형태로 되어 있기 때문에
숫자로 사용하기 위해선 형변환을 해야합니다.
float( data['o']['q'] )
data['o']['s']는 코인 이름이기 때문에 숫자로 형변환을 하면 안됩니다.
주문이 체결되는 등의 이벤트로 계좌에 변동에 생기면
다음의 데이터를 전달받게 됩니다.
{"e":"ACCOUNT_UPDATE",
"T":1686518836619,
"E":1686518836631,
"a":{
"B" : [ { "a":"USDT", # 현금. 정확히는 USDT 스테이블 코인
"wb":"146.84106420", # 지갑 잔액
"cw":"146.84106420", # 교차 지갑 잔액
"bc":"0"}],
"P" : [ { "s":"ETHUSDT", # 보유 코인
"pa":"0.010", # 보유 수량. short일 경우 "-0.010"으로 표기됨
"ep":"1769.00000000", # 평단가
"cr":"28.50606903", # 누적 실현 손익
"up":"0.00190000", # 미실현 손익
...
"ps":"LONG", # 포지션 방향
"ma":"USDT" } ],
"m":"ORDER"}}
여기에서 가장 많이 쓰이는 것은 지갑 잔액, 보유 코인, 수량, 평단가 네가지입니다.
( data['a']['B'][0]['wb'], data['a']['P'][0]['s'], data['a']['P'][0]['pa'], data['a']['P'][0]['ep'] )
마찬가지로 잔고, 수량, 평단가는 float으로 형변환을 해줘야 합니다.
'파이썬 > 바이낸스 선물 웹소켓' 카테고리의 다른 글
[선물 WS] 1분, 20분 상승 순위 실시간 출력하기 (0) | 2024.12.08 |
---|---|
[선물 WS] 실시간 체결 확인하기 (0) | 2024.12.01 |
[선물 WS] 호가창 일부분 실시간 (0) | 2024.12.01 |
[선물 WS] 전체 시장 청산 주문 금액 1분마다 확인하기 (0) | 2024.11.24 |
[선물 WS] 차트 데이터 실시간으로 받기 (Kline Stream) (0) | 2023.06.18 |