limit usage of ccxt to freqtrade/exchange only
This commit is contained in:
		| @@ -9,14 +9,15 @@ from argparse import Namespace | |||||||
| from logging.handlers import RotatingFileHandler | from logging.handlers import RotatingFileHandler | ||||||
| from typing import Any, Dict, List, Optional | from typing import Any, Dict, List, Optional | ||||||
|  |  | ||||||
| import ccxt |  | ||||||
| from jsonschema import Draft4Validator, validate | from jsonschema import Draft4Validator, validate | ||||||
| from jsonschema.exceptions import ValidationError, best_match | from jsonschema.exceptions import ValidationError, best_match | ||||||
|  |  | ||||||
| from freqtrade import OperationalException, constants | from freqtrade import OperationalException, constants | ||||||
|  | from freqtrade.exchange import is_exchange_supported, supported_exchanges | ||||||
| from freqtrade.misc import deep_merge_dicts | from freqtrade.misc import deep_merge_dicts | ||||||
| from freqtrade.state import RunMode | from freqtrade.state import RunMode | ||||||
|  |  | ||||||
|  |  | ||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -374,10 +375,11 @@ class Configuration(object): | |||||||
|         :return: True or raised an exception if the exchange if not supported |         :return: True or raised an exception if the exchange if not supported | ||||||
|         """ |         """ | ||||||
|         exchange = config.get('exchange', {}).get('name').lower() |         exchange = config.get('exchange', {}).get('name').lower() | ||||||
|         if exchange not in ccxt.exchanges: |         if not is_exchange_supported(exchange): | ||||||
|  |  | ||||||
|             exception_msg = f'Exchange "{exchange}" not supported.\n' \ |             exception_msg = f'Exchange "{exchange}" not supported.\n' \ | ||||||
|                             f'The following exchanges are supported: {", ".join(ccxt.exchanges)}' |                             f'The following exchanges are supported: ' \ | ||||||
|  |                             f'{", ".join(supported_exchanges())}' | ||||||
|  |  | ||||||
|             logger.critical(exception_msg) |             logger.critical(exception_msg) | ||||||
|             raise OperationalException( |             raise OperationalException( | ||||||
|   | |||||||
| @@ -2,9 +2,9 @@ | |||||||
| Functions to convert data from one format to another | Functions to convert data from one format to another | ||||||
| """ | """ | ||||||
| import logging | import logging | ||||||
|  |  | ||||||
| import pandas as pd | import pandas as pd | ||||||
| from pandas import DataFrame, to_datetime | from pandas import DataFrame, to_datetime | ||||||
| from freqtrade.misc import timeframe_to_minutes |  | ||||||
|  |  | ||||||
|  |  | ||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
| @@ -58,6 +58,8 @@ def ohlcv_fill_up_missing_data(dataframe: DataFrame, ticker_interval: str) -> Da | |||||||
|     using the previous close as price for "open", "high" "low" and "close", volume is set to 0 |     using the previous close as price for "open", "high" "low" and "close", volume is set to 0 | ||||||
|  |  | ||||||
|     """ |     """ | ||||||
|  |     from freqtrade.exchange import timeframe_to_minutes | ||||||
|  |  | ||||||
|     ohlc_dict = { |     ohlc_dict = { | ||||||
|         'open': 'first', |         'open': 'first', | ||||||
|         'high': 'max', |         'high': 'max', | ||||||
|   | |||||||
| @@ -1,10 +1,10 @@ | |||||||
| """ | """ | ||||||
| Handle historic data (ohlcv). | Handle historic data (ohlcv). | ||||||
| includes: |  | ||||||
|  | Includes: | ||||||
| * load data for a pair (or a list of pairs) from disk | * load data for a pair (or a list of pairs) from disk | ||||||
| * download data from exchange and store to disk | * download data from exchange and store to disk | ||||||
| """ | """ | ||||||
|  |  | ||||||
| import logging | import logging | ||||||
| from pathlib import Path | from pathlib import Path | ||||||
| from typing import Optional, List, Dict, Tuple, Any | from typing import Optional, List, Dict, Tuple, Any | ||||||
| @@ -15,8 +15,7 @@ from pandas import DataFrame | |||||||
| from freqtrade import misc, OperationalException | from freqtrade import misc, OperationalException | ||||||
| from freqtrade.arguments import TimeRange | from freqtrade.arguments import TimeRange | ||||||
| from freqtrade.data.converter import parse_ticker_dataframe | from freqtrade.data.converter import parse_ticker_dataframe | ||||||
| from freqtrade.exchange import Exchange | from freqtrade.exchange import Exchange, timeframe_to_minutes | ||||||
| from freqtrade.misc import timeframe_to_minutes |  | ||||||
|  |  | ||||||
|  |  | ||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
|   | |||||||
| @@ -1,3 +1,8 @@ | |||||||
| from freqtrade.exchange.exchange import Exchange  # noqa: F401 | from freqtrade.exchange.exchange import Exchange  # noqa: F401 | ||||||
|  | from freqtrade.exchange.exchange import (is_exchange_supported,  # noqa: F401 | ||||||
|  |                                          supported_exchanges) | ||||||
|  | from freqtrade.exchange.exchange import (timeframe_to_seconds,  # noqa: F401 | ||||||
|  |                                          timeframe_to_minutes, | ||||||
|  |                                          timeframe_to_msecs) | ||||||
| from freqtrade.exchange.kraken import Kraken  # noqa: F401 | from freqtrade.exchange.kraken import Kraken  # noqa: F401 | ||||||
| from freqtrade.exchange.binance import Binance  # noqa: F401 | from freqtrade.exchange.binance import Binance  # noqa: F401 | ||||||
|   | |||||||
| @@ -1,5 +1,7 @@ | |||||||
| # pragma pylint: disable=W0603 | # pragma pylint: disable=W0603 | ||||||
| """ Cryptocurrency Exchanges support """ | """ | ||||||
|  | Cryptocurrency Exchanges support | ||||||
|  | """ | ||||||
| import logging | import logging | ||||||
| import inspect | import inspect | ||||||
| from random import randint | from random import randint | ||||||
| @@ -16,7 +18,6 @@ from pandas import DataFrame | |||||||
| from freqtrade import (constants, DependencyException, OperationalException, | from freqtrade import (constants, DependencyException, OperationalException, | ||||||
|                        TemporaryError, InvalidOrderException) |                        TemporaryError, InvalidOrderException) | ||||||
| from freqtrade.data.converter import parse_ticker_dataframe | from freqtrade.data.converter import parse_ticker_dataframe | ||||||
| from freqtrade.misc import timeframe_to_seconds, timeframe_to_msecs |  | ||||||
|  |  | ||||||
|  |  | ||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
| @@ -138,7 +139,7 @@ class Exchange(object): | |||||||
|         # Find matching class for the given exchange name |         # Find matching class for the given exchange name | ||||||
|         name = exchange_config['name'] |         name = exchange_config['name'] | ||||||
|  |  | ||||||
|         if name not in ccxt_module.exchanges: |         if not is_exchange_supported(name, ccxt_module): | ||||||
|             raise OperationalException(f'Exchange {name} is not supported') |             raise OperationalException(f'Exchange {name} is not supported') | ||||||
|  |  | ||||||
|         ex_config = { |         ex_config = { | ||||||
| @@ -690,3 +691,35 @@ class Exchange(object): | |||||||
|                 f'Could not get fee info due to {e.__class__.__name__}. Message: {e}') |                 f'Could not get fee info due to {e.__class__.__name__}. Message: {e}') | ||||||
|         except ccxt.BaseError as e: |         except ccxt.BaseError as e: | ||||||
|             raise OperationalException(e) |             raise OperationalException(e) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def is_exchange_supported(exchange: str, ccxt_module=None) -> bool: | ||||||
|  |     return exchange in supported_exchanges(ccxt_module) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def supported_exchanges(ccxt_module=None) -> str: | ||||||
|  |     exchanges = ccxt_module.exchanges if ccxt_module is not None else ccxt.exchanges | ||||||
|  |     return exchanges | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def timeframe_to_seconds(ticker_interval: str) -> int: | ||||||
|  |     """ | ||||||
|  |     Translates the timeframe interval value written in the human readable | ||||||
|  |     form ('1m', '5m', '1h', '1d', '1w', etc.) to the number | ||||||
|  |     of seconds for one timeframe interval. | ||||||
|  |     """ | ||||||
|  |     return ccxt.Exchange.parse_timeframe(ticker_interval) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def timeframe_to_minutes(ticker_interval: str) -> int: | ||||||
|  |     """ | ||||||
|  |     Same as above, but returns minutes. | ||||||
|  |     """ | ||||||
|  |     return ccxt.Exchange.parse_timeframe(ticker_interval) // 60 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def timeframe_to_msecs(ticker_interval: str) -> int: | ||||||
|  |     """ | ||||||
|  |     Same as above, but returns milliseconds. | ||||||
|  |     """ | ||||||
|  |     return ccxt.Exchange.parse_timeframe(ticker_interval) * 1000 | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ from freqtrade import (DependencyException, OperationalException, InvalidOrderEx | |||||||
| from freqtrade.data.converter import order_book_to_dataframe | from freqtrade.data.converter import order_book_to_dataframe | ||||||
| from freqtrade.data.dataprovider import DataProvider | from freqtrade.data.dataprovider import DataProvider | ||||||
| from freqtrade.edge import Edge | from freqtrade.edge import Edge | ||||||
| from freqtrade.misc import timeframe_to_minutes | from freqtrade.exchange import timeframe_to_minutes | ||||||
| from freqtrade.persistence import Trade | from freqtrade.persistence import Trade | ||||||
| from freqtrade.rpc import RPCManager, RPCMessageType | from freqtrade.rpc import RPCManager, RPCMessageType | ||||||
| from freqtrade.resolvers import ExchangeResolver, StrategyResolver, PairListResolver | from freqtrade.resolvers import ExchangeResolver, StrategyResolver, PairListResolver | ||||||
| @@ -460,7 +460,7 @@ class FreqtradeBot(object): | |||||||
|     def get_real_amount(self, trade: Trade, order: Dict) -> float: |     def get_real_amount(self, trade: Trade, order: Dict) -> float: | ||||||
|         """ |         """ | ||||||
|         Get real amount for the trade |         Get real amount for the trade | ||||||
|         Necessary for self.exchanges which charge fees in base currency (e.g. binance) |         Necessary for exchanges which charge fees in base currency (e.g. binance) | ||||||
|         """ |         """ | ||||||
|         order_amount = order['amount'] |         order_amount = order['amount'] | ||||||
|         # Only run for closed orders |         # Only run for closed orders | ||||||
|   | |||||||
| @@ -1,18 +1,17 @@ | |||||||
| """ | """ | ||||||
| Various tool function for Freqtrade and scripts | Various tool function for Freqtrade and scripts | ||||||
| """ | """ | ||||||
|  |  | ||||||
| import gzip | import gzip | ||||||
| import logging | import logging | ||||||
| import re | import re | ||||||
| from datetime import datetime | from datetime import datetime | ||||||
| from typing import Dict | from typing import Dict | ||||||
|  |  | ||||||
| from ccxt import Exchange |  | ||||||
| import numpy as np | import numpy as np | ||||||
| from pandas import DataFrame | from pandas import DataFrame | ||||||
| import rapidjson | import rapidjson | ||||||
|  |  | ||||||
|  |  | ||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -132,26 +131,3 @@ def deep_merge_dicts(source, destination): | |||||||
|             destination[key] = value |             destination[key] = value | ||||||
|  |  | ||||||
|     return destination |     return destination | ||||||
|  |  | ||||||
|  |  | ||||||
| def timeframe_to_seconds(ticker_interval: str) -> int: |  | ||||||
|     """ |  | ||||||
|     Translates the timeframe interval value written in the human readable |  | ||||||
|     form ('1m', '5m', '1h', '1d', '1w', etc.) to the number |  | ||||||
|     of seconds for one timeframe interval. |  | ||||||
|     """ |  | ||||||
|     return Exchange.parse_timeframe(ticker_interval) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def timeframe_to_minutes(ticker_interval: str) -> int: |  | ||||||
|     """ |  | ||||||
|     Same as above, but returns minutes. |  | ||||||
|     """ |  | ||||||
|     return Exchange.parse_timeframe(ticker_interval) // 60 |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def timeframe_to_msecs(ticker_interval: str) -> int: |  | ||||||
|     """ |  | ||||||
|     Same as above, but returns milliseconds. |  | ||||||
|     """ |  | ||||||
|     return Exchange.parse_timeframe(ticker_interval) * 1000 |  | ||||||
|   | |||||||
| @@ -19,12 +19,14 @@ from freqtrade.arguments import Arguments | |||||||
| from freqtrade.configuration import Configuration | from freqtrade.configuration import Configuration | ||||||
| from freqtrade.data import history | from freqtrade.data import history | ||||||
| from freqtrade.data.dataprovider import DataProvider | from freqtrade.data.dataprovider import DataProvider | ||||||
| from freqtrade.misc import file_dump_json, timeframe_to_minutes | from freqtrade.exchange import timeframe_to_minutes | ||||||
|  | from freqtrade.misc import file_dump_json | ||||||
| from freqtrade.persistence import Trade | from freqtrade.persistence import Trade | ||||||
| from freqtrade.resolvers import ExchangeResolver, StrategyResolver | from freqtrade.resolvers import ExchangeResolver, StrategyResolver | ||||||
| from freqtrade.state import RunMode | from freqtrade.state import RunMode | ||||||
| from freqtrade.strategy.interface import SellType, IStrategy | from freqtrade.strategy.interface import SellType, IStrategy | ||||||
|  |  | ||||||
|  |  | ||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ from freqtrade.strategy.interface import IStrategy | |||||||
| # Import Default-Strategy to have hyperopt correctly resolve | # Import Default-Strategy to have hyperopt correctly resolve | ||||||
| from freqtrade.strategy.default_strategy import DefaultStrategy  # noqa: F401 | from freqtrade.strategy.default_strategy import DefaultStrategy  # noqa: F401 | ||||||
|  |  | ||||||
|  |  | ||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -16,7 +17,6 @@ def import_strategy(strategy: IStrategy, config: dict) -> IStrategy: | |||||||
|     """ |     """ | ||||||
|  |  | ||||||
|     # Copy all attributes from base class and class |     # Copy all attributes from base class and class | ||||||
|  |  | ||||||
|     comb = {**strategy.__class__.__dict__, **strategy.__dict__} |     comb = {**strategy.__class__.__dict__, **strategy.__dict__} | ||||||
|  |  | ||||||
|     # Delete '_abc_impl' from dict as deepcopy fails on 3.7 with |     # Delete '_abc_impl' from dict as deepcopy fails on 3.7 with | ||||||
| @@ -26,6 +26,7 @@ def import_strategy(strategy: IStrategy, config: dict) -> IStrategy: | |||||||
|         del comb['_abc_impl'] |         del comb['_abc_impl'] | ||||||
|  |  | ||||||
|     attr = deepcopy(comb) |     attr = deepcopy(comb) | ||||||
|  |  | ||||||
|     # Adjust module name |     # Adjust module name | ||||||
|     attr['__module__'] = 'freqtrade.strategy' |     attr['__module__'] = 'freqtrade.strategy' | ||||||
|  |  | ||||||
|   | |||||||
| @@ -13,10 +13,11 @@ import arrow | |||||||
| from pandas import DataFrame | from pandas import DataFrame | ||||||
|  |  | ||||||
| from freqtrade.data.dataprovider import DataProvider | from freqtrade.data.dataprovider import DataProvider | ||||||
| from freqtrade.misc import timeframe_to_minutes | from freqtrade.exchange import timeframe_to_minutes | ||||||
| from freqtrade.persistence import Trade | from freqtrade.persistence import Trade | ||||||
| from freqtrade.wallets import Wallets | from freqtrade.wallets import Wallets | ||||||
|  |  | ||||||
|  |  | ||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ from typing import NamedTuple, List | |||||||
| import arrow | import arrow | ||||||
| from pandas import DataFrame | from pandas import DataFrame | ||||||
|  |  | ||||||
| from freqtrade.misc import timeframe_to_minutes | from freqtrade.exchange import timeframe_to_minutes | ||||||
| from freqtrade.strategy.interface import SellType | from freqtrade.strategy.interface import SellType | ||||||
|  |  | ||||||
| ticker_start_time = arrow.get(2018, 10, 3) | ticker_start_time = arrow.get(2018, 10, 3) | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
| from freqtrade import optimize | from freqtrade import optimize | ||||||
| from freqtrade.arguments import TimeRange | from freqtrade.arguments import TimeRange | ||||||
| from freqtrade.data import history | from freqtrade.data import history | ||||||
| from freqtrade.misc import timeframe_to_minutes | from freqtrade.exchange import timeframe_to_minutes | ||||||
| from freqtrade.strategy.default_strategy import DefaultStrategy | from freqtrade.strategy.default_strategy import DefaultStrategy | ||||||
| from freqtrade.tests.conftest import log_has, patch_exchange | from freqtrade.tests.conftest import log_has, patch_exchange | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,8 @@ | |||||||
| import os | import os | ||||||
| import sys | import sys | ||||||
|  |  | ||||||
|  | from freqtrade.exchange import is_exchange_supported, supported_exchanges | ||||||
|  |  | ||||||
| root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | ||||||
| sys.path.append(root + '/python') | sys.path.append(root + '/python') | ||||||
|  |  | ||||||
| @@ -44,7 +46,7 @@ def dump(*args): | |||||||
|  |  | ||||||
|  |  | ||||||
| def print_supported_exchanges(): | def print_supported_exchanges(): | ||||||
|     dump('Supported exchanges:', green(', '.join(ccxt.exchanges))) |     dump('Supported exchanges:', green(', '.join(supported_exchanges()))) | ||||||
|  |  | ||||||
|  |  | ||||||
| try: | try: | ||||||
| @@ -52,9 +54,7 @@ try: | |||||||
|     id = sys.argv[1]  # get exchange id from command line arguments |     id = sys.argv[1]  # get exchange id from command line arguments | ||||||
|  |  | ||||||
|     # check if the exchange is supported by ccxt |     # check if the exchange is supported by ccxt | ||||||
|     exchange_found = id in ccxt.exchanges |     if is_exchange_supported(id): | ||||||
|  |  | ||||||
|     if exchange_found: |  | ||||||
|         dump('Instantiating', green(id), 'exchange') |         dump('Instantiating', green(id), 'exchange') | ||||||
|  |  | ||||||
|         # instantiate the exchange by id |         # instantiate the exchange by id | ||||||
| @@ -79,9 +79,7 @@ try: | |||||||
|  |  | ||||||
|         for (k, v) in tuples: |         for (k, v) in tuples: | ||||||
|             dump('{:<15} {:<15} {:<15} {:<15}'.format(v['id'], v['symbol'], v['base'], v['quote'])) |             dump('{:<15} {:<15} {:<15} {:<15}'.format(v['id'], v['symbol'], v['base'], v['quote'])) | ||||||
|  |  | ||||||
|     else: |     else: | ||||||
|  |  | ||||||
|         dump('Exchange ' + red(id) + ' not found') |         dump('Exchange ' + red(id) + ' not found') | ||||||
|         print_supported_exchanges() |         print_supported_exchanges() | ||||||
|  |  | ||||||
|   | |||||||
| @@ -27,10 +27,12 @@ from plotly.offline import plot | |||||||
| from freqtrade.arguments import Arguments | from freqtrade.arguments import Arguments | ||||||
| from freqtrade.configuration import Configuration | from freqtrade.configuration import Configuration | ||||||
| from freqtrade.data import history | from freqtrade.data import history | ||||||
| from freqtrade.misc import common_datearray, timeframe_to_seconds | from freqtrade.exchange import timeframe_to_seconds | ||||||
|  | from freqtrade.misc import common_datearray | ||||||
| from freqtrade.resolvers import StrategyResolver | from freqtrade.resolvers import StrategyResolver | ||||||
| from freqtrade.state import RunMode | from freqtrade.state import RunMode | ||||||
|  |  | ||||||
|  |  | ||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user