limit usage of ccxt to freqtrade/exchange only
This commit is contained in:
parent
6856848efc
commit
9fbe573cca
@ -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__)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user