맨위로버튼이미지

1. 들어가기 전에

처음 Bitcoin 자동 매매 프로그램을 개발하고 벌써 5개월이란 시간이 흘렀네요.
자동 매매 프로그램의 시작은 주식이였지만 처음 성적은 별로 좋지 않았습니다.
그 때 배운게 인터넷에 떠 있는 소스는 절대 믿으면 안된다 였습니다.
생각해 보면 자동 매매 프로그램을 개발하시는 분들 대부분은 각자의 철학과 전략이 있기에 다른 어떤이와도 생각이 일치할 수도 없거니와 계속 변경되는 환경에서 이전의 소스가 맞을 리가 없었는데 말이죠.
그리고 나서 pyBithum이라는 python lib가 있다는 것을 알게 되었습니다.
고민도 할거 없이 나의 첫번째 자동 매매 프로그램은 그렇게 단 몇시간만에 탄생하게 되었습니다.
하지만 운영하면서 계속되는 원인을 알 수 없는 에러를 debugging하면서 Bithum API 자체 결함이 많다는 것을 서서히 눈치챘습니다.
pyBithum lib는 그저 껍데기 일뿐 Bithum API를 호출하는 구조였던 거죠.
결국 Bithum API가 개선 되지 않는 이상 이 문제들은 해결될 수 없다는 것도 알게 되었습니다. 그러면서 각 거래소별 API에 대한 이야기를 다른 블로그를 통해서 알게 되었습니다.
그나마 Bithum API가 업계에서는 괜찮은 편이라는 거죠.
음 이거 실화냥? ㅠㅠ;
비싼 수수료에 영세업체 수준의 API 이것이 저의 생각입니다.
Bithum 관계자가 이 글을 보면 저에게 소송을 걸까요?
그렇다면 이 문장을 수정해야 겠네요.
아실지 모르지만 우리나라에는 '사실즉시 명예훼손'이라는 법이 있습니다.
비록 그 내용이 '사실'이라 해도 그 내용을 공공에 게시하여 당사자의 명예를 훼손한다면 형사 처벌을 받는 법입니다.
헌법에 크게 위배된다고 생각한 많은 사람들이 헌법 소원을 했지만 작년 가을 헌제에서 '합헌 결정'이 났습니다.
민사로 충분히 처리가 가능하지만 형사처벌 조항이 있어 이중 처벌의 위험성이 있는데도 말이죠.
무엇이 무서웠을 까요?

2. Bithum API의 근본적인 문제점

1. version 정보 없음.

저도 현역 프로그래머로써 이 곳 저 곳을 다니면서 소위 RestAPI라는 것을 개발하고 있습니다.
처음에는 표준이 뭔지도 몰라 여기 저기 똥을 싸고 다녔지만 하다가 보니 저기는 왜 저렇게 했는지 여기는 왜 이렇게 했는지가 하나 둘씩 보이기 시작 했습니다.
그러면서 가장 먼저 눈에 띈게 바로 version정보 입니다.
API path 중간에 (예시 : '/api/v1/info/user_transaction') 버젼 정보를 표시하고 있다는 거죠.
혹시 tensorflow를 사용해 보신 분이 계신가요? tensorflow v1에서 v2로 되면서 거의 천지개벽 수준으로 api변경이 되었습니다.
keras의 위치가 중요하게 되면서 기존 v1의 기능은 대폭 축소 되고 모든 것을 keras에게 위임하는 형식으로 소스가 변경되고 간략화 되어 기존 v1소스는 폐기의 수준이 되었습죠. ㅠㅠ

from tensorflow.compat import v1 as tf tf.disable_v2_behavior() tf.random.set_random_seed(seed)

위 처럼 해주지 않으면 v2로 처리가 되어 거의 모든 함수에서 에러가 발생합니다.
눈치 채셨나요?
지금 거래소 API중 어떤것도 version 정보가 없습니다. (지금은 Upbit API로도 개발 중인데 Upbit API에는 버젼 정보가 있더군요. Upbit는 모기업이 KAKAO라 대기업의 냄새가 납니다.)
중간 중간에 실 운영기 소스를 수정하고 아무런 공지도 없습니다.
갑자기 잘 돌던 프로그램에서 type오류가 납니다. 원인은 API의 변경으로 리턴값이 바뀐겁니다.
현 체제로는 방법이 없는 거죠.

