Merge pull request #5670 from sergeykhliustin/develop
Added min_profit param to PerformanceFilter
This commit is contained in:
commit
794862a35a
@ -194,17 +194,22 @@ Trade count is used as a tie breaker.
|
|||||||
You can use the `minutes` parameter to only consider performance of the past X minutes (rolling window).
|
You can use the `minutes` parameter to only consider performance of the past X minutes (rolling window).
|
||||||
Not defining this parameter (or setting it to 0) will use all-time performance.
|
Not defining this parameter (or setting it to 0) will use all-time performance.
|
||||||
|
|
||||||
|
The optional `min_profit` parameter defines the minimum profit a pair must have to be considered.
|
||||||
|
Pairs below this level will be filtered out.
|
||||||
|
Using this parameter without `minutes` is highly discouraged, as it can lead to an empty pairlist without without a way to recover.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
"pairlists": [
|
"pairlists": [
|
||||||
// ...
|
// ...
|
||||||
{
|
{
|
||||||
"method": "PerformanceFilter",
|
"method": "PerformanceFilter",
|
||||||
"minutes": 1440 // rolling 24h
|
"minutes": 1440, // rolling 24h
|
||||||
|
"min_profit": 0.01
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! Note
|
!!! Warning "Backtesting"
|
||||||
`PerformanceFilter` does not support backtesting mode.
|
`PerformanceFilter` does not support backtesting mode.
|
||||||
|
|
||||||
#### PrecisionFilter
|
#### PrecisionFilter
|
||||||
|
@ -21,6 +21,7 @@ class PerformanceFilter(IPairList):
|
|||||||
super().__init__(exchange, pairlistmanager, config, pairlistconfig, pairlist_pos)
|
super().__init__(exchange, pairlistmanager, config, pairlistconfig, pairlist_pos)
|
||||||
|
|
||||||
self._minutes = pairlistconfig.get('minutes', 0)
|
self._minutes = pairlistconfig.get('minutes', 0)
|
||||||
|
self._min_profit = pairlistconfig.get('min_profit', None)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def needstickers(self) -> bool:
|
def needstickers(self) -> bool:
|
||||||
@ -68,6 +69,14 @@ class PerformanceFilter(IPairList):
|
|||||||
sorted_df = list_df.merge(performance, on='pair', how='left')\
|
sorted_df = list_df.merge(performance, on='pair', how='left')\
|
||||||
.fillna(0).sort_values(by=['count', 'pair'], ascending=True)\
|
.fillna(0).sort_values(by=['count', 'pair'], ascending=True)\
|
||||||
.sort_values(by=['profit'], ascending=False)
|
.sort_values(by=['profit'], ascending=False)
|
||||||
|
if self._min_profit is not None:
|
||||||
|
removed = sorted_df[sorted_df['profit'] < self._min_profit]
|
||||||
|
for _, row in removed.iterrows():
|
||||||
|
self.log_once(
|
||||||
|
f"Removing pair {row['pair']} since {row['profit']} is "
|
||||||
|
f"below {self._min_profit}", logger.info)
|
||||||
|
sorted_df = sorted_df[sorted_df['profit'] >= self._min_profit]
|
||||||
|
|
||||||
pairlist = sorted_df['pair'].tolist()
|
pairlist = sorted_df['pair'].tolist()
|
||||||
|
|
||||||
return pairlist
|
return pairlist
|
||||||
|
@ -665,11 +665,11 @@ def test_PerformanceFilter_error(mocker, whitelist_conf, caplog) -> None:
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("init_persistence")
|
@pytest.mark.usefixtures("init_persistence")
|
||||||
def test_PerformanceFilter_lookback(mocker, whitelist_conf, fee) -> None:
|
def test_PerformanceFilter_lookback(mocker, whitelist_conf, fee, caplog) -> None:
|
||||||
whitelist_conf['exchange']['pair_whitelist'].append('XRP/BTC')
|
whitelist_conf['exchange']['pair_whitelist'].append('XRP/BTC')
|
||||||
whitelist_conf['pairlists'] = [
|
whitelist_conf['pairlists'] = [
|
||||||
{"method": "StaticPairList"},
|
{"method": "StaticPairList"},
|
||||||
{"method": "PerformanceFilter", "minutes": 60}
|
{"method": "PerformanceFilter", "minutes": 60, "min_profit": 0.01}
|
||||||
]
|
]
|
||||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||||
exchange = get_patched_exchange(mocker, whitelist_conf)
|
exchange = get_patched_exchange(mocker, whitelist_conf)
|
||||||
@ -681,7 +681,8 @@ def test_PerformanceFilter_lookback(mocker, whitelist_conf, fee) -> None:
|
|||||||
with time_machine.travel("2021-09-01 05:00:00 +00:00") as t:
|
with time_machine.travel("2021-09-01 05:00:00 +00:00") as t:
|
||||||
create_mock_trades(fee)
|
create_mock_trades(fee)
|
||||||
pm.refresh_pairlist()
|
pm.refresh_pairlist()
|
||||||
assert pm.whitelist == ['XRP/BTC', 'ETH/BTC', 'TKN/BTC']
|
assert pm.whitelist == ['XRP/BTC']
|
||||||
|
assert log_has_re(r'Removing pair .* since .* is below .*', caplog)
|
||||||
|
|
||||||
# Move to "outside" of lookback window, so original sorting is restored.
|
# Move to "outside" of lookback window, so original sorting is restored.
|
||||||
t.move_to("2021-09-01 07:00:00 +00:00")
|
t.move_to("2021-09-01 07:00:00 +00:00")
|
||||||
|
Loading…
Reference in New Issue
Block a user