본문 바로가기
트레이딩/암호화폐

bybit. API. WebSocket 서버 3개 동시 접속 파이썬 코드.

by 리치굿맨 2020. 10. 31.

 

개요 

- bybit 의 USD 종목용 websocket 서버 1개와 , USDT 종목용 websocket 서버 2개에 동시 접속 파이썬 코딩.  

 

작동방식.

1. 파이썬 코드 실행되면 파일 apikey_url_bybit.txt 를 읽어서 접속서버주소와 api key, secret 값들을 읽어들이고, 

2. 이후 asyncio 로 동시에 3개의 서버 접속 실행되게 한다.  

3. 각각의 서버 핸들링 하는 loop 함수 내에서 보안접속  

4. 종목들 각각의 체결정보 실시간 요청 송신하며, while 문내에서 실시간 수신 데이터 출력한다.

 

asyncio  로 동시 3개의 웹소켓 구동 핵심 코드. 

 

myy_loop.run_until_complete(asyncio.gather(*[my_loop_WebSocket_bybit(),my_loop_WebSocket_usdt_private_bybit(),my_loop_WebSocket_usdt_public_bybit()]));

 

 

 

 

실행모습. 

 

 

 

 

 

 

연관 

- 아래 링크 1, 2, 3, 4 순서대로 읽어오면 본 글의 코드 쉽게 이해됨. 

 

1. 

 

암호화폐. API. bybit. 실시간 시세수신. WebSocket. Python

