diff --git a/README.md b/README.md index 96a718a..2cb270f 100644 --- a/README.md +++ b/README.md @@ -77,10 +77,13 @@ http://www.coindesk.com/api ### CryptoMKT +Public API: + from trading_api_wrappers import CryptoMKT - client = CryptoMKT() + client = CryptoMKT.Public() -*No API Docs for CryptoMKT!* +CryptoMKT API Doc: +https://developers.cryptomkt.com/ ## Licence diff --git a/requirements.txt b/requirements.txt index 1e15e3c..623ef4b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ coverage==4.4.1 -pytest==3.2.2 +pytest==3.2.3 python-decouple==3.1 requests==2.18.4 -tox==2.8.2 +tox==2.9.1 diff --git a/setup.py b/setup.py index d4613c8..bbcda9f 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ setup( name='trading_api_wrappers', - version='0.3.5', + version='0.3.7', description='Trading API Wrappers for Python 3.5', url='https://github.com/delta575/trading-api-wrappers', author='Felipe Aránguiz, Sebastián Aránguiz', diff --git a/trading_api_wrappers/cryptomkt/__init__.py b/trading_api_wrappers/cryptomkt/__init__.py index 6d8220f..b58aafe 100644 --- a/trading_api_wrappers/cryptomkt/__init__.py +++ b/trading_api_wrappers/cryptomkt/__init__.py @@ -1,6 +1,6 @@ from . import constants as _c from . import models as _m -from .client import CryptoMKTPublic +from .client_public import CryptoMKTPublic class CryptoMKT(CryptoMKTPublic): @@ -9,7 +9,10 @@ class CryptoMKT(CryptoMKTPublic): # Enum Types Currency = _c.Currency Market = _c.Market + OrderBook = _c.OrderBook TimeFrame = _c.TimeFrame + # Clients + Public = CryptoMKTPublic __all__ = [ diff --git a/trading_api_wrappers/cryptomkt/client.py b/trading_api_wrappers/cryptomkt/client.py deleted file mode 100644 index a94822c..0000000 --- a/trading_api_wrappers/cryptomkt/client.py +++ /dev/null @@ -1,28 +0,0 @@ -# local -from . import constants as _c -from . import models as _m -from ..base import Client -from .server import CryptoMKTServer - -_p = _c.Path - - -class CryptoMKTPublic(Client): - def __init__(self, timeout=30): - Client.__init__(self, CryptoMKTServer(), timeout) - - def prices(self, - market_id: _c.Market, - time_frame: _c.TimeFrame): - market_id = _c.Market.check(market_id).value - time_frame = _c.TimeFrame.check(time_frame).value - path_arg = (market_id, time_frame) - url, path = self.url_path_for(_p.PRICES, path_arg=path_arg) - data = self.get(url)['data'] - return _m.PriceCandles.create_from_json(data) - - def last_prices(self, - market_id: _c.Market, - time_frame: _c.TimeFrame = _c.TimeFrame.MINUTES_1): - prices = self.prices(market_id, time_frame) - return _m.LastPriceCandle.create_from_data(prices) diff --git a/trading_api_wrappers/cryptomkt/client_public.py b/trading_api_wrappers/cryptomkt/client_public.py new file mode 100644 index 0000000..7bd12bf --- /dev/null +++ b/trading_api_wrappers/cryptomkt/client_public.py @@ -0,0 +1,61 @@ +# local +from . import constants as _c +from . import models as _m +from ..base import Client +from .server import CryptoMKTServer + +_p = _c.Path + + +class CryptoMKTPublic(Client): + + error_key = 'message' + + def __init__(self, timeout=30): + Client.__init__(self, CryptoMKTServer(), timeout) + + def markets(self): + url = self.url_for(_p.MARKETS) + data = self.get(url)['data'] + return data + + def ticker(self, market_id: _c.Market): + url = self.url_for(_p.TICKER) + params = { + 'market': _c.Market.check(market_id).value + } + data = self.get(url, params=params)['data'] + return _m.Ticker.create_from_json(data) + + def order_book(self, + market_id: _c.Market, + book_side: _c.OrderBook, + page: int=None, + limit: int=None): + params = { + 'market': _c.Market.check(market_id).value, + 'type': _c.OrderBook.check(book_side).value, + 'page': page, + 'limit': limit + } + url = self.url_for(_p.ORDER_BOOK) + data = self.get(url, params=params) + return _m.OrderBook.create_from_json(data['data'], data['pagination']) + + def trades(self, + market_id: _c.Market, + start: str=None, + end: str=None, + page: int=None, + limit: int=None): + params = { + 'market': _c.Market.check(market_id).value, + 'start': start, + 'end': end, + 'page': page, + 'limit': limit + } + url = self.url_for(_p.TRADES) + data = self.get(url, params=params) + return _m.Trades.create_from_json( + data['data'], data.get('pagination')) diff --git a/trading_api_wrappers/cryptomkt/constants.py b/trading_api_wrappers/cryptomkt/constants.py index 16ebe16..8ee68e8 100644 --- a/trading_api_wrappers/cryptomkt/constants.py +++ b/trading_api_wrappers/cryptomkt/constants.py @@ -3,7 +3,17 @@ # API paths class Path(object): - PRICES = '%s/%s.json' + MARKETS = 'market' + TICKER = "ticker" + ORDER_BOOK = 'book' + TRADES = 'trades' + ORDERS = 'orders' + ACTIVE_ORDER = 'orders/active' + EXCECUTED_ORDERS = 'orders/executed' + NEW_ORDER = 'orders/create' + ORDER_STATUS = 'orders/status' + CANCEL_ORDER = 'orders/cancel' + BALANCE = 'balance' class Currency(_Enum): @@ -13,6 +23,10 @@ class Currency(_Enum): ETH = 'ETH' EUR = 'EUR' +class OrderBook(_Enum): + BUY = 'buy' + SELL = 'sell' + class Market(_Enum): ETH_ARS = 'ethars' diff --git a/trading_api_wrappers/cryptomkt/models.py b/trading_api_wrappers/cryptomkt/models.py index 4a2271d..111141e 100644 --- a/trading_api_wrappers/cryptomkt/models.py +++ b/trading_api_wrappers/cryptomkt/models.py @@ -5,6 +5,33 @@ def parse_datetime(datetime_str): return datetime.strptime(datetime_str, '%Y-%m-%d %H:%M') +def parse_iso_datetime(datetime_str): + return datetime.strptime(datetime_str, '%Y-%m-%dT%H:%M:%S.%f') + +def int_or_null(value): + return int(value) if value != 'null' else None + + +class Pagination( + namedtuple('pagination', [ + 'previous', + 'limit', + 'page', + 'next' + ]) +): + + @classmethod + def create_from_json(cls, meta): + if meta: + return cls( + previous=int_or_null(meta['previous']), + limit=int(meta['limit']), + page=int(meta['page']), + next=int_or_null(meta['next']) + ) + return meta + class PriceCandle( namedtuple('price', [ @@ -60,3 +87,96 @@ def create_from_data(cls, prices: PriceCandles): ask=prices.asks[1], bid=prices.bids[1], ) + + +class Ticker( + namedtuple('ticker', [ + 'high', + 'low', + 'ask', + 'bid', + 'last_price', + 'volume', + 'market', + 'timestamp' + ]) +): + + @classmethod + def create_from_json(cls, ticker): + return cls( + high=float(ticker[0]['high']), + low=float(ticker[0]['low']), + ask=float(ticker[0]['ask']), + bid=float(ticker[0]['bid']), + last_price=float(ticker[0]['last_price']), + volume=float(ticker[0]['volume']), + market=ticker[0]['market'], + timestamp=parse_iso_datetime(ticker[0]['timestamp']) + ) + +class OrderBookEntry( + namedtuple('book_entry', [ + 'price', + 'amount', + 'timestamp' + ]) +): + @classmethod + def create_from_json(cls, book_entry): + return cls( + price=float(book_entry['price']), + amount=float(book_entry['amount']), + timestamp=parse_iso_datetime(book_entry['timestamp']) + ) + + +class OrderBook( + namedtuple('order_book', [ + 'order_book', + 'pagination', + ]) +): + + @classmethod + def create_from_json(cls, book, pagination): + return cls( + order_book=[OrderBookEntry.create_from_json(book_entry) + for book_entry in book], + pagination=Pagination.create_from_json(pagination), + ) + +class TradesEntry( + namedtuple('trades_entry', [ + 'market_taker', + 'timestamp', + 'price', + 'amount', + 'market' + ]) +): + @classmethod + def create_from_json(cls, trades_entry): + return cls( + market_taker=trades_entry['market_taker'], + timestamp=parse_iso_datetime(trades_entry['timestamp']), + price=float(trades_entry['price']), + amount=float(trades_entry['amount']), + market=trades_entry['market'] + ) + + +class Trades( + namedtuple('trades', [ + 'trades', + 'pagination', + ]) +): + + @classmethod + def create_from_json(cls, trades, pagination): + return cls( + trades=[TradesEntry.create_from_json(trades_entry) + for trades_entry in trades], + pagination=Pagination.create_from_json(pagination), + ) \ No newline at end of file diff --git a/trading_api_wrappers/cryptomkt/server.py b/trading_api_wrappers/cryptomkt/server.py index c002ce6..0b2361d 100644 --- a/trading_api_wrappers/cryptomkt/server.py +++ b/trading_api_wrappers/cryptomkt/server.py @@ -2,10 +2,11 @@ # Server PROTOCOL = 'https' -HOST = 'www.cryptomkt.com/api' +HOST = 'api.cryptomkt.com' +VERSION = 'v1' # CryptoMKT server class CryptoMKTServer(Server): def __init__(self): - Server.__init__(self, PROTOCOL, HOST) + Server.__init__(self, PROTOCOL, HOST, VERSION) \ No newline at end of file