Merge branch 'develop' into feat/freqai

This commit is contained in:
Matthias
2022-08-13 08:43:24 +02:00
23 changed files with 219 additions and 154 deletions

View File

@@ -214,7 +214,8 @@ def mock_trade_4(fee, is_short: bool):
open_order_id=f'prod_buy_{direc(is_short)}_12345',
strategy='StrategyTestV3',
timeframe=5,
is_short=is_short
is_short=is_short,
stop_loss_pct=0.10
)
o = Order.parse_from_ccxt_object(mock_order_4(is_short), 'ETC/BTC', entry_side(is_short))
trade.orders.append(o)
@@ -270,7 +271,8 @@ def mock_trade_5(fee, is_short: bool):
enter_tag='TEST1',
stoploss_order_id=f'prod_stoploss_{direc(is_short)}_3455',
timeframe=5,
is_short=is_short
is_short=is_short,
stop_loss_pct=0.10,
)
o = Order.parse_from_ccxt_object(mock_order_5(is_short), 'XRP/BTC', entry_side(is_short))
trade.orders.append(o)

View File

@@ -1,14 +1,14 @@
from ccxt import Precise
from freqtrade.util import FtPrecise
ws = Precise('-1.123e-6')
ws = Precise('-1.123e-6')
xs = Precise('0.00000002')
ys = Precise('69696900000')
zs = Precise('0')
ws = FtPrecise('-1.123e-6')
ws = FtPrecise('-1.123e-6')
xs = FtPrecise('0.00000002')
ys = FtPrecise('69696900000')
zs = FtPrecise('0')
def test_precise():
def test_FtPrecise():
assert ys * xs == '1393.938'
assert xs * ys == '1393.938'
@@ -45,31 +45,36 @@ def test_precise():
assert xs + zs == '0.00000002'
assert ys + zs == '69696900000'
assert abs(Precise('-500.1')) == '500.1'
assert abs(Precise('213')) == '213'
assert abs(FtPrecise('-500.1')) == '500.1'
assert abs(FtPrecise('213')) == '213'
assert abs(Precise('-500.1')) == '500.1'
assert -Precise('213') == '-213'
assert abs(FtPrecise('-500.1')) == '500.1'
assert -FtPrecise('213') == '-213'
assert Precise('10.1') % Precise('0.5') == '0.1'
assert Precise('5550') % Precise('120') == '30'
assert FtPrecise('10.1') % FtPrecise('0.5') == '0.1'
assert FtPrecise('5550') % FtPrecise('120') == '30'
assert Precise('-0.0') == Precise('0')
assert Precise('5.534000') == Precise('5.5340')
assert FtPrecise('-0.0') == FtPrecise('0')
assert FtPrecise('5.534000') == FtPrecise('5.5340')
assert min(Precise('-3.1415'), Precise('-2')) == '-3.1415'
assert min(FtPrecise('-3.1415'), FtPrecise('-2')) == '-3.1415'
assert max(Precise('3.1415'), Precise('-2')) == '3.1415'
assert max(FtPrecise('3.1415'), FtPrecise('-2')) == '3.1415'
assert Precise('2') > Precise('1.2345')
assert not Precise('-3.1415') > Precise('-2')
assert not Precise('3.1415') > Precise('3.1415')
assert Precise.string_gt('3.14150000000000000000001', '3.1415')
assert FtPrecise('2') > FtPrecise('1.2345')
assert not FtPrecise('-3.1415') > FtPrecise('-2')
assert not FtPrecise('3.1415') > FtPrecise('3.1415')
assert FtPrecise.string_gt('3.14150000000000000000001', '3.1415')
assert Precise('3.1415') >= Precise('3.1415')
assert Precise('3.14150000000000000000001') >= Precise('3.1415')
assert FtPrecise('3.1415') >= FtPrecise('3.1415')
assert FtPrecise('3.14150000000000000000001') >= FtPrecise('3.1415')
assert not Precise('3.1415') < Precise('3.1415')
assert not FtPrecise('3.1415') < FtPrecise('3.1415')
assert Precise('3.1415') <= Precise('3.1415')
assert Precise('3.1415') <= Precise('3.14150000000000000000001')
assert FtPrecise('3.1415') <= FtPrecise('3.1415')
assert FtPrecise('3.1415') <= FtPrecise('3.14150000000000000000001')
assert FtPrecise(213) == '213'
assert FtPrecise(-213) == '-213'
assert str(FtPrecise(-213)) == '-213'
assert FtPrecise(213.2) == '213.2'

View File

