마켓 메이킹 봇 - makes meiking bos

//blog.naver.com/opop4615/222313500451

[COIN X QUANT] 맛보기 # 암호화폐 마켓메이킹

안녕하세요 WILLBE입니다. 블로그에서 오랜만에 인사드리네요 😁 취업이후 블로그에 많이 소홀했던...

blog.naver.com

에 개념적으로 간단하게 잘 되어 있는 마켓 메이킹 봇 소스 코드가 있다.

그런데 거기에 나와 있는 소스 코드는 작동하지 않는다. API 명세가 바뀌어서인지...

그래서, 작동하도록 소스 코드를 변경하였다. 로직도 일부 변경했다. 고정된 몇 틱 호가가 아니라 위 아래로 몇 % 구간에 주문을 넣는다.

매수, 매도 호가에 1쌍의 주문을 계속 대기시키는 로직이다.

시장의 잡음(noise)를 수익화하는 로직이다. 그런데 요즘 장은 노이즈가 별로 없는 듯 하다.

미체결 주문이 현재 가격에서 너무 멀어지면 취소시키고 다시 주문한다.

업비트 API 매매는 직접 API 명세를 보고 프로그래밍해도 되지만, 미리 만들어진 API wrapper인 pyupbit을 사용하는 것이 편리하다.

# api_key.py:

#access_key = "업비트에서 발급받은 api access key" #secret_key = "업비트에서 발급받은 api secret key" access_key = "" secret_key = ""

이 파일은 노출되지 않게 잘 관리해야 한다.

# upbitmm.py:

# 참고: [COIN X QUANT] 맛보기 # 암호화폐 마켓메이킹|작성자 WILLBE //blog.naver.com/opop4615/222313500451 # //github.com/sharebook-kr/pyupbit import api_key import pyupbit import time import traceback upbit = pyupbit.Upbit(api_key.access_key, api_key.secret_key) # 시장 상수 # 최소 주문 금액 min_KRW_quantity = 5000 # 수수료율 fee_rate = 0.05 / 100 # Setting tickers = ['KRW-BTC', 'KRW-XRP', 'KRW-SOL', 'KRW-ETH', 'KRW-BCH', 'KRW-BSV', 'KRW-ADA', 'KRW-DOT', 'KRW-DOGE'] KRW_quantity = 5500 # 목표 스프레드 spread = 1 / 100 spread = max(spread, fee_rate * 2) # 수수료 이상이 되게 # order interval (in seconds) order_interval = 1 #tickers_all = pyupbit.get_tickers() #print('All Tickers:', tickers_all) tickers_krw = pyupbit.get_tickers(fiat = 'KRW') print('KRW Tickers:', tickers_krw) #tickers = tickers_krw print('My Tickers ', tickers) print('KRW Quantity: ', KRW_quantity) def get_order_new(ticker, order_type): """ bid/ask 미체결 주문 현황 미체결주문 존재시 주문 ID, 미존재시 None 반환 """ order = upbit.get_order(ticker) if not order: return None for x in order: if x['side'] == order_type: return x['uuid'] return None def cancel_all(): for ticker in tickers: orders = upbit.get_order(ticker) for x in orders: print('Cancel: ', x) upbit.cancel_order(x['uuid']) def make_market(ticker): orderbook = pyupbit.get_orderbook(ticker = ticker) ask_target_price = orderbook['orderbook_units'][0]['ask_price'] bid_target_price = orderbook['orderbook_units'][0]['bid_price'] ask_target_price_delta = orderbook['orderbook_units'][1]['ask_price'] - ask_target_price bid_target_price_delta = bid_target_price - orderbook['orderbook_units'][1]['bid_price'] price_delta = max(ask_target_price_delta, bid_target_price_delta) # 스프레드 도달할 때까지 호가 위치를 벌린다. while ask_target_price / bid_target_price - 1 < spread: ask_target_price += price_delta bid_target_price -= price_delta # .9999 방지 ask_target_price = round(ask_target_price, 4) bid_target_price = round(bid_target_price, 4) print('target price:', ask_target_price, bid_target_price) # //docs.upbit.com/reference/%ED%98%B8%EA%B0%80-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C # orderbook_unit 리스트에는 15호가 정보가 들어가며 차례대로 1호가, 2호가 ... 15호가의 정보를 담고 있습니다. # ask 주문 (매도) balance = upbit.get_balance(ticker) if balance * ask_target_price >= min_KRW_quantity: ask_order = get_order_new(ticker, 'ask') if ask_order == None: # 미체결 주문이 없으면 # print('orderbook: ', orderbook) quantity = round(KRW_quantity / bid_target_price, 8) # 매수 수량으로 팔아야 수량이 쌓이지 않는다. if balance < quantity * 2: quantity = balance upbit.sell_limit_order(ticker, ask_target_price, quantity) print(ticker, 'new ask order. price:', ask_target_price) else: # 미체결 주문이 있으면 old_ask_price = float(upbit.get_order(ask_order)['price']) print('old ask price: ', old_ask_price) if old_ask_price > ask_target_price * (1 + spread / 2): upbit.cancel_order(ask_order) print('ask order cancel', old_ask_price) # bid 주문 (매수) balance = upbit.get_balance('KRW') if balance >= KRW_quantity: bid_order = get_order_new(ticker, 'bid') if bid_order == None: # 미체결 주문이 없으면 quantity = round(KRW_quantity / bid_target_price, 8) upbit.buy_limit_order(ticker, bid_target_price, quantity) print(ticker, 'new bid order. price:', bid_target_price) else: # 미체결 주문이 있으면 old_bid_price = float(upbit.get_order(bid_order)['price']) print('old bid price: ', old_bid_price) if old_bid_price < bid_target_price / (1 + spread / 2): upbit.cancel_order(bid_order) print('bid order cancel', old_bid_price) def loop_make(): cancel_all() while True: print() print('upbitmm') t = time.localtime() print(time.strftime("%H:%M:%S", t)) for ticker in tickers: print('*', ticker, pyupbit.get_current_price(ticker)) #make_market(ticker) try: make_market(ticker) except Exception as e: #print(e) print(traceback.format_exc()) time.sleep(1) time.sleep(1 / 8 * 2) # 주문은 초당 8회, 분당 200회 / 주문 외 요청은 초당 30회, 분당 900회 사용 가능합니다. time.sleep(order_interval) loop_make()

흔한 마켓 메이킹 알고리즘이다.

참고: 33. 단순 마켓메이킹 (Market Making) 전략 : 네이버 블로그 (naver.com)

33. 단순 마켓메이킹 (Market Making) 전략

알고리즘 트레이딩 (Algorithmic Trading) - 전략 (33) 단순 마켓메이킹 (Market Making) 전략 상대호...

blog.naver.com

관련 게시물

Toplist

최신 우편물

태그