From 49b119f1dce3fa33eda2612a76a6435663fddd52 Mon Sep 17 00:00:00 2001 From: David Arena Date: Fri, 11 Apr 2025 23:53:27 +0200 Subject: [PATCH 1/4] Feat: option for order_by_id --- freqtrade/rpc/api_server/api_v1.py | 3 ++- ft_client/freqtrade_client/ft_rest_client.py | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/freqtrade/rpc/api_server/api_v1.py b/freqtrade/rpc/api_server/api_v1.py index 0081871f0..6d7dc8bb5 100644 --- a/freqtrade/rpc/api_server/api_v1.py +++ b/freqtrade/rpc/api_server/api_v1.py @@ -200,9 +200,10 @@ def status(rpc: RPC = Depends(get_rpc)): def trades( limit: int = Query(500, ge=1, description="Maximum number of different trades to return data"), offset: int = Query(0, ge=0, description="Number of trades to skip for pagination"), + order_by_id: bool = Query(True, description="Sort trades by id (default: True). If False, sorts by latest timestamp"), rpc: RPC = Depends(get_rpc), ): - return rpc._rpc_trade_history(limit, offset=offset, order_by_id=True) + return rpc._rpc_trade_history(limit, offset=offset, order_by_id=order_by_id) @router.get("/trade/{tradeid}", response_model=OpenTradeSchema, tags=["info", "trading"]) diff --git a/ft_client/freqtrade_client/ft_rest_client.py b/ft_client/freqtrade_client/ft_rest_client.py index 5e15bc185..c3be342f5 100755 --- a/ft_client/freqtrade_client/ft_rest_client.py +++ b/ft_client/freqtrade_client/ft_rest_client.py @@ -255,11 +255,12 @@ class FtRestClient: """ return self._get("logs", params={"limit": limit} if limit else {}) - def trades(self, limit=None, offset=None): - """Return trades history, sorted by id + def trades(self, limit=None, offset=None, order_by_id=True): + """Return trades history, sorted by id (or by latest timestamp if order_by_id=False) :param limit: Limits trades to the X last trades. Max 500 trades. :param offset: Offset by this amount of trades. + :param order_by_id: Sort trades by id (default: True). If False, sorts by latest timestamp. :return: json object """ params = {} @@ -267,6 +268,8 @@ class FtRestClient: params["limit"] = limit if offset: params["offset"] = offset + if order_by_id: + params["order_by_id"] = True return self._get("trades", params) def list_open_trades_custom_data(self, key=None, limit=100, offset=0): From 751d98495f317b798ac61e11b94ab528dbecede0 Mon Sep 17 00:00:00 2001 From: David Arena Date: Sat, 12 Apr 2025 00:02:31 +0200 Subject: [PATCH 2/4] fix: tests/formatting --- freqtrade/rpc/api_server/api_v1.py | 4 +++- ft_client/test_client/test_rest_client.py | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/freqtrade/rpc/api_server/api_v1.py b/freqtrade/rpc/api_server/api_v1.py index 6d7dc8bb5..348ffd7a3 100644 --- a/freqtrade/rpc/api_server/api_v1.py +++ b/freqtrade/rpc/api_server/api_v1.py @@ -200,7 +200,9 @@ def status(rpc: RPC = Depends(get_rpc)): def trades( limit: int = Query(500, ge=1, description="Maximum number of different trades to return data"), offset: int = Query(0, ge=0, description="Number of trades to skip for pagination"), - order_by_id: bool = Query(True, description="Sort trades by id (default: True). If False, sorts by latest timestamp"), + order_by_id: bool = Query( + True, description="Sort trades by id (default: True). If False, sorts by latest timestamp" + ), rpc: RPC = Depends(get_rpc), ): return rpc._rpc_trade_history(limit, offset=offset, order_by_id=order_by_id) diff --git a/ft_client/test_client/test_rest_client.py b/ft_client/test_client/test_rest_client.py index c1af6ded2..9d5e484aa 100644 --- a/ft_client/test_client/test_rest_client.py +++ b/ft_client/test_client/test_rest_client.py @@ -85,6 +85,8 @@ def test_FtRestClient_call_invalid(caplog): ("trades", [], {}), ("trades", [5], {}), ("trades", [5, 5], {}), # With offset + ("trades", [5, 5, True], {}), # Explicit order_by_id=True + ("trades", [5, 5, False], {}), # order_by_id=False ("trade", [1], {}), ("delete_trade", [1], {}), ("cancel_open_order", [1], {}), @@ -127,6 +129,10 @@ def test_FtRestClient_call_invalid(caplog): ("pair_candles", ["XRP/USDT", "5m", 500], {"columns": ["close_time,close"]}), ("pair_history", ["XRP/USDT", "5m", "SampleStrategy"], {}), ("pair_history", ["XRP/USDT", "5m"], {"strategy": "SampleStrategy"}), + ("trades", [], {"order_by_id": True}), + ("trades", [], {"order_by_id": False}), + ("trades", [5], {"order_by_id": False}), + ("trades", [5, 5], {"order_by_id": True}), ("sysinfo", [], {}), ("health", [], {}), ], From 194d53acf83f30f89e85ee6a52562457871cfbc7 Mon Sep 17 00:00:00 2001 From: David Arena Date: Sat, 12 Apr 2025 16:57:30 +0200 Subject: [PATCH 3/4] fix: adding checks for trades and order_by_id --- tests/rpc/test_rpc_apiserver.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index 6261f1ae1..901a08c67 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -782,6 +782,18 @@ def test_api_trades(botclient, mocker, fee, markets, is_short): assert rc.json()["trades_count"] == 1 assert rc.json()["total_trades"] == 2 + # Test ascending order (default) + rc = client_get(client, f"{BASE_URI}/trades?order_by_id=true") + assert_response(rc) + assert rc.json()["trades"][0]["trade_id"] == 2 + assert rc.json()["trades"][1]["trade_id"] == 3 + + # Test descending order + rc = client_get(client, f"{BASE_URI}/trades?order_by_id=false") + assert_response(rc) + assert rc.json()["trades"][0]["trade_id"] == 3 + assert rc.json()["trades"][1]["trade_id"] == 2 + @pytest.mark.parametrize("is_short", [True, False]) def test_api_trade_single(botclient, mocker, fee, ticker, markets, is_short): From a6d76cad392c316306affcb64436a35bca3714db Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 13 Apr 2025 10:24:34 +0200 Subject: [PATCH 4/4] test: improve api test to ensure the default is what we expect --- tests/rpc/test_rpc_apiserver.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index 901a08c67..89251233b 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -776,6 +776,10 @@ def test_api_trades(botclient, mocker, fee, markets, is_short): assert rc.json()["trades_count"] == 2 assert rc.json()["total_trades"] == 2 assert rc.json()["trades"][0]["is_short"] == is_short + # Ensure the trades are sorted by trade_id (the default, see below) + assert rc.json()["trades"][0]["trade_id"] == 2 + assert rc.json()["trades"][1]["trade_id"] == 3 + rc = client_get(client, f"{BASE_URI}/trades?limit=1") assert_response(rc) assert len(rc.json()["trades"]) == 1