@@ -203,7 +203,7 @@ def test_fetch_stoploss_order_ftx(default_conf, mocker, limit_sell_order, limit_
'info': {
'orderId': 'mocked_limit_sell',
}}])
api_mock.fetch_order = MagicMock(return_value=limit_sell_order)
api_mock.fetch_order = MagicMock(return_value=limit_sell_order.copy())
# No orderId field - no call to fetch_order
resp = exchange.fetch_stoploss_order('X', 'TKN/BTC')
@@ -219,11 +219,23 @@ def test_fetch_stoploss_order_ftx(default_conf, mocker, limit_sell_order, limit_
order = {'id': 'X', 'status': 'closed', 'info': {'orderId': None}, 'average': 0.254}
api_mock.fetch_orders = MagicMock(return_value=[order])
api_mock.fetch_order.reset_mock()
api_mock.privateGetConditionalOrdersConditionalOrderIdTriggers = MagicMock(
return_value={'result': [
{'orderId': 'mocked_market_sell', 'type': 'market', 'side': 'sell', 'price': 0.254}
]})
resp = exchange.fetch_stoploss_order('X', 'TKN/BTC')
assert resp
# fetch_order not called (no regular order ID)
assert api_mock.fetch_order.call_count == 0
assert order == order
assert api_mock.fetch_order.call_count == 1
api_mock.privateGetConditionalOrdersConditionalOrderIdTriggers.call_count == 1
expected_resp = limit_sell_order.copy()
expected_resp.update({
'id_stop': 'X',
'id': 'X',
'type': 'stop',
'status_stop': 'triggered',
})
assert expected_resp == resp
with pytest.raises(InvalidOrderException):
api_mock.fetch_orders = MagicMock(side_effect=ccxt.InvalidOrder("Order not found"))

View File

@@ -305,6 +305,7 @@ def test_LowProfitPairs(mocker, default_conf, fee, caplog, only_per_side):
min_ago_open=800, min_ago_close=450, profit_rate=0.9,
))
Trade.commit()
# Not locked with 1 trade
assert not freqtrade.protections.global_stop()
assert not freqtrade.protections.stop_per_pair('XRP/BTC')
@@ -316,6 +317,7 @@ def test_LowProfitPairs(mocker, default_conf, fee, caplog, only_per_side):
min_ago_open=200, min_ago_close=120, profit_rate=0.9,
))
Trade.commit()
# Not locked with 1 trade (first trade is outside of lookback_period)
assert not freqtrade.protections.global_stop()
assert not freqtrade.protections.stop_per_pair('XRP/BTC')
@@ -327,14 +329,16 @@ def test_LowProfitPairs(mocker, default_conf, fee, caplog, only_per_side):
'XRP/BTC', fee.return_value, False, exit_reason=ExitType.ROI.value,
min_ago_open=20, min_ago_close=10, profit_rate=1.15, is_short=True
))
Trade.commit()
assert freqtrade.protections.stop_per_pair('XRP/BTC') != only_per_side
assert not PairLocks.is_pair_locked('XRP/BTC', side='*')
assert PairLocks.is_pair_locked('XRP/BTC', side='long') == only_per_side
Trade.query.session.add(generate_mock_trade(
'XRP/BTC', fee.return_value, False, exit_reason=ExitType.STOP_LOSS.value,
min_ago_open=110, min_ago_close=20, profit_rate=0.8,
min_ago_open=110, min_ago_close=21, profit_rate=0.8,
))
Trade.commit()
# Locks due to 2nd trade
assert freqtrade.protections.global_stop() != only_per_side
@@ -342,6 +346,7 @@ def test_LowProfitPairs(mocker, default_conf, fee, caplog, only_per_side):
assert PairLocks.is_pair_locked('XRP/BTC', side='long')
assert PairLocks.is_pair_locked('XRP/BTC', side='*') != only_per_side
assert not PairLocks.is_global_lock()
Trade.commit()
@pytest.mark.usefixtures("init_persistence")

View File

