From 85ac99aee021522e60f2b1823b2c6a2998d2a144 Mon Sep 17 00:00:00 2001 From: iuvbio Date: Thu, 21 Mar 2019 19:11:47 +0100 Subject: [PATCH 1/5] move exchange urls to constants --- freqtrade/constants.py | 6 ++++++ freqtrade/exchange/exchange.py | 7 ------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 02062acc4..bd021c327 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -22,6 +22,12 @@ ORDERTIF_POSSIBILITIES = ['gtc', 'fok', 'ioc'] AVAILABLE_PAIRLISTS = ['StaticPairList', 'VolumePairList'] DRY_RUN_WALLET = 999.9 +# Urls to exchange markets, insert quote and base with .format() +_EXCHANGE_URLS = { + "Bittrex": '/Market/Index?MarketName={quote}-{base}', + "Binance": '/tradeDetail.html?symbol={base}_{quote}', +} + TICKER_INTERVAL_MINUTES = { '1m': 1, '3m': 3, diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index ea8bcfac1..7781c85e4 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -21,13 +21,6 @@ logger = logging.getLogger(__name__) API_RETRY_COUNT = 4 -# Urls to exchange markets, insert quote and base with .format() -_EXCHANGE_URLS = { - ccxt.bittrex.__name__: '/Market/Index?MarketName={quote}-{base}', - ccxt.binance.__name__: '/tradeDetail.html?symbol={base}_{quote}', -} - - def retrier_async(f): async def wrapper(*args, **kwargs): count = kwargs.pop('count', API_RETRY_COUNT) From 4005b8d1d254f94840cc00034521e2c7421c17a5 Mon Sep 17 00:00:00 2001 From: iuvbio Date: Thu, 21 Mar 2019 19:12:15 +0100 Subject: [PATCH 2/5] remove the if condition for binance --- freqtrade/exchange/binance.py | 6 ++++++ freqtrade/exchange/exchange.py | 7 +++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 127f4e916..1d633be2b 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -24,3 +24,9 @@ class Binance(Exchange): limit = min(list(filter(lambda x: limit <= x, limit_range))) return super().get_order_book(pair, limit) + + def validate_order_time_in_force(self, order_time_in_force: Dict) -> None: + """ + Checks if order time in force configured in strategy/config are supported + """ + pass diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 7781c85e4..d422e2bbf 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -13,7 +13,7 @@ import ccxt import ccxt.async_support as ccxt_async from pandas import DataFrame -from freqtrade import constants, OperationalException, DependencyException, TemporaryError +from freqtrade import constants, DependencyException, OperationalException, TemporaryError from freqtrade.data.converter import parse_ticker_dataframe logger = logging.getLogger(__name__) @@ -269,9 +269,8 @@ class Exchange(object): Checks if order time in force configured in strategy/config are supported """ if any(v != 'gtc' for k, v in order_time_in_force.items()): - if self.name != 'Binance': - raise OperationalException( - f'Time in force policies are not supporetd for {self.name} yet.') + raise OperationalException( + f'Time in force policies are not supporetd for {self.name} yet.') def exchange_has(self, endpoint: str) -> bool: """ From 8dea640e9a671b315675f27557361e46e5eee084 Mon Sep 17 00:00:00 2001 From: iuvbio Date: Mon, 25 Mar 2019 23:58:02 +0100 Subject: [PATCH 3/5] remove exchange urls --- freqtrade/constants.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index bd021c327..02062acc4 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -22,12 +22,6 @@ ORDERTIF_POSSIBILITIES = ['gtc', 'fok', 'ioc'] AVAILABLE_PAIRLISTS = ['StaticPairList', 'VolumePairList'] DRY_RUN_WALLET = 999.9 -# Urls to exchange markets, insert quote and base with .format() -_EXCHANGE_URLS = { - "Bittrex": '/Market/Index?MarketName={quote}-{base}', - "Binance": '/tradeDetail.html?symbol={base}_{quote}', -} - TICKER_INTERVAL_MINUTES = { '1m': 1, '3m': 3, From e15f2ef11ad07c4f71e5086d0edaad1c22c80e11 Mon Sep 17 00:00:00 2001 From: iuvbio Date: Tue, 26 Mar 2019 00:49:39 +0100 Subject: [PATCH 4/5] add order_time_in_force in _ft_has and revert binance --- freqtrade/exchange/binance.py | 7 +------ freqtrade/exchange/exchange.py | 6 ++++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 1d633be2b..18e754e3f 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -11,6 +11,7 @@ class Binance(Exchange): _ft_has: Dict = { "stoploss_on_exchange": True, + "order_time_in_force": ['gtc', 'fok', 'ioc'], } def get_order_book(self, pair: str, limit: int = 100) -> dict: @@ -24,9 +25,3 @@ class Binance(Exchange): limit = min(list(filter(lambda x: limit <= x, limit_range))) return super().get_order_book(pair, limit) - - def validate_order_time_in_force(self, order_time_in_force: Dict) -> None: - """ - Checks if order time in force configured in strategy/config are supported - """ - pass diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index d422e2bbf..2ec5c0e25 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -65,8 +65,9 @@ class Exchange(object): # Dict to specify which options each exchange implements # TODO: this should be merged with attributes from subclasses # To avoid having to copy/paste this to all subclasses. - _ft_has = { + _ft_has: Dict = { "stoploss_on_exchange": False, + "order_time_in_force": ["gtc"], } def __init__(self, config: dict) -> None: @@ -268,7 +269,8 @@ class Exchange(object): """ Checks if order time in force configured in strategy/config are supported """ - if any(v != 'gtc' for k, v in order_time_in_force.items()): + if any(v not in self._ft_has["order_time_in_force"] + for k, v in order_time_in_force.items()): raise OperationalException( f'Time in force policies are not supporetd for {self.name} yet.') From 9b22d5cab135d743d7c5b3841427a24636de11ee Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 27 Mar 2019 20:51:55 +0100 Subject: [PATCH 5/5] Fix typo, add test for validate_order_tif --- freqtrade/exchange/exchange.py | 2 +- freqtrade/tests/exchange/test_exchange.py | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 2ec5c0e25..011be58e5 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -272,7 +272,7 @@ class Exchange(object): if any(v not in self._ft_has["order_time_in_force"] for k, v in order_time_in_force.items()): raise OperationalException( - f'Time in force policies are not supporetd for {self.name} yet.') + f'Time in force policies are not supported for {self.name} yet.') def exchange_has(self, endpoint: str) -> bool: """ diff --git a/freqtrade/tests/exchange/test_exchange.py b/freqtrade/tests/exchange/test_exchange.py index 736f2298a..eed16d39b 100644 --- a/freqtrade/tests/exchange/test_exchange.py +++ b/freqtrade/tests/exchange/test_exchange.py @@ -139,6 +139,28 @@ def test_exchange_resolver(default_conf, mocker, caplog): caplog.record_tuples) +def test_validate_order_time_in_force(default_conf, mocker, caplog): + caplog.set_level(logging.INFO) + # explicitly test bittrex, exchanges implementing other policies need seperate tests + ex = get_patched_exchange(mocker, default_conf, id="bittrex") + tif = { + "buy": "gtc", + "sell": "gtc", + } + + ex.validate_order_time_in_force(tif) + tif2 = { + "buy": "fok", + "sell": "ioc", + } + with pytest.raises(OperationalException, match=r"Time in force.*not supported for .*"): + ex.validate_order_time_in_force(tif2) + + # Patch to see if this will pass if the values are in the ft dict + ex._ft_has.update({"order_time_in_force": ["gtc", "fok", "ioc"]}) + ex.validate_order_time_in_force(tif2) + + def test_symbol_amount_prec(default_conf, mocker): ''' Test rounds down to 4 Decimal places