2. 오류 코드 묶음 처리

모든 API는 정상적으로 아주 잘 만들어 진 코드라고 해도 에러가 발생합니다.
정확하게는 예외사항이죠.
프로그래머도 컴퓨터도 어쩔 수 없는 사항이 발생한다는 거죠.
그런 때를 대비해서 오류코드가 있는 거죠.
제가 가장 황당했던건 Bithum API를 사용하면서 5500 에러와 5600에러 속에 수 많은 종류의 오류가 코드 없이 묶음으로 존재한다는 거였습니다.
사실 상당 수의 에러는 오류 처리를 할 필요도 없는데 말이죠.
아 그렇군 하는 정도면 되는데 말이죠.
근데 몇몇 프로그램에 아주 critical한 오류가 같이 섞여 있다는 게 문제 인거죠.
지금 제가 운영하고 있는 자동 매매 프로그램의 trading 부분 소스는 방어코드의 총망라 입죠.
오류코드가 세분화 안되어 있으니 프로그램에서 다 방어를 해야 한다는 느낌.
뭐 그렇습니다.

3. 운영 유지만 version up은 언제쯤?

사실 초기에는 Bithum에 몇 번 전화를 했었습니다.
전화 받는 분이 자기네 회사 오류코드 체계도 모르시더군요.
딱 봐도 전문 텔러가 아닌데 말이죠.
(저는 초기에 콜센터 프로그램만 5년을 넘게 했었습니다. 전화 응대만 들어도 전문 텔러 인지 아닌지 알 수 있습니다.)
운영이나 개발인력의 수준을 눈치 채는데는 그리 많은 시간이 필요하지 않았습니다.
군데 군데 보이는 critical한 문제가 과연 고쳐 질까?
마치 창문 없는 집을 보고 '저 집에 창문은 어떻게 낼 수 있을까?' 고민하는 수준 이랄까요?

3. 나의 Bithum API 극복기

1. 주문량이 사용가능 KRW를 초과하였습니다.

해쉬태그로 뭘 달까 고민할 필요도 없이 '주문량이 사용가능 KRW를 초과하였습니다.'를 선택했습니다.
다른 블러그나 게시판에 아주 논쟁이 뜨겁습니다. 어떤 사람은 자기는 발생하지 않는데 난다고 한다고 하고 저 같은 경우는 계속 발생합니다.
제가 알아 낸 사실은 총 현금 보유 금액의 85%만 거래가 가능하다는 겁니다.
확실히 버그라고 하기에는 어딘가에 하드코딩되어 있는 뭔가가 있는 것 같습니다.
저 같은 경우는 보유 KRW의 85%를 구해서 여러번 분할 매수를 하게 프로그램 되어 있습니다.
그래서 계속 매수 하다 보면 결국 보유 현금의 100%까지 매수가 가능 합니다.
물론 최소 거래 금액과 0.0001 미만의 코인은 매수 되지 않습니다.
(지금 up-bit 계좌로도 프로그램을 만들고 있는데 upbit는 최소 거래 금액이 bithum보다는 크지만 그것은 일회 거래금액의 단위이고 소수점 제약등은 존재하지 않습니다.)
 

