From bd92ce938c6b92c2092cd119b597fc29d26ec2ab Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 18 Apr 2021 16:05:28 +0200 Subject: [PATCH] trade_history should paginate through results this avoids huge results --- freqtrade/rpc/api_server/api_schemas.py | 1 + freqtrade/rpc/api_server/api_v1.py | 4 ++-- freqtrade/rpc/rpc.py | 10 ++++++---- scripts/rest_client.py | 14 ++++++++++---- tests/rpc/test_rpc_apiserver.py | 2 +- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/freqtrade/rpc/api_server/api_schemas.py b/freqtrade/rpc/api_server/api_schemas.py index 12bee1cf2..e582f6aa8 100644 --- a/freqtrade/rpc/api_server/api_schemas.py +++ b/freqtrade/rpc/api_server/api_schemas.py @@ -199,6 +199,7 @@ class OpenTradeSchema(TradeSchema): class TradeResponse(BaseModel): trades: List[TradeSchema] trades_count: int + total_trades: int class ForceBuyResponse(BaseModel): diff --git a/freqtrade/rpc/api_server/api_v1.py b/freqtrade/rpc/api_server/api_v1.py index ebfafc290..cb3a5a710 100644 --- a/freqtrade/rpc/api_server/api_v1.py +++ b/freqtrade/rpc/api_server/api_v1.py @@ -85,8 +85,8 @@ def status(rpc: RPC = Depends(get_rpc)): # Using the responsemodel here will cause a ~100% increase in response time (from 1s to 2s) # on big databases. Correct response model: response_model=TradeResponse, @router.get('/trades', tags=['info', 'trading']) -def trades(limit: int = 0, rpc: RPC = Depends(get_rpc)): - return rpc._rpc_trade_history(limit) +def trades(limit: int = 500, offset: int = 0, rpc: RPC = Depends(get_rpc)): + return rpc._rpc_trade_history(min(limit, 500), offset=offset, order_by_id=True) @router.get('/trade/{tradeid}', response_model=OpenTradeSchema, tags=['info', 'trading']) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index e5c0dffba..a7a4dcf5c 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -300,11 +300,12 @@ class RPC: 'data': data } - def _rpc_trade_history(self, limit: int) -> Dict: + def _rpc_trade_history(self, limit: int, offset: int = 0, order_by_id: bool = False) -> Dict: """ Returns the X last trades """ - if limit > 0: + order_by = Trade.id if order_by_id else Trade.close_date.desc() + if limit: trades = Trade.get_trades([Trade.is_open.is_(False)]).order_by( - Trade.close_date.desc()).limit(limit) + order_by).limit(limit).offset(offset) else: trades = Trade.get_trades([Trade.is_open.is_(False)]).order_by( Trade.close_date.desc()).all() @@ -313,7 +314,8 @@ class RPC: return { "trades": output, - "trades_count": len(output) + "trades_count": len(output), + "total_trades": Trade.get_trades([Trade.is_open.is_(False)]).count(), } def _rpc_stats(self) -> Dict[str, Any]: diff --git a/scripts/rest_client.py b/scripts/rest_client.py index 40b338ce8..900b784f2 100755 --- a/scripts/rest_client.py +++ b/scripts/rest_client.py @@ -200,13 +200,19 @@ class FtRestClient(): """ return self._get("logs", params={"limit": limit} if limit else 0) - def trades(self, limit=None): - """Return trades history. + def trades(self, limit=None, offset=None): + """Return trades history, sorted by id - :param limit: Limits trades to the X last trades. No limit to get all the trades. + :param limit: Limits trades to the X last trades. Max 500 trades. + :param offset: Offset by this amount of trades. :return: json object """ - return self._get("trades", params={"limit": limit} if limit else 0) + params = {} + if limit: + params['limit'] = limit + if offset: + params['offset'] = offset + return self._get("trades", params) def trade(self, trade_id): """Return specific trade diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index 6505629eb..d87d4e59d 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -506,7 +506,7 @@ def test_api_trades(botclient, mocker, fee, markets): ) rc = client_get(client, f"{BASE_URI}/trades") assert_response(rc) - assert len(rc.json()) == 2 + assert len(rc.json()) == 3 assert rc.json()['trades_count'] == 0 create_mock_trades(fee)