Repository: freqtrade/freqtrade
Pull request: Added days parameter to PerformanceFilter
## Summary

Sometimes I want to use PerformanceFilter only according to performance of last N days

## Quick changelog

- added 'minutes' param to PerformanceFilter config
- if minutes > 0 getting performance only of last N days


closes #5060.

Problem statement:
PerformanceFilter - last x mins  
Hi for the first time and thank you for this magnificent piece of software :) 

I just discovered PerformanceFilter for the pairlists. I am excited about it and I would like to share some thoughts about possible improvements to this. 

Idea is to give possibility of taking into account performance from last x mins, hours, days. It can happen that one of the pairs had bad streak in first hour losing f.e. -3% and other pairs winning 0.1%. Having 30 pairs and trading 10 best of them it would mean that for this pair it's impossible to move to top 10 before all other pairs will prove to be worse. It can actually never happen and this pair could be the best in 2nd hour.

Hints from issue discussion:
i guess it could be added ... 

You'll need to be careful with your scenario though - assuming from the 30 pairs, 11 or 12 are "mostly" winners - you'll exclude most of the latter pairs "in principle" - just because they never got a chance to prove themselfs - so using this sorting method to reduce the number of pairs can be dangerous too.

I understand your concern. I was also thinking about it. My strategy is doing a lot of short trades on 1m timeframe and it is vulnerable to the local trends or price moving sideways. If all of my pairs are winning - I am happy enough :) 

Basically I think in case when this setting is not in place is even more risky that those pairs will never have chance to prove value. 

In my case I see it like this:
1. I would be using the sorting based on last 1hr performance.
2. If all the pairs have buy signal at the same time - best 10 will have priority. 
3. If not all from top 10 receive buy signal - pairs from the bottom have chance to prove themselves.
4. Pairs that didn't have chance to prove themselves in last period will have a chance over those losing in last period.

In my head it makes sense but maybe I am missing something :)

Commit message: Updates after review to PerformanceFilter days param

Patch to review:
diff --git a/freqtrade/persistence/models.py b/freqtrade/persistence/models.py
index 8c8c1e0a905..222be716934 100644
--- a/freqtrade/persistence/models.py
+++ b/freqtrade/persistence/models.py
@@ -2,7 +2,7 @@
 This module contains the class to persist trades into SQLite
 """
 import logging
-from datetime import datetime, timezone
+from datetime import datetime, timezone, timedelta
 from decimal import Decimal
 from typing import Any, Dict, List, Optional
 
@@ -832,17 +832,21 @@ def total_open_trades_stakes() -> float:
         return total_open_stake_amount or 0
 
     @staticmethod
-    def get_overall_performance() -> List[Dict[str, Any]]:
+    def get_overall_performance(days=None) -> List[Dict[str, Any]]:
         """
         Returns List of dicts containing all Trades, including profit and trade count
         NOTE: Not supported in Backtesting.
         """
+        filters = [Trade.is_open.is_(False)]
+        if days:
+            start_date = datetime.today() - timedelta(days)
+            filters.append((Trade.close_date >= start_date))
         pair_rates = Trade.query.with_entities(
             Trade.pair,
             func.sum(Trade.close_profit).label('profit_sum'),
             func.sum(Trade.close_profit_abs).label('profit_sum_abs'),
             func.count(Trade.pair).label('count')
-        ).filter(Trade.is_open.is_(False))\
+        ).filter(filters)\
             .group_by(Trade.pair) \
             .order_by(desc('profit_sum_abs')) \
             .all()
diff --git a/freqtrade/plugins/pairlist/PerformanceFilter.py b/freqtrade/plugins/pairlist/PerformanceFilter.py
index 46a289ae676..920b884a08c 100644
--- a/freqtrade/plugins/pairlist/PerformanceFilter.py
+++ b/freqtrade/plugins/pairlist/PerformanceFilter.py
@@ -2,11 +2,12 @@
 Performance pair list filter
 """
 import logging
-from typing import Dict, List
+from typing import Dict, List, Any
 
 import pandas as pd
 
 from freqtrade.persistence import Trade
+from freqtrade.exceptions import OperationalException
 from freqtrade.plugins.pairlist.IPairList import IPairList
 
 
@@ -15,6 +16,13 @@
 
 class PerformanceFilter(IPairList):
 
+    def __init__(self, exchange, pairlistmanager,
+                 config: Dict[str, Any], pairlistconfig: Dict[str, Any],
+                 pairlist_pos: int) -> None:
+        super().__init__(exchange, pairlistmanager, config, pairlistconfig, pairlist_pos)
+
+        self._days = pairlistconfig.get('days', 0)
+
     @property
     def needstickers(self) -> bool:
         """
@@ -40,7 +48,7 @@ def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]:
         """
         # Get the trading performance for pairs from database
         try:
-            performance = pd.DataFrame(Trade.get_overall_performance())
+            performance = pd.DataFrame(Trade.get_overall_performance(self._days))
         except AttributeError:
             # Performancefilter does not work in backtesting.
             self.log_once("PerformanceFilter is not available in this mode.", logger.warning)


Code review comments:
diff_hunk: @@ -832,17 +832,21 @@ def total_open_trades_stakes() -> float:
         return total_open_stake_amount or 0
 
     @staticmethod
-    def get_overall_performance() -> List[Dict[str, Any]]:
+    def get_overall_performance(days=None) -> List[Dict[str, Any]]:
         """
         Returns List of dicts containing all Trades, including profit and trade count
         NOTE: Not supported in Backtesting.
         """
+        filters = [Trade.is_open.is_(False)]
+        if days:
+            start_date = datetime.today() - timedelta(days)
+            filters.append((Trade.close_date >= start_date))
         pair_rates = Trade.query.with_entities(
             Trade.pair,
             func.sum(Trade.close_profit).label('profit_sum'),
             func.sum(Trade.close_profit_abs).label('profit_sum_abs'),
             func.count(Trade.pair).label('count')
-        ).filter(Trade.is_open.is_(False))\
+        ).filter(filters)\
path: freqtrade/persistence/models.py
text: @user1:
```suggestion
        ).filter(*filters)\
```