balance = get_balance() #잔고 조회 if balance is not None: self.logger.info("잔고조회: %.5f %.5f %.2f %.2f", balance[0], balance[1], balance[2], balance[3]) krw = balance[2] #구매 가능 보유 금액 
buy_krw = buy_price * unit #구매할 krw를 계산 
remind_krw = krw - buy_krw #잔여 금액 계산 
possible_krw = krw 
if remind_krw <= buy_krw * 0.15: # 정액쿠폰 구매와 상관 없이 수수료 계산 
    possible_krw = krw - buy_krw * 0.15 
    unit = possible_krw/buy_price #구매 수량 계산 
    unit = int(unit * 10000)/10000 #unit은 소수점 네자리 아래 삭제 처리 
    order = bithumb.buy_limit_order(ticker, buy_price, unit, payment_currency="KRW") #매수 주문 
    if order is not None and type(order) is tuple: 
        self.logger.info("order success:%s, timing_price:%d, buy_price:%d" 
           % (str(order), timing_price, buy_price)) self.last_order_id = order; 
        for i in range(0,19): 
            resp = self.order_detail(order) 
            self.logger.info("order detail : " + str(resp)) 
            if resp is not None and resp.get('status') == '0000': 
                orderStaus = resp.get('data').get('order_status') 
                if orderStaus == 'Completed': 
                    slack.chat.post_message(slackkey.SLACKER_CHAN, time.ctime() + ":`order detail : " + str(resp) + "`") 
                    break 
        return

클래스로 구현된 trading 모듈을 간략화해서 붙이는 거라 소스중간에 self가 보이는 부분 양해 바랍니다.
소스를 저렇게 고치고 나니 그 후 '주문량이 사용가능 KRW를 초과하였습니다.' 오류는 발생하지 않았습니다.
시장가 주문에서도 지정가 주문에서도 동일한 부분이 필요 합니다.
시장가 주문을 할 경우는 orderbook의 가장 첫번째 ask값을 buy_price로 해서 계산하면 됩니다.
Bithum에서 수정한다면 거래를 태우기 전에 수수료를 먼저 검사해서 (아마도 app에서는 이 부분이 수정되어 있는 것 같습니다. app상에서는 이런 오류가 한번도 없었습니다.) 수수료 무료 고객은 수수료 부분까지도 구매가 가능하게 api를 수정하면 될 것 같습니다.
Bithum에서 수정이 안된다면 우리는 계속 위의 소스를 유지 해야 겠죠.

2. 홈페이지 API 문서에는 있지만 pyBithum에는 없는 API들

혹시 pyBithum에 없는 API를 직접 함수로 구현하려고 HttpRequest를 사용하려고 시도하신 분들이 있을 까요?
제 생각에는 아마도 안되실 겁니다.
이유는 public API는 아무 상관 없이 개방되어 있지만 ( public과 private는 같은 함수라도 정보 조회 건수가 다른건 아실 겁니다.) private는 HttpRequest Header에 HMAC 값이 있습니다.
혹시 알고 계셨던 분들도 있으신가요?
HMAC 계산은 아주 복잡하고 까다롭습니다.
하지만 pyBithum에는 이미 HMAC계산이 다 되어 있습니다. 아래 소스를 보시죠

from pybithumb.core import BithumbHttp
http = BithumbHttp(key.con_key, key.secu_key) #API KEY와 SECU KEY로 http초기화 
url = '/info/user_transactions' #API 문서에 있는 url 값 
                                #주의 : 중요한 것은 앞쪽에 있는 '/'가 없으면 type 에러 발생함.  
try: 
    resp = http.post(url, offset=offset, count=count, searchGb='2', order_currency=self.ticker, payment_currency='KRW') 
    print("user_transactions:" + str(resp)) 
    if resp != None and resp['status'] == '5600': 
        return None return resp 
except Exception as ex: 
	exc_type, exc_obj, exc_tb = sys.exc_info() 
    fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 
    print("user_transactions -> exception! %s : %s %d" % (str(ex) , fname, exc_tb.tb_lineno))

몇가지 import가 더 있지만 충분히 알 수 있는 내용이라 생략 했습니다.
생각보다 간단하죠?
pyBithum에는 이미 이런 내용이 다 반영이 되어 있습니다.
예를 들면 Bithum API문서에는 Stop-Limit라는 기능이 있습니다.
지정가로 호가가 있으면 그때마다 매수를 하게 지정하는 함수 인데 pyBithum에는 아직 기능이 없습니다.
아마도 제 생각에는 pyBithum은 더 이상의 버젼업이 없을 것 같습니다.
이 기능을 구현하려면 url부분에 '/trade/stop_limit' 를 넣고 해당 Request Param중에 apiKey와 secretKey를 제외한 나머지 부분중 필수 값을 채우고 필수가 아닌 값은 보고 판단하시면 될 것 같습니다.

