limit usage of ccxt to freqtrade/exchange only

This commit is contained in:
hroff-1902 2019-04-09 12:27:35 +03:00
parent 6856848efc
commit 9fbe573cca
14 changed files with 71 additions and 50 deletions

View File

@ -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(

View File

@ -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',

View File

@ -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__)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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__)

View File

@ -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'

View File

@ -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__)

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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__)