Merge pull request #2417 from freqtrade/whitelist_docs
DynamicPairlist - pair_whitelist
This commit is contained in:
commit
b947f3c2a5
@ -75,8 +75,8 @@ Mandatory parameters are marked as **Required**, which means that they are requi
|
|||||||
| `exchange.key` | '' | API key to use for the exchange. Only required when you are in production mode. ***Keep it in secrete, do not disclose publicly.***
|
| `exchange.key` | '' | API key to use for the exchange. Only required when you are in production mode. ***Keep it in secrete, do not disclose publicly.***
|
||||||
| `exchange.secret` | '' | API secret to use for the exchange. Only required when you are in production mode. ***Keep it in secrete, do not disclose publicly.***
|
| `exchange.secret` | '' | API secret to use for the exchange. Only required when you are in production mode. ***Keep it in secrete, do not disclose publicly.***
|
||||||
| `exchange.password` | '' | API password to use for the exchange. Only required when you are in production mode and for exchanges that use password for API requests. ***Keep it in secrete, do not disclose publicly.***
|
| `exchange.password` | '' | API password to use for the exchange. Only required when you are in production mode and for exchanges that use password for API requests. ***Keep it in secrete, do not disclose publicly.***
|
||||||
| `exchange.pair_whitelist` | [] | List of pairs to use by the bot for trading and to check for potential trades during backtesting. Can be overriden by dynamic pairlists (see [below](#dynamic-pairlists)).
|
| `exchange.pair_whitelist` | [] | List of pairs to use by the bot for trading and to check for potential trades during backtesting. Not used by VolumePairList (see [below](#dynamic-pairlists)).
|
||||||
| `exchange.pair_blacklist` | [] | List of pairs the bot must absolutely avoid for trading and backtesting. Can be overriden by dynamic pairlists (see [below](#dynamic-pairlists)).
|
| `exchange.pair_blacklist` | [] | List of pairs the bot must absolutely avoid for trading and backtesting (see [below](#dynamic-pairlists)).
|
||||||
| `exchange.ccxt_config` | None | Additional CCXT parameters passed to the regular ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://ccxt.readthedocs.io/en/latest/manual.html#instantiation)
|
| `exchange.ccxt_config` | None | Additional CCXT parameters passed to the regular ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://ccxt.readthedocs.io/en/latest/manual.html#instantiation)
|
||||||
| `exchange.ccxt_async_config` | None | Additional CCXT parameters passed to the async ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://ccxt.readthedocs.io/en/latest/manual.html#instantiation)
|
| `exchange.ccxt_async_config` | None | Additional CCXT parameters passed to the async ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://ccxt.readthedocs.io/en/latest/manual.html#instantiation)
|
||||||
| `exchange.markets_refresh_interval` | 60 | The interval in minutes in which markets are reloaded.
|
| `exchange.markets_refresh_interval` | 60 | The interval in minutes in which markets are reloaded.
|
||||||
@ -425,10 +425,16 @@ section of the configuration.
|
|||||||
`askVolume`, `bidVolume` and `quoteVolume`, defaults to `quoteVolume`.
|
`askVolume`, `bidVolume` and `quoteVolume`, defaults to `quoteVolume`.
|
||||||
* There is a possibility to filter low-value coins that would not allow setting a stop loss
|
* There is a possibility to filter low-value coins that would not allow setting a stop loss
|
||||||
(set `precision_filter` parameter to `true` for this).
|
(set `precision_filter` parameter to `true` for this).
|
||||||
|
* `VolumePairList` does not consider `pair_whitelist`, but builds this automatically based the pairlist configuration.
|
||||||
|
* Pairs in `pair_blacklist` are not considered for VolumePairList, even if all other filters would match.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
"exchange": {
|
||||||
|
"pair_whitelist": [],
|
||||||
|
"pair_blacklist": ["BNB/BTC"]
|
||||||
|
},
|
||||||
"pairlist": {
|
"pairlist": {
|
||||||
"method": "VolumePairList",
|
"method": "VolumePairList",
|
||||||
"config": {
|
"config": {
|
||||||
|
@ -5,7 +5,7 @@ from jsonschema import Draft4Validator, validators
|
|||||||
from jsonschema.exceptions import ValidationError, best_match
|
from jsonschema.exceptions import ValidationError, best_match
|
||||||
|
|
||||||
from freqtrade import constants, OperationalException
|
from freqtrade import constants, OperationalException
|
||||||
|
from freqtrade.state import RunMode
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -64,6 +64,7 @@ def validate_config_consistency(conf: Dict[str, Any]) -> None:
|
|||||||
# validating trailing stoploss
|
# validating trailing stoploss
|
||||||
_validate_trailing_stoploss(conf)
|
_validate_trailing_stoploss(conf)
|
||||||
_validate_edge(conf)
|
_validate_edge(conf)
|
||||||
|
_validate_whitelist(conf)
|
||||||
|
|
||||||
|
|
||||||
def _validate_trailing_stoploss(conf: Dict[str, Any]) -> None:
|
def _validate_trailing_stoploss(conf: Dict[str, Any]) -> None:
|
||||||
@ -111,3 +112,15 @@ def _validate_edge(conf: Dict[str, Any]) -> None:
|
|||||||
"Edge and VolumePairList are incompatible, "
|
"Edge and VolumePairList are incompatible, "
|
||||||
"Edge will override whatever pairs VolumePairlist selects."
|
"Edge will override whatever pairs VolumePairlist selects."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _validate_whitelist(conf: Dict[str, Any]) -> None:
|
||||||
|
"""
|
||||||
|
Dynamic whitelist does not require pair_whitelist to be set - however StaticWhitelist does.
|
||||||
|
"""
|
||||||
|
if conf.get('runmode', RunMode.OTHER) in [RunMode.OTHER, RunMode.PLOT]:
|
||||||
|
return
|
||||||
|
|
||||||
|
if (conf.get('pairlist', {}).get('method', 'StaticPairList') == 'StaticPairList'
|
||||||
|
and not conf.get('exchange', {}).get('pair_whitelist')):
|
||||||
|
raise OperationalException("StaticPairList requires pair_whitelist to be set.")
|
||||||
|
@ -179,6 +179,9 @@ class Configuration:
|
|||||||
config['exchange']['name'] = self.args["exchange"]
|
config['exchange']['name'] = self.args["exchange"]
|
||||||
logger.info(f"Using exchange {config['exchange']['name']}")
|
logger.info(f"Using exchange {config['exchange']['name']}")
|
||||||
|
|
||||||
|
if 'pair_whitelist' not in config['exchange']:
|
||||||
|
config['exchange']['pair_whitelist'] = []
|
||||||
|
|
||||||
if 'user_data_dir' in self.args and self.args["user_data_dir"]:
|
if 'user_data_dir' in self.args and self.args["user_data_dir"]:
|
||||||
config.update({'user_data_dir': self.args["user_data_dir"]})
|
config.update({'user_data_dir': self.args["user_data_dir"]})
|
||||||
elif 'user_data_dir' not in config:
|
elif 'user_data_dir' not in config:
|
||||||
|
@ -235,7 +235,7 @@ CONF_SCHEMA = {
|
|||||||
'ccxt_config': {'type': 'object'},
|
'ccxt_config': {'type': 'object'},
|
||||||
'ccxt_async_config': {'type': 'object'}
|
'ccxt_async_config': {'type': 'object'}
|
||||||
},
|
},
|
||||||
'required': ['name', 'pair_whitelist']
|
'required': ['name']
|
||||||
},
|
},
|
||||||
'edge': {
|
'edge': {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
|
@ -77,7 +77,7 @@ class FreqtradeBot:
|
|||||||
self.edge = Edge(self.config, self.exchange, self.strategy) if \
|
self.edge = Edge(self.config, self.exchange, self.strategy) if \
|
||||||
self.config.get('edge', {}).get('enabled', False) else None
|
self.config.get('edge', {}).get('enabled', False) else None
|
||||||
|
|
||||||
self.active_pair_whitelist: List[str] = self.config['exchange']['pair_whitelist']
|
self.active_pair_whitelist = self._refresh_whitelist()
|
||||||
|
|
||||||
persistence.init(self.config.get('db_url', None),
|
persistence.init(self.config.get('db_url', None),
|
||||||
clean_open_orders=self.config.get('dry_run', False))
|
clean_open_orders=self.config.get('dry_run', False))
|
||||||
@ -123,21 +123,10 @@ class FreqtradeBot:
|
|||||||
# Check whether markets have to be reloaded
|
# Check whether markets have to be reloaded
|
||||||
self.exchange._reload_markets()
|
self.exchange._reload_markets()
|
||||||
|
|
||||||
# Refresh whitelist
|
|
||||||
self.pairlists.refresh_pairlist()
|
|
||||||
self.active_pair_whitelist = self.pairlists.whitelist
|
|
||||||
|
|
||||||
# Calculating Edge positioning
|
|
||||||
if self.edge:
|
|
||||||
self.edge.calculate()
|
|
||||||
self.active_pair_whitelist = self.edge.adjust(self.active_pair_whitelist)
|
|
||||||
|
|
||||||
# Query trades from persistence layer
|
# Query trades from persistence layer
|
||||||
trades = Trade.get_open_trades()
|
trades = Trade.get_open_trades()
|
||||||
|
|
||||||
# Extend active-pair whitelist with pairs from open trades
|
self.active_pair_whitelist = self._refresh_whitelist(trades)
|
||||||
# It ensures that tickers are downloaded for open trades
|
|
||||||
self._extend_whitelist_with_trades(self.active_pair_whitelist, trades)
|
|
||||||
|
|
||||||
# Refreshing candles
|
# Refreshing candles
|
||||||
self.dataprovider.refresh(self._create_pair_whitelist(self.active_pair_whitelist),
|
self.dataprovider.refresh(self._create_pair_whitelist(self.active_pair_whitelist),
|
||||||
@ -160,11 +149,24 @@ class FreqtradeBot:
|
|||||||
logger.info(f"Bot heartbeat. PID={getpid()}")
|
logger.info(f"Bot heartbeat. PID={getpid()}")
|
||||||
self._heartbeat_msg = arrow.utcnow().timestamp
|
self._heartbeat_msg = arrow.utcnow().timestamp
|
||||||
|
|
||||||
def _extend_whitelist_with_trades(self, whitelist: List[str], trades: List[Any]):
|
def _refresh_whitelist(self, trades: List[Trade] = []) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Extend whitelist with pairs from open trades
|
Refresh whitelist from pairlist or edge and extend it with trades.
|
||||||
"""
|
"""
|
||||||
whitelist.extend([trade.pair for trade in trades if trade.pair not in whitelist])
|
# Refresh whitelist
|
||||||
|
self.pairlists.refresh_pairlist()
|
||||||
|
_whitelist = self.pairlists.whitelist
|
||||||
|
|
||||||
|
# Calculating Edge positioning
|
||||||
|
if self.edge:
|
||||||
|
self.edge.calculate()
|
||||||
|
_whitelist = self.edge.adjust(_whitelist)
|
||||||
|
|
||||||
|
if trades:
|
||||||
|
# Extend active-pair whitelist with pairs from open trades
|
||||||
|
# It ensures that tickers are downloaded for open trades
|
||||||
|
_whitelist.extend([trade.pair for trade in trades if trade.pair not in _whitelist])
|
||||||
|
return _whitelist
|
||||||
|
|
||||||
def _create_pair_whitelist(self, pairs: List[str]) -> List[Tuple[str, str]]:
|
def _create_pair_whitelist(self, pairs: List[str]) -> List[Tuple[str, str]]:
|
||||||
"""
|
"""
|
||||||
|
@ -54,7 +54,7 @@ class VolumePairList(IPairList):
|
|||||||
"""
|
"""
|
||||||
# Generate dynamic whitelist
|
# Generate dynamic whitelist
|
||||||
self._whitelist = self._gen_pair_whitelist(
|
self._whitelist = self._gen_pair_whitelist(
|
||||||
self._config['stake_currency'], self._sort_key)[:self._number_pairs]
|
self._config['stake_currency'], self._sort_key)
|
||||||
|
|
||||||
@cached(TTLCache(maxsize=1, ttl=1800))
|
@cached(TTLCache(maxsize=1, ttl=1800))
|
||||||
def _gen_pair_whitelist(self, base_currency: str, key: str) -> List[str]:
|
def _gen_pair_whitelist(self, base_currency: str, key: str) -> List[str]:
|
||||||
@ -91,6 +91,6 @@ class VolumePairList(IPairList):
|
|||||||
valid_tickers.remove(t)
|
valid_tickers.remove(t)
|
||||||
|
|
||||||
pairs = [s['symbol'] for s in valid_tickers]
|
pairs = [s['symbol'] for s in valid_tickers]
|
||||||
logger.info(f"Searching pairs: {self._whitelist}")
|
logger.info(f"Searching pairs: {pairs[:self._number_pairs]}")
|
||||||
|
|
||||||
return pairs
|
return pairs
|
||||||
|
@ -55,13 +55,16 @@ def patched_configuration_load_config_file(mocker, config) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def patch_exchange(mocker, api_mock=None, id='bittrex') -> None:
|
def patch_exchange(mocker, api_mock=None, id='bittrex', mock_markets=True) -> None:
|
||||||
mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={}))
|
mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={}))
|
||||||
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock())
|
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock())
|
||||||
mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock())
|
mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock())
|
||||||
mocker.patch('freqtrade.exchange.Exchange.validate_ordertypes', MagicMock())
|
mocker.patch('freqtrade.exchange.Exchange.validate_ordertypes', MagicMock())
|
||||||
mocker.patch('freqtrade.exchange.Exchange.id', PropertyMock(return_value=id))
|
mocker.patch('freqtrade.exchange.Exchange.id', PropertyMock(return_value=id))
|
||||||
mocker.patch('freqtrade.exchange.Exchange.name', PropertyMock(return_value=id.title()))
|
mocker.patch('freqtrade.exchange.Exchange.name', PropertyMock(return_value=id.title()))
|
||||||
|
if mock_markets:
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange.markets',
|
||||||
|
PropertyMock(return_value=get_markets()))
|
||||||
|
|
||||||
if api_mock:
|
if api_mock:
|
||||||
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
|
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
|
||||||
@ -69,8 +72,9 @@ def patch_exchange(mocker, api_mock=None, id='bittrex') -> None:
|
|||||||
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock())
|
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock())
|
||||||
|
|
||||||
|
|
||||||
def get_patched_exchange(mocker, config, api_mock=None, id='bittrex') -> Exchange:
|
def get_patched_exchange(mocker, config, api_mock=None, id='bittrex',
|
||||||
patch_exchange(mocker, api_mock, id)
|
mock_markets=True) -> Exchange:
|
||||||
|
patch_exchange(mocker, api_mock, id, mock_markets)
|
||||||
config["exchange"]["name"] = id
|
config["exchange"]["name"] = id
|
||||||
try:
|
try:
|
||||||
exchange = ExchangeResolver(id, config).exchange
|
exchange = ExchangeResolver(id, config).exchange
|
||||||
@ -85,6 +89,11 @@ def patch_wallet(mocker, free=999.9) -> None:
|
|||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
def patch_whitelist(mocker, conf) -> None:
|
||||||
|
mocker.patch('freqtrade.freqtradebot.FreqtradeBot._refresh_whitelist',
|
||||||
|
MagicMock(return_value=conf['exchange']['pair_whitelist']))
|
||||||
|
|
||||||
|
|
||||||
def patch_edge(mocker) -> None:
|
def patch_edge(mocker) -> None:
|
||||||
# "ETH/BTC",
|
# "ETH/BTC",
|
||||||
# "LTC/BTC",
|
# "LTC/BTC",
|
||||||
@ -120,6 +129,7 @@ def patch_freqtradebot(mocker, config) -> None:
|
|||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
mocker.patch('freqtrade.freqtradebot.RPCManager._init', MagicMock())
|
mocker.patch('freqtrade.freqtradebot.RPCManager._init', MagicMock())
|
||||||
mocker.patch('freqtrade.freqtradebot.RPCManager.send_msg', MagicMock())
|
mocker.patch('freqtrade.freqtradebot.RPCManager.send_msg', MagicMock())
|
||||||
|
patch_whitelist(mocker, config)
|
||||||
|
|
||||||
|
|
||||||
def get_patched_freqtradebot(mocker, config) -> FreqtradeBot:
|
def get_patched_freqtradebot(mocker, config) -> FreqtradeBot:
|
||||||
@ -287,6 +297,10 @@ def ticker_sell_down():
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def markets():
|
def markets():
|
||||||
|
return get_markets()
|
||||||
|
|
||||||
|
|
||||||
|
def get_markets():
|
||||||
return {
|
return {
|
||||||
'ETH/BTC': {
|
'ETH/BTC': {
|
||||||
'id': 'ethbtc',
|
'id': 'ethbtc',
|
||||||
@ -369,7 +383,7 @@ def markets():
|
|||||||
'symbol': 'LTC/BTC',
|
'symbol': 'LTC/BTC',
|
||||||
'base': 'LTC',
|
'base': 'LTC',
|
||||||
'quote': 'BTC',
|
'quote': 'BTC',
|
||||||
'active': False,
|
'active': True,
|
||||||
'precision': {
|
'precision': {
|
||||||
'price': 8,
|
'price': 8,
|
||||||
'amount': 8,
|
'amount': 8,
|
||||||
@ -394,7 +408,7 @@ def markets():
|
|||||||
'symbol': 'XRP/BTC',
|
'symbol': 'XRP/BTC',
|
||||||
'base': 'XRP',
|
'base': 'XRP',
|
||||||
'quote': 'BTC',
|
'quote': 'BTC',
|
||||||
'active': False,
|
'active': True,
|
||||||
'precision': {
|
'precision': {
|
||||||
'price': 8,
|
'price': 8,
|
||||||
'amount': 8,
|
'amount': 8,
|
||||||
@ -419,7 +433,7 @@ def markets():
|
|||||||
'symbol': 'NEO/BTC',
|
'symbol': 'NEO/BTC',
|
||||||
'base': 'NEO',
|
'base': 'NEO',
|
||||||
'quote': 'BTC',
|
'quote': 'BTC',
|
||||||
'active': False,
|
'active': True,
|
||||||
'precision': {
|
'precision': {
|
||||||
'price': 8,
|
'price': 8,
|
||||||
'amount': 8,
|
'amount': 8,
|
||||||
@ -444,7 +458,7 @@ def markets():
|
|||||||
'symbol': 'BTT/BTC',
|
'symbol': 'BTT/BTC',
|
||||||
'base': 'BTT',
|
'base': 'BTT',
|
||||||
'quote': 'BTC',
|
'quote': 'BTC',
|
||||||
'active': True,
|
'active': False,
|
||||||
'precision': {
|
'precision': {
|
||||||
'base': 8,
|
'base': 8,
|
||||||
'quote': 8,
|
'quote': 8,
|
||||||
@ -494,7 +508,7 @@ def markets():
|
|||||||
'symbol': 'LTC/USDT',
|
'symbol': 'LTC/USDT',
|
||||||
'base': 'LTC',
|
'base': 'LTC',
|
||||||
'quote': 'USDT',
|
'quote': 'USDT',
|
||||||
'active': True,
|
'active': False,
|
||||||
'precision': {
|
'precision': {
|
||||||
'amount': 8,
|
'amount': 8,
|
||||||
'price': 8
|
'price': 8
|
||||||
|
@ -533,21 +533,22 @@ def test_refresh_backtest_ohlcv_data(mocker, default_conf, markets, caplog, test
|
|||||||
|
|
||||||
def test_download_data_no_markets(mocker, default_conf, caplog, testdatadir):
|
def test_download_data_no_markets(mocker, default_conf, caplog, testdatadir):
|
||||||
dl_mock = mocker.patch('freqtrade.data.history.download_pair_history', MagicMock())
|
dl_mock = mocker.patch('freqtrade.data.history.download_pair_history', MagicMock())
|
||||||
|
|
||||||
|
ex = get_patched_exchange(mocker, default_conf)
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
'freqtrade.exchange.Exchange.markets', PropertyMock(return_value={})
|
'freqtrade.exchange.Exchange.markets', PropertyMock(return_value={})
|
||||||
)
|
)
|
||||||
ex = get_patched_exchange(mocker, default_conf)
|
|
||||||
timerange = TimeRange.parse_timerange("20190101-20190102")
|
timerange = TimeRange.parse_timerange("20190101-20190102")
|
||||||
unav_pairs = refresh_backtest_ohlcv_data(exchange=ex, pairs=["ETH/BTC", "XRP/BTC"],
|
unav_pairs = refresh_backtest_ohlcv_data(exchange=ex, pairs=["BTT/BTC", "LTC/USDT"],
|
||||||
timeframes=["1m", "5m"],
|
timeframes=["1m", "5m"],
|
||||||
dl_path=testdatadir,
|
dl_path=testdatadir,
|
||||||
timerange=timerange, erase=False
|
timerange=timerange, erase=False
|
||||||
)
|
)
|
||||||
|
|
||||||
assert dl_mock.call_count == 0
|
assert dl_mock.call_count == 0
|
||||||
assert "ETH/BTC" in unav_pairs
|
assert "BTT/BTC" in unav_pairs
|
||||||
assert "XRP/BTC" in unav_pairs
|
assert "LTC/USDT" in unav_pairs
|
||||||
assert log_has("Skipping pair ETH/BTC...", caplog)
|
assert log_has("Skipping pair BTT/BTC...", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_refresh_backtest_trades_data(mocker, default_conf, markets, caplog, testdatadir):
|
def test_refresh_backtest_trades_data(mocker, default_conf, markets, caplog, testdatadir):
|
||||||
|
@ -177,16 +177,11 @@ def test_symbol_amount_prec(default_conf, mocker):
|
|||||||
'''
|
'''
|
||||||
Test rounds down to 4 Decimal places
|
Test rounds down to 4 Decimal places
|
||||||
'''
|
'''
|
||||||
api_mock = MagicMock()
|
|
||||||
api_mock.load_markets = MagicMock(return_value={
|
|
||||||
'ETH/BTC': '', 'LTC/BTC': '', 'XRP/BTC': '', 'NEO/BTC': ''
|
|
||||||
})
|
|
||||||
mocker.patch('freqtrade.exchange.Exchange.name', PropertyMock(return_value='binance'))
|
|
||||||
|
|
||||||
markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'amount': 4}}})
|
markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'amount': 4}}})
|
||||||
type(api_mock).markets = markets
|
|
||||||
|
|
||||||
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
exchange = get_patched_exchange(mocker, default_conf, id="binance")
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange.markets', markets)
|
||||||
|
|
||||||
amount = 2.34559
|
amount = 2.34559
|
||||||
pair = 'ETH/BTC'
|
pair = 'ETH/BTC'
|
||||||
@ -198,16 +193,10 @@ def test_symbol_price_prec(default_conf, mocker):
|
|||||||
'''
|
'''
|
||||||
Test rounds up to 4 decimal places
|
Test rounds up to 4 decimal places
|
||||||
'''
|
'''
|
||||||
api_mock = MagicMock()
|
|
||||||
api_mock.load_markets = MagicMock(return_value={
|
|
||||||
'ETH/BTC': '', 'LTC/BTC': '', 'XRP/BTC': '', 'NEO/BTC': ''
|
|
||||||
})
|
|
||||||
mocker.patch('freqtrade.exchange.Exchange.name', PropertyMock(return_value='binance'))
|
|
||||||
|
|
||||||
markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'price': 4}}})
|
markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'price': 4}}})
|
||||||
type(api_mock).markets = markets
|
|
||||||
|
|
||||||
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
exchange = get_patched_exchange(mocker, default_conf, id="binance")
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange.markets', markets)
|
||||||
|
|
||||||
price = 2.34559
|
price = 2.34559
|
||||||
pair = 'ETH/BTC'
|
pair = 'ETH/BTC'
|
||||||
@ -279,7 +268,7 @@ def test__load_markets(default_conf, mocker, caplog):
|
|||||||
api_mock.load_markets = MagicMock(return_value=expected_return)
|
api_mock.load_markets = MagicMock(return_value=expected_return)
|
||||||
type(api_mock).markets = expected_return
|
type(api_mock).markets = expected_return
|
||||||
default_conf['exchange']['pair_whitelist'] = ['ETH/BTC']
|
default_conf['exchange']['pair_whitelist'] = ['ETH/BTC']
|
||||||
ex = get_patched_exchange(mocker, default_conf, api_mock, id="binance")
|
ex = get_patched_exchange(mocker, default_conf, api_mock, id="binance", mock_markets=False)
|
||||||
assert ex.markets == expected_return
|
assert ex.markets == expected_return
|
||||||
|
|
||||||
|
|
||||||
@ -294,7 +283,8 @@ def test__reload_markets(default_conf, mocker, caplog):
|
|||||||
api_mock.load_markets = load_markets
|
api_mock.load_markets = load_markets
|
||||||
type(api_mock).markets = initial_markets
|
type(api_mock).markets = initial_markets
|
||||||
default_conf['exchange']['markets_refresh_interval'] = 10
|
default_conf['exchange']['markets_refresh_interval'] = 10
|
||||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, id="binance")
|
exchange = get_patched_exchange(mocker, default_conf, api_mock, id="binance",
|
||||||
|
mock_markets=False)
|
||||||
exchange._last_markets_refresh = arrow.utcnow().timestamp
|
exchange._last_markets_refresh = arrow.utcnow().timestamp
|
||||||
updated_markets = {'ETH/BTC': {}, "LTC/BTC": {}}
|
updated_markets = {'ETH/BTC': {}, "LTC/BTC": {}}
|
||||||
|
|
||||||
@ -1715,15 +1705,16 @@ def test_get_valid_pair_combination(default_conf, mocker, markets):
|
|||||||
'LTC/USDT', 'NEO/BTC', 'TKN/BTC', 'XLTCUSDT', 'XRP/BTC']),
|
'LTC/USDT', 'NEO/BTC', 'TKN/BTC', 'XLTCUSDT', 'XRP/BTC']),
|
||||||
# active markets
|
# active markets
|
||||||
([], [], False, True,
|
([], [], False, True,
|
||||||
['BLK/BTC', 'BTT/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/USD', 'LTC/USDT',
|
['BLK/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/USD', 'NEO/BTC',
|
||||||
'TKN/BTC', 'XLTCUSDT']),
|
'TKN/BTC', 'XLTCUSDT', 'XRP/BTC']),
|
||||||
# all pairs
|
# all pairs
|
||||||
([], [], True, False,
|
([], [], True, False,
|
||||||
['BLK/BTC', 'BTT/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/USD',
|
['BLK/BTC', 'BTT/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/USD',
|
||||||
'LTC/USDT', 'NEO/BTC', 'TKN/BTC', 'XRP/BTC']),
|
'LTC/USDT', 'NEO/BTC', 'TKN/BTC', 'XRP/BTC']),
|
||||||
# active pairs
|
# active pairs
|
||||||
([], [], True, True,
|
([], [], True, True,
|
||||||
['BLK/BTC', 'BTT/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/USD', 'LTC/USDT', 'TKN/BTC']),
|
['BLK/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/USD', 'NEO/BTC',
|
||||||
|
'TKN/BTC', 'XRP/BTC']),
|
||||||
# all markets, base=ETH, LTC
|
# all markets, base=ETH, LTC
|
||||||
(['ETH', 'LTC'], [], False, False,
|
(['ETH', 'LTC'], [], False, False,
|
||||||
['ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/USD', 'LTC/USDT', 'XLTCUSDT']),
|
['ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/USD', 'LTC/USDT', 'XLTCUSDT']),
|
||||||
|
@ -80,7 +80,7 @@ def test_refresh_pairlist_dynamic(mocker, markets, tickers, whitelist_conf):
|
|||||||
freqtradebot = get_patched_freqtradebot(mocker, whitelist_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, whitelist_conf)
|
||||||
|
|
||||||
# argument: use the whitelist dynamically by exchange-volume
|
# argument: use the whitelist dynamically by exchange-volume
|
||||||
whitelist = ['ETH/BTC', 'TKN/BTC', 'BTT/BTC']
|
whitelist = ['ETH/BTC', 'TKN/BTC', 'LTC/BTC']
|
||||||
freqtradebot.pairlists.refresh_pairlist()
|
freqtradebot.pairlists.refresh_pairlist()
|
||||||
|
|
||||||
assert whitelist == freqtradebot.pairlists.whitelist
|
assert whitelist == freqtradebot.pairlists.whitelist
|
||||||
@ -108,12 +108,12 @@ def test_VolumePairList_refresh_empty(mocker, markets_empty, whitelist_conf):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("precision_filter,base_currency,key,whitelist_result", [
|
@pytest.mark.parametrize("precision_filter,base_currency,key,whitelist_result", [
|
||||||
(False, "BTC", "quoteVolume", ['ETH/BTC', 'TKN/BTC', 'BTT/BTC']),
|
(False, "BTC", "quoteVolume", ['ETH/BTC', 'TKN/BTC', 'LTC/BTC']),
|
||||||
(False, "BTC", "bidVolume", ['BTT/BTC', 'TKN/BTC', 'ETH/BTC']),
|
(False, "BTC", "bidVolume", ['LTC/BTC', 'TKN/BTC', 'ETH/BTC']),
|
||||||
(False, "USDT", "quoteVolume", ['ETH/USDT', 'LTC/USDT']),
|
(False, "USDT", "quoteVolume", ['ETH/USDT']),
|
||||||
(False, "ETH", "quoteVolume", []), # this replaces tests that were removed from test_exchange
|
(False, "ETH", "quoteVolume", []), # this replaces tests that were removed from test_exchange
|
||||||
(True, "BTC", "quoteVolume", ["ETH/BTC", "TKN/BTC"]),
|
(True, "BTC", "quoteVolume", ["LTC/BTC", "ETH/BTC", "TKN/BTC"]),
|
||||||
(True, "BTC", "bidVolume", ["TKN/BTC", "ETH/BTC"])
|
(True, "BTC", "bidVolume", ["LTC/BTC", "TKN/BTC", "ETH/BTC"])
|
||||||
])
|
])
|
||||||
def test_VolumePairList_whitelist_gen(mocker, whitelist_conf, markets, tickers, base_currency, key,
|
def test_VolumePairList_whitelist_gen(mocker, whitelist_conf, markets, tickers, base_currency, key,
|
||||||
whitelist_result, precision_filter) -> None:
|
whitelist_result, precision_filter) -> None:
|
||||||
@ -127,7 +127,7 @@ def test_VolumePairList_whitelist_gen(mocker, whitelist_conf, markets, tickers,
|
|||||||
freqtrade.pairlists._precision_filter = precision_filter
|
freqtrade.pairlists._precision_filter = precision_filter
|
||||||
freqtrade.config['stake_currency'] = base_currency
|
freqtrade.config['stake_currency'] = base_currency
|
||||||
whitelist = freqtrade.pairlists._gen_pair_whitelist(base_currency=base_currency, key=key)
|
whitelist = freqtrade.pairlists._gen_pair_whitelist(base_currency=base_currency, key=key)
|
||||||
assert whitelist == whitelist_result
|
assert sorted(whitelist) == sorted(whitelist_result)
|
||||||
|
|
||||||
|
|
||||||
def test_gen_pair_whitelist_not_supported(mocker, default_conf, tickers) -> None:
|
def test_gen_pair_whitelist_not_supported(mocker, default_conf, tickers) -> None:
|
||||||
@ -160,7 +160,7 @@ def test_pairlist_class(mocker, whitelist_conf, markets, pairlist):
|
|||||||
(['ETH/BTC', 'TKN/BTC', 'TRX/ETH'], "is not compatible with exchange"), # TRX/ETH wrong stake
|
(['ETH/BTC', 'TKN/BTC', 'TRX/ETH'], "is not compatible with exchange"), # TRX/ETH wrong stake
|
||||||
(['ETH/BTC', 'TKN/BTC', 'BCH/BTC'], "is not compatible with exchange"), # BCH/BTC not available
|
(['ETH/BTC', 'TKN/BTC', 'BCH/BTC'], "is not compatible with exchange"), # BCH/BTC not available
|
||||||
(['ETH/BTC', 'TKN/BTC', 'BLK/BTC'], "is not compatible with exchange"), # BLK/BTC in blacklist
|
(['ETH/BTC', 'TKN/BTC', 'BLK/BTC'], "is not compatible with exchange"), # BLK/BTC in blacklist
|
||||||
(['ETH/BTC', 'TKN/BTC', 'LTC/BTC'], "Market is not active") # LTC/BTC is inactive
|
(['ETH/BTC', 'TKN/BTC', 'BTT/BTC'], "Market is not active") # BTT/BTC is inactive
|
||||||
])
|
])
|
||||||
def test_validate_whitelist(mocker, whitelist_conf, markets, pairlist, whitelist, caplog,
|
def test_validate_whitelist(mocker, whitelist_conf, markets, pairlist, whitelist, caplog,
|
||||||
log_message):
|
log_message):
|
||||||
|
@ -9,12 +9,11 @@ from numpy import isnan
|
|||||||
|
|
||||||
from freqtrade import DependencyException, TemporaryError
|
from freqtrade import DependencyException, TemporaryError
|
||||||
from freqtrade.edge import PairInfo
|
from freqtrade.edge import PairInfo
|
||||||
from freqtrade.freqtradebot import FreqtradeBot
|
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
from freqtrade.rpc import RPC, RPCException
|
from freqtrade.rpc import RPC, RPCException
|
||||||
from freqtrade.rpc.fiat_convert import CryptoToFiatConverter
|
from freqtrade.rpc.fiat_convert import CryptoToFiatConverter
|
||||||
from freqtrade.state import State
|
from freqtrade.state import State
|
||||||
from tests.conftest import patch_exchange, patch_get_signal
|
from tests.conftest import patch_get_signal, get_patched_freqtradebot
|
||||||
|
|
||||||
|
|
||||||
# Functions for recurrent object patching
|
# Functions for recurrent object patching
|
||||||
@ -26,17 +25,15 @@ def prec_satoshi(a, b) -> float:
|
|||||||
|
|
||||||
|
|
||||||
# Unit tests
|
# Unit tests
|
||||||
def test_rpc_trade_status(default_conf, ticker, fee, markets, mocker) -> None:
|
def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
|
|
||||||
@ -98,17 +95,15 @@ def test_rpc_trade_status(default_conf, ticker, fee, markets, mocker) -> None:
|
|||||||
} == results[0]
|
} == results[0]
|
||||||
|
|
||||||
|
|
||||||
def test_rpc_status_table(default_conf, ticker, fee, markets, mocker) -> None:
|
def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
|
|
||||||
@ -134,7 +129,6 @@ def test_rpc_status_table(default_conf, ticker, fee, markets, mocker) -> None:
|
|||||||
|
|
||||||
def test_rpc_daily_profit(default_conf, update, ticker, fee,
|
def test_rpc_daily_profit(default_conf, update, ticker, fee,
|
||||||
limit_buy_order, limit_sell_order, markets, mocker) -> None:
|
limit_buy_order, limit_sell_order, markets, mocker) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
@ -143,7 +137,7 @@ def test_rpc_daily_profit(default_conf, update, ticker, fee,
|
|||||||
markets=PropertyMock(return_value=markets)
|
markets=PropertyMock(return_value=markets)
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
stake_currency = default_conf['stake_currency']
|
stake_currency = default_conf['stake_currency']
|
||||||
fiat_display_currency = default_conf['fiat_display_currency']
|
fiat_display_currency = default_conf['fiat_display_currency']
|
||||||
@ -181,22 +175,20 @@ def test_rpc_daily_profit(default_conf, update, ticker, fee,
|
|||||||
|
|
||||||
|
|
||||||
def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee,
|
def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee,
|
||||||
limit_buy_order, limit_sell_order, markets, mocker) -> None:
|
limit_buy_order, limit_sell_order, mocker) -> None:
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.rpc.fiat_convert.Market',
|
'freqtrade.rpc.fiat_convert.Market',
|
||||||
ticker=MagicMock(return_value={'price_usd': 15000.0}),
|
ticker=MagicMock(return_value={'price_usd': 15000.0}),
|
||||||
)
|
)
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
stake_currency = default_conf['stake_currency']
|
stake_currency = default_conf['stake_currency']
|
||||||
fiat_display_currency = default_conf['fiat_display_currency']
|
fiat_display_currency = default_conf['fiat_display_currency']
|
||||||
@ -267,9 +259,8 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee,
|
|||||||
|
|
||||||
# Test that rpc_trade_statistics can handle trades that lacks
|
# Test that rpc_trade_statistics can handle trades that lacks
|
||||||
# trade.open_rate (it is set to None)
|
# trade.open_rate (it is set to None)
|
||||||
def test_rpc_trade_statistics_closed(mocker, default_conf, ticker, fee, markets,
|
def test_rpc_trade_statistics_closed(mocker, default_conf, ticker, fee,
|
||||||
ticker_sell_up, limit_buy_order, limit_sell_order):
|
ticker_sell_up, limit_buy_order, limit_sell_order):
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.rpc.fiat_convert.Market',
|
'freqtrade.rpc.fiat_convert.Market',
|
||||||
ticker=MagicMock(return_value={'price_usd': 15000.0}),
|
ticker=MagicMock(return_value={'price_usd': 15000.0}),
|
||||||
@ -281,10 +272,9 @@ def test_rpc_trade_statistics_closed(mocker, default_conf, ticker, fee, markets,
|
|||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
stake_currency = default_conf['stake_currency']
|
stake_currency = default_conf['stake_currency']
|
||||||
fiat_display_currency = default_conf['fiat_display_currency']
|
fiat_display_currency = default_conf['fiat_display_currency']
|
||||||
@ -343,7 +333,6 @@ def test_rpc_balance_handle_error(default_conf, mocker):
|
|||||||
'freqtrade.rpc.fiat_convert.Market',
|
'freqtrade.rpc.fiat_convert.Market',
|
||||||
ticker=MagicMock(return_value={'price_usd': 15000.0}),
|
ticker=MagicMock(return_value={'price_usd': 15000.0}),
|
||||||
)
|
)
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
@ -352,7 +341,7 @@ def test_rpc_balance_handle_error(default_conf, mocker):
|
|||||||
get_ticker=MagicMock(side_effect=TemporaryError('Could not load ticker due to xxx'))
|
get_ticker=MagicMock(side_effect=TemporaryError('Could not load ticker due to xxx'))
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
rpc._fiat_converter = CryptoToFiatConverter()
|
rpc._fiat_converter = CryptoToFiatConverter()
|
||||||
@ -394,7 +383,6 @@ def test_rpc_balance_handle(default_conf, mocker):
|
|||||||
'freqtrade.rpc.fiat_convert.Market',
|
'freqtrade.rpc.fiat_convert.Market',
|
||||||
ticker=MagicMock(return_value={'price_usd': 15000.0}),
|
ticker=MagicMock(return_value={'price_usd': 15000.0}),
|
||||||
)
|
)
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
@ -406,7 +394,7 @@ def test_rpc_balance_handle(default_conf, mocker):
|
|||||||
side_effect=lambda a, b: f"{b}/{a}" if a == "PAX" else f"{a}/{b}")
|
side_effect=lambda a, b: f"{b}/{a}" if a == "PAX" else f"{a}/{b}")
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
rpc._fiat_converter = CryptoToFiatConverter()
|
rpc._fiat_converter = CryptoToFiatConverter()
|
||||||
@ -438,14 +426,13 @@ def test_rpc_balance_handle(default_conf, mocker):
|
|||||||
|
|
||||||
|
|
||||||
def test_rpc_start(mocker, default_conf) -> None:
|
def test_rpc_start(mocker, default_conf) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=MagicMock()
|
get_ticker=MagicMock()
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
freqtradebot.state = State.STOPPED
|
freqtradebot.state = State.STOPPED
|
||||||
@ -460,14 +447,13 @@ def test_rpc_start(mocker, default_conf) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_rpc_stop(mocker, default_conf) -> None:
|
def test_rpc_stop(mocker, default_conf) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=MagicMock()
|
get_ticker=MagicMock()
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
freqtradebot.state = State.RUNNING
|
freqtradebot.state = State.RUNNING
|
||||||
@ -483,14 +469,13 @@ def test_rpc_stop(mocker, default_conf) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_rpc_stopbuy(mocker, default_conf) -> None:
|
def test_rpc_stopbuy(mocker, default_conf) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=MagicMock()
|
get_ticker=MagicMock()
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
freqtradebot.state = State.RUNNING
|
freqtradebot.state = State.RUNNING
|
||||||
@ -501,8 +486,7 @@ def test_rpc_stopbuy(mocker, default_conf) -> None:
|
|||||||
assert freqtradebot.config['max_open_trades'] == 0
|
assert freqtradebot.config['max_open_trades'] == 0
|
||||||
|
|
||||||
|
|
||||||
def test_rpc_forcesell(default_conf, ticker, fee, mocker, markets) -> None:
|
def test_rpc_forcesell(default_conf, ticker, fee, mocker) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
|
|
||||||
cancel_order_mock = MagicMock()
|
cancel_order_mock = MagicMock()
|
||||||
@ -518,10 +502,9 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker, markets) -> None:
|
|||||||
}
|
}
|
||||||
),
|
),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
|
|
||||||
@ -606,18 +589,16 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker, markets) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_performance_handle(default_conf, ticker, limit_buy_order, fee,
|
def test_performance_handle(default_conf, ticker, limit_buy_order, fee,
|
||||||
limit_sell_order, markets, mocker) -> None:
|
limit_sell_order, mocker) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_balances=MagicMock(return_value=ticker),
|
get_balances=MagicMock(return_value=ticker),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
|
|
||||||
@ -641,18 +622,16 @@ def test_performance_handle(default_conf, ticker, limit_buy_order, fee,
|
|||||||
assert prec_satoshi(res[0]['profit'], 6.2)
|
assert prec_satoshi(res[0]['profit'], 6.2)
|
||||||
|
|
||||||
|
|
||||||
def test_rpc_count(mocker, default_conf, ticker, fee, markets) -> None:
|
def test_rpc_count(mocker, default_conf, ticker, fee) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_balances=MagicMock(return_value=ticker),
|
get_balances=MagicMock(return_value=ticker),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
|
|
||||||
@ -665,9 +644,8 @@ def test_rpc_count(mocker, default_conf, ticker, fee, markets) -> None:
|
|||||||
assert counts["current"] == 1
|
assert counts["current"] == 1
|
||||||
|
|
||||||
|
|
||||||
def test_rpcforcebuy(mocker, default_conf, ticker, fee, markets, limit_buy_order) -> None:
|
def test_rpcforcebuy(mocker, default_conf, ticker, fee, limit_buy_order) -> None:
|
||||||
default_conf['forcebuy_enable'] = True
|
default_conf['forcebuy_enable'] = True
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
buy_mm = MagicMock(return_value={'id': limit_buy_order['id']})
|
buy_mm = MagicMock(return_value={'id': limit_buy_order['id']})
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
@ -675,11 +653,10 @@ def test_rpcforcebuy(mocker, default_conf, ticker, fee, markets, limit_buy_order
|
|||||||
get_balances=MagicMock(return_value=ticker),
|
get_balances=MagicMock(return_value=ticker),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets),
|
|
||||||
buy=buy_mm
|
buy=buy_mm
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
pair = 'ETH/BTC'
|
pair = 'ETH/BTC'
|
||||||
@ -704,7 +681,7 @@ def test_rpcforcebuy(mocker, default_conf, ticker, fee, markets, limit_buy_order
|
|||||||
|
|
||||||
# Test not buying
|
# Test not buying
|
||||||
default_conf['stake_amount'] = 0.0000001
|
default_conf['stake_amount'] = 0.0000001
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
pair = 'TKN/BTC'
|
pair = 'TKN/BTC'
|
||||||
@ -715,10 +692,9 @@ def test_rpcforcebuy(mocker, default_conf, ticker, fee, markets, limit_buy_order
|
|||||||
def test_rpcforcebuy_stopped(mocker, default_conf) -> None:
|
def test_rpcforcebuy_stopped(mocker, default_conf) -> None:
|
||||||
default_conf['forcebuy_enable'] = True
|
default_conf['forcebuy_enable'] = True
|
||||||
default_conf['initial_state'] = 'stopped'
|
default_conf['initial_state'] = 'stopped'
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
pair = 'ETH/BTC'
|
pair = 'ETH/BTC'
|
||||||
@ -727,10 +703,9 @@ def test_rpcforcebuy_stopped(mocker, default_conf) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_rpcforcebuy_disabled(mocker, default_conf) -> None:
|
def test_rpcforcebuy_disabled(mocker, default_conf) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
pair = 'ETH/BTC'
|
pair = 'ETH/BTC'
|
||||||
@ -739,10 +714,9 @@ def test_rpcforcebuy_disabled(mocker, default_conf) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_rpc_whitelist(mocker, default_conf) -> None:
|
def test_rpc_whitelist(mocker, default_conf) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
ret = rpc._rpc_whitelist()
|
ret = rpc._rpc_whitelist()
|
||||||
assert ret['method'] == 'StaticPairList'
|
assert ret['method'] == 'StaticPairList'
|
||||||
@ -750,14 +724,13 @@ def test_rpc_whitelist(mocker, default_conf) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_rpc_whitelist_dynamic(mocker, default_conf) -> None:
|
def test_rpc_whitelist_dynamic(mocker, default_conf) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
default_conf['pairlist'] = {'method': 'VolumePairList',
|
default_conf['pairlist'] = {'method': 'VolumePairList',
|
||||||
'config': {'number_assets': 4}
|
'config': {'number_assets': 4}
|
||||||
}
|
}
|
||||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
ret = rpc._rpc_whitelist()
|
ret = rpc._rpc_whitelist()
|
||||||
assert ret['method'] == 'VolumePairList'
|
assert ret['method'] == 'VolumePairList'
|
||||||
@ -766,10 +739,9 @@ def test_rpc_whitelist_dynamic(mocker, default_conf) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_rpc_blacklist(mocker, default_conf) -> None:
|
def test_rpc_blacklist(mocker, default_conf) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
ret = rpc._rpc_blacklist(None)
|
ret = rpc._rpc_blacklist(None)
|
||||||
assert ret['method'] == 'StaticPairList'
|
assert ret['method'] == 'StaticPairList'
|
||||||
@ -785,23 +757,21 @@ def test_rpc_blacklist(mocker, default_conf) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_rpc_edge_disabled(mocker, default_conf) -> None:
|
def test_rpc_edge_disabled(mocker, default_conf) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
with pytest.raises(RPCException, match=r'Edge is not enabled.'):
|
with pytest.raises(RPCException, match=r'Edge is not enabled.'):
|
||||||
rpc._rpc_edge()
|
rpc._rpc_edge()
|
||||||
|
|
||||||
|
|
||||||
def test_rpc_edge_enabled(mocker, edge_conf) -> None:
|
def test_rpc_edge_enabled(mocker, edge_conf) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
mocker.patch('freqtrade.edge.Edge._cached_pairs', mocker.PropertyMock(
|
mocker.patch('freqtrade.edge.Edge._cached_pairs', mocker.PropertyMock(
|
||||||
return_value={
|
return_value={
|
||||||
'E/F': PairInfo(-0.02, 0.66, 3.71, 0.50, 1.71, 10, 60),
|
'E/F': PairInfo(-0.02, 0.66, 3.71, 0.50, 1.71, 10, 60),
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
freqtradebot = FreqtradeBot(edge_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, edge_conf)
|
||||||
|
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
ret = rpc._rpc_edge()
|
ret = rpc._rpc_edge()
|
||||||
|
@ -22,7 +22,7 @@ from freqtrade.rpc.telegram import Telegram, authorized_only
|
|||||||
from freqtrade.state import State
|
from freqtrade.state import State
|
||||||
from freqtrade.strategy.interface import SellType
|
from freqtrade.strategy.interface import SellType
|
||||||
from tests.conftest import (get_patched_freqtradebot, log_has, patch_exchange,
|
from tests.conftest import (get_patched_freqtradebot, log_has, patch_exchange,
|
||||||
patch_get_signal)
|
patch_get_signal, patch_whitelist)
|
||||||
|
|
||||||
|
|
||||||
class DummyCls(Telegram):
|
class DummyCls(Telegram):
|
||||||
@ -143,17 +143,15 @@ def test_authorized_only_exception(default_conf, mocker, caplog) -> None:
|
|||||||
assert log_has('Exception occurred within Telegram module', caplog)
|
assert log_has('Exception occurred within Telegram module', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_status(default_conf, update, mocker, fee, ticker, markets) -> None:
|
def test_status(default_conf, update, mocker, fee, ticker,) -> None:
|
||||||
update.message.chat.id = 123
|
update.message.chat.id = 123
|
||||||
default_conf['telegram']['enabled'] = False
|
default_conf['telegram']['enabled'] = False
|
||||||
default_conf['telegram']['chat_id'] = 123
|
default_conf['telegram']['chat_id'] = 123
|
||||||
|
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(markets)
|
|
||||||
)
|
)
|
||||||
msg_mock = MagicMock()
|
msg_mock = MagicMock()
|
||||||
status_table = MagicMock()
|
status_table = MagicMock()
|
||||||
@ -184,9 +182,8 @@ def test_status(default_conf, update, mocker, fee, ticker, markets) -> None:
|
|||||||
_status_table=status_table,
|
_status_table=status_table,
|
||||||
_send_msg=msg_mock
|
_send_msg=msg_mock
|
||||||
)
|
)
|
||||||
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
telegram = Telegram(freqtradebot)
|
telegram = Telegram(freqtradebot)
|
||||||
|
|
||||||
@ -204,13 +201,11 @@ def test_status(default_conf, update, mocker, fee, ticker, markets) -> None:
|
|||||||
assert status_table.call_count == 1
|
assert status_table.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
def test_status_handle(default_conf, update, ticker, fee, markets, mocker) -> None:
|
def test_status_handle(default_conf, update, ticker, fee, mocker) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(markets)
|
|
||||||
)
|
)
|
||||||
msg_mock = MagicMock()
|
msg_mock = MagicMock()
|
||||||
status_table = MagicMock()
|
status_table = MagicMock()
|
||||||
@ -220,9 +215,9 @@ def test_status_handle(default_conf, update, ticker, fee, markets, mocker) -> No
|
|||||||
_status_table=status_table,
|
_status_table=status_table,
|
||||||
_send_msg=msg_mock
|
_send_msg=msg_mock
|
||||||
)
|
)
|
||||||
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
|
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
|
|
||||||
telegram = Telegram(freqtradebot)
|
telegram = Telegram(freqtradebot)
|
||||||
@ -256,14 +251,12 @@ def test_status_handle(default_conf, update, ticker, fee, markets, mocker) -> No
|
|||||||
assert 'ETH/BTC' in msg_mock.call_args_list[0][0][0]
|
assert 'ETH/BTC' in msg_mock.call_args_list[0][0][0]
|
||||||
|
|
||||||
|
|
||||||
def test_status_table_handle(default_conf, update, ticker, fee, markets, mocker) -> None:
|
def test_status_table_handle(default_conf, update, ticker, fee, mocker) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
buy=MagicMock(return_value={'id': 'mocked_order_id'}),
|
buy=MagicMock(return_value={'id': 'mocked_order_id'}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(markets)
|
|
||||||
)
|
)
|
||||||
msg_mock = MagicMock()
|
msg_mock = MagicMock()
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
@ -271,10 +264,9 @@ def test_status_table_handle(default_conf, update, ticker, fee, markets, mocker)
|
|||||||
_init=MagicMock(),
|
_init=MagicMock(),
|
||||||
_send_msg=msg_mock
|
_send_msg=msg_mock
|
||||||
)
|
)
|
||||||
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
|
||||||
|
|
||||||
default_conf['stake_amount'] = 15.0
|
default_conf['stake_amount'] = 15.0
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
|
|
||||||
telegram = Telegram(freqtradebot)
|
telegram = Telegram(freqtradebot)
|
||||||
@ -307,8 +299,7 @@ def test_status_table_handle(default_conf, update, ticker, fee, markets, mocker)
|
|||||||
|
|
||||||
|
|
||||||
def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee,
|
def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee,
|
||||||
limit_sell_order, markets, mocker) -> None:
|
limit_sell_order, mocker) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
default_conf['max_open_trades'] = 1
|
default_conf['max_open_trades'] = 1
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
'freqtrade.rpc.rpc.CryptoToFiatConverter._find_price',
|
'freqtrade.rpc.rpc.CryptoToFiatConverter._find_price',
|
||||||
@ -318,7 +309,6 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee,
|
|||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(markets)
|
|
||||||
)
|
)
|
||||||
msg_mock = MagicMock()
|
msg_mock = MagicMock()
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
@ -326,9 +316,8 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee,
|
|||||||
_init=MagicMock(),
|
_init=MagicMock(),
|
||||||
_send_msg=msg_mock
|
_send_msg=msg_mock
|
||||||
)
|
)
|
||||||
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
telegram = Telegram(freqtradebot)
|
telegram = Telegram(freqtradebot)
|
||||||
|
|
||||||
@ -382,7 +371,6 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee,
|
|||||||
|
|
||||||
|
|
||||||
def test_daily_wrong_input(default_conf, update, ticker, mocker) -> None:
|
def test_daily_wrong_input(default_conf, update, ticker, mocker) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=ticker
|
get_ticker=ticker
|
||||||
@ -393,9 +381,8 @@ def test_daily_wrong_input(default_conf, update, ticker, mocker) -> None:
|
|||||||
_init=MagicMock(),
|
_init=MagicMock(),
|
||||||
_send_msg=msg_mock
|
_send_msg=msg_mock
|
||||||
)
|
)
|
||||||
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
telegram = Telegram(freqtradebot)
|
telegram = Telegram(freqtradebot)
|
||||||
|
|
||||||
@ -420,14 +407,12 @@ def test_daily_wrong_input(default_conf, update, ticker, mocker) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee,
|
def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee,
|
||||||
limit_buy_order, limit_sell_order, markets, mocker) -> None:
|
limit_buy_order, limit_sell_order, mocker) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(markets)
|
|
||||||
)
|
)
|
||||||
msg_mock = MagicMock()
|
msg_mock = MagicMock()
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
@ -435,9 +420,8 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee,
|
|||||||
_init=MagicMock(),
|
_init=MagicMock(),
|
||||||
_send_msg=msg_mock
|
_send_msg=msg_mock
|
||||||
)
|
)
|
||||||
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
telegram = Telegram(freqtradebot)
|
telegram = Telegram(freqtradebot)
|
||||||
|
|
||||||
@ -724,16 +708,16 @@ def test_reload_conf_handle(default_conf, update, mocker) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_forcesell_handle(default_conf, update, ticker, fee,
|
def test_forcesell_handle(default_conf, update, ticker, fee,
|
||||||
ticker_sell_up, markets, mocker) -> None:
|
ticker_sell_up, mocker) -> None:
|
||||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||||
rpc_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', MagicMock())
|
rpc_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', MagicMock())
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
|
patch_whitelist(mocker, default_conf)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = FreqtradeBot(default_conf)
|
||||||
@ -775,17 +759,18 @@ def test_forcesell_handle(default_conf, update, ticker, fee,
|
|||||||
|
|
||||||
|
|
||||||
def test_forcesell_down_handle(default_conf, update, ticker, fee,
|
def test_forcesell_down_handle(default_conf, update, ticker, fee,
|
||||||
ticker_sell_down, markets, mocker) -> None:
|
ticker_sell_down, mocker) -> None:
|
||||||
mocker.patch('freqtrade.rpc.fiat_convert.CryptoToFiatConverter._find_price',
|
mocker.patch('freqtrade.rpc.fiat_convert.CryptoToFiatConverter._find_price',
|
||||||
return_value=15000.0)
|
return_value=15000.0)
|
||||||
rpc_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', MagicMock())
|
rpc_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', MagicMock())
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
|
patch_whitelist(mocker, default_conf)
|
||||||
|
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = FreqtradeBot(default_conf)
|
||||||
@ -830,17 +815,17 @@ def test_forcesell_down_handle(default_conf, update, ticker, fee,
|
|||||||
} == last_msg
|
} == last_msg
|
||||||
|
|
||||||
|
|
||||||
def test_forcesell_all_handle(default_conf, update, ticker, fee, markets, mocker) -> None:
|
def test_forcesell_all_handle(default_conf, update, ticker, fee, mocker) -> None:
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
mocker.patch('freqtrade.rpc.fiat_convert.CryptoToFiatConverter._find_price',
|
mocker.patch('freqtrade.rpc.fiat_convert.CryptoToFiatConverter._find_price',
|
||||||
return_value=15000.0)
|
return_value=15000.0)
|
||||||
rpc_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', MagicMock())
|
rpc_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', MagicMock())
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
||||||
|
patch_whitelist(mocker, default_conf)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets),
|
|
||||||
)
|
)
|
||||||
default_conf['max_open_trades'] = 4
|
default_conf['max_open_trades'] = 4
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = FreqtradeBot(default_conf)
|
||||||
@ -885,9 +870,8 @@ def test_forcesell_handle_invalid(default_conf, update, mocker) -> None:
|
|||||||
_init=MagicMock(),
|
_init=MagicMock(),
|
||||||
_send_msg=msg_mock
|
_send_msg=msg_mock
|
||||||
)
|
)
|
||||||
patch_exchange(mocker)
|
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
telegram = Telegram(freqtradebot)
|
telegram = Telegram(freqtradebot)
|
||||||
|
|
||||||
@ -980,8 +964,7 @@ def test_forcebuy_handle_exception(default_conf, update, markets, mocker) -> Non
|
|||||||
|
|
||||||
|
|
||||||
def test_performance_handle(default_conf, update, ticker, fee,
|
def test_performance_handle(default_conf, update, ticker, fee,
|
||||||
limit_buy_order, limit_sell_order, markets, mocker) -> None:
|
limit_buy_order, limit_sell_order, mocker) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
msg_mock = MagicMock()
|
msg_mock = MagicMock()
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.rpc.telegram.Telegram',
|
'freqtrade.rpc.telegram.Telegram',
|
||||||
@ -992,10 +975,8 @@ def test_performance_handle(default_conf, update, ticker, fee,
|
|||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(markets),
|
|
||||||
)
|
)
|
||||||
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
telegram = Telegram(freqtradebot)
|
telegram = Telegram(freqtradebot)
|
||||||
|
|
||||||
@ -1018,8 +999,7 @@ def test_performance_handle(default_conf, update, ticker, fee,
|
|||||||
assert '<code>ETH/BTC\t6.20% (1)</code>' in msg_mock.call_args_list[0][0][0]
|
assert '<code>ETH/BTC\t6.20% (1)</code>' in msg_mock.call_args_list[0][0][0]
|
||||||
|
|
||||||
|
|
||||||
def test_count_handle(default_conf, update, ticker, fee, markets, mocker) -> None:
|
def test_count_handle(default_conf, update, ticker, fee, mocker) -> None:
|
||||||
patch_exchange(mocker)
|
|
||||||
msg_mock = MagicMock()
|
msg_mock = MagicMock()
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.rpc.telegram.Telegram',
|
'freqtrade.rpc.telegram.Telegram',
|
||||||
@ -1030,10 +1010,9 @@ def test_count_handle(default_conf, update, ticker, fee, markets, mocker) -> Non
|
|||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
buy=MagicMock(return_value={'id': 'mocked_order_id'}),
|
buy=MagicMock(return_value={'id': 'mocked_order_id'}),
|
||||||
markets=PropertyMock(markets)
|
get_fee=fee,
|
||||||
)
|
)
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
|
||||||
patch_get_signal(freqtradebot, (True, False))
|
patch_get_signal(freqtradebot, (True, False))
|
||||||
telegram = Telegram(freqtradebot)
|
telegram = Telegram(freqtradebot)
|
||||||
|
|
||||||
|
@ -729,6 +729,30 @@ def test_validate_edge(edge_conf):
|
|||||||
validate_config_consistency(edge_conf)
|
validate_config_consistency(edge_conf)
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_whitelist(default_conf):
|
||||||
|
default_conf['runmode'] = RunMode.DRY_RUN
|
||||||
|
# Test regular case - has whitelist and uses StaticPairlist
|
||||||
|
validate_config_consistency(default_conf)
|
||||||
|
conf = deepcopy(default_conf)
|
||||||
|
del conf['exchange']['pair_whitelist']
|
||||||
|
# Test error case
|
||||||
|
with pytest.raises(OperationalException,
|
||||||
|
match="StaticPairList requires pair_whitelist to be set."):
|
||||||
|
|
||||||
|
validate_config_consistency(conf)
|
||||||
|
|
||||||
|
conf = deepcopy(default_conf)
|
||||||
|
|
||||||
|
conf.update({"pairlist": {
|
||||||
|
"method": "VolumePairList",
|
||||||
|
}})
|
||||||
|
# Dynamic whitelist should not care about pair_whitelist
|
||||||
|
validate_config_consistency(conf)
|
||||||
|
del conf['exchange']['pair_whitelist']
|
||||||
|
|
||||||
|
validate_config_consistency(conf)
|
||||||
|
|
||||||
|
|
||||||
def test_load_config_test_comments() -> None:
|
def test_load_config_test_comments() -> None:
|
||||||
"""
|
"""
|
||||||
Load config with comments
|
Load config with comments
|
||||||
@ -801,7 +825,7 @@ def test_pairlist_resolving():
|
|||||||
|
|
||||||
args = Arguments(arglist).get_parsed_arg()
|
args = Arguments(arglist).get_parsed_arg()
|
||||||
|
|
||||||
configuration = Configuration(args)
|
configuration = Configuration(args, RunMode.OTHER)
|
||||||
config = configuration.get_config()
|
config = configuration.get_config()
|
||||||
|
|
||||||
assert config['pairs'] == ['ETH/BTC', 'XRP/BTC']
|
assert config['pairs'] == ['ETH/BTC', 'XRP/BTC']
|
||||||
@ -895,7 +919,7 @@ def test_pairlist_resolving_fallback(mocker):
|
|||||||
# Fix flaky tests if config.json exists
|
# Fix flaky tests if config.json exists
|
||||||
args["config"] = None
|
args["config"] = None
|
||||||
|
|
||||||
configuration = Configuration(args)
|
configuration = Configuration(args, RunMode.OTHER)
|
||||||
config = configuration.get_config()
|
config = configuration.get_config()
|
||||||
|
|
||||||
assert config['pairs'] == ['ETH/BTC', 'XRP/BTC']
|
assert config['pairs'] == ['ETH/BTC', 'XRP/BTC']
|
||||||
|
@ -23,7 +23,7 @@ from freqtrade.strategy.interface import SellCheckTuple, SellType
|
|||||||
from freqtrade.worker import Worker
|
from freqtrade.worker import Worker
|
||||||
from tests.conftest import (get_patched_freqtradebot, get_patched_worker,
|
from tests.conftest import (get_patched_freqtradebot, get_patched_worker,
|
||||||
log_has, log_has_re, patch_edge, patch_exchange,
|
log_has, log_has_re, patch_edge, patch_exchange,
|
||||||
patch_get_signal, patch_wallet)
|
patch_get_signal, patch_wallet, patch_whitelist)
|
||||||
|
|
||||||
|
|
||||||
def patch_RPCManager(mocker) -> MagicMock:
|
def patch_RPCManager(mocker) -> MagicMock:
|
||||||
@ -1247,11 +1247,10 @@ def test_create_stoploss_order_invalid_order(mocker, default_conf, caplog, fee,
|
|||||||
|
|
||||||
|
|
||||||
def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog,
|
def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog,
|
||||||
markets, limit_buy_order, limit_sell_order) -> None:
|
limit_buy_order, limit_sell_order) -> None:
|
||||||
# When trailing stoploss is set
|
# When trailing stoploss is set
|
||||||
stoploss_limit = MagicMock(return_value={'id': 13434334})
|
stoploss_limit = MagicMock(return_value={'id': 13434334})
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=MagicMock(return_value={
|
get_ticker=MagicMock(return_value={
|
||||||
@ -1262,7 +1261,6 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog,
|
|||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
sell=MagicMock(return_value={'id': limit_sell_order['id']}),
|
sell=MagicMock(return_value={'id': limit_sell_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets),
|
|
||||||
stoploss_limit=stoploss_limit
|
stoploss_limit=stoploss_limit
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1272,7 +1270,7 @@ def test_handle_stoploss_on_exchange_trailing(mocker, default_conf, fee, caplog,
|
|||||||
# disabling ROI
|
# disabling ROI
|
||||||
default_conf['minimal_roi']['0'] = 999999999
|
default_conf['minimal_roi']['0'] = 999999999
|
||||||
|
|
||||||
freqtrade = FreqtradeBot(default_conf)
|
freqtrade = get_patched_freqtradebot(mocker, default_conf)
|
||||||
|
|
||||||
# enabling stoploss on exchange
|
# enabling stoploss on exchange
|
||||||
freqtrade.strategy.order_types['stoploss_on_exchange'] = True
|
freqtrade.strategy.order_types['stoploss_on_exchange'] = True
|
||||||
@ -1825,20 +1823,18 @@ def test_handle_overlpapping_signals(default_conf, ticker, limit_buy_order,
|
|||||||
|
|
||||||
|
|
||||||
def test_handle_trade_roi(default_conf, ticker, limit_buy_order,
|
def test_handle_trade_roi(default_conf, ticker, limit_buy_order,
|
||||||
fee, mocker, markets, caplog) -> None:
|
fee, mocker, caplog) -> None:
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
|
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtrade = FreqtradeBot(default_conf)
|
freqtrade = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtrade, value=(True, False))
|
patch_get_signal(freqtrade, value=(True, False))
|
||||||
freqtrade.strategy.min_roi_reached = MagicMock(return_value=True)
|
freqtrade.strategy.min_roi_reached = MagicMock(return_value=True)
|
||||||
|
|
||||||
@ -1859,20 +1855,18 @@ def test_handle_trade_roi(default_conf, ticker, limit_buy_order,
|
|||||||
|
|
||||||
|
|
||||||
def test_handle_trade_use_sell_signal(
|
def test_handle_trade_use_sell_signal(
|
||||||
default_conf, ticker, limit_buy_order, fee, mocker, markets, caplog) -> None:
|
default_conf, ticker, limit_buy_order, fee, mocker, caplog) -> None:
|
||||||
# use_sell_signal is True buy default
|
# use_sell_signal is True buy default
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtrade = FreqtradeBot(default_conf)
|
freqtrade = get_patched_freqtradebot(mocker, default_conf)
|
||||||
patch_get_signal(freqtrade)
|
patch_get_signal(freqtrade)
|
||||||
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
|
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
|
||||||
freqtrade.create_trades()
|
freqtrade.create_trades()
|
||||||
@ -2237,6 +2231,7 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, markets, moc
|
|||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
markets=PropertyMock(return_value=markets)
|
||||||
)
|
)
|
||||||
|
patch_whitelist(mocker, default_conf)
|
||||||
freqtrade = FreqtradeBot(default_conf)
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
patch_get_signal(freqtrade)
|
patch_get_signal(freqtrade)
|
||||||
|
|
||||||
@ -2283,6 +2278,7 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, markets,
|
|||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
markets=PropertyMock(return_value=markets)
|
||||||
)
|
)
|
||||||
|
patch_whitelist(mocker, default_conf)
|
||||||
freqtrade = FreqtradeBot(default_conf)
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
patch_get_signal(freqtrade)
|
patch_get_signal(freqtrade)
|
||||||
|
|
||||||
@ -2332,6 +2328,7 @@ def test_execute_sell_down_stoploss_on_exchange_dry_run(default_conf, ticker, fe
|
|||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
markets=PropertyMock(return_value=markets)
|
||||||
)
|
)
|
||||||
|
patch_whitelist(mocker, default_conf)
|
||||||
freqtrade = FreqtradeBot(default_conf)
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
patch_get_signal(freqtrade)
|
patch_get_signal(freqtrade)
|
||||||
|
|
||||||
@ -2648,6 +2645,7 @@ def test_execute_sell_market_order(default_conf, ticker, fee,
|
|||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
markets=PropertyMock(return_value=markets)
|
||||||
)
|
)
|
||||||
|
patch_whitelist(mocker, default_conf)
|
||||||
freqtrade = FreqtradeBot(default_conf)
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
patch_get_signal(freqtrade)
|
patch_get_signal(freqtrade)
|
||||||
|
|
||||||
@ -2815,14 +2813,13 @@ def test_sell_profit_only_disable_loss(default_conf, limit_buy_order, fee, marke
|
|||||||
assert trade.sell_reason == SellType.SELL_SIGNAL.value
|
assert trade.sell_reason == SellType.SELL_SIGNAL.value
|
||||||
|
|
||||||
|
|
||||||
def test_locked_pairs(default_conf, ticker, fee, ticker_sell_down, markets, mocker, caplog) -> None:
|
def test_locked_pairs(default_conf, ticker, fee, ticker_sell_down, mocker, caplog) -> None:
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
|
||||||
)
|
)
|
||||||
freqtrade = FreqtradeBot(default_conf)
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
patch_get_signal(freqtrade)
|
patch_get_signal(freqtrade)
|
||||||
@ -2852,7 +2849,7 @@ def test_locked_pairs(default_conf, ticker, fee, ticker_sell_down, markets, mock
|
|||||||
assert log_has(f"Pair {trade.pair} is currently locked.", caplog)
|
assert log_has(f"Pair {trade.pair} is currently locked.", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_ignore_roi_if_buy_signal(default_conf, limit_buy_order, fee, markets, mocker) -> None:
|
def test_ignore_roi_if_buy_signal(default_conf, limit_buy_order, fee, mocker) -> None:
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
@ -2864,7 +2861,6 @@ def test_ignore_roi_if_buy_signal(default_conf, limit_buy_order, fee, markets, m
|
|||||||
}),
|
}),
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
|
||||||
)
|
)
|
||||||
default_conf['ask_strategy'] = {
|
default_conf['ask_strategy'] = {
|
||||||
'ignore_roi_if_buy_signal': True
|
'ignore_roi_if_buy_signal': True
|
||||||
@ -2886,7 +2882,7 @@ def test_ignore_roi_if_buy_signal(default_conf, limit_buy_order, fee, markets, m
|
|||||||
assert trade.sell_reason == SellType.ROI.value
|
assert trade.sell_reason == SellType.ROI.value
|
||||||
|
|
||||||
|
|
||||||
def test_trailing_stop_loss(default_conf, limit_buy_order, fee, markets, caplog, mocker) -> None:
|
def test_trailing_stop_loss(default_conf, limit_buy_order, fee, caplog, mocker) -> None:
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
@ -2898,9 +2894,9 @@ def test_trailing_stop_loss(default_conf, limit_buy_order, fee, markets, caplog,
|
|||||||
}),
|
}),
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets),
|
|
||||||
)
|
)
|
||||||
default_conf['trailing_stop'] = True
|
default_conf['trailing_stop'] = True
|
||||||
|
patch_whitelist(mocker, default_conf)
|
||||||
freqtrade = FreqtradeBot(default_conf)
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
patch_get_signal(freqtrade)
|
patch_get_signal(freqtrade)
|
||||||
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
|
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
|
||||||
@ -2938,7 +2934,7 @@ def test_trailing_stop_loss(default_conf, limit_buy_order, fee, markets, caplog,
|
|||||||
assert trade.sell_reason == SellType.TRAILING_STOP_LOSS.value
|
assert trade.sell_reason == SellType.TRAILING_STOP_LOSS.value
|
||||||
|
|
||||||
|
|
||||||
def test_trailing_stop_loss_positive(default_conf, limit_buy_order, fee, markets,
|
def test_trailing_stop_loss_positive(default_conf, limit_buy_order, fee,
|
||||||
caplog, mocker) -> None:
|
caplog, mocker) -> None:
|
||||||
buy_price = limit_buy_order['price']
|
buy_price = limit_buy_order['price']
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
@ -2952,10 +2948,11 @@ def test_trailing_stop_loss_positive(default_conf, limit_buy_order, fee, markets
|
|||||||
}),
|
}),
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets),
|
|
||||||
)
|
)
|
||||||
default_conf['trailing_stop'] = True
|
default_conf['trailing_stop'] = True
|
||||||
default_conf['trailing_stop_positive'] = 0.01
|
default_conf['trailing_stop_positive'] = 0.01
|
||||||
|
patch_whitelist(mocker, default_conf)
|
||||||
|
|
||||||
freqtrade = FreqtradeBot(default_conf)
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
patch_get_signal(freqtrade)
|
patch_get_signal(freqtrade)
|
||||||
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
|
freqtrade.strategy.min_roi_reached = MagicMock(return_value=False)
|
||||||
@ -2995,7 +2992,7 @@ def test_trailing_stop_loss_positive(default_conf, limit_buy_order, fee, markets
|
|||||||
|
|
||||||
|
|
||||||
def test_trailing_stop_loss_offset(default_conf, limit_buy_order, fee,
|
def test_trailing_stop_loss_offset(default_conf, limit_buy_order, fee,
|
||||||
caplog, mocker, markets) -> None:
|
caplog, mocker) -> None:
|
||||||
buy_price = limit_buy_order['price']
|
buy_price = limit_buy_order['price']
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
@ -3008,9 +3005,8 @@ def test_trailing_stop_loss_offset(default_conf, limit_buy_order, fee,
|
|||||||
}),
|
}),
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets),
|
|
||||||
)
|
)
|
||||||
|
patch_whitelist(mocker, default_conf)
|
||||||
default_conf['trailing_stop'] = True
|
default_conf['trailing_stop'] = True
|
||||||
default_conf['trailing_stop_positive'] = 0.01
|
default_conf['trailing_stop_positive'] = 0.01
|
||||||
default_conf['trailing_stop_positive_offset'] = 0.011
|
default_conf['trailing_stop_positive_offset'] = 0.011
|
||||||
@ -3055,7 +3051,7 @@ def test_trailing_stop_loss_offset(default_conf, limit_buy_order, fee,
|
|||||||
|
|
||||||
|
|
||||||
def test_tsl_only_offset_reached(default_conf, limit_buy_order, fee,
|
def test_tsl_only_offset_reached(default_conf, limit_buy_order, fee,
|
||||||
caplog, mocker, markets) -> None:
|
caplog, mocker) -> None:
|
||||||
buy_price = limit_buy_order['price']
|
buy_price = limit_buy_order['price']
|
||||||
# buy_price: 0.00001099
|
# buy_price: 0.00001099
|
||||||
|
|
||||||
@ -3070,9 +3066,8 @@ def test_tsl_only_offset_reached(default_conf, limit_buy_order, fee,
|
|||||||
}),
|
}),
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets),
|
|
||||||
)
|
)
|
||||||
|
patch_whitelist(mocker, default_conf)
|
||||||
default_conf['trailing_stop'] = True
|
default_conf['trailing_stop'] = True
|
||||||
default_conf['trailing_stop_positive'] = 0.05
|
default_conf['trailing_stop_positive'] = 0.05
|
||||||
default_conf['trailing_stop_positive_offset'] = 0.055
|
default_conf['trailing_stop_positive_offset'] = 0.055
|
||||||
|
@ -188,8 +188,8 @@ def test_list_markets(mocker, markets, capsys):
|
|||||||
]
|
]
|
||||||
start_list_markets(get_args(args), False)
|
start_list_markets(get_args(args), False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ("Exchange Bittrex has 8 active markets: "
|
assert ("Exchange Bittrex has 9 active markets: "
|
||||||
"BLK/BTC, BTT/BTC, ETH/BTC, ETH/USDT, LTC/USD, LTC/USDT, TKN/BTC, XLTCUSDT.\n"
|
"BLK/BTC, ETH/BTC, ETH/USDT, LTC/BTC, LTC/USD, NEO/BTC, TKN/BTC, XLTCUSDT, XRP/BTC.\n"
|
||||||
in captured.out)
|
in captured.out)
|
||||||
|
|
||||||
patch_exchange(mocker, api_mock=api_mock, id="binance")
|
patch_exchange(mocker, api_mock=api_mock, id="binance")
|
||||||
@ -202,7 +202,7 @@ def test_list_markets(mocker, markets, capsys):
|
|||||||
pargs['config'] = None
|
pargs['config'] = None
|
||||||
start_list_markets(pargs, False)
|
start_list_markets(pargs, False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert re.match("\nExchange Binance has 8 active markets:\n",
|
assert re.match("\nExchange Binance has 9 active markets:\n",
|
||||||
captured.out)
|
captured.out)
|
||||||
|
|
||||||
patch_exchange(mocker, api_mock=api_mock, id="bittrex")
|
patch_exchange(mocker, api_mock=api_mock, id="bittrex")
|
||||||
@ -227,8 +227,8 @@ def test_list_markets(mocker, markets, capsys):
|
|||||||
]
|
]
|
||||||
start_list_markets(get_args(args), True)
|
start_list_markets(get_args(args), True)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ("Exchange Bittrex has 7 active pairs: "
|
assert ("Exchange Bittrex has 8 active pairs: "
|
||||||
"BLK/BTC, BTT/BTC, ETH/BTC, ETH/USDT, LTC/USD, LTC/USDT, TKN/BTC.\n"
|
"BLK/BTC, ETH/BTC, ETH/USDT, LTC/BTC, LTC/USD, NEO/BTC, TKN/BTC, XRP/BTC.\n"
|
||||||
in captured.out)
|
in captured.out)
|
||||||
|
|
||||||
# Test list-pairs subcommand with --all: all pairs
|
# Test list-pairs subcommand with --all: all pairs
|
||||||
@ -254,7 +254,7 @@ def test_list_markets(mocker, markets, capsys):
|
|||||||
start_list_markets(get_args(args), False)
|
start_list_markets(get_args(args), False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ("Exchange Bittrex has 5 active markets with ETH, LTC as base currencies: "
|
assert ("Exchange Bittrex has 5 active markets with ETH, LTC as base currencies: "
|
||||||
"ETH/BTC, ETH/USDT, LTC/USD, LTC/USDT, XLTCUSDT.\n"
|
"ETH/BTC, ETH/USDT, LTC/BTC, LTC/USD, XLTCUSDT.\n"
|
||||||
in captured.out)
|
in captured.out)
|
||||||
|
|
||||||
# active markets, base=LTC
|
# active markets, base=LTC
|
||||||
@ -267,7 +267,7 @@ def test_list_markets(mocker, markets, capsys):
|
|||||||
start_list_markets(get_args(args), False)
|
start_list_markets(get_args(args), False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ("Exchange Bittrex has 3 active markets with LTC as base currency: "
|
assert ("Exchange Bittrex has 3 active markets with LTC as base currency: "
|
||||||
"LTC/USD, LTC/USDT, XLTCUSDT.\n"
|
"LTC/BTC, LTC/USD, XLTCUSDT.\n"
|
||||||
in captured.out)
|
in captured.out)
|
||||||
|
|
||||||
# active markets, quote=USDT, USD
|
# active markets, quote=USDT, USD
|
||||||
@ -279,8 +279,8 @@ def test_list_markets(mocker, markets, capsys):
|
|||||||
]
|
]
|
||||||
start_list_markets(get_args(args), False)
|
start_list_markets(get_args(args), False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ("Exchange Bittrex has 4 active markets with USDT, USD as quote currencies: "
|
assert ("Exchange Bittrex has 3 active markets with USDT, USD as quote currencies: "
|
||||||
"ETH/USDT, LTC/USD, LTC/USDT, XLTCUSDT.\n"
|
"ETH/USDT, LTC/USD, XLTCUSDT.\n"
|
||||||
in captured.out)
|
in captured.out)
|
||||||
|
|
||||||
# active markets, quote=USDT
|
# active markets, quote=USDT
|
||||||
@ -292,8 +292,8 @@ def test_list_markets(mocker, markets, capsys):
|
|||||||
]
|
]
|
||||||
start_list_markets(get_args(args), False)
|
start_list_markets(get_args(args), False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ("Exchange Bittrex has 3 active markets with USDT as quote currency: "
|
assert ("Exchange Bittrex has 2 active markets with USDT as quote currency: "
|
||||||
"ETH/USDT, LTC/USDT, XLTCUSDT.\n"
|
"ETH/USDT, XLTCUSDT.\n"
|
||||||
in captured.out)
|
in captured.out)
|
||||||
|
|
||||||
# active markets, base=LTC, quote=USDT
|
# active markets, base=LTC, quote=USDT
|
||||||
@ -305,21 +305,21 @@ def test_list_markets(mocker, markets, capsys):
|
|||||||
]
|
]
|
||||||
start_list_markets(get_args(args), False)
|
start_list_markets(get_args(args), False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ("Exchange Bittrex has 2 active markets with LTC as base currency and "
|
assert ("Exchange Bittrex has 1 active market with LTC as base currency and "
|
||||||
"with USDT as quote currency: LTC/USDT, XLTCUSDT.\n"
|
"with USDT as quote currency: XLTCUSDT.\n"
|
||||||
in captured.out)
|
in captured.out)
|
||||||
|
|
||||||
# active pairs, base=LTC, quote=USDT
|
# active pairs, base=LTC, quote=USDT
|
||||||
args = [
|
args = [
|
||||||
'--config', 'config.json.example',
|
'--config', 'config.json.example',
|
||||||
"list-pairs",
|
"list-pairs",
|
||||||
"--base", "LTC", "--quote", "USDT",
|
"--base", "LTC", "--quote", "USD",
|
||||||
"--print-list",
|
"--print-list",
|
||||||
]
|
]
|
||||||
start_list_markets(get_args(args), True)
|
start_list_markets(get_args(args), True)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ("Exchange Bittrex has 1 active pair with LTC as base currency and "
|
assert ("Exchange Bittrex has 1 active pair with LTC as base currency and "
|
||||||
"with USDT as quote currency: LTC/USDT.\n"
|
"with USD as quote currency: LTC/USD.\n"
|
||||||
in captured.out)
|
in captured.out)
|
||||||
|
|
||||||
# active markets, base=LTC, quote=USDT, NONEXISTENT
|
# active markets, base=LTC, quote=USDT, NONEXISTENT
|
||||||
@ -331,8 +331,8 @@ def test_list_markets(mocker, markets, capsys):
|
|||||||
]
|
]
|
||||||
start_list_markets(get_args(args), False)
|
start_list_markets(get_args(args), False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ("Exchange Bittrex has 2 active markets with LTC as base currency and "
|
assert ("Exchange Bittrex has 1 active market with LTC as base currency and "
|
||||||
"with USDT, NONEXISTENT as quote currencies: LTC/USDT, XLTCUSDT.\n"
|
"with USDT, NONEXISTENT as quote currencies: XLTCUSDT.\n"
|
||||||
in captured.out)
|
in captured.out)
|
||||||
|
|
||||||
# active markets, base=LTC, quote=NONEXISTENT
|
# active markets, base=LTC, quote=NONEXISTENT
|
||||||
@ -355,7 +355,7 @@ def test_list_markets(mocker, markets, capsys):
|
|||||||
]
|
]
|
||||||
start_list_markets(get_args(args), False)
|
start_list_markets(get_args(args), False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ("Exchange Bittrex has 8 active markets:\n"
|
assert ("Exchange Bittrex has 9 active markets:\n"
|
||||||
in captured.out)
|
in captured.out)
|
||||||
|
|
||||||
# Test tabular output, no markets found
|
# Test tabular output, no markets found
|
||||||
@ -378,7 +378,8 @@ def test_list_markets(mocker, markets, capsys):
|
|||||||
]
|
]
|
||||||
start_list_markets(get_args(args), False)
|
start_list_markets(get_args(args), False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ('["BLK/BTC","BTT/BTC","ETH/BTC","ETH/USDT","LTC/USD","LTC/USDT","TKN/BTC","XLTCUSDT"]'
|
assert ('["BLK/BTC","ETH/BTC","ETH/USDT","LTC/BTC","LTC/USD","NEO/BTC",'
|
||||||
|
'"TKN/BTC","XLTCUSDT","XRP/BTC"]'
|
||||||
in captured.out)
|
in captured.out)
|
||||||
|
|
||||||
# Test --print-csv
|
# Test --print-csv
|
||||||
@ -391,7 +392,7 @@ def test_list_markets(mocker, markets, capsys):
|
|||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ("Id,Symbol,Base,Quote,Active,Is pair" in captured.out)
|
assert ("Id,Symbol,Base,Quote,Active,Is pair" in captured.out)
|
||||||
assert ("blkbtc,BLK/BTC,BLK,BTC,True,True" in captured.out)
|
assert ("blkbtc,BLK/BTC,BLK,BTC,True,True" in captured.out)
|
||||||
assert ("BTTBTC,BTT/BTC,BTT,BTC,True,True" in captured.out)
|
assert ("USD-LTC,LTC/USD,LTC,USD,True,True" in captured.out)
|
||||||
|
|
||||||
# Test --one-column
|
# Test --one-column
|
||||||
args = [
|
args = [
|
||||||
@ -402,7 +403,7 @@ def test_list_markets(mocker, markets, capsys):
|
|||||||
start_list_markets(get_args(args), False)
|
start_list_markets(get_args(args), False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert re.search(r"^BLK/BTC$", captured.out, re.MULTILINE)
|
assert re.search(r"^BLK/BTC$", captured.out, re.MULTILINE)
|
||||||
assert re.search(r"^BTT/BTC$", captured.out, re.MULTILINE)
|
assert re.search(r"^LTC/USD$", captured.out, re.MULTILINE)
|
||||||
|
|
||||||
|
|
||||||
def test_create_datadir_failed(caplog):
|
def test_create_datadir_failed(caplog):
|
||||||
|
Loading…
Reference in New Issue
Block a user