Update statistics output
This commit is contained in:
parent
7619fd08d6
commit
390e600f55
@ -20,36 +20,60 @@ def direc(is_short: bool):
|
|||||||
|
|
||||||
def mock_order_usdt_1(is_short: bool):
|
def mock_order_usdt_1(is_short: bool):
|
||||||
return {
|
return {
|
||||||
'id': f'1234_{direc(is_short)}',
|
'id': f'prod_entry_1_{direc(is_short)}',
|
||||||
'symbol': 'ADA/USDT',
|
'symbol': 'LTC/USDT',
|
||||||
'status': 'closed',
|
'status': 'closed',
|
||||||
'side': entry_side(is_short),
|
'side': entry_side(is_short),
|
||||||
'type': 'limit',
|
'type': 'limit',
|
||||||
'price': 2.0,
|
'price': 10.0,
|
||||||
'amount': 10.0,
|
'amount': 2.0,
|
||||||
'filled': 10.0,
|
'filled': 2.0,
|
||||||
|
'remaining': 0.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def mock_order_usdt_1_exit(is_short: bool):
|
||||||
|
return {
|
||||||
|
'id': f'prod_exit_1_{direc(is_short)}',
|
||||||
|
'symbol': 'LTC/USDT',
|
||||||
|
'status': 'closed',
|
||||||
|
'side': exit_side(is_short),
|
||||||
|
'type': 'limit',
|
||||||
|
'price': 8.0,
|
||||||
|
'amount': 2.0,
|
||||||
|
'filled': 2.0,
|
||||||
'remaining': 0.0,
|
'remaining': 0.0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def mock_trade_usdt_1(fee, is_short: bool):
|
def mock_trade_usdt_1(fee, is_short: bool):
|
||||||
|
"""
|
||||||
|
Simulate prod entry with open sell order
|
||||||
|
"""
|
||||||
trade = Trade(
|
trade = Trade(
|
||||||
pair='ADA/USDT',
|
pair='LTC/USDT',
|
||||||
stake_amount=20.0,
|
stake_amount=20.0,
|
||||||
amount=10.0,
|
amount=2.0,
|
||||||
amount_requested=10.0,
|
amount_requested=2.0,
|
||||||
|
open_date=datetime.now(tz=timezone.utc) - timedelta(days=2, minutes=20),
|
||||||
|
close_date=datetime.now(tz=timezone.utc) - timedelta(days=2, minutes=5),
|
||||||
fee_open=fee.return_value,
|
fee_open=fee.return_value,
|
||||||
fee_close=fee.return_value,
|
fee_close=fee.return_value,
|
||||||
is_open=True,
|
is_open=False,
|
||||||
open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=17),
|
open_rate=10.0,
|
||||||
open_rate=2.0,
|
close_rate=8.0,
|
||||||
|
close_profit=-0.2,
|
||||||
|
close_profit_abs=-4.0,
|
||||||
exchange='binance',
|
exchange='binance',
|
||||||
open_order_id=f'1234_{direc(is_short)}',
|
strategy='SampleStrategy',
|
||||||
strategy='StrategyTestV2',
|
open_order_id=f'prod_exit_1_{direc(is_short)}',
|
||||||
timeframe=5,
|
timeframe=5,
|
||||||
is_short=is_short,
|
is_short=is_short,
|
||||||
)
|
)
|
||||||
o = Order.parse_from_ccxt_object(mock_order_usdt_1(is_short), 'ADA/USDT', entry_side(is_short))
|
o = Order.parse_from_ccxt_object(mock_order_usdt_1(is_short), 'LTC/USDT', entry_side(is_short))
|
||||||
|
trade.orders.append(o)
|
||||||
|
o = Order.parse_from_ccxt_object(mock_order_usdt_1_exit(is_short),
|
||||||
|
'LTC/USDT', exit_side(is_short))
|
||||||
trade.orders.append(o)
|
trade.orders.append(o)
|
||||||
return trade
|
return trade
|
||||||
|
|
||||||
@ -330,59 +354,35 @@ def mock_trade_usdt_6(fee, is_short: bool):
|
|||||||
|
|
||||||
def mock_order_usdt_7(is_short: bool):
|
def mock_order_usdt_7(is_short: bool):
|
||||||
return {
|
return {
|
||||||
'id': f'prod_entry_7_{direc(is_short)}',
|
'id': f'1234_{direc(is_short)}',
|
||||||
'symbol': 'LTC/USDT',
|
'symbol': 'ADA/USDT',
|
||||||
'status': 'closed',
|
'status': 'closed',
|
||||||
'side': entry_side(is_short),
|
'side': entry_side(is_short),
|
||||||
'type': 'limit',
|
'type': 'limit',
|
||||||
'price': 10.0,
|
'price': 2.0,
|
||||||
'amount': 2.0,
|
'amount': 10.0,
|
||||||
'filled': 2.0,
|
'filled': 10.0,
|
||||||
'remaining': 0.0,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def mock_order_usdt_7_exit(is_short: bool):
|
|
||||||
return {
|
|
||||||
'id': f'prod_exit_7_{direc(is_short)}',
|
|
||||||
'symbol': 'LTC/USDT',
|
|
||||||
'status': 'closed',
|
|
||||||
'side': exit_side(is_short),
|
|
||||||
'type': 'limit',
|
|
||||||
'price': 8.0,
|
|
||||||
'amount': 2.0,
|
|
||||||
'filled': 2.0,
|
|
||||||
'remaining': 0.0,
|
'remaining': 0.0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def mock_trade_usdt_7(fee, is_short: bool):
|
def mock_trade_usdt_7(fee, is_short: bool):
|
||||||
"""
|
|
||||||
Simulate prod entry with open sell order
|
|
||||||
"""
|
|
||||||
trade = Trade(
|
trade = Trade(
|
||||||
pair='LTC/USDT',
|
pair='ADA/USDT',
|
||||||
stake_amount=20.0,
|
stake_amount=20.0,
|
||||||
amount=2.0,
|
amount=10.0,
|
||||||
amount_requested=2.0,
|
amount_requested=10.0,
|
||||||
open_date=datetime.now(tz=timezone.utc) - timedelta(days=2, minutes=20),
|
|
||||||
close_date=datetime.now(tz=timezone.utc) - timedelta(days=2, minutes=5),
|
|
||||||
fee_open=fee.return_value,
|
fee_open=fee.return_value,
|
||||||
fee_close=fee.return_value,
|
fee_close=fee.return_value,
|
||||||
is_open=False,
|
is_open=True,
|
||||||
open_rate=10.0,
|
open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=17),
|
||||||
close_rate=8.0,
|
open_rate=2.0,
|
||||||
close_profit=-0.2,
|
|
||||||
close_profit_abs=-4.0,
|
|
||||||
exchange='binance',
|
exchange='binance',
|
||||||
strategy='SampleStrategy',
|
open_order_id=f'1234_{direc(is_short)}',
|
||||||
open_order_id=f'prod_exit_7_{direc(is_short)}',
|
strategy='StrategyTestV2',
|
||||||
timeframe=5,
|
timeframe=5,
|
||||||
is_short=is_short,
|
is_short=is_short,
|
||||||
)
|
)
|
||||||
o = Order.parse_from_ccxt_object(mock_order_usdt_7(is_short), 'LTC/USDT', entry_side(is_short))
|
o = Order.parse_from_ccxt_object(mock_order_usdt_7(is_short), 'ADA/USDT', entry_side(is_short))
|
||||||
trade.orders.append(o)
|
|
||||||
o = Order.parse_from_ccxt_object(mock_order_usdt_7_exit(is_short),
|
|
||||||
'LTC/USDT', exit_side(is_short))
|
|
||||||
trade.orders.append(o)
|
trade.orders.append(o)
|
||||||
return trade
|
return trade
|
||||||
|
@ -407,13 +407,9 @@ def test_rpc_delete_trade(mocker, default_conf, fee, markets, caplog, is_short):
|
|||||||
assert stoploss_mock.call_count == 0
|
assert stoploss_mock.call_count == 0
|
||||||
|
|
||||||
|
|
||||||
def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee,
|
def test_rpc_trade_statistics11(default_conf_usdt, ticker, fee,
|
||||||
limit_buy_order, limit_sell_order, mocker) -> None:
|
mocker) -> None:
|
||||||
mocker.patch.multiple(
|
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=1.1)
|
||||||
'freqtrade.rpc.fiat_convert.CoinGeckoAPI',
|
|
||||||
get_price=MagicMock(return_value={'bitcoin': {'usd': 15000.0}}),
|
|
||||||
)
|
|
||||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
@ -421,10 +417,9 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee,
|
|||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf_usdt)
|
||||||
patch_get_signal(freqtradebot)
|
stake_currency = default_conf_usdt['stake_currency']
|
||||||
stake_currency = default_conf['stake_currency']
|
fiat_display_currency = default_conf_usdt['fiat_display_currency']
|
||||||
fiat_display_currency = default_conf['fiat_display_currency']
|
|
||||||
|
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
rpc._fiat_converter = CryptoToFiatConverter()
|
rpc._fiat_converter = CryptoToFiatConverter()
|
||||||
@ -437,62 +432,32 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee,
|
|||||||
assert res['latest_trade_timestamp'] == 0
|
assert res['latest_trade_timestamp'] == 0
|
||||||
|
|
||||||
# Create some test data
|
# Create some test data
|
||||||
freqtradebot.enter_positions()
|
create_mock_trades_usdt(fee)
|
||||||
trade = Trade.query.first()
|
|
||||||
# Simulate fulfilled LIMIT_BUY order for trade
|
|
||||||
oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'sell')
|
|
||||||
trade.update_trade(oobj)
|
|
||||||
|
|
||||||
# Update the ticker with a market going up
|
|
||||||
mocker.patch.multiple(
|
|
||||||
'freqtrade.exchange.Exchange',
|
|
||||||
fetch_ticker=ticker_sell_up
|
|
||||||
)
|
|
||||||
oobj = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell')
|
|
||||||
trade.update_trade(oobj)
|
|
||||||
trade.close_date = datetime.utcnow()
|
|
||||||
trade.is_open = False
|
|
||||||
|
|
||||||
freqtradebot.enter_positions()
|
|
||||||
trade = Trade.query.first()
|
|
||||||
# Simulate fulfilled LIMIT_BUY order for trade
|
|
||||||
oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'buy')
|
|
||||||
trade.update_trade(oobj)
|
|
||||||
|
|
||||||
# Update the ticker with a market going up
|
|
||||||
mocker.patch.multiple(
|
|
||||||
'freqtrade.exchange.Exchange',
|
|
||||||
fetch_ticker=ticker_sell_up
|
|
||||||
)
|
|
||||||
oobj = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell')
|
|
||||||
trade.update_trade(oobj)
|
|
||||||
trade.close_date = datetime.utcnow()
|
|
||||||
trade.is_open = False
|
|
||||||
|
|
||||||
stats = rpc._rpc_trade_statistics(stake_currency, fiat_display_currency)
|
stats = rpc._rpc_trade_statistics(stake_currency, fiat_display_currency)
|
||||||
assert prec_satoshi(stats['profit_closed_coin'], 6.217e-05)
|
assert pytest.approx(stats['profit_closed_coin']) == 9.83
|
||||||
assert prec_satoshi(stats['profit_closed_percent_mean'], 6.2)
|
assert pytest.approx(stats['profit_closed_percent_mean']) == -1.67
|
||||||
assert prec_satoshi(stats['profit_closed_fiat'], 0.93255)
|
assert pytest.approx(stats['profit_closed_fiat']) == 10.813
|
||||||
assert prec_satoshi(stats['profit_all_coin'], 5.802e-05)
|
assert pytest.approx(stats['profit_all_coin']) == -77.45964918
|
||||||
assert prec_satoshi(stats['profit_all_percent_mean'], 2.89)
|
assert pytest.approx(stats['profit_all_percent_mean']) == -57.86
|
||||||
assert prec_satoshi(stats['profit_all_fiat'], 0.8703)
|
assert pytest.approx(stats['profit_all_fiat']) == -85.205614098
|
||||||
assert stats['trade_count'] == 2
|
assert stats['trade_count'] == 7
|
||||||
assert stats['first_trade_date'] == 'just now'
|
assert stats['first_trade_date'] == '2 days ago'
|
||||||
assert stats['latest_trade_date'] == 'just now'
|
assert stats['latest_trade_date'] == '17 minutes ago'
|
||||||
assert stats['avg_duration'] in ('0:00:00', '0:00:01', '0:00:02')
|
assert stats['avg_duration'] in ('0:17:40')
|
||||||
assert stats['best_pair'] == 'ETH/BTC'
|
assert stats['best_pair'] == 'XRP/USDT'
|
||||||
assert prec_satoshi(stats['best_rate'], 6.2)
|
assert stats['best_rate'] == 10.0
|
||||||
|
|
||||||
# Test non-available pair
|
# Test non-available pair
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_rate',
|
mocker.patch('freqtrade.exchange.Exchange.get_rate',
|
||||||
MagicMock(side_effect=ExchangeError("Pair 'ETH/BTC' not available")))
|
MagicMock(side_effect=ExchangeError("Pair 'XRP/USDT' not available")))
|
||||||
stats = rpc._rpc_trade_statistics(stake_currency, fiat_display_currency)
|
stats = rpc._rpc_trade_statistics(stake_currency, fiat_display_currency)
|
||||||
assert stats['trade_count'] == 2
|
assert stats['trade_count'] == 7
|
||||||
assert stats['first_trade_date'] == 'just now'
|
assert stats['first_trade_date'] == '2 days ago'
|
||||||
assert stats['latest_trade_date'] == 'just now'
|
assert stats['latest_trade_date'] == '17 minutes ago'
|
||||||
assert stats['avg_duration'] in ('0:00:00', '0:00:01', '0:00:02')
|
assert stats['avg_duration'] in ('0:17:40')
|
||||||
assert stats['best_pair'] == 'ETH/BTC'
|
assert stats['best_pair'] == 'XRP/USDT'
|
||||||
assert prec_satoshi(stats['best_rate'], 6.2)
|
assert stats['best_rate'] == 10.0
|
||||||
assert isnan(stats['profit_all_coin'])
|
assert isnan(stats['profit_all_coin'])
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user