Move performance-calculation to persistence
This commit is contained in:
		| @@ -8,17 +8,15 @@ from typing import Any, Dict, List, Optional | |||||||
|  |  | ||||||
| import arrow | import arrow | ||||||
| from sqlalchemy import (Boolean, Column, DateTime, Float, Integer, String, | from sqlalchemy import (Boolean, Column, DateTime, Float, Integer, String, | ||||||
|                         create_engine, inspect) |                         create_engine, desc, func, inspect) | ||||||
| from sqlalchemy.exc import NoSuchModuleError | from sqlalchemy.exc import NoSuchModuleError | ||||||
| from sqlalchemy.ext.declarative import declarative_base | from sqlalchemy.ext.declarative import declarative_base | ||||||
| from sqlalchemy.orm.scoping import scoped_session | from sqlalchemy.orm.scoping import scoped_session | ||||||
| from sqlalchemy.orm.session import sessionmaker | from sqlalchemy.orm.session import sessionmaker | ||||||
| from sqlalchemy import func |  | ||||||
| from sqlalchemy.pool import StaticPool | from sqlalchemy.pool import StaticPool | ||||||
|  |  | ||||||
| from freqtrade import OperationalException | from freqtrade import OperationalException | ||||||
|  |  | ||||||
|  |  | ||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -404,6 +402,25 @@ class Trade(_DECL_BASE): | |||||||
|             .scalar() |             .scalar() | ||||||
|         return total_open_stake_amount or 0 |         return total_open_stake_amount or 0 | ||||||
|  |  | ||||||
|  |     @staticmethod | ||||||
|  |     def get_overall_performance() -> Dict: | ||||||
|  |         pair_rates = Trade.session.query( | ||||||
|  |             Trade.pair, | ||||||
|  |             func.sum(Trade.close_profit).label('profit_sum'), | ||||||
|  |             func.count(Trade.pair).label('count') | ||||||
|  |         ).filter(Trade.is_open.is_(False))\ | ||||||
|  |             .group_by(Trade.pair) \ | ||||||
|  |             .order_by(desc('profit_sum')) \ | ||||||
|  |             .all() | ||||||
|  |         return [ | ||||||
|  |             { | ||||||
|  |                 'pair': pair, | ||||||
|  |                 'profit': round(rate * 100, 2), | ||||||
|  |                 'count': count | ||||||
|  |             } | ||||||
|  |             for pair, rate, count in pair_rates | ||||||
|  |         ] | ||||||
|  |  | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def get_open_trades() -> List[Any]: |     def get_open_trades() -> List[Any]: | ||||||
|         """ |         """ | ||||||
|   | |||||||
| @@ -442,18 +442,7 @@ class RPC: | |||||||
|         Handler for performance. |         Handler for performance. | ||||||
|         Shows a performance statistic from finished trades |         Shows a performance statistic from finished trades | ||||||
|         """ |         """ | ||||||
|  |         return Trade.get_overall_performance() | ||||||
|         pair_rates = Trade.session.query(Trade.pair, |  | ||||||
|                                          sql.func.sum(Trade.close_profit).label('profit_sum'), |  | ||||||
|                                          sql.func.count(Trade.pair).label('count')) \ |  | ||||||
|             .filter(Trade.is_open.is_(False)) \ |  | ||||||
|             .group_by(Trade.pair) \ |  | ||||||
|             .order_by(sql.text('profit_sum DESC')) \ |  | ||||||
|             .all() |  | ||||||
|         return [ |  | ||||||
|             {'pair': pair, 'profit': round(rate * 100, 2), 'count': count} |  | ||||||
|             for pair, rate, count in pair_rates |  | ||||||
|         ] |  | ||||||
|  |  | ||||||
|     def _rpc_count(self) -> Dict[str, float]: |     def _rpc_count(self) -> Dict[str, float]: | ||||||
|         """ Returns the number of trades running """ |         """ Returns the number of trades running """ | ||||||
|   | |||||||
| @@ -35,6 +35,8 @@ def create_mock_trades(fee): | |||||||
|         fee_open=fee.return_value, |         fee_open=fee.return_value, | ||||||
|         fee_close=fee.return_value, |         fee_close=fee.return_value, | ||||||
|         open_rate=0.123, |         open_rate=0.123, | ||||||
|  |         close_rate=0.128, | ||||||
|  |         close_profit=0.005, | ||||||
|         exchange='bittrex', |         exchange='bittrex', | ||||||
|         is_open=False, |         is_open=False, | ||||||
|         open_order_id='dry_run_sell_12345' |         open_order_id='dry_run_sell_12345' | ||||||
| @@ -835,3 +837,25 @@ def test_stoploss_reinitialization(default_conf, fee): | |||||||
|     assert trade_adj.stop_loss_pct == -0.04 |     assert trade_adj.stop_loss_pct == -0.04 | ||||||
|     assert trade_adj.initial_stop_loss == 0.96 |     assert trade_adj.initial_stop_loss == 0.96 | ||||||
|     assert trade_adj.initial_stop_loss_pct == -0.04 |     assert trade_adj.initial_stop_loss_pct == -0.04 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @pytest.mark.usefixtures("init_persistence") | ||||||
|  | def test_total_open_trades_stakes(fee): | ||||||
|  |  | ||||||
|  |     res = Trade.total_open_trades_stakes() | ||||||
|  |     assert res == 0 | ||||||
|  |     create_mock_trades(fee) | ||||||
|  |     res = Trade.total_open_trades_stakes() | ||||||
|  |     assert res == 0.002 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @pytest.mark.usefixtures("init_persistence") | ||||||
|  | def test_get_overall_performance(fee): | ||||||
|  |  | ||||||
|  |     create_mock_trades(fee) | ||||||
|  |     res = Trade.get_overall_performance() | ||||||
|  |  | ||||||
|  |     assert len(res) == 1 | ||||||
|  |     assert 'pair' in res[0] | ||||||
|  |     assert 'profit' in res[0] | ||||||
|  |     assert 'count' in res[0] | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user