backtest 전략을 실제 투자에 적용하기 #2
고려해야할 사항 (계속)
이번엔 매수를 하는 API를 어떻게 구현할지 고민해본다.
요구사항1. top 5 거래량은 어떻게 추출할 것인지 (완료)
2. 매수를 하는 API는 어떻게 구현 하는지
3. 매수 할 때의 금액은 어떻게 계산할 것인지
4. 매수 플래그는 어떻게 세팅할 것인지
5. 주문은 했으나, 구매에 성공했는지 안했는지 어떻게 확인할 수 있는지
6. 매수한 코인의 수익율은 어떻게 실시간으로 계산하는지
7. 매수한 코인의 매도에 실패 했을 때, 어떻게 주문을 취소하고 재 매도할 수 있는지
bithumb api - 매수 및 매도
빗썸 API 가이드를 따르자면 구매 및 판매를 할 때, api 키
와 secret 키
가 필요하다고 한다.
파이썬 예제 코드는 빗썸 API 가이드에서 가져왔으며, 천천히 분석한다.
매수 및 매도 |
---|
| import requests
url = "https://api.bithumb.com/trade/place"
headers = {
"accept": "application/json",
"content-type": "application/x-www-form-urlencoded",
"Api-Key": "사용자 Access Key",
"Api-Nonce": "현재시각(ms)",
"Api-Sign": "상세 가이드 참고"
}
response = requests.post(url, headers=headers)
print(response.text)
|
5 번째 줄
의 headers
변수에 사용자 API를 세팅하고, POST
메소드를 이용해 호출하는 것 으로 분석된다.
10 번째 줄
에서 상세 가이드
에 나와 있는대로 API를 세팅하면, API를 사용할 수 있을 것이다.
bithumb api - private api 상세 가이드
인증 헤더 만들기에서 API 헤더를 만드는 내용이 첨부되어 있으며
파이썬 예제코드가 있어서 바로 실행해 보았다. 아래는 빗썸에서 제공하고 있는 파이썬 예제 코드이다
인증 헤더 구현.py |
---|
| import time
import math
import base64
import hmac, hashlib
import urllib.parse
import requests
class XCoinAPI:
api_url = "https://api.bithumb.com";
api_key = "";
api_secret = "";
def __init__(self, api_key, api_secret):
self.api_key = api_key;
self.api_secret = api_secret;
def body_callback(self, buf):
self.contents = buf;
def microtime(self, get_as_float = False):
if get_as_float:
return time.time()
else:
return '%f %d' % math.modf(time.time())
def usecTime(self) :
mt = self.microtime(False)
mt_array = mt.split(" ")[:2];
return mt_array[1] + mt_array[0][2:5];
def xcoinApiCall(self, endpoint, rgParams):
# 1. Api-Sign and Api-Nonce information generation.
# 2. Request related information from the Bithumb API server.
#
# - nonce: it is an arbitrary number that may only be used once.
# - api_sign: API signature information created in various combinations values.
endpoint_item_array = {
"endpoint" : endpoint
}
uri_array = dict(endpoint_item_array, **rgParams) # Concatenate the two arrays.
str_data = urllib.parse.urlencode(uri_array)
nonce = self.usecTime()
data = endpoint + chr(0) + str_data + chr(0) + nonce
utf8_data = data.encode('utf-8')
key = self.api_secret
utf8_key = key.encode('utf-8')
h = hmac.new(bytes(utf8_key), utf8_data, hashlib.sha512)
hex_output = h.hexdigest()
utf8_hex_output = hex_output.encode('utf-8')
api_sign = base64.b64encode(utf8_hex_output)
utf8_api_sign = api_sign.decode('utf-8')
headers = {
"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded",
"Api-Key": self.api_key,
"Api-Nonce": nonce,
"Api-Sign": utf8_api_sign
}
url = self.api_url + endpoint
r = requests.post(url, headers=headers, data=rgParams)
return r.json()
|
아래의 코드로 위의 예제코드를 실행해 보았다.
인증 API 예제.pyif __name__ == '__main__':
bithumb = XCoinAPI('api_key','secret_key')
print(bithumb2.xcoinApiCall('/info/balance',{'currency':'BTC'}))
하지만 결과는 아래와 같이 나온다.
실행 결과(env) ubuntu@ubuntu:~/coding-interview$ python bithumb_api.py
{'status': '5100', 'message': 'Bad Request.(Auth Data)'}
가이드 대로 했는데 왜 5100에러가 나타나는 건가.. 라고 하는 순간 가이드 를 보면 아래와 같이 Api-Sign을 설정하는 것을 확인할 수 있었다.
Api-Sign : End Point + Request Parameter + Api-Nonce + 사용자 Secret Key를 조합하여 인코딩한 값
하지만 예제 코드에는 endpoint를 두번 감싼다.
예제 코드2.py |
---|
| import time
import math
import base64
import hmac, hashlib
import urllib.parse
import requests
class XCoinAPI:
api_url = "https://api.bithumb.com";
api_key = "";
api_secret = "";
# ...(중략)...
def xcoinApiCall(self, endpoint, rgParams):
# 1. Api-Sign and Api-Nonce information generation.
# 2. Request related information from the Bithumb API server.
#
# - nonce: it is an arbitrary number that may only be used once.
# - api_sign: API signature information created in various combinations values.
endpoint_item_array = {
"endpoint" : endpoint
}
uri_array = dict(endpoint_item_array, **rgParams) # Concatenate the two arrays.
str_data = urllib.parse.urlencode(uri_array)
nonce = self.usecTime()
# str_data에 endpoint 파라미터가 들어가게 된다.
data = endpoint + chr(0) + str_data + chr(0) + nonce
utf8_data = data.encode('utf-8')
key = self.api_secret
utf8_key = key.encode('utf-8')
h = hmac.new(bytes(utf8_key), utf8_data, hashlib.sha512)
hex_output = h.hexdigest()
utf8_hex_output = hex_output.encode('utf-8')
api_sign = base64.b64encode(utf8_hex_output)
utf8_api_sign = api_sign.decode('utf-8')
headers = {
"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded",
"Api-Key": self.api_key,
"Api-Nonce": nonce,
"Api-Sign": utf8_api_sign
}
url = self.api_url + endpoint
r = requests.post(url, headers=headers, data=rgParams)
return r.json()
|
따라서, 중복인 endpoint
값을 제거하고 str_data
를 rgParams
만 넣고 수정한 후 실행하면 잘 나오는 것을 확인할 수 있다.
수정 된 예제 코드.py |
---|
| import time
import math
import base64
import hmac, hashlib
import urllib.parse
import requests
class XCoinAPI:
api_url = "https://api.bithumb.com";
api_key = "";
api_secret = "";
# ...(중략)...
def xcoinApiCall(self, endpoint, rgParams):
# 1. Api-Sign and Api-Nonce information generation.
# 2. Request related information from the Bithumb API server.
#
# - nonce: it is an arbitrary number that may only be used once.
# - api_sign: API signature information created in various combinations values.
str_data = urllib.parse.urlencode(rgParams)
nonce = self.usecTime()
# str_data에 endpoint 파라미터가 들어가게 된다.
data = endpoint + chr(0) + str_data + chr(0) + nonce
utf8_data = data.encode('utf-8')
key = self.api_secret
utf8_key = key.encode('utf-8')
h = hmac.new(bytes(utf8_key), utf8_data, hashlib.sha512)
hex_output = h.hexdigest()
utf8_hex_output = hex_output.encode('utf-8')
api_sign = base64.b64encode(utf8_hex_output)
utf8_api_sign = api_sign.decode('utf-8')
headers = {
"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded",
"Api-Key": self.api_key,
"Api-Nonce": nonce,
"Api-Sign": utf8_api_sign
}
url = self.api_url + endpoint
r = requests.post(url, headers=headers, data=rgParams)
return r.json()
if __name__ == '__main__':
bithumb = XCoinAPI('api_key','secret_key')
print(bithumb2.xcoinApiCall('/info/balance',{'currency':'BTC'}))
|
실행 결과(env) ubuntu@ubuntu:~/coding-interview$ python bithumb_api.py
{'status': '0000', 'data': {'total_krw': '현금', 'in_use_krw': '현금', 'available_krw': '현금', 'total_btc': '비트코인', 'in_use_btc': '비트코인', 'available_btc': '비트코인', 'xcoin_last_btc': '비트코인'}}
다음은?
다음 내용은 API 구현 찾느라 시간이 지체되었다. 문서의 오류는 pybithumb
과 비교하였으며, 본격적으로 pybithumb
을 분석해 볼 것이다.