주문 시나리오는 아래와 같다.
이는 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"]
주문 할 떄 한 번에 설정하는 것이 없다고 한 것 같다. 그냥 개별적으로 주문을 넣게 하였다.
어차피 현물이 얼마나 떨어지는지, 올라가는지만 생각하면 되니까 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
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