exchange refactor
This commit is contained in:
parent
447bcf98e1
commit
845af384de
@ -6,12 +6,12 @@ Common Interface for bot and strategy to access data.
|
|||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Tuple
|
from typing import List, Optional, Tuple
|
||||||
|
|
||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
|
|
||||||
from freqtrade.data.history import load_pair_history
|
from freqtrade.data.history import load_pair_history
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange, get_exchange
|
||||||
from freqtrade.state import RunMode
|
from freqtrade.state import RunMode
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -19,9 +19,9 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
class DataProvider():
|
class DataProvider():
|
||||||
|
|
||||||
def __init__(self, config: dict, exchange: Exchange) -> None:
|
def __init__(self, config: dict, exchange_name: Optional[str] = None) -> None:
|
||||||
self._config = config
|
self._config = config
|
||||||
self._exchange = exchange
|
self._exchange: Exchange = get_exchange(config, exchange_name)
|
||||||
|
|
||||||
def refresh(self,
|
def refresh(self,
|
||||||
pairlist: List[Tuple[str, str]],
|
pairlist: List[Tuple[str, str]],
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
from freqtrade.exchange.exchange import Exchange # noqa: F401
|
from freqtrade.exchange.exchange import Exchange # noqa: F401
|
||||||
|
from freqtrade.exchange.exchange import (get_exchange, # noqa: F401
|
||||||
|
delete_exchange)
|
||||||
from freqtrade.exchange.exchange import (get_exchange_bad_reason, # noqa: F401
|
from freqtrade.exchange.exchange import (get_exchange_bad_reason, # noqa: F401
|
||||||
is_exchange_bad,
|
is_exchange_bad,
|
||||||
is_exchange_available,
|
is_exchange_available,
|
||||||
|
@ -21,6 +21,7 @@ from freqtrade import (DependencyException, InvalidOrderException,
|
|||||||
from freqtrade.data.converter import parse_ticker_dataframe
|
from freqtrade.data.converter import parse_ticker_dataframe
|
||||||
from freqtrade.misc import deep_merge_dicts
|
from freqtrade.misc import deep_merge_dicts
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -772,6 +773,39 @@ class Exchange(object):
|
|||||||
raise OperationalException(e) from e
|
raise OperationalException(e) from e
|
||||||
|
|
||||||
|
|
||||||
|
# Store Exchange objects created
|
||||||
|
__exchanges: Dict[str, Exchange] = {}
|
||||||
|
|
||||||
|
|
||||||
|
def get_exchange(config, exchange_name: Optional[str] = None) -> Exchange:
|
||||||
|
"""
|
||||||
|
Return Exchange object for exchange with name `exchange_name`.
|
||||||
|
Creates Exchange if it was not created before.
|
||||||
|
"""
|
||||||
|
from freqtrade.resolvers import ExchangeResolver
|
||||||
|
|
||||||
|
name = exchange_name or config['exchange']['name']
|
||||||
|
if name not in __exchanges:
|
||||||
|
logger.info(f"Creating Exchange object for '{name}'...")
|
||||||
|
__exchanges[name] = ExchangeResolver(name, config).exchange
|
||||||
|
logger.info(f"Exchange object for '{name}' created.")
|
||||||
|
|
||||||
|
return __exchanges[name]
|
||||||
|
|
||||||
|
|
||||||
|
def delete_exchange(config, exchange_name: Optional[str] = None):
|
||||||
|
"""
|
||||||
|
Delete Exchange object for exchange with name `exchange_name`.
|
||||||
|
"""
|
||||||
|
name = exchange_name or config['exchange']['name']
|
||||||
|
logger.info(f"Deleting Exchange object for '{name}'...")
|
||||||
|
if name in __exchanges:
|
||||||
|
del __exchanges[name]
|
||||||
|
logger.info(f"Exchange object for '{name}' deleted.")
|
||||||
|
else:
|
||||||
|
logger.warning(f"Exchange object for '{name}' was not found, cannot be deleted.")
|
||||||
|
|
||||||
|
|
||||||
def is_exchange_bad(exchange_name: str) -> bool:
|
def is_exchange_bad(exchange_name: str) -> bool:
|
||||||
return exchange_name in BAD_EXCHANGES
|
return exchange_name in BAD_EXCHANGES
|
||||||
|
|
||||||
|
@ -17,10 +17,10 @@ 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.configuration import validate_config_consistency
|
from freqtrade.configuration import validate_config_consistency
|
||||||
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_next_date
|
from freqtrade.exchange import Exchange, get_exchange, timeframe_to_minutes, timeframe_to_next_date
|
||||||
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 StrategyResolver, PairListResolver
|
||||||
from freqtrade.state import State, RunMode
|
from freqtrade.state import State, RunMode
|
||||||
from freqtrade.strategy.interface import SellType, IStrategy
|
from freqtrade.strategy.interface import SellType, IStrategy
|
||||||
from freqtrade.wallets import Wallets
|
from freqtrade.wallets import Wallets
|
||||||
@ -57,10 +57,10 @@ class FreqtradeBot(object):
|
|||||||
|
|
||||||
self.rpc: RPCManager = RPCManager(self)
|
self.rpc: RPCManager = RPCManager(self)
|
||||||
|
|
||||||
self.exchange = ExchangeResolver(self.config['exchange']['name'], self.config).exchange
|
self.exchange: Exchange = get_exchange(self.config)
|
||||||
|
|
||||||
self.wallets = Wallets(self.config, self.exchange)
|
self.wallets = Wallets(self.config)
|
||||||
self.dataprovider = DataProvider(self.config, self.exchange)
|
self.dataprovider = DataProvider(self.config)
|
||||||
|
|
||||||
# Attach Dataprovider to Strategy baseclass
|
# Attach Dataprovider to Strategy baseclass
|
||||||
IStrategy.dp = self.dataprovider
|
IStrategy.dp = self.dataprovider
|
||||||
|
@ -15,10 +15,10 @@ from freqtrade import OperationalException
|
|||||||
from freqtrade.configuration import TimeRange
|
from freqtrade.configuration import TimeRange
|
||||||
from freqtrade.data import history
|
from freqtrade.data import history
|
||||||
from freqtrade.data.dataprovider import DataProvider
|
from freqtrade.data.dataprovider import DataProvider
|
||||||
from freqtrade.exchange import timeframe_to_minutes
|
from freqtrade.exchange import Exchange, get_exchange, timeframe_to_minutes
|
||||||
from freqtrade.misc import file_dump_json
|
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 StrategyResolver
|
||||||
from freqtrade.state import RunMode
|
from freqtrade.state import RunMode
|
||||||
from freqtrade.strategy.interface import IStrategy, SellType
|
from freqtrade.strategy.interface import IStrategy, SellType
|
||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
@ -64,11 +64,11 @@ class Backtesting(object):
|
|||||||
self.config['dry_run'] = True
|
self.config['dry_run'] = True
|
||||||
self.strategylist: List[IStrategy] = []
|
self.strategylist: List[IStrategy] = []
|
||||||
|
|
||||||
self.exchange = ExchangeResolver(self.config['exchange']['name'], self.config).exchange
|
exchange: Exchange = get_exchange(self.config)
|
||||||
self.fee = self.exchange.get_fee()
|
self.fee = exchange.get_fee()
|
||||||
|
|
||||||
if self.config.get('runmode') != RunMode.HYPEROPT:
|
if self.config.get('runmode') != RunMode.HYPEROPT:
|
||||||
self.dataprovider = DataProvider(self.config, self.exchange)
|
self.dataprovider = DataProvider(self.config)
|
||||||
IStrategy.dp = self.dataprovider
|
IStrategy.dp = self.dataprovider
|
||||||
|
|
||||||
if self.config.get('strategy_list', None):
|
if self.config.get('strategy_list', None):
|
||||||
@ -406,12 +406,13 @@ class Backtesting(object):
|
|||||||
|
|
||||||
timerange = TimeRange.parse_timerange(None if self.config.get(
|
timerange = TimeRange.parse_timerange(None if self.config.get(
|
||||||
'timerange') is None else str(self.config.get('timerange')))
|
'timerange') is None else str(self.config.get('timerange')))
|
||||||
|
exchange: Exchange = get_exchange(self.config)
|
||||||
data = history.load_data(
|
data = history.load_data(
|
||||||
datadir=Path(self.config['datadir']) if self.config.get('datadir') else None,
|
datadir=Path(self.config['datadir']) if self.config.get('datadir') else None,
|
||||||
pairs=pairs,
|
pairs=pairs,
|
||||||
ticker_interval=self.ticker_interval,
|
ticker_interval=self.ticker_interval,
|
||||||
refresh_pairs=self.config.get('refresh_pairs', False),
|
refresh_pairs=self.config.get('refresh_pairs', False),
|
||||||
exchange=self.exchange,
|
exchange=exchange,
|
||||||
timerange=timerange,
|
timerange=timerange,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ from freqtrade import constants
|
|||||||
from freqtrade.edge import Edge
|
from freqtrade.edge import Edge
|
||||||
|
|
||||||
from freqtrade.configuration import TimeRange
|
from freqtrade.configuration import TimeRange
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange, get_exchange
|
||||||
from freqtrade.resolvers import StrategyResolver
|
from freqtrade.resolvers import StrategyResolver
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -35,7 +35,7 @@ class EdgeCli(object):
|
|||||||
self.config['exchange']['uid'] = ''
|
self.config['exchange']['uid'] = ''
|
||||||
self.config['stake_amount'] = constants.UNLIMITED_STAKE_AMOUNT
|
self.config['stake_amount'] = constants.UNLIMITED_STAKE_AMOUNT
|
||||||
self.config['dry_run'] = True
|
self.config['dry_run'] = True
|
||||||
self.exchange = Exchange(self.config)
|
self.exchange: Exchange = get_exchange(self.config)
|
||||||
self.strategy = StrategyResolver(self.config).strategy
|
self.strategy = StrategyResolver(self.config).strategy
|
||||||
|
|
||||||
self.edge = Edge(config, self.exchange, self.strategy)
|
self.edge = Edge(config, self.exchange, self.strategy)
|
||||||
|
@ -24,6 +24,7 @@ from skopt.space import Dimension
|
|||||||
|
|
||||||
from freqtrade.configuration import TimeRange
|
from freqtrade.configuration import TimeRange
|
||||||
from freqtrade.data.history import load_data, get_timeframe
|
from freqtrade.data.history import load_data, get_timeframe
|
||||||
|
from freqtrade.exchange import Exchange, get_exchange
|
||||||
from freqtrade.optimize.backtesting import Backtesting
|
from freqtrade.optimize.backtesting import Backtesting
|
||||||
# Import IHyperOptLoss to allow users import from this file
|
# Import IHyperOptLoss to allow users import from this file
|
||||||
from freqtrade.optimize.hyperopt_loss_interface import IHyperOptLoss # noqa: F4
|
from freqtrade.optimize.hyperopt_loss_interface import IHyperOptLoss # noqa: F4
|
||||||
@ -342,12 +343,13 @@ class Hyperopt(Backtesting):
|
|||||||
def start(self) -> None:
|
def start(self) -> None:
|
||||||
timerange = TimeRange.parse_timerange(None if self.config.get(
|
timerange = TimeRange.parse_timerange(None if self.config.get(
|
||||||
'timerange') is None else str(self.config.get('timerange')))
|
'timerange') is None else str(self.config.get('timerange')))
|
||||||
|
exchange: Exchange = get_exchange(self.config)
|
||||||
data = load_data(
|
data = load_data(
|
||||||
datadir=Path(self.config['datadir']) if self.config.get('datadir') else None,
|
datadir=Path(self.config['datadir']) if self.config.get('datadir') else None,
|
||||||
pairs=self.config['exchange']['pair_whitelist'],
|
pairs=self.config['exchange']['pair_whitelist'],
|
||||||
ticker_interval=self.ticker_interval,
|
ticker_interval=self.ticker_interval,
|
||||||
refresh_pairs=self.config.get('refresh_pairs', False),
|
refresh_pairs=self.config.get('refresh_pairs', False),
|
||||||
exchange=self.exchange,
|
exchange=exchange,
|
||||||
timerange=timerange
|
timerange=timerange
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -371,9 +373,6 @@ class Hyperopt(Backtesting):
|
|||||||
|
|
||||||
dump(preprocessed, self.tickerdata_pickle)
|
dump(preprocessed, self.tickerdata_pickle)
|
||||||
|
|
||||||
# We don't need exchange instance anymore while running hyperopt
|
|
||||||
self.exchange = None # type: ignore
|
|
||||||
|
|
||||||
self.load_previous_results()
|
self.load_previous_results()
|
||||||
|
|
||||||
cpus = cpu_count()
|
cpus = cpu_count()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, List, Optional
|
from typing import Dict, List
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
@ -8,8 +8,9 @@ from freqtrade.configuration import TimeRange
|
|||||||
from freqtrade.data import history
|
from freqtrade.data import history
|
||||||
from freqtrade.data.btanalysis import (combine_tickers_with_mean,
|
from freqtrade.data.btanalysis import (combine_tickers_with_mean,
|
||||||
create_cum_profit, load_trades)
|
create_cum_profit, load_trades)
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange, get_exchange
|
||||||
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
|
from freqtrade.resolvers import StrategyResolver
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -19,7 +20,7 @@ try:
|
|||||||
from plotly.offline import plot
|
from plotly.offline import plot
|
||||||
import plotly.graph_objects as go
|
import plotly.graph_objects as go
|
||||||
except ImportError:
|
except ImportError:
|
||||||
logger.exception("Module plotly not found \n Please install using `pip install plotly`")
|
logger.exception("Module plotly not found.\nPlease install using `pip install plotly`.")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
@ -28,12 +29,11 @@ def init_plotscript(config):
|
|||||||
Initialize objects needed for plotting
|
Initialize objects needed for plotting
|
||||||
:return: Dict with tickers, trades, pairs and strategy
|
:return: Dict with tickers, trades, pairs and strategy
|
||||||
"""
|
"""
|
||||||
exchange: Optional[Exchange] = None
|
exchange: Exchange = None
|
||||||
|
|
||||||
# Exchange is only needed when downloading data!
|
# Exchange is only needed when downloading data!
|
||||||
if config.get("refresh_pairs", False):
|
if config.get("refresh_pairs", False):
|
||||||
exchange = ExchangeResolver(config.get('exchange', {}).get('name'),
|
exchange = get_exchange(config)
|
||||||
config).exchange
|
|
||||||
|
|
||||||
strategy = StrategyResolver(config).strategy
|
strategy = StrategyResolver(config).strategy
|
||||||
if "pairs" in config:
|
if "pairs" in config:
|
||||||
|
@ -3,7 +3,6 @@ This module loads custom exchanges
|
|||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from freqtrade.exchange import Exchange
|
|
||||||
import freqtrade.exchange as exchanges
|
import freqtrade.exchange as exchanges
|
||||||
from freqtrade.resolvers import IResolver
|
from freqtrade.resolvers import IResolver
|
||||||
|
|
||||||
@ -29,10 +28,10 @@ class ExchangeResolver(IResolver):
|
|||||||
logger.info(
|
logger.info(
|
||||||
f"No {exchange_name} specific subclass found. Using the generic class instead.")
|
f"No {exchange_name} specific subclass found. Using the generic class instead.")
|
||||||
if not hasattr(self, "exchange"):
|
if not hasattr(self, "exchange"):
|
||||||
self.exchange = Exchange(config)
|
self.exchange = exchanges.Exchange(config)
|
||||||
|
|
||||||
def _load_exchange(
|
def _load_exchange(
|
||||||
self, exchange_name: str, kwargs: dict) -> Exchange:
|
self, exchange_name: str, kwargs: dict) -> exchanges.Exchange:
|
||||||
"""
|
"""
|
||||||
Loads the specified exchange.
|
Loads the specified exchange.
|
||||||
Only checks for exchanges exported in freqtrade.exchanges
|
Only checks for exchanges exported in freqtrade.exchanges
|
||||||
|
@ -14,7 +14,7 @@ def test_ohlcv(mocker, default_conf, ticker_history):
|
|||||||
exchange._klines[("XRP/BTC", ticker_interval)] = ticker_history
|
exchange._klines[("XRP/BTC", ticker_interval)] = ticker_history
|
||||||
exchange._klines[("UNITTEST/BTC", ticker_interval)] = ticker_history
|
exchange._klines[("UNITTEST/BTC", ticker_interval)] = ticker_history
|
||||||
|
|
||||||
dp = DataProvider(default_conf, exchange)
|
dp = DataProvider(default_conf)
|
||||||
assert dp.runmode == RunMode.DRY_RUN
|
assert dp.runmode == RunMode.DRY_RUN
|
||||||
assert ticker_history.equals(dp.ohlcv("UNITTEST/BTC", ticker_interval))
|
assert ticker_history.equals(dp.ohlcv("UNITTEST/BTC", ticker_interval))
|
||||||
assert isinstance(dp.ohlcv("UNITTEST/BTC", ticker_interval), DataFrame)
|
assert isinstance(dp.ohlcv("UNITTEST/BTC", ticker_interval), DataFrame)
|
||||||
@ -27,12 +27,12 @@ def test_ohlcv(mocker, default_conf, ticker_history):
|
|||||||
assert dp.ohlcv("UNITTEST/BTC", ticker_interval).equals(dp.ohlcv("UNITTEST/BTC"))
|
assert dp.ohlcv("UNITTEST/BTC", ticker_interval).equals(dp.ohlcv("UNITTEST/BTC"))
|
||||||
|
|
||||||
default_conf["runmode"] = RunMode.LIVE
|
default_conf["runmode"] = RunMode.LIVE
|
||||||
dp = DataProvider(default_conf, exchange)
|
dp = DataProvider(default_conf)
|
||||||
assert dp.runmode == RunMode.LIVE
|
assert dp.runmode == RunMode.LIVE
|
||||||
assert isinstance(dp.ohlcv("UNITTEST/BTC", ticker_interval), DataFrame)
|
assert isinstance(dp.ohlcv("UNITTEST/BTC", ticker_interval), DataFrame)
|
||||||
|
|
||||||
default_conf["runmode"] = RunMode.BACKTEST
|
default_conf["runmode"] = RunMode.BACKTEST
|
||||||
dp = DataProvider(default_conf, exchange)
|
dp = DataProvider(default_conf)
|
||||||
assert dp.runmode == RunMode.BACKTEST
|
assert dp.runmode == RunMode.BACKTEST
|
||||||
assert dp.ohlcv("UNITTEST/BTC", ticker_interval).empty
|
assert dp.ohlcv("UNITTEST/BTC", ticker_interval).empty
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ def test_historic_ohlcv(mocker, default_conf, ticker_history):
|
|||||||
historymock = MagicMock(return_value=ticker_history)
|
historymock = MagicMock(return_value=ticker_history)
|
||||||
mocker.patch("freqtrade.data.dataprovider.load_pair_history", historymock)
|
mocker.patch("freqtrade.data.dataprovider.load_pair_history", historymock)
|
||||||
|
|
||||||
dp = DataProvider(default_conf, None)
|
dp = DataProvider(default_conf)
|
||||||
data = dp.historic_ohlcv("UNITTEST/BTC", "5m")
|
data = dp.historic_ohlcv("UNITTEST/BTC", "5m")
|
||||||
assert isinstance(data, DataFrame)
|
assert isinstance(data, DataFrame)
|
||||||
assert historymock.call_count == 1
|
assert historymock.call_count == 1
|
||||||
@ -57,7 +57,7 @@ def test_get_pair_dataframe(mocker, default_conf, ticker_history):
|
|||||||
exchange._klines[("XRP/BTC", ticker_interval)] = ticker_history
|
exchange._klines[("XRP/BTC", ticker_interval)] = ticker_history
|
||||||
exchange._klines[("UNITTEST/BTC", ticker_interval)] = ticker_history
|
exchange._klines[("UNITTEST/BTC", ticker_interval)] = ticker_history
|
||||||
|
|
||||||
dp = DataProvider(default_conf, exchange)
|
dp = DataProvider(default_conf)
|
||||||
assert dp.runmode == RunMode.DRY_RUN
|
assert dp.runmode == RunMode.DRY_RUN
|
||||||
assert ticker_history.equals(dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval))
|
assert ticker_history.equals(dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval))
|
||||||
assert isinstance(dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval), DataFrame)
|
assert isinstance(dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval), DataFrame)
|
||||||
@ -70,7 +70,7 @@ def test_get_pair_dataframe(mocker, default_conf, ticker_history):
|
|||||||
ticker_interval).equals(dp.get_pair_dataframe("UNITTEST/BTC"))
|
ticker_interval).equals(dp.get_pair_dataframe("UNITTEST/BTC"))
|
||||||
|
|
||||||
default_conf["runmode"] = RunMode.LIVE
|
default_conf["runmode"] = RunMode.LIVE
|
||||||
dp = DataProvider(default_conf, exchange)
|
dp = DataProvider(default_conf)
|
||||||
assert dp.runmode == RunMode.LIVE
|
assert dp.runmode == RunMode.LIVE
|
||||||
assert isinstance(dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval), DataFrame)
|
assert isinstance(dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval), DataFrame)
|
||||||
assert dp.get_pair_dataframe("NONESENSE/AAA", ticker_interval).empty
|
assert dp.get_pair_dataframe("NONESENSE/AAA", ticker_interval).empty
|
||||||
@ -78,7 +78,7 @@ def test_get_pair_dataframe(mocker, default_conf, ticker_history):
|
|||||||
historymock = MagicMock(return_value=ticker_history)
|
historymock = MagicMock(return_value=ticker_history)
|
||||||
mocker.patch("freqtrade.data.dataprovider.load_pair_history", historymock)
|
mocker.patch("freqtrade.data.dataprovider.load_pair_history", historymock)
|
||||||
default_conf["runmode"] = RunMode.BACKTEST
|
default_conf["runmode"] = RunMode.BACKTEST
|
||||||
dp = DataProvider(default_conf, exchange)
|
dp = DataProvider(default_conf)
|
||||||
assert dp.runmode == RunMode.BACKTEST
|
assert dp.runmode == RunMode.BACKTEST
|
||||||
assert isinstance(dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval), DataFrame)
|
assert isinstance(dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval), DataFrame)
|
||||||
# assert dp.get_pair_dataframe("NONESENSE/AAA", ticker_interval).empty
|
# assert dp.get_pair_dataframe("NONESENSE/AAA", ticker_interval).empty
|
||||||
@ -90,7 +90,7 @@ def test_available_pairs(mocker, default_conf, ticker_history):
|
|||||||
exchange._klines[("XRP/BTC", ticker_interval)] = ticker_history
|
exchange._klines[("XRP/BTC", ticker_interval)] = ticker_history
|
||||||
exchange._klines[("UNITTEST/BTC", ticker_interval)] = ticker_history
|
exchange._klines[("UNITTEST/BTC", ticker_interval)] = ticker_history
|
||||||
|
|
||||||
dp = DataProvider(default_conf, exchange)
|
dp = DataProvider(default_conf)
|
||||||
assert len(dp.available_pairs) == 2
|
assert len(dp.available_pairs) == 2
|
||||||
assert dp.available_pairs == [
|
assert dp.available_pairs == [
|
||||||
("XRP/BTC", ticker_interval),
|
("XRP/BTC", ticker_interval),
|
||||||
@ -108,7 +108,7 @@ def test_refresh(mocker, default_conf, ticker_history):
|
|||||||
|
|
||||||
pairs_non_trad = [("ETH/USDT", ticker_interval), ("BTC/TUSD", "1h")]
|
pairs_non_trad = [("ETH/USDT", ticker_interval), ("BTC/TUSD", "1h")]
|
||||||
|
|
||||||
dp = DataProvider(default_conf, exchange)
|
dp = DataProvider(default_conf)
|
||||||
dp.refresh(pairs)
|
dp.refresh(pairs)
|
||||||
|
|
||||||
assert refresh_mock.call_count == 1
|
assert refresh_mock.call_count == 1
|
||||||
|
@ -9,8 +9,7 @@ import arrow
|
|||||||
from freqtrade.configuration import Configuration, TimeRange
|
from freqtrade.configuration import Configuration, TimeRange
|
||||||
from freqtrade.configuration.directory_operations import create_userdata_dir
|
from freqtrade.configuration.directory_operations import create_userdata_dir
|
||||||
from freqtrade.data.history import download_pair_history
|
from freqtrade.data.history import download_pair_history
|
||||||
from freqtrade.exchange import available_exchanges
|
from freqtrade.exchange import Exchange, get_exchange, available_exchanges
|
||||||
from freqtrade.resolvers import ExchangeResolver
|
|
||||||
from freqtrade.state import RunMode
|
from freqtrade.state import RunMode
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -79,7 +78,7 @@ def start_download_data(args: Namespace) -> None:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
# Init exchange
|
# Init exchange
|
||||||
exchange = ExchangeResolver(config['exchange']['name'], config).exchange
|
exchange: Exchange = get_exchange(config)
|
||||||
|
|
||||||
for pair in config["pairs"]:
|
for pair in config["pairs"]:
|
||||||
if pair not in exchange.markets:
|
if pair not in exchange.markets:
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
""" Wallet """
|
""" Wallet """
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from typing import Dict, NamedTuple
|
from typing import Dict, NamedTuple, Optional
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange, get_exchange
|
||||||
from freqtrade import constants
|
from freqtrade import constants
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -19,9 +19,9 @@ class Wallet(NamedTuple):
|
|||||||
|
|
||||||
class Wallets(object):
|
class Wallets(object):
|
||||||
|
|
||||||
def __init__(self, config: dict, exchange: Exchange) -> None:
|
def __init__(self, config: dict, exchange_name: Optional[str] = None) -> None:
|
||||||
self._config = config
|
self._config = config
|
||||||
self._exchange = exchange
|
self._exchange_name = exchange_name
|
||||||
self._wallets: Dict[str, Wallet] = {}
|
self._wallets: Dict[str, Wallet] = {}
|
||||||
|
|
||||||
self.update()
|
self.update()
|
||||||
@ -61,7 +61,8 @@ class Wallets(object):
|
|||||||
|
|
||||||
def update(self) -> None:
|
def update(self) -> None:
|
||||||
|
|
||||||
balances = self._exchange.get_balances()
|
exchange: Exchange = get_exchange(self._config, self._exchange_name)
|
||||||
|
balances = exchange.get_balances()
|
||||||
|
|
||||||
for currency in balances:
|
for currency in balances:
|
||||||
self._wallets[currency] = Wallet(
|
self._wallets[currency] = Wallet(
|
||||||
|
Loading…
Reference in New Issue
Block a user