돈벌고싶다

바이비트와 파이썬을 이용한 자동매매 프로그램 - 6. 투자 금액 자동화 본문

자동매매-바이비트

바이비트와 파이썬을 이용한 자동매매 프로그램 - 6. 투자 금액 자동화

coinwithpython 2022. 8. 4. 23:32
728x90
반응형

설명

여기서 투자 금액 자동화란 연산을 통해 포트폴리오를 생성하여 최적의 투자 금액을 찾아가는 것이 아닌, 바이비트 api에서 내가 포지션을 잡을 수 있는 코인 수량 크기를 계산하고 진입에 적용하는 것을 뜻한다.

 


코드

 

1. 라이브러리 호출

import pandas as pd
import numpy as np
import datetime
import calendar
import schedule
import math
import time
import math
from pybit import usdt_perpetual

 

2. 필요 함수 호출

def get_session(net='test'):
    if net == 'test':
        session = usdt_perpetual.HTTP(
            endpoint="https://api-testnet.bybit.com", 
            api_key='my_api_key', 
            api_secret='my_api_secret')
    elif net == 'main':
        session = usdt_perpetual.HTTP(
            endpoint="https://api.bybit.com", 
            api_key='my_api_key',
            api_secret='my_api_secret')
    return session
    
    
    def get_qty(session, symbol):
        # 슬리피지가 발생하기 때문에 -20을 하여 전체 자산의 99.9%에 대해서만 주문 가능하게 만듬
        usdt_balance = session.get_wallet_balance(coin='USDT')['result']['USDT']['available_balance'] - 20
        cur_price = session.public_trading_records(symbol=symbol,limit=1)['result'][0]['price']
        amount = math.floor((usdt_balance * 1000000)/cur_price) / 1000000
        return round(amount, 3)
  • get_session 함수 : API 연동을 위한 session을 불러오는 기능을 한다. 계정이 접속하여 wallet 정보를 받아와야 하기 때문에, api key 및 api 비밀번호가 모두 필요하다.
  • get_qty 함수 : 투자를 하고 있지 않는 동안은 보통 USDT로 자산을 보유한다. 하지만 포지션을 잡을 경우 수량 단위가 포지션을 잡는 코인이기 때문에, [ USDT - 거래 코인 ] 단위 변환을 해주어야 한다. get_qty는 변환을 해주는 함수이며, 만약 다른 스테이블 코인을 통해 자산을 보유하고 계시다면 코드에서 USDT가 기입되어 있는 파라미터를 수정해야 한다. 출처가 따로 있는 코드인데, 옛날에 받아와 기억은 안난다.

 

3. 사용법

session = get_session('test')                               # session 호출
symbol = "BTCUSDT"                                          # 코인명
hour_split = 8                                              # 매수 매도 분할 수
qty = round(get_qty(session, symbol)/(hour_split+1), 3)     # 주문수량

필요 변수를 불러온 후, get(session, symbol) 을 실행하면 내 계좌에 있는 USDT 중 포지션 진입에 활용할 수 있는 전체 금액을 출력한다. 위 코드에서는 추가로 분할매수/분할매도를 진행하기 위해 [ 분할 수 + 1 ] 로 전체 금액을 나누고, BTC의 경우 포지션을 잡기 위한 최소 단위가 0.001이기 때문에 round(, 3) 한 상태이다. [ 분할 수 + 1] 로 전체를 나눈 이유는 슬리피지 때문에 가끔 발생 할 수 있는 오류 때문이다.

 

번외로 코드가 처음 실행될 때는 위와 같은 식으로 하면 되지만, 계속되는 매매를 통해 전체 자금이 변동될텐데 어떤식으로 갱신하는 것이 효율적일까? 본인의 경우엔 아래와 같이 하였다.

 

# get qty
long_size = session.my_position(symbol=symbol)['result'][0]['size']
short_size = session.my_position(symbol=symbol)['result'][1]['size']
if long_size + short_size == 0:
    qty = round(get_qty(session, symbol)/(hour_split+1), 3)

코드가 반복문을 통해 계속해서 실행되어 지고 있다고 생각하자. 우리가 분할매수하여 포지션을 잡는다면, get_qty 함수를 이용하여 출력한 포지션 진입 가능 금액은 [ 전체 수량 - 분할매수 진입 수량 ] 으로 바뀐다. 따라서 매 순간 get_qty 함수를 실행하며 분할매수 수량을 연산할 경우, 기존 분할매수에 진입한 수량과 달라질 수 밖에 없다. 물론 분할 매수를 진행할수록 더 적은 수량으로 하겠다라면 아무 상관 없겠지만, 우리는 같은 수량으로 분할하는 것이 기본 전략이기 때문에 위에서 발생하는 것은 의도치 않은 문제이다. 그렇다고 수량을 갱신하지 않자니, 손실이 날 경우엔 전체 수량만큼 재주문을 실행할 경우 오류가 날 것이며, 수익이 나는 경우엔 더 큰 금액으로 재투자가 불가능하다.

 

위와 같은 문제를 해결하기 위해 본인이 활용한 가장 간단한 방법 중 하나는, 포지션이 적용되고 있는 동안(분할 매수 분할 매도가 진행되는 동안)에는 투자 금액을 갱신하지 않고, 포지션이 없을 경우 갱신하는 것이다. 따라서 my_position을 활용하여 long 포지션과 short 포지션 진입 수량을 불러와 둘의 합이 0일 경우 투자 금액을 갱신한다.

728x90
반응형
Comments