개요. - 암호화폐 거래소 바이빗 에서 제공하는 WebSocket 기반 실시간 시세수신(= 실시간 체결 틱 데이터) 파이썬 코드. 코드. - Python 실행 영상. 코드 구현 요점 설명. 코드에서 함수 websocket.send('{"op

igotit.tistory.com

 

 

2. 

 

bybit. API. 보안접속 코드 . 파이썬

개요 - 암호화폐 거래소 bybit API 이용하여 접속시 api key, secrete 로 보안접속 파이썬 코드. - 이전 작업했던 파이썬 코드 에서 아래 코드 추가한다. 즉, 접속첫자리에서 본인의 보안정보 송신하면

igotit.tistory.com

 

3. 

 

bybit. API. 서버 주소 정리. 파이썬에서 파일 읽기 처리.

개요 - 암호화폐 거래소 바이빗 API 에서 접속하는 서버 주소 정리. - API 이용하는 파이썬 코드에서 주소와 api 키와 시크릿 키를 저장해두고 파이썬 실행시 파일에 있는 값을 읽어들여 처리하기. b

igotit.tistory.com

 

4.

- asyncio 에서 2개 이상의 코루틴 실행.

 

Python. asyncio. 비동기 모듈.

Python asyncio 모듈. - event loop 에서 실행할 것들을 schedule(등록) 하고 작업들을 실행, 취소, 일시 중지 가능. - 파이썬 3.4 부터 첫배포, 버전에 따라 기능 추가. - 파이썬 3.6 에서의 기능 상태. - - asyn..

igotit.tistory.com

 


첫 등록 : 2020.10.31

최종 수정 : 

단축 주소 : https://igotit.tistory.com/2676

 


 

댓글11

  • Mirai 2022.01.31 20:19

    안녕하세요. 글 잘 읽었습니다. 언제나 도움 받고 있네요. 질문 하나 해도 될까요? 실시간으로 들어오는 데이터를 프린트 구문이 아닌, 전역변수로 옮기려는데, 상당히 애를 먹고 있네요. 혹시 도움될만한 내용이 있을까요? 구글링해도 답을 찾을 수가 없네요.
    답글

  • 코인봇 2022.02.11 18:20

    안녕하세요, bybit api 작성에 많은 도움이 됐습니다.
    혹시 USDT PERPETUAL 수신을 위해
    '{"op":"subscribe","args":["candle.1.ETHUSDT", "trade.ETHUSDT"]}'
    를 수신 중인데요,
    bybit 웹페이지의 candle차트와 제가 수신하는 캔들데이터의 값에 차이가 있는 거 같아서요..
    그리고 recent trades 화면의 데이터랑 제가 수신하는 trade.ETHISDT 의 데이터에도 차이가 있네요..

    혹시 websocket으로 수신하는 데이터가 bybit 웹페이지의 제공 데이터랑 조금 다른 것인가요?
    혹시 이런 문제 겪어 보셨는지 문의 드립니다.
    답글

    • Favicon of https://igotit.tistory.com BlogIcon 리치굿맨 2022.02.11 20:57 신고

      개발 초기 시점에 혹시나 싶어 점검했었는데요, 웹소켓으로 수신되는 trade 데이터는 웹페이지 에서 보이는 trade 데이터와 완전히 일치하였습니다.

      현재 코인봇님 작업중인 코드에서 오류 야기하는 원인지점 추정하기로는...


      data_rcv_strjson = await ws_usdt_public.recv();

      위와 같이 확보되는 data_rcv_strjson 에 있는 "data" 리스트 요소 수가 1개가 아닌 여러개의 요소가 있을 수 있기 때문에 필수 data 의 요소 수량 체크하여 모든 요소를 다 받아야 누락없는 데이터 확보가능합니다.

      처리코드 예제.
      data_rcv_strjason = await websocket.recv();
      data_rcv_dict = json.loads(data_rcv_strjason); # convert to Pyhton type dict data_trade_list = data_rcv_dict.get('data',0);
      num_data_trade_list = len(data_trade_list); print("Num List : " + str(num_data_trade_list));

      for data_trade_dict in data_trade_list : ## variable number of element(dictionary) in List per one packet. print("timestamp : " + data_trade_dict.get('timestamp',0) + ", price : " + str(data_trade_dict.get('price',0)) + ", size : " + str(data_trade_dict.get('size',0)) );

      위 코드는 댓글로는 알아보기 힘들테니.. https://igotit.tistory.com/2490 의 코드라인 17~26 부분입니다. 핵심은 "data" 에 있는 리스트 요소 수량 구하고 요소 수량 만큼 루프돌면서 각각의 요소마다 필요한 데이터 항목들을 모두 확보합니다.


  • 코인봇 2022.02.12 13:23

    네 빠른 답변 감사합니다.
    말씀하신대로 리스트 요소수가 1개가 아닌 여러개였네요. 저는 리스트[0] 으로 첫번째 데이터만 가져와서 누락이 있었던 것 같습니다.
    하지만 이와 별개로 여전히 숫자는 맞지 않네요..
    ETHUSDT 혹시 확인 한번만 부탁 드려도 될까요?
    저는 약 2달러 정도 계속 차이나는 상태입니다. 제가 출력한 숫자가 현재시간 기준으로 앞뒤 몇분 안에도 없는것을 보면 다른 데이터를 가져오는 것이 아닌가 의문도 듭니다.

    혹시 websocket url 의 차이일지.. 웹페이지에서 쓰는 url과 api에서 사용하는 url의 차이?
    (저는 wss://stream-testnet.bybit.com/realtime_public 를 사용했습니다.)

    혹은 서버시간의 차이? 한국시간과 웹페이지의 시간 차이로 인한? 이런 이유들은 혹시 없을지요?

    저도 출신이 개발자가 아닌지라 미천한 질문이어서 죄송합니다..ㅜㅜ
    답글

    • Favicon of https://igotit.tistory.com BlogIcon 리치굿맨 2022.02.12 21:53 신고

      네 좀전에 USDT 무기한 종목 ETHUSDT 와 바이비트 웹에서의 ETHUSDT 가격을 비교해봤습니다. 완전히 동일한 수치임을 확인했습니다. 사용된 코드는 https://igotit.tistory.com/2490 의 뒷부분에 소제목 "USDT 무기한 종목 실시간 시세 받기 " 에 추가해뒀습니다. 이코드를 이용하여 시험 해보시면......

      ======

      헐.............. 답글 달다가 코인봇님의 글을 다시 보니 코인봇님이 접속한 서버 주소가 모의 서버인 testnet 인데요? .... 겪고있는 문제 일으킨 핵심 원인지점입니다.

      testnet 은 실 거래서버와는 완전히 분리되어 따로 운영되고 testnet 의 시세도 실제 거래소 시세가 아닌 testnet 내부적으로만 이뤄지는 거래데이터 입니다.

      따라서 정식 거래 데이터를 보여주는 웹과는 전혀 다른 별개의 데이터 입니다.



      웹소켓 접속 주소를 wss://stream.bybit.com/realtime_public
      으로 수정하여 데이터 수신해보면 웹에서의 데이터와 완전히 일치하는 걸 확인 가능합니다. ~~


      기타.
      testnet 은 기본적인 코드의 오류 점검 정도로만 활용하고, 이후 매매로직 수익 검토 위한 시험용에서는 testnet 아닌 실매매 서버에서 하는게 타당합니다. 실전 시험과정중 손실이 생겨도 괜찮을 정도의 최소금액으로 진입하면 전혀 부담되지도 않아요.. 실전 소액 시험 방식으로 하는게 훨씬 개발 속도가 향상될겁니다.

  • 코인봇 2022.02.13 17:23

    와 맞네요... test-net......
    아 어쩐지... 정말 감사합니다~!!!

    (왜 bybit api 사이트에는 test-net으로 나와있는지... 나쁜..bybit)
    이제 완전 똑같이 나오네요!!!
    답글

  • 수퍼싸이어인 2022.03.11 02:13

    안녕하세요 매일 트레이딩을 하는 java 개발자입니다. 항상 좋은 정보 감사합니다.
    궁금한게 있는데요, 실시간으로 손절 및 익절 가를 정하는 로직을 구현하고 싶어서 여쭈어 봅니다.
    현재의 포지션(진입가)를 기준으로 상승분에 해당하는 스탑로스와 익절가를 실시간으로 반영하고 싶은데
    포지션유무 또는 진입가를 알기 위해선 private 웹소켓을 이용하여야 하고, 현재가에 대한 데이터는 public 을 이용해야하는데
    두가지를 비동기 방식으로 웹소켓 구독을 해놓고 실시간으로 서로의 데이터를 비교할 수는 있나요??
    아직 파이썬을 시작한지는 일주일도 되지가 않지만 업무가 바빠서 시간이 많이 나지 않는다는 핑계로
    염치불구하고 여쭈어 봅니다.
    제 생각으로는 실시간 시세정보를 얻을 수 있는 public 웹소켓에서 현재의 포지션 및 SL/TP의 정보를 가져오는 rest 동기함수를 호출해야 하는건지
    아니면 public 및 private 정보에 대한 비동기 방식 데이터구독에서도 서로다른 비동기 함수에서 얻어지는 데이터를 비교할 수 있는
    방법이 있는것인지가 너무 궁굼합니다.
    답글

    • Favicon of https://igotit.tistory.com BlogIcon 리치굿맨 2022.03.11 18:14 신고

      질문1
      포지션유무 또는 진입가를 알기 위해선 private 웹소켓을 이용하여야 하고, 현재가에 대한 데이터는 public 을 이용해야하는데
      두가지를 비동기 방식으로 웹소켓 구독을 해놓고 실시간으로 서로의 데이터를 비교할 수는 있나요??
      ..
      public 및 private 정보에 대한 비동기 방식 데이터구독에서도 서로다른 비동기 함수에서 얻어지는 데이터를 비교할 수 있는 방법.

      답변1.
      네 웹소켓은 가격이든, 포지션이든 변경된 정보를 가장 빠르게 확보할 수 있는 수단입니다. 매매로직은 아래 예처럼 항상 내 계좌 상태에 따른 조건문으로 구현될것입니다 . 그리고 아래 함수가 호출되는 시점은 웹소켓으로 포지션 변경시, 가격 변동시 모두 호출하는 식으로 구현될것입니다.

      if (정보1. 청산대상 포지션 있다면) {
      if(정보2. 웹소켓으로 수신된 실시간 가격 > 내
      포지션 가격 ) {
      청산주문 함수 호출
      }
      }

      위 조건문에서의 정보1 과 정보2 각각이 서로다른 비동기 웹소켓으로 수신되는 정보여도 각각의 웹소켓 수신 처리부에서 필요한 정보 추출하여 정보1, 정보2에 요구되는 변수들에 값을 기록하면 됩니다.
      결론 : 2개의 웹소켓이 비동기라는 점이 매매로직 진행에 문제를 일으키지는 않습니다.
      추가 : 자바 개발자이시니 스레드 충돌 류 같은 문제를 미리 걱정하시는것 같기도 한데요.. 파이썬이 이상한게(아니 장점) 대충 뭘 구현해도 문제없이 잘 작동한다능..C++ 에서는 별짓을 다해야 달성되는게 파이썬에서는 머이래 그냥되냐? 이런 경우가 많더라구요. ^^

      질문2.
      제 생각으로는 실시간 시세정보를 얻을 수 있는 public 웹소켓에서 현재의 포지션 및 SL/TP의 정보를 가져오는 rest 동기함수를 호출해야 하는건지

      답변2.
      실시간 시세정보는 거래소의 체결틱 정보이기 때문에 수신되는 빈도가 너무 빠르기도 하고 불규칙적인 시간격으로 수신됩니다. rest 요청은 실시간 웹소켓보다는 파이썬에서 일정시간되면 반복하는 루틴을 만들고 이곳에서 호출하는게 더 편하게 코딩 가능합니다. 파이썬에서 일정시간 반복 구현 코드 상세 : https://igotit.tistory.com/2917

      반복하는 주기는 매매로직상 적당한 선으로 정해주면 됩니다. 5초 마다 반복하면서 rest 요청해도 되고요, 느린 매매 로직이라면 1시간마다 반복해도 되고요. 임의 선택하여 요청가능합니다.

      기타.
      웹소켓은 매매로직 구현시 필수는 아닙니다. 느리게 진행해도 되는 매매로직에서는 웹소켓 사용하지 않고 전적으로 rest 만으로도 매매로직 모두 구현됩니다.

      웹소켓이 필연적으로 사용되는 경우로 가장 대표적인 상황이 아래와 같은 요구사항이 있을때 입니다. 대부분이 초단타류들입니다.

      상황예 .
      1. 주문 걸어둔 것들이 체결되면 "즉시" 다른 주문 제출해야 하는 경우.

      2. 2개 종목이상 짧은시간(수초이내) 발생하는 불균형 감시 하면서 즉시 매매 해야하는 경우. 즉 수초 짜리 차익거래시에는 필연적으로 웹소켓 기반으로 구현됩니다.

      통상 실시간 기반으로 구현시 작업 부하가 높다보니 상기 상황예가 아닌 경우에는 가능하면 rest 기반으로 먼저 구현하시길 추천합니다.

  • 수퍼싸이어인 2022.03.12 07:34

    답변 감사합니다.
    질문 1번의 경우 제가 생각했던 실행계획에 의한 데이터 오차 또는 스레드에 의한 오류 발생에 대해 쓸데 없었던 걱정을 한방에 날려주시는 답변이었습니다. 감사합니다. (내공이 역시...)

    손매매를 떠나서 이걸 시스템화 할 수 있을까 라는 생각은 10년도 더 전에 했는데 이렇게 도전하고 계속 공부하고 연구하시는 분이 계시다니 대단하신거 같습니다. 자주 올께요~ 좋은 글 많이 올려주세요!
    답글


.    
현물 |선물 인버스 |선물 USDT     현물 | 선물 USDT |봇제작툴/카피트레이딩     현물 |선물 인버스 |선물 USDT     .