Skip to content

Instantly share code, notes, and snippets.

@jeakwon
Last active March 30, 2021 21:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeakwon/17edc0e416ddcab1fbdab9f5757ddad0 to your computer and use it in GitHub Desktop.
Save jeakwon/17edc0e416ddcab1fbdab9f5757ddad0 to your computer and use it in GitHub Desktop.
rebalance in upbit api
class UpbitAPI:
"""
:라이브러리:
import requests, jwt, uuid, hashlib, time
from urllib.parse import urlencode
:사용법:
with open(r"C:\Users\Jay\Desktop\upbit.txt", 'r') as f:
access_key, secret_key = f.read().splitlines()
api = UpbitAPI(access_key, secret_key)
api.rebalance(cash_ratio=0.1)
"""
urls = {
"전체계좌조회": "https://api.upbit.com/v1/accounts",
"주문가능정보": "https://api.upbit.com/v1/orders/chance",
"개별주문조회": "https://api.upbit.com/v1/order",
"주문리스트조회": "https://api.upbit.com/v1/orders",
"주문취소접수": "https://api.upbit.com/v1/order",
"주문하기": "https://api.upbit.com/v1/orders",
"출금리스트조회": "https://api.upbit.com/v1/withdraws",
"개별출금조회": "https://api.upbit.com/v1/v1/withdraw",
"출금가능정보": "https://api.upbit.com/v1/withdraws/chance",
"코인출금하기": "https://api.upbit.com/v1/withdraws/coin",
"원화출금하기": "https://api.upbit.com/v1/withdraws/krw",
"입금리스트조회": "https://api.upbit.com/v1/deposits",
"개별입금조회": "https://api.upbit.com/v1/deposit",
"입금주소생성요청": "https://api.upbit.com/v1/deposits/generate_coin_address",
"전체입금주소조회": "https://api.upbit.com/v1/deposits/coin_addresses",
"개별입금주소조회": "https://api.upbit.com/v1/deposits/coin_address",
"원화입금하기": "https://api.upbit.com/v1/deposits/krw",
"입출금현황": "https://api.upbit.com/v1/status/wallet",
"API키리스트조회": "https://api.upbit.com/v1/api_keys",
"마켓코드조회": "https://api.upbit.com/v1/market/all",
"분캔들1": "https://api.upbit.com/v1/candles/minutes/1",
"분캔들3": "https://api.upbit.com/v1/candles/minutes/3",
"분캔들5": "https://api.upbit.com/v1/candles/minutes/5",
"분캔들10": "https://api.upbit.com/v1/candles/minutes/10",
"분캔들15": "https://api.upbit.com/v1/candles/minutes/15",
"분캔들30": "https://api.upbit.com/v1/candles/minutes/30",
"분캔들60": "https://api.upbit.com/v1/candles/minutes/60",
"분캔들240": "https://api.upbit.com/v1/candles/minutes/240",
"일캔들": "https://api.upbit.com/v1/candles/days",
"주캔들": "https://api.upbit.com/v1/candles/weeks",
"월캔들": "https://api.upbit.com/v1/candles/months",
"최근체결내역": "https://api.upbit.com/v1/trades/ticks",
"현재가정보": "https://api.upbit.com/v1/ticker",
"호가정보조회": "https://api.upbit.com/v1/orderbook",
}
def __init__(self, access_key, secret_key):
self.access_key = access_key
self.secret_key = secret_key
def get_headers(self, query=None, uuids=None, txids=None):
if query:
query_string = urlencode(query).encode()
if uuids:
uuids_query_string = '&'.join(
["uuids[]={}".format(uuid) for uuid in uuids])
query['uuids[]'] = uuids
query_string = "{0}&{1}".format(
query_string, uuids_query_string).encode()
if txids:
txids_query_string = '&'.join(
["txids[]={}".format(txid) for txid in txids])
query['txids[]'] = txids
query_string = "{0}&{1}".format(
query_string, txids_query_string).encode()
m = hashlib.sha512()
m.update(query_string)
query_hash = m.hexdigest()
else:
query_hash = None
payload = {
'access_key': self.access_key,
'nonce': str(uuid.uuid4()),
'query_hash': query_hash,
'query_hash_alg': 'SHA512',
}
jwt_token = jwt.encode(payload, self.secret_key)
authorize_token = 'Bearer {}'.format(jwt_token)
headers = {"Authorization": authorize_token}
return headers
def get_account(self):
headers = self.get_headers()
return requests.get(self.urls["전체계좌조회"], headers=headers)
def buy(self, market, price):
query = dict(
market=market,
side='bid',
price=price,
ord_type='price',
)
headers = self.get_headers(query=query)
return requests.post(self.urls["주문하기"], params=query, headers=headers)
def sell(self, market, volume):
query = dict(
market=market,
side='ask',
volume=volume,
ord_type='market',
)
headers = self.get_headers(query=query)
return requests.post(self.urls["주문하기"], params=query, headers=headers)
def get_order_chance(self, market):
query = dict(
market=market,
)
headers = self.get_headers(query=query)
return requests.get(self.urls["주문가능정보"], params=query, headers=headers)
def get_ticker(self, markets):
query = dict(
markets=markets,
)
return requests.get(self.urls["현재가정보"], params=query)
def get_assets(self):
assets = dict()
while True:
resp = self.get_account()
if resp.ok: break
else: time.sleep(1)
account = resp.json()
for item in account:
if item['currency'] == 'KRW':
cash = float(item['balance'])
market = '{}-{}'.format(item['unit_currency'], item['currency'])
print(f"{market} 주문가능정보 조회중 ", end='\r')
resp = self.get_order_chance(market)
if resp.ok:
data = resp.json()
assets[market] = dict(
avg_buy_price=float(data['ask_account']['avg_buy_price']),
balance=float(data['ask_account']['balance']),
)
markets = ', '.join(list(assets.keys()))
while True:
resp = self.get_ticker(markets)
if resp.ok: break
else: time.sleep(1)
tickers = resp.json()
for ticker in tickers:
market = ticker['market']
assets[market]['price'] = float(ticker['trade_price'])
evaluation = assets[market]['price'] * assets[market]['balance']
assets[market]['evaluation'] = evaluation
assets_total_evaluation = 0
for market, asset_info in assets.items():
assets_total_evaluation += asset_info['evaluation']
total_evaluation = cash + assets_total_evaluation
return dict(
cash=cash,
assets=assets,
assets_total_evaluation=assets_total_evaluation,
total_evaluation=total_evaluation,
)
def rebalance(self, cash_ratio=0.1):
assets = self.get_assets()
target_evaluation = assets['total_evaluation']*(1-cash_ratio)/len(assets['assets'])
print(f'종목별 목표평가금액(KRW): {target_evaluation:10,.0f}')
print(f"현금/자산/총합(KRW): {assets['cash']:10,.0f}/{assets['assets_total_evaluation']:10,.0f}/{assets['total_evaluation']:10,.0f}")
for market, info in assets['assets'].items():
delta_evaluation = target_evaluation-info['evaluation']
if delta_evaluation>5000: # Buy
while True:
resp = self.buy(market=market, price=delta_evaluation)
if resp.ok:
print(f'[매수 {market:10}] 차액:{delta_evaluation:+10,.0f}')
break
else:
print(f'[지연 {market:10}] 차액:{delta_evaluation:+10,.0f}', end='\r')
time.sleep(1)
elif delta_evaluation<-5000: # Sell
while True:
resp = self.sell(market=market, volume=-delta_evaluation/info['price'])
if resp.ok:
print(f'[매도 {market:10}] 차액:{delta_evaluation:+10,.0f}')
break
else:
print(f'[지연 {market:10}] 차액:{delta_evaluation:+10,.0f}', end='\r')
time.sleep(1)
else:
print(f'[홀드 {market:10}] 차액:{delta_evaluation:+10,.0f}')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment