kraken-bot/pykraken.py
2024-08-30 11:07:52 -04:00

132 lines
4.2 KiB
Python

import base64
import hashlib
import hmac
import os
import requests
import time
import urllib.parse
class Kraken():
class Order():
class Close():
def __init__(self, ordertype, price, price2):
self.ordertype = ordertype
self.price = price
self.price2 = price2
def asdict(self):
data = {
'ordertype': self.ordertype,
'price': self.price
}
if self.price2:
data['price2'] = self.price2
return data
def __init__(self, ordertype, price, type, volume, close=None, pair=None, price2=None, timeinforce=None, userref=None):
self.close = close
self.ordertype = ordertype
self.pair = pair
self.price = price
self.price2 = price2
self.timeinforce = timeinforce
self.type = type
self.userref = userref
self.volume = volume
def asdict(self):
data = {
'nonce': str(int(1000*time.time())),
'ordertype': self.ordertype,
'price': self.price,
'type': self.type,
'volume': self.volume
}
if self.close:
data['close'] = self.close
if self.pair:
data['pair'] = self.pair
if self.price2:
data['price2'] = self.price2
if self.timeinforce:
data['timeinforce'] = self.timeinforce
if self.userref:
data['userref'] = self.userref
return data
class KrakenError(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return f'Kraken API Error: {self.message}'
# Core
def __init__(self):
self.api_url = 'https://api.kraken.com/'
self.api_token = os.getenv('KRAKEN_API_TOKEN')
self.api_sec = os.getenv('KRAKEN_API_SEC')
self.asset_pairs = self.get_asset_pairs()['result']
def _kraken_signature(self, urlpath, data, secret):
return base64.b64encode(
hmac.new(
base64.b64decode(secret),
urlpath.encode() + hashlib.sha256(
(str(data['nonce']) + urllib.parse.urlencode(data)).encode()
).digest(),
hashlib.sha512
).digest()).decode()
def _kraken_post(self, uri_path, data):
resp = requests.post(
f'{self.api_url}{uri_path}',
headers = {
'API-Key': self.api_sec,
'API-Sign': self._kraken_signature(uri_path, data, self.api_sec)
},
data=data
).json()
for error in resp['error']:
raise self.KrakenError(error)
def _kraken_get(self, uri_path):
resp = requests.get(f'{self.api_url}{uri_path}').json()
for error in resp['error']:
raise self.KrakenError(err)
return resp
# Misc.
def get_asset_markets(self, asset):
return [
each for each in self.asset_pairs if
self.asset_pairs[each]['base'] == asset or
self.asset_pairs[each]['quote'] == asset
]
# Spot market data
def get_asset_pairs(self):
return _kraken_get('/0/public/AssetPairs')
def get_ohlc(self, asset_pair):
return _kraken_get('/0/public/OHLC?pair={asset_pair}')
def get_depth(self, asset_pair):
return _kraken_get('/0/public/Depth?pair={asset_pair}')
def get_trades(self, asset_pair):
return _kraken_get('/0/public/Trades?pair={asset_pair}')
def get_spread(self, asset_pair):
return _kraken_get('/0/public/Spread?pair={asset_pair}')
# Account data
def get_account_balance(self):
return self._kraken_post('/0/private/Balance', {'nonce': str(int(1000*time.time()))})
# Spot trading
def add_order(self, order):
return self._kraken_post('/0/private/AddOrder', dict(order))