@@ -461,46 +461,6 @@ def test_rpc_trade_statistics(default_conf_usdt, ticker, fee, mocker) -> None:
assert isnan(stats['profit_all_coin'])
# Test that rpc_trade_statistics can handle trades that lacks
# trade.open_rate (it is set to None)
def test_rpc_trade_statistics_closed(mocker, default_conf_usdt, ticker, fee):
mocker.patch('freqtrade.rpc.fiat_convert.CryptoToFiatConverter._find_price',
return_value=1.1)
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
mocker.patch.multiple(
'freqtrade.exchange.Exchange',
fetch_ticker=ticker,
get_fee=fee,
)
freqtradebot = get_patched_freqtradebot(mocker, default_conf_usdt)
patch_get_signal(freqtradebot)
stake_currency = default_conf_usdt['stake_currency']
fiat_display_currency = default_conf_usdt['fiat_display_currency']
rpc = RPC(freqtradebot)
# Create some test data
create_mock_trades_usdt(fee)
for trade in Trade.query.order_by(Trade.id).all():
trade.open_rate = None
stats = rpc._rpc_trade_statistics(stake_currency, fiat_display_currency)
assert stats['profit_closed_coin'] == 0
assert stats['profit_closed_percent_mean'] == 0
assert stats['profit_closed_fiat'] == 0
assert stats['profit_all_coin'] == 0
assert stats['profit_all_percent_mean'] == 0
assert stats['profit_all_fiat'] == 0
assert stats['trade_count'] == 7
assert stats['first_trade_date'] == '2 days ago'
assert stats['latest_trade_date'] == '17 minutes ago'
assert stats['avg_duration'] == '0:00:00'
assert stats['best_pair'] == 'XRP/USDT'
assert stats['best_rate'] == 10.0
def test_rpc_balance_handle_error(default_conf, mocker):
mock_balance = {
'BTC': {

View File

@@ -1205,7 +1205,7 @@ def test_api_forceexit(botclient, mocker, ticker, fee, markets):
fetch_ticker=ticker,
get_fee=fee,
markets=PropertyMock(return_value=markets),
_is_dry_limit_order_filled=MagicMock(return_value=False),
_is_dry_limit_order_filled=MagicMock(return_value=True),
)
patch_get_signal(ftbot)
@@ -1215,12 +1215,27 @@ def test_api_forceexit(botclient, mocker, ticker, fee, markets):
assert rc.json() == {"error": "Error querying /api/v1/forceexit: invalid argument"}
Trade.query.session.rollback()
ftbot.enter_positions()
create_mock_trades(fee)
trade = Trade.get_trades([Trade.id == 5]).first()
assert pytest.approx(trade.amount) == 123
rc = client_post(client, f"{BASE_URI}/forceexit",
data='{"tradeid": "5", "ordertype": "market", "amount": 23}')
assert_response(rc)
assert rc.json() == {'result': 'Created sell order for trade 5.'}
Trade.query.session.rollback()
trade = Trade.get_trades([Trade.id == 5]).first()
assert pytest.approx(trade.amount) == 100
assert trade.is_open is True
rc = client_post(client, f"{BASE_URI}/forceexit",
data='{"tradeid": "1"}')
data='{"tradeid": "5"}')
assert_response(rc)
assert rc.json() == {'result': 'Created sell order for trade 1.'}
assert rc.json() == {'result': 'Created sell order for trade 5.'}
Trade.query.session.rollback()
trade = Trade.get_trades([Trade.id == 5]).first()
assert trade.is_open is False
def test_api_pair_candles(botclient, ohlcv_history):

View File

@@ -973,6 +973,14 @@ def test_execute_entry(mocker, default_conf_usdt, fee, limit_order,
trade.is_short = is_short
assert pytest.approx(trade.stake_amount) == 500
order['id'] = '55673'
freqtrade.strategy.leverage.reset_mock()
assert freqtrade.execute_entry(pair, 200, leverage_=3)
assert freqtrade.strategy.leverage.call_count == 0
trade = Trade.query.all()[10]
assert trade.leverage == 1 if trading_mode == 'spot' else 3
@pytest.mark.parametrize("is_short", [False, True])
def test_execute_entry_confirm_error(mocker, default_conf_usdt, fee, limit_order, is_short) -> None:

View File

@@ -291,7 +291,7 @@ def test_dca_short(default_conf_usdt, ticker_usdt, fee, mocker) -> None:
'freqtrade.exchange.Exchange',
fetch_ticker=ticker_usdt,
get_fee=fee,
amount_to_precision=lambda s, x, y: y,
amount_to_precision=lambda s, x, y: round(y, 4),
price_to_precision=lambda s, x, y: y,
)
@@ -303,6 +303,7 @@ def test_dca_short(default_conf_usdt, ticker_usdt, fee, mocker) -> None:
assert len(trade.orders) == 1
assert pytest.approx(trade.stake_amount) == 60
assert trade.open_rate == 2.02
assert trade.orders[0].amount == trade.amount
# No adjustment
freqtrade.process()
trade = Trade.get_trades().first()
@@ -331,8 +332,7 @@ def test_dca_short(default_conf_usdt, ticker_usdt, fee, mocker) -> None:
trade = Trade.get_trades().first()
assert len(trade.orders) == 2
assert pytest.approx(trade.stake_amount) == 120
# assert trade.orders[0].amount == 30
assert trade.orders[1].amount == 60 / ticker_usdt_modif['ask']
assert trade.orders[1].amount == round(60 / ticker_usdt_modif['ask'], 4)
assert trade.amount == trade.orders[0].amount + trade.orders[1].amount
assert trade.nr_of_successful_entries == 2
@@ -344,7 +344,7 @@ def test_dca_short(default_conf_usdt, ticker_usdt, fee, mocker) -> None:
assert trade.is_open is False
# assert trade.orders[0].amount == 30
assert trade.orders[0].side == 'sell'
assert trade.orders[1].amount == 60 / ticker_usdt_modif['ask']
assert trade.orders[1].amount == round(60 / ticker_usdt_modif['ask'], 4)
# Sold everything
assert trade.orders[-1].side == 'buy'
assert trade.orders[2].amount == trade.amount

View File

@@ -1,6 +1,6 @@
import time_machine
from freqtrade.configuration import PeriodicCache
from freqtrade.util import PeriodicCache
def test_ttl_cache():