Merge pull request #4769 from freqtrade/trades_pagination

Trades pagination
This commit is contained in:
Matthias 2021-04-22 19:13:19 +02:00 committed by GitHub
commit 4693cba10d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 27 additions and 15 deletions

View File

@ -124,7 +124,7 @@ python3 scripts/rest_client.py --config rest_config.json <command> [optional par
| `stop` | Stops the trader. | `stop` | Stops the trader.
| `stopbuy` | Stops the trader from opening new trades. Gracefully closes open trades according to their rules. | `stopbuy` | Stops the trader from opening new trades. Gracefully closes open trades according to their rules.
| `reload_config` | Reloads the configuration file. | `reload_config` | Reloads the configuration file.
| `trades` | List last trades. | `trades` | List last trades. Limited to 500 trades per call.
| `trade/<tradeid>` | Get specific trade. | `trade/<tradeid>` | Get specific trade.
| `delete_trade <trade_id>` | Remove trade from the database. Tries to close open orders. Requires manual handling of this trade on the exchange. | `delete_trade <trade_id>` | Remove trade from the database. Tries to close open orders. Requires manual handling of this trade on the exchange.
| `show_config` | Shows part of the current configuration with relevant settings to operation. | `show_config` | Shows part of the current configuration with relevant settings to operation.
@ -280,16 +280,16 @@ trade
:param trade_id: Specify which trade to get. :param trade_id: Specify which trade to get.
trades trades
Return trades history. 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.
version version
Return the version of the bot. Return the version of the bot.
whitelist whitelist
Show the current whitelist. Show the current whitelist.
``` ```
### OpenAPI interface ### OpenAPI interface

View File

@ -199,6 +199,7 @@ class OpenTradeSchema(TradeSchema):
class TradeResponse(BaseModel): class TradeResponse(BaseModel):
trades: List[TradeSchema] trades: List[TradeSchema]
trades_count: int trades_count: int
total_trades: int
class ForceBuyResponse(BaseModel): class ForceBuyResponse(BaseModel):

View File

@ -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) # 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, # on big databases. Correct response model: response_model=TradeResponse,
@router.get('/trades', tags=['info', 'trading']) @router.get('/trades', tags=['info', 'trading'])
def trades(limit: int = 0, rpc: RPC = Depends(get_rpc)): def trades(limit: int = 500, offset: int = 0, rpc: RPC = Depends(get_rpc)):
return rpc._rpc_trade_history(limit) return rpc._rpc_trade_history(limit, offset=offset, order_by_id=True)
@router.get('/trade/{tradeid}', response_model=OpenTradeSchema, tags=['info', 'trading']) @router.get('/trade/{tradeid}', response_model=OpenTradeSchema, tags=['info', 'trading'])

View File

@ -300,11 +300,12 @@ class RPC:
'data': data '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 """ """ 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( trades = Trade.get_trades([Trade.is_open.is_(False)]).order_by(
Trade.close_date.desc()).limit(limit) order_by).limit(limit).offset(offset)
else: else:
trades = Trade.get_trades([Trade.is_open.is_(False)]).order_by( trades = Trade.get_trades([Trade.is_open.is_(False)]).order_by(
Trade.close_date.desc()).all() Trade.close_date.desc()).all()
@ -313,7 +314,8 @@ class RPC:
return { return {
"trades": output, "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]: def _rpc_stats(self) -> Dict[str, Any]:

View File

@ -200,13 +200,19 @@ class FtRestClient():
""" """
return self._get("logs", params={"limit": limit} if limit else 0) return self._get("logs", params={"limit": limit} if limit else 0)
def trades(self, limit=None): def trades(self, limit=None, offset=None):
"""Return trades history. """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: 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): def trade(self, trade_id):
"""Return specific trade """Return specific trade

View File

@ -506,8 +506,9 @@ def test_api_trades(botclient, mocker, fee, markets):
) )
rc = client_get(client, f"{BASE_URI}/trades") rc = client_get(client, f"{BASE_URI}/trades")
assert_response(rc) assert_response(rc)
assert len(rc.json()) == 2 assert len(rc.json()) == 3
assert rc.json()['trades_count'] == 0 assert rc.json()['trades_count'] == 0
assert rc.json()['total_trades'] == 0
create_mock_trades(fee) create_mock_trades(fee)
Trade.query.session.flush() Trade.query.session.flush()
@ -516,10 +517,12 @@ def test_api_trades(botclient, mocker, fee, markets):
assert_response(rc) assert_response(rc)
assert len(rc.json()['trades']) == 2 assert len(rc.json()['trades']) == 2
assert rc.json()['trades_count'] == 2 assert rc.json()['trades_count'] == 2
assert rc.json()['total_trades'] == 2
rc = client_get(client, f"{BASE_URI}/trades?limit=1") rc = client_get(client, f"{BASE_URI}/trades?limit=1")
assert_response(rc) assert_response(rc)
assert len(rc.json()['trades']) == 1 assert len(rc.json()['trades']) == 1
assert rc.json()['trades_count'] == 1 assert rc.json()['trades_count'] == 1
assert rc.json()['total_trades'] == 2
def test_api_trade_single(botclient, mocker, fee, ticker, markets): def test_api_trade_single(botclient, mocker, fee, ticker, markets):