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 typing import Any, Dict, List, Optional | ||||
|  | ||||
| import ccxt | ||||
| from jsonschema import Draft4Validator, validate | ||||
| from jsonschema.exceptions import ValidationError, best_match | ||||
|  | ||||
| from freqtrade import OperationalException, constants | ||||
| from freqtrade.exchange import is_exchange_supported, supported_exchanges | ||||
| from freqtrade.misc import deep_merge_dicts | ||||
| from freqtrade.state import RunMode | ||||
|  | ||||
|  | ||||
| logger = logging.getLogger(__name__) | ||||
|  | ||||
|  | ||||
| @@ -374,10 +375,11 @@ class Configuration(object): | ||||
|         :return: True or raised an exception if the exchange if not supported | ||||
|         """ | ||||
|         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' \ | ||||
|                             f'The following exchanges are supported: {", ".join(ccxt.exchanges)}' | ||||
|                             f'The following exchanges are supported: ' \ | ||||
|                             f'{", ".join(supported_exchanges())}' | ||||
|  | ||||
|             logger.critical(exception_msg) | ||||
|             raise OperationalException( | ||||
|   | ||||
| @@ -2,9 +2,9 @@ | ||||
| Functions to convert data from one format to another | ||||
| """ | ||||
| import logging | ||||
|  | ||||
| import pandas as pd | ||||
| from pandas import DataFrame, to_datetime | ||||
| from freqtrade.misc import timeframe_to_minutes | ||||
|  | ||||
|  | ||||
| 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 | ||||
|  | ||||
|     """ | ||||
|     from freqtrade.exchange import timeframe_to_minutes | ||||
|  | ||||
|     ohlc_dict = { | ||||
|         'open': 'first', | ||||
|         'high': 'max', | ||||
|   | ||||
| @@ -1,10 +1,10 @@ | ||||
| """ | ||||
| Handle historic data (ohlcv). | ||||
| includes: | ||||
|  | ||||
| Includes: | ||||
| * load data for a pair (or a list of pairs) from disk | ||||
| * download data from exchange and store to disk | ||||
| """ | ||||
|  | ||||
| import logging | ||||
| from pathlib import Path | ||||
| from typing import Optional, List, Dict, Tuple, Any | ||||
| @@ -15,8 +15,7 @@ from pandas import DataFrame | ||||
| from freqtrade import misc, OperationalException | ||||
| from freqtrade.arguments import TimeRange | ||||
| from freqtrade.data.converter import parse_ticker_dataframe | ||||
| from freqtrade.exchange import Exchange | ||||
| from freqtrade.misc import timeframe_to_minutes | ||||
| from freqtrade.exchange import Exchange, timeframe_to_minutes | ||||
|  | ||||
|  | ||||
| logger = logging.getLogger(__name__) | ||||
|   | ||||
| @@ -1,3 +1,8 @@ | ||||
| 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.binance import Binance  # noqa: F401 | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| # pragma pylint: disable=W0603 | ||||
| """ Cryptocurrency Exchanges support """ | ||||
| """ | ||||
| Cryptocurrency Exchanges support | ||||
| """ | ||||
| import logging | ||||
| import inspect | ||||
| from random import randint | ||||
| @@ -16,7 +18,6 @@ from pandas import DataFrame | ||||
| from freqtrade import (constants, DependencyException, OperationalException, | ||||
|                        TemporaryError, InvalidOrderException) | ||||
| from freqtrade.data.converter import parse_ticker_dataframe | ||||
| from freqtrade.misc import timeframe_to_seconds, timeframe_to_msecs | ||||
|  | ||||
|  | ||||
| logger = logging.getLogger(__name__) | ||||
| @@ -138,7 +139,7 @@ class Exchange(object): | ||||
|         # Find matching class for the given exchange 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') | ||||
|  | ||||
|         ex_config = { | ||||
| @@ -690,3 +691,35 @@ class Exchange(object): | ||||
|                 f'Could not get fee info due to {e.__class__.__name__}. Message: {e}') | ||||
|         except ccxt.BaseError as 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.dataprovider import DataProvider | ||||
| 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.rpc import RPCManager, RPCMessageType | ||||
| from freqtrade.resolvers import ExchangeResolver, StrategyResolver, PairListResolver | ||||
| @@ -460,7 +460,7 @@ class FreqtradeBot(object): | ||||
|     def get_real_amount(self, trade: Trade, order: Dict) -> float: | ||||
|         """ | ||||
|         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'] | ||||
|         # Only run for closed orders | ||||
|   | ||||
| @@ -1,18 +1,17 @@ | ||||
| """ | ||||
| Various tool function for Freqtrade and scripts | ||||
| """ | ||||
|  | ||||
| import gzip | ||||
| import logging | ||||
| import re | ||||
| from datetime import datetime | ||||
| from typing import Dict | ||||
|  | ||||
| from ccxt import Exchange | ||||
| import numpy as np | ||||
| from pandas import DataFrame | ||||
| import rapidjson | ||||
|  | ||||
|  | ||||
| logger = logging.getLogger(__name__) | ||||
|  | ||||
|  | ||||
| @@ -132,26 +131,3 @@ def deep_merge_dicts(source, destination): | ||||
|             destination[key] = value | ||||
|  | ||||
|     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.data import history | ||||
| 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.resolvers import ExchangeResolver, StrategyResolver | ||||
| from freqtrade.state import RunMode | ||||
| from freqtrade.strategy.interface import SellType, IStrategy | ||||
|  | ||||
|  | ||||
| logger = logging.getLogger(__name__) | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -6,6 +6,7 @@ from freqtrade.strategy.interface import IStrategy | ||||
| # Import Default-Strategy to have hyperopt correctly resolve | ||||
| from freqtrade.strategy.default_strategy import DefaultStrategy  # noqa: F401 | ||||
|  | ||||
|  | ||||
| logger = logging.getLogger(__name__) | ||||
|  | ||||
|  | ||||
| @@ -16,7 +17,6 @@ def import_strategy(strategy: IStrategy, config: dict) -> IStrategy: | ||||
|     """ | ||||
|  | ||||
|     # Copy all attributes from base class and class | ||||
|  | ||||
|     comb = {**strategy.__class__.__dict__, **strategy.__dict__} | ||||
|  | ||||
|     # 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'] | ||||
|  | ||||
|     attr = deepcopy(comb) | ||||
|  | ||||
|     # Adjust module name | ||||
|     attr['__module__'] = 'freqtrade.strategy' | ||||
|  | ||||
|   | ||||
| @@ -13,10 +13,11 @@ import arrow | ||||
| from pandas import DataFrame | ||||
|  | ||||
| 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.wallets import Wallets | ||||
|  | ||||
|  | ||||
| logger = logging.getLogger(__name__) | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,7 @@ from typing import NamedTuple, List | ||||
| import arrow | ||||
| from pandas import DataFrame | ||||
|  | ||||
| from freqtrade.misc import timeframe_to_minutes | ||||
| from freqtrade.exchange import timeframe_to_minutes | ||||
| from freqtrade.strategy.interface import SellType | ||||
|  | ||||
| ticker_start_time = arrow.get(2018, 10, 3) | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| from freqtrade import optimize | ||||
| from freqtrade.arguments import TimeRange | ||||
| 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.tests.conftest import log_has, patch_exchange | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| import os | ||||
| 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__)))) | ||||
| sys.path.append(root + '/python') | ||||
|  | ||||
| @@ -44,7 +46,7 @@ def dump(*args): | ||||
|  | ||||
|  | ||||
| def print_supported_exchanges(): | ||||
|     dump('Supported exchanges:', green(', '.join(ccxt.exchanges))) | ||||
|     dump('Supported exchanges:', green(', '.join(supported_exchanges()))) | ||||
|  | ||||
|  | ||||
| try: | ||||
| @@ -52,9 +54,7 @@ try: | ||||
|     id = sys.argv[1]  # get exchange id from command line arguments | ||||
|  | ||||
|     # check if the exchange is supported by ccxt | ||||
|     exchange_found = id in ccxt.exchanges | ||||
|  | ||||
|     if exchange_found: | ||||
|     if is_exchange_supported(id): | ||||
|         dump('Instantiating', green(id), 'exchange') | ||||
|  | ||||
|         # instantiate the exchange by id | ||||
| @@ -79,9 +79,7 @@ try: | ||||
|  | ||||
|         for (k, v) in tuples: | ||||
|             dump('{:<15} {:<15} {:<15} {:<15}'.format(v['id'], v['symbol'], v['base'], v['quote'])) | ||||
|  | ||||
|     else: | ||||
|  | ||||
|         dump('Exchange ' + red(id) + ' not found') | ||||
|         print_supported_exchanges() | ||||
|  | ||||
|   | ||||
| @@ -27,10 +27,12 @@ from plotly.offline import plot | ||||
| from freqtrade.arguments import Arguments | ||||
| from freqtrade.configuration import Configuration | ||||
| 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.state import RunMode | ||||
|  | ||||
|  | ||||
| logger = logging.getLogger(__name__) | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user