[가상화폐] BingX API 활용한 주문

LONGNEW·2024년 1월 16일
0

자동화

목록 보기
3/4

주문 시나리오는 아래와 같다.

  1. 포지션 존재
  2. 포지션 정리
  3. 새로운 포지션 오픈
  4. SL, TP 설정

포지션 확인

이는 DB를 이용해서 확인하기로 하였다.
firebase로 편하게 python module 연결해서 API 이용했다.

	#fire base init하는 템플릿
    cred = credentials.Certificate('src/mykey.json')
    # cred = credentials.Certificate('mykey.json')
    firebase_admin.initialize_app(cred,{
        'databaseURL' : ''
    })
    
    # bingX APIKEY, SECRETKEY를 저장해둬서 가져와서 사용.
    APIURL = "https://open-api.bingx.com"
    APIKEY = db.reference("/bingx_APIKEY").get()
    SECRETKEY = db.reference("/bingx_SECRETKEY").get()

	# 포지션 여부를 DB에 저장해서 가져오기.
    BB_ETH_pos = db.reference("BB/ETH_pos").get()
    BB_BTC_pos = db.reference("BB/BTC_pos").get()

포지션 정리

주문을 넣기보다는 "closeAllPositions" API를 통해 특정 "symbol"의 포지션을 다 정리한다.

def wipe_order(symbol):
    payload = {}
    path = '/openApi/swap/v2/trade/closeAllPositions'
    method = "POST"

    current_time = datetime.now()
    milliseconds = int(current_time.timestamp() * 1000)

    paramsMap = {
        "timestamp": milliseconds,
        "symbol": symbol,
        "recvWindow": "10000"
    }
    paramsStr = praseParam(paramsMap)
    res = send_request(method, path, paramsStr, payload)
    return res

포지션 오픈

"order" API를 활용하는데 전체 주문에 들어가는 USDT로 계산을 할 수 없어 symbol_price / balance를 통해 주문할 양을 계산한다.

현재 코인의 가격을 알아야 symbol_price변수를 쓸 수 있다. 이를 위해서도 API를 한번 호출해준다.

def order(symbol, position, balance):
    payload = {}
    path = '/openApi/swap/v2/trade/order'
    method = "POST"

	# 주문할 수량을 계산
    symbol_price = float(real_time_price(symbol))
    quantity = round(balance / symbol_price, 5)

    # position open을 위한 주문
    # position 매개변수를 통해 LONG, SHORT 포지션을 구분한다.
    paramsMap = {
    "symbol": symbol,
    "side": "BUY" if position == 1 else "SELL",
    "positionSide": "BOTH",
    "type": "MARKET",
    "quantity": quantity
}
    paramsStr = praseParam(paramsMap)
    res = json.loads(send_request(method, path, paramsStr, payload))
    error = res["code"]
    print(f"position open : {error}")
    return quantity, symbol_price
 
 def real_time_price(symbol):
    payload = {}
    path = '/openApi/swap/v2/quote/price'
    method = "GET"

    current_time = datetime.now()
    milliseconds = int(current_time.timestamp() * 1000)
    paramsMap = {
        "timestamp": str(milliseconds),
        "symbol": symbol
    }
    paramsStr = praseParam(paramsMap)
    res = json.loads(send_request(method, path, paramsStr, payload))
    return res["data"]["price"]

SL 설정

주문 할 떄 한 번에 설정하는 것이 없다고 한 것 같다. 그냥 개별적으로 주문을 넣게 하였다.
어차피 현물이 얼마나 떨어지는지, 올라가는지만 생각하면 되니까 diff는 손절폭만 넘겨준다.

def set_SL(symbol, position, quantity, symbol_price, loss_percen):
    lo_diff = ((symbol_price / 100) * loss_percen)
    payload = {}
    path = '/openApi/swap/v2/trade/order'
    method = "POST"

    # stop loss 걸기
    paramsMap = {
        "symbol": symbol,
        "side": "BUY" if position != 1 else "SELL",
        "positionSide": "BOTH",
        "type": "STOP_MARKET",
        "quantity": quantity,
        "stopPrice": symbol_price + lo_diff if position != 1 else symbol_price - lo_diff,
        "reduceOnly": "true"
    }
    paramsStr = praseParam(paramsMap)
    res = json.loads(send_request(method, path, paramsStr, payload))
    error = res["code"]
    print(f"SL open : {error}")
    return

TP 설정

SL과 동일한데 , diff로 익절폭이 간다는 것이 다르다.

def set_TP(symbol, position, quantity, symbol_price, earn_percen):
    hi_diff = ((symbol_price / 100) * earn_percen)
    payload = {}
    path = '/openApi/swap/v2/trade/order'
    method = "POST"

    # take profit 걸기
    paramsMap = {
        "symbol": symbol,
        "side": "BUY" if position != 1 else "SELL",
        "positionSide": "BOTH",
        "type": "TAKE_PROFIT_MARKET",
        "quantity": quantity,
        "stopPrice": symbol_price - hi_diff if position != 1 else symbol_price + hi_diff,
        "reduceOnly": "true"
    }
    paramsStr = praseParam(paramsMap)
    res = json.loads(send_request(method, path, paramsStr, payload))
    error = res["code"]
    print(f"TP open : {error}")
    return

0개의 댓글