Allow edge to use dynamic pairlists

closes #4298
This commit is contained in:
Matthias 2021-03-30 20:20:24 +02:00
parent 89cfcc8ba6
commit 2869d5368d
7 changed files with 11 additions and 33 deletions

View File

@ -3,7 +3,7 @@
The `Edge Positioning` module uses probability to calculate your win rate and risk reward ratio. It will use these statistics to control your strategy trade entry points, position size and, stoploss.
!!! Warning
`Edge positioning` is not compatible with dynamic (volume-based) whitelist.
WHen using `Edge positioning` with a dynamic whitelist (VolumePairList), make sure to also use `AgeFilter` and set it to at least `calculate_since_number_of_days` to avoid problems with missing data.
!!! Note
`Edge Positioning` only considers *its own* buy/sell/stoploss signals. It ignores the stoploss, trailing stoploss, and ROI settings in the strategy configuration file.

View File

@ -149,11 +149,6 @@ def _validate_edge(conf: Dict[str, Any]) -> None:
if not conf.get('edge', {}).get('enabled'):
return
if conf.get('pairlist', {}).get('method') == 'VolumePairList':
raise OperationalException(
"Edge and VolumePairList are incompatible, "
"Edge will override whatever pairs VolumePairlist selects."
)
if not conf.get('ask_strategy', {}).get('use_sell_signal', True):
raise OperationalException(
"Edge requires `use_sell_signal` to be True, otherwise no sells will happen."

View File

@ -84,9 +84,8 @@ class Edge:
self.fee = self.exchange.get_fee(symbol=expand_pairlist(
self.config['exchange']['pair_whitelist'], list(self.exchange.markets))[0])
def calculate(self) -> bool:
pairs = expand_pairlist(self.config['exchange']['pair_whitelist'],
list(self.exchange.markets))
def calculate(self, pairs: List[str]) -> bool:
heartbeat = self.edge_config.get('process_throttle_secs')
if (self._last_updated > 0) and (

View File

@ -225,7 +225,7 @@ class FreqtradeBot(LoggingMixin):
# Calculating Edge positioning
if self.edge:
self.edge.calculate()
self.edge.calculate(_whitelist)
_whitelist = self.edge.adjust(_whitelist)
if trades:

View File

@ -44,7 +44,7 @@ class EdgeCli:
'timerange') is None else str(self.config.get('timerange')))
def start(self) -> None:
result = self.edge.calculate()
result = self.edge.calculate(self.config['exchange']['pair_whitelist'])
if result:
print('') # blank line for readability
print(generate_edge_table(self.edge._cached_pairs))

View File

@ -266,7 +266,7 @@ def test_edge_heartbeat_calculate(mocker, edge_conf):
# should not recalculate if heartbeat not reached
edge._last_updated = arrow.utcnow().int_timestamp - heartbeat + 1
assert edge.calculate() is False
assert edge.calculate(edge_conf['exchange']['pair_whitelist']) is False
def mocked_load_data(datadir, pairs=[], timeframe='0m',
@ -310,7 +310,7 @@ def test_edge_process_downloaded_data(mocker, edge_conf):
mocker.patch('freqtrade.edge.edge_positioning.load_data', mocked_load_data)
edge = Edge(edge_conf, freqtrade.exchange, freqtrade.strategy)
assert edge.calculate()
assert edge.calculate(edge_conf['exchange']['pair_whitelist'])
assert len(edge._cached_pairs) == 2
assert edge._last_updated <= arrow.utcnow().int_timestamp + 2
@ -322,7 +322,7 @@ def test_edge_process_no_data(mocker, edge_conf, caplog):
mocker.patch('freqtrade.edge.edge_positioning.load_data', MagicMock(return_value={}))
edge = Edge(edge_conf, freqtrade.exchange, freqtrade.strategy)
assert not edge.calculate()
assert not edge.calculate(edge_conf['exchange']['pair_whitelist'])
assert len(edge._cached_pairs) == 0
assert log_has("No data found. Edge is stopped ...", caplog)
assert edge._last_updated == 0
@ -337,7 +337,7 @@ def test_edge_process_no_trades(mocker, edge_conf, caplog):
mocker.patch('freqtrade.edge.Edge._find_trades_for_stoploss_range', MagicMock(return_value=[]))
edge = Edge(edge_conf, freqtrade.exchange, freqtrade.strategy)
assert not edge.calculate()
assert not edge.calculate(edge_conf['exchange']['pair_whitelist'])
assert len(edge._cached_pairs) == 0
assert log_has("No trades found.", caplog)

View File

@ -860,22 +860,6 @@ def test_validate_tsl(default_conf):
validate_config_consistency(default_conf)
def test_validate_edge(edge_conf):
edge_conf.update({"pairlist": {
"method": "VolumePairList",
}})
with pytest.raises(OperationalException,
match="Edge and VolumePairList are incompatible, "
"Edge will override whatever pairs VolumePairlist selects."):
validate_config_consistency(edge_conf)
edge_conf.update({"pairlist": {
"method": "StaticPairList",
}})
validate_config_consistency(edge_conf)
def test_validate_edge2(edge_conf):
edge_conf.update({"ask_strategy": {
"use_sell_signal": True,