4. 마치며

Bithum관계자에게 간곡히 부탁드립니다.
만약에 혹시라도 이 게시물을 보신다면 '사실즉시 명예훼손'으로 고소하지 말아 주세요.
하시기전에 저에게 email(yubank@naver.com)한통이면 이 글 중 명예 훼손이 되는 부분은 전부 삭제 처리 하고 다른 프로그램에 필요한 내용만 남겨 두겠습니다.
그 마저도 불편하다고 생각 하시면 전체를 비공개로 전환하겠습니다.
아직 저의 블로그 방문자는 10명 내외로 미미한 수준입니다.
혹시라도 이곳에서 이 글을 보신다면 제가 Bithum을 비방하려는 목적이 아님을 아실 겁니다.
저도 처음에는 '주문량이 사용가능 KRW를 초과하였습니다.' 오류로 프로그램에 중간에 멈추는 현상이 아주 잦았습니다.
원인을 알고 수정하고 주문을 여러번에 나눠서 하게 수정을 해서 겨우 해결을 했습니다.
아직도 이 문제를 해결하지 못하신 분들도 인터넷 게시판을 디지다 보면 많은 것을 알고 있습니다.
새로 시작하시는 분들도 상당 수 이 문제에 봉착 하시라 생각 됩니다.
그리고 Bithum뿐만 아니라 현재의 우리나라 Bitcoin 거래소들의 출발이나 현재의 모습이 어떨지 왜 그랬는지를 알고 앞으로가 어떨지도 알고 있습니다.
현재 시점 수 많은 거래소가 정부 가이드를 못 맞춰서 대표자 횡령혐의로 입건 되거나 폐쇄의 길을 걷고 있다는 뉴스는 쉽게 접할 수 있습니다.
그래도 대표 4개 거래소는 끝까지 살아 남았으면 하는 바램이 아주 큽니다.
정부에서는 증권거래소와 같이 중앙 거래소와 증권사를 두는 방식의 개편을 준비 중인 것 같습니다.
그렇게 되는 데만도 족히 4~5년은 걸릴 것 이고 은행들은 새로운 BIS기준 때문에 일부 Bitcoin 거래소의 전용계좌 개설 및 기존 계좌를 폐쇄하려고 하고 있죠.
그럼 아마도 Bitcoin거래소는 재계순위 4위까지만 살아 남고 나머지는 거의 다 폐쇄될 것으로 보입니다.
그 이후에는 진짜 제대로 모습을 갖춘 거래소들이 다시 생기겠죠.
사실 Bitcoin의 운명도 불투명합니다.
미국은 달러연계 암호화 화폐를 준비중입니다.
사실 미국이라는 나라는 남미의 국가들에게는 소리없는 죽음의 침략자입니다.
과거에는 전쟁으로 영토를 침략했다면 지금은 금융으로 타 국가의 이익을 소리도 없이 점령합니다.
수 많은 사람들이 죽음으로 내 몰리지만 저희는 알 수도 없습니다.
이유는 기축통화인 달러를 자기 나라의 이익을 위해 맘데로 운영을 하면서 남미의 국가 나 또는 폐그제를 운영하는 여러 나라에 막대한 피해를 입히고 있습니다.
그런데 이 영향을 안 받는게 Bitcoin이죠.
그래서 미국은 또 다른 침략인 달러 연계 암호화 화폐를 만들려고 합니다.
그리고 우리나라도 원화 연계 암호화 화폐(소위 말하는 전자 화폐)를 개발하고 있습니다.
Bitcoin은 악용되는 사례도 많습니다.
수 많은 나라에서 납치범들이 몸값을 요구하는 수단으로 Bitcoin을 사용하고 있고 마약거래 및 인신매매에도 사용되고 있죠.
그래서 부자들 중 워랜버핏 같은 사람은 Bitcoin혐오 주의자 중 한명이기도 합니다.
지금이 Bitcoin및 거래소들이 중요 갈림길이라고 봅니다.
4~5년 후에도 살아 남으려면 과연 무엇을 준비해야 할까요?

반응형
LIST

+ Recent posts