diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index 769d076e9..170acbf3d 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -1,6 +1,6 @@ import enum import logging -from typing import List +from typing import List, Dict import arrow diff --git a/freqtrade/exchange/bittrex.py b/freqtrade/exchange/bittrex.py index 0b70e7a3b..306a7b698 100644 --- a/freqtrade/exchange/bittrex.py +++ b/freqtrade/exchange/bittrex.py @@ -1,5 +1,5 @@ import logging -from typing import List, Optional +from typing import List, Optional, Dict import arrow import requests @@ -36,6 +36,11 @@ class Bittrex(Exchange): _EXCHANGE_CONF.update(config) _API = _Bittrex(api_key=_EXCHANGE_CONF['key'], api_secret=_EXCHANGE_CONF['secret']) + @property + def fee(self) -> float: + # See https://bittrex.com/fees + return 0.0025 + def buy(self, pair: str, rate: float, amount: float) -> str: data = _API.buy_limit(pair.replace('_', '-'), amount, rate) if not data['success']: @@ -87,24 +92,27 @@ class Bittrex(Exchange): raise RuntimeError('{}: {}'.format(self.name.upper(), data['message'])) return data + def get_order(self, order_id: str) -> Dict: + data = _API.get_order(order_id) + if not data['success']: + raise RuntimeError('{}: {}'.format(self.name.upper(), data['message'])) + data = data['result'] + return { + 'id': data['OrderUuid'], + 'type': data['Type'], + 'pair': data['Exchange'].replace('-', '_'), + 'opened': data['Opened'], + 'rate': data['PricePerUnit'], + 'amount': data['Quantity'], + 'remaining': data['QuantityRemaining'], + 'closed': data['Closed'], + } + def cancel_order(self, order_id: str) -> None: data = _API.cancel(order_id) if not data['success']: raise RuntimeError('{}: {}'.format(self.name.upper(), data['message'])) - def get_open_orders(self, pair: str) -> List[dict]: - data = _API.get_open_orders(pair.replace('_', '-')) - if not data['success']: - raise RuntimeError('{}: {}'.format(self.name.upper(), data['message'])) - return [{ - 'id': entry['OrderUuid'], - 'type': entry['OrderType'], - 'opened': entry['Opened'], - 'rate': entry['PricePerUnit'], - 'amount': entry['Quantity'], - 'remaining': entry['QuantityRemaining'], - } for entry in data['result']] - def get_pair_detail_url(self, pair: str) -> str: return self.PAIR_DETAIL_METHOD + '?MarketName={}'.format(pair.replace('_', '-')) diff --git a/freqtrade/exchange/interface.py b/freqtrade/exchange/interface.py index 7c6f30be2..364b5afa4 100644 --- a/freqtrade/exchange/interface.py +++ b/freqtrade/exchange/interface.py @@ -1,5 +1,5 @@ from abc import ABC, abstractmethod -from typing import List, Optional +from typing import List, Optional, Dict import arrow @@ -13,6 +13,14 @@ class Exchange(ABC): """ return self.__class__.__name__ + @property + def fee(self) -> float: + """ + Fee for placing an order + :return: percentage in float + """ + return 0.0 + @property @abstractmethod def sleep_time(self) -> float: @@ -100,6 +108,22 @@ class Exchange(ABC): } """ + def get_order(self, order_id: str) -> Dict: + """ + Get order details for the given order_id. + :param order_id: ID as str + :return: dict, format: { + 'id': str, + 'type': str, + 'pair': str, + 'opened': str ISO 8601 datetime, + 'closed': str ISO 8601 datetime, + 'rate': float, + 'amount': float, + 'remaining': int + } + """ + @abstractmethod def cancel_order(self, order_id: str) -> None: """ @@ -108,24 +132,6 @@ class Exchange(ABC): :return: None """ - @abstractmethod - def get_open_orders(self, pair: str) -> List[dict]: - """ - Gets all open orders for given pair. - :param pair: Pair as str, format: BTC_ETC - :return: List of dicts, format: [ - { - 'id': str, - 'type': str, - 'opened': datetime, - 'rate': float, - 'amount': float, - 'remaining': int, - }, - ... - ] - """ - @abstractmethod def get_pair_detail_url(self, pair: str) -> str: """