This commit is contained in:
Eric Meehan 2024-08-30 11:07:52 -04:00
parent f316cf2029
commit f9ebe19191
4 changed files with 77 additions and 109 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
*__pycache__* *__pycache__*
venv/* venv/*
.env .env
kraken.key

101
app.py
View File

@ -1,81 +1,28 @@
import numpy import krakenex
import pandas
from dotenv import load_dotenv from dotenv import load_dotenv
from Kraken import Kraken from pykrakenapi import KrakenAPI
from scipy import stats from scipy.stats import linregress
from time import sleep
load_dotenv() k = krakenex.API()
k.load_key('kraken.key')
kraken = KrakenAPI(k, tier='Pro')
kraken = Kraken() def get_markets_by_asset(asset):
raw = { tradable_asset_pairs = kraken.get_tradable_asset_pairs()
asset: { return tradable_asset_pairs[
asset_pair: kraken.ohlc(asset_pair) for asset_pair in kraken.ASSET_PAIRS[asset] ((tradable_asset_pairs['base'] == asset | tradable_asset_pairs['quote'] == asset)
} for asset in kraken.ASSETS & (tradable_asset_pairs['status'] == 'online'))
} ]
processed = {
asset: { def get_ohlc_linear_regression(ohlc):
asset_pair: { regressions = pandas.DataFrame({
'time': numpy.array( 'open': linregress(ohlc['time'].astype(float), ohlc['open'].astype(float)),
[int(each[0]) for each in raw[asset][asset_pair]['result'][kraken.ASSET_PAIRS[asset][asset_pair]]] 'high': linregress(ohlc['time'].astype(float), ohlc['high'].astype(float)),
), 'low': linregress(ohlc['time'].astype(float), ohlc['low'].astype(float)),
'open': numpy.array( 'close': linregress(ohlc['time'].astype(float), ohlc['close'].astype(float))
[float(each[1]) for each in raw[asset][asset_pair]['result'][kraken.ASSET_PAIRS[asset][asset_pair]]] }).transpose()
), regressions.columns = ['slope', 'intercept', 'r_value', 'p_value', 'stderr']
'high': numpy.array( return regressions
[float(each[2]) for each in raw[asset][asset_pair]['result'][kraken.ASSET_PAIRS[asset][asset_pair]]]
),
'low': numpy.array(
[float(each[3]) for each in raw[asset][asset_pair]['result'][kraken.ASSET_PAIRS[asset][asset_pair]]]
),
'close': numpy.array(
[float(each[4]) for each in raw[asset][asset_pair]['result'][kraken.ASSET_PAIRS[asset][asset_pair]]]
),
'volume': numpy.array(
[float(each[5]) for each in raw[asset][asset_pair]['result'][kraken.ASSET_PAIRS[asset][asset_pair]]]
),
'count': numpy.array(
[float(each[6]) for each in raw[asset][asset_pair]['result'][kraken.ASSET_PAIRS[asset][asset_pair]]]
)
} for asset_pair in kraken.ASSET_PAIRS[asset]
} for asset in kraken.ASSETS
}
linregresses = {
asset: {
asset_pair: {
'open': stats.linregress(
processed[asset][asset_pair]['time'],
processed[asset][asset_pair]['open']
),
'high': stats.linregress(
processed[asset][asset_pair]['time'],
processed[asset][asset_pair]['high']
),
'low': stats.linregress(
processed[asset][asset_pair]['time'],
processed[asset][asset_pair]['low']
),
'close': stats.linregress(
processed[asset][asset_pair]['time'],
processed[asset][asset_pair]['close']
)
} for asset_pair in kraken.ASSET_PAIRS[asset]
} for asset in kraken.ASSETS
}
slopes = {
asset: {
asset_pair: {
'open': linregresses[asset][asset_pair]['open'].slope,
'high': linregresses[asset][asset_pair]['high'].slope,
'low': linregresses[asset][asset_pair]['low'].slope,
'close': linregresses[asset][asset_pair]['close'].slope
} for asset_pair in kraken.ASSET_PAIRS[asset]
} for asset in kraken.ASSETS
}
averages = {
asset: {
asset_pair: sum(
[slopes[asset][asset_pair][each] for each in slopes[asset][asset_pair]]
)/4 for asset_pair in kraken.ASSET_PAIRS[asset]
} for asset in kraken.ASSETS
}
print(averages)

View File

@ -7,26 +7,6 @@ import time
import urllib.parse import urllib.parse
class Kraken(): class Kraken():
ASSETS = [
'ZUSD',
'XETH',
'XXBT'
]
ASSET_PAIRS = {
'ZUSD': {
'ETHUSD': 'XETHZUSD',
'XBTUSD': 'XXBTZUSD'
},
'XETH': {
'ETHUSD': 'XETHZUSD',
'ETHXBT': 'XETHXXBT'
},
'XXBT': {
'ETHXBT': 'XETHXXBT',
'XBTUSD': 'XXBTZUSD'
}
}
class Order(): class Order():
@ -76,12 +56,21 @@ class Kraken():
data['userref'] = self.userref data['userref'] = self.userref
return data 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): def __init__(self):
self.api_url = 'https://api.kraken.com/' self.api_url = 'https://api.kraken.com/'
self.api_token = os.getenv('KRAKEN_API_TOKEN') self.api_token = os.getenv('KRAKEN_API_TOKEN')
self.api_sec = os.getenv('KRAKEN_API_SEC') self.api_sec = os.getenv('KRAKEN_API_SEC')
self.asset_pairs = self.get_asset_pairs()['result']
def _get_kraken_signature(self, urlpath, data, secret): def _kraken_signature(self, urlpath, data, secret):
return base64.b64encode( return base64.b64encode(
hmac.new( hmac.new(
base64.b64decode(secret), base64.b64decode(secret),
@ -91,21 +80,52 @@ class Kraken():
hashlib.sha512 hashlib.sha512
).digest()).decode() ).digest()).decode()
def _kraken_request(self, uri_path, data): def _kraken_post(self, uri_path, data):
return requests.post( resp = requests.post(
(self.api_url + uri_path), f'{self.api_url}{uri_path}',
headers = { headers = {
'API-Key': self.api_sec, 'API-Key': self.api_sec,
'API-Sign': self._get_kraken_signature(uri_path, data, self.api_sec) 'API-Sign': self._kraken_signature(uri_path, data, self.api_sec)
}, },
data=data data=data
).json() ).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): def get_account_balance(self):
return self._kraken_request('/0/private/Balance', {'nonce': str(int(1000*time.time()))}) return self._kraken_post('/0/private/Balance', {'nonce': str(int(1000*time.time()))})
# Spot trading
def add_order(self, order): def add_order(self, order):
return self._kraken_request('/0/private/AddOrder', dict(order)) return self._kraken_post('/0/private/AddOrder', dict(order))
def ohlc(self, asset_pair):
return requests.get(f'{self.api_url}/0/public/OHLC?pair={asset_pair}').json()

View File

@ -1,4 +1,4 @@
numpy krakenex
pykrakenapi
python-dotenv python-dotenv
requests
scipy scipy