Merge pull request #5592 from samgermain/test-freqtradebot-usdt

Test freqtradebot usdt
This commit is contained in:
Matthias 2021-10-03 09:41:08 +02:00 committed by GitHub
commit ad6ca3773d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 1362 additions and 940 deletions

View File

@ -25,6 +25,8 @@ from freqtrade.resolvers import ExchangeResolver
from freqtrade.worker import Worker from freqtrade.worker import Worker
from tests.conftest_trades import (mock_trade_1, mock_trade_2, mock_trade_3, mock_trade_4, from tests.conftest_trades import (mock_trade_1, mock_trade_2, mock_trade_3, mock_trade_4,
mock_trade_5, mock_trade_6) mock_trade_5, mock_trade_6)
from tests.conftest_trades_usdt import (mock_trade_usdt_1, mock_trade_usdt_2, mock_trade_usdt_3,
mock_trade_usdt_4, mock_trade_usdt_5, mock_trade_usdt_6)
logging.getLogger('').setLevel(logging.INFO) logging.getLogger('').setLevel(logging.INFO)
@ -227,6 +229,39 @@ def create_mock_trades(fee, use_db: bool = True):
Trade.query.session.flush() Trade.query.session.flush()
def create_mock_trades_usdt(fee, use_db: bool = True):
"""
Create some fake trades ...
"""
def add_trade(trade):
if use_db:
Trade.query.session.add(trade)
else:
LocalTrade.add_bt_trade(trade)
# Simulate dry_run entries
trade = mock_trade_usdt_1(fee)
add_trade(trade)
trade = mock_trade_usdt_2(fee)
add_trade(trade)
trade = mock_trade_usdt_3(fee)
add_trade(trade)
trade = mock_trade_usdt_4(fee)
add_trade(trade)
trade = mock_trade_usdt_5(fee)
add_trade(trade)
trade = mock_trade_usdt_6(fee)
add_trade(trade)
if use_db:
Trade.query.session.flush()
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def patch_coingekko(mocker) -> None: def patch_coingekko(mocker) -> None:
""" """
@ -259,6 +294,11 @@ def default_conf(testdatadir):
return get_default_conf(testdatadir) return get_default_conf(testdatadir)
@pytest.fixture(scope="function")
def default_conf_usdt(testdatadir):
return get_default_conf_usdt(testdatadir)
def get_default_conf(testdatadir): def get_default_conf(testdatadir):
""" Returns validated configuration suitable for most tests """ """ Returns validated configuration suitable for most tests """
configuration = { configuration = {
@ -333,6 +373,32 @@ def get_default_conf(testdatadir):
return configuration return configuration
def get_default_conf_usdt(testdatadir):
configuration = get_default_conf(testdatadir)
configuration.update({
"stake_amount": 60.0,
"stake_currency": "USDT",
"exchange": {
"name": "binance",
"enabled": True,
"key": "key",
"secret": "secret",
"pair_whitelist": [
"ETH/USDT",
"LTC/USDT",
"XRP/USDT",
"NEO/USDT",
"TKN/USDT",
],
"pair_blacklist": [
"DOGE/USDT",
"HOT/USDT",
]
},
})
return configuration
@pytest.fixture @pytest.fixture
def update(): def update():
_update = Update(0) _update = Update(0)
@ -372,6 +438,33 @@ def ticker_sell_down():
}) })
@pytest.fixture
def ticker_usdt():
return MagicMock(return_value={
'bid': 2.0,
'ask': 2.02,
'last': 2.0,
})
@pytest.fixture
def ticker_usdt_sell_up():
return MagicMock(return_value={
'bid': 2.2,
'ask': 2.3,
'last': 2.2,
})
@pytest.fixture
def ticker_usdt_sell_down():
return MagicMock(return_value={
'bid': 2.01,
'ask': 2.0,
'last': 2.01,
})
@pytest.fixture @pytest.fixture
def markets(): def markets():
return get_markets() return get_markets()
@ -604,6 +697,81 @@ def get_markets():
}, },
'info': {}, 'info': {},
}, },
'XRP/USDT': {
'id': 'xrpusdt',
'symbol': 'XRP/USDT',
'base': 'XRP',
'quote': 'USDT',
'active': True,
'precision': {
'price': 8,
'amount': 8,
'cost': 8,
},
'lot': 0.00000001,
'limits': {
'amount': {
'min': 0.01,
'max': 1000,
},
'price': 500000,
'cost': {
'min': 0.0001,
'max': 500000,
},
},
'info': {},
},
'NEO/USDT': {
'id': 'neousdt',
'symbol': 'NEO/USDT',
'base': 'NEO',
'quote': 'USDT',
'active': True,
'precision': {
'price': 8,
'amount': 8,
'cost': 8,
},
'lot': 0.00000001,
'limits': {
'amount': {
'min': 0.01,
'max': 1000,
},
'price': 500000,
'cost': {
'min': 0.0001,
'max': 500000,
},
},
'info': {},
},
'TKN/USDT': {
'id': 'tknusdt',
'symbol': 'TKN/USDT',
'base': 'TKN',
'quote': 'USDT',
'active': True,
'precision': {
'price': 8,
'amount': 8,
'cost': 8,
},
'lot': 0.00000001,
'limits': {
'amount': {
'min': 0.01,
'max': 1000,
},
'price': 500000,
'cost': {
'min': 0.0001,
'max': 500000,
},
},
'info': {},
},
'LTC/USD': { 'LTC/USD': {
'id': 'USD-LTC', 'id': 'USD-LTC',
'symbol': 'LTC/USD', 'symbol': 'LTC/USD',
@ -1536,27 +1704,34 @@ def result(testdatadir):
@pytest.fixture(scope="function") @pytest.fixture(scope="function")
def trades_for_order(): def trades_for_order():
return [{'info': {'id': 34567, return [{
'orderId': 123456, 'info': {
'price': '0.24544100', 'id': 34567,
'qty': '8.00000000', 'orderId': 123456,
'commission': '0.00800000', 'price': '2.0',
'commissionAsset': 'LTC', 'qty': '8.00000000',
'time': 1521663363189, 'commission': '0.00800000',
'isBuyer': True, 'commissionAsset': 'LTC',
'isMaker': False, 'time': 1521663363189,
'isBestMatch': True}, 'isBuyer': True,
'timestamp': 1521663363189, 'isMaker': False,
'datetime': '2018-03-21T20:16:03.189Z', 'isBestMatch': True
'symbol': 'LTC/ETH', },
'id': '34567', 'timestamp': 1521663363189,
'order': '123456', 'datetime': '2018-03-21T20:16:03.189Z',
'type': None, 'symbol': 'LTC/USDT',
'side': 'buy', 'id': '34567',
'price': 0.245441, 'order': '123456',
'cost': 1.963528, 'type': None,
'amount': 8.0, 'side': 'buy',
'fee': {'cost': 0.008, 'currency': 'LTC'}}] 'price': 2.0,
'cost': 16.0,
'amount': 8.0,
'fee': {
'cost': 0.008,
'currency': 'LTC'
}
}]
@pytest.fixture(scope="function") @pytest.fixture(scope="function")
@ -1821,6 +1996,22 @@ def open_trade():
) )
@pytest.fixture(scope="function")
def open_trade_usdt():
return Trade(
pair='ADA/USDT',
open_rate=2.0,
exchange='binance',
open_order_id='123456789',
amount=30.0,
fee_open=0.0,
fee_close=0.0,
stake_amount=60.0,
open_date=arrow.utcnow().shift(minutes=-601).datetime,
is_open=True
)
@pytest.fixture @pytest.fixture
def saved_hyperopt_results(): def saved_hyperopt_results():
hyperopt_res = [ hyperopt_res = [
@ -1964,7 +2155,7 @@ def saved_hyperopt_results():
@pytest.fixture(scope='function') @pytest.fixture(scope='function')
def limit_buy_order_usdt_open(): def limit_buy_order_usdt_open():
return { return {
'id': 'mocked_limit_buy', 'id': 'mocked_limit_buy_usdt',
'type': 'limit', 'type': 'limit',
'side': 'buy', 'side': 'buy',
'symbol': 'mocked', 'symbol': 'mocked',
@ -1991,7 +2182,7 @@ def limit_buy_order_usdt(limit_buy_order_usdt_open):
@pytest.fixture @pytest.fixture
def limit_sell_order_usdt_open(): def limit_sell_order_usdt_open():
return { return {
'id': 'mocked_limit_sell', 'id': 'mocked_limit_sell_usdt',
'type': 'limit', 'type': 'limit',
'side': 'sell', 'side': 'sell',
'pair': 'mocked', 'pair': 'mocked',

View File

@ -0,0 +1,305 @@
from datetime import datetime, timedelta, timezone
from freqtrade.persistence.models import Order, Trade
MOCK_TRADE_COUNT = 6
def mock_order_usdt_1():
return {
'id': '1234',
'symbol': 'ADA/USDT',
'status': 'closed',
'side': 'buy',
'type': 'limit',
'price': 2.0,
'amount': 10.0,
'filled': 10.0,
'remaining': 0.0,
}
def mock_trade_usdt_1(fee):
trade = Trade(
pair='ADA/USDT',
stake_amount=20.0,
amount=10.0,
amount_requested=10.0,
fee_open=fee.return_value,
fee_close=fee.return_value,
is_open=True,
open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=17),
open_rate=2.0,
exchange='binance',
open_order_id='dry_run_buy_12345',
strategy='StrategyTestV2',
timeframe=5,
)
o = Order.parse_from_ccxt_object(mock_order_usdt_1(), 'ADA/USDT', 'buy')
trade.orders.append(o)
return trade
def mock_order_usdt_2():
return {
'id': '1235',
'symbol': 'ETC/USDT',
'status': 'closed',
'side': 'buy',
'type': 'limit',
'price': 2.0,
'amount': 100.0,
'filled': 100.0,
'remaining': 0.0,
}
def mock_order_usdt_2_sell():
return {
'id': '12366',
'symbol': 'ETC/USDT',
'status': 'closed',
'side': 'sell',
'type': 'limit',
'price': 2.05,
'amount': 100.0,
'filled': 100.0,
'remaining': 0.0,
}
def mock_trade_usdt_2(fee):
"""
Closed trade...
"""
trade = Trade(
pair='ETC/USDT',
stake_amount=200.0,
amount=100.0,
amount_requested=100.0,
fee_open=fee.return_value,
fee_close=fee.return_value,
open_rate=2.0,
close_rate=2.05,
close_profit=5.0,
close_profit_abs=3.9875,
exchange='binance',
is_open=False,
open_order_id='dry_run_sell_12345',
strategy='StrategyTestV2',
timeframe=5,
sell_reason='sell_signal',
open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=20),
close_date=datetime.now(tz=timezone.utc) - timedelta(minutes=2),
)
o = Order.parse_from_ccxt_object(mock_order_usdt_2(), 'ETC/USDT', 'buy')
trade.orders.append(o)
o = Order.parse_from_ccxt_object(mock_order_usdt_2_sell(), 'ETC/USDT', 'sell')
trade.orders.append(o)
return trade
def mock_order_usdt_3():
return {
'id': '41231a12a',
'symbol': 'XRP/USDT',
'status': 'closed',
'side': 'buy',
'type': 'limit',
'price': 1.0,
'amount': 30.0,
'filled': 30.0,
'remaining': 0.0,
}
def mock_order_usdt_3_sell():
return {
'id': '41231a666a',
'symbol': 'XRP/USDT',
'status': 'closed',
'side': 'sell',
'type': 'stop_loss_limit',
'price': 1.1,
'average': 1.1,
'amount': 30.0,
'filled': 30.0,
'remaining': 0.0,
}
def mock_trade_usdt_3(fee):
"""
Closed trade
"""
trade = Trade(
pair='XRP/USDT',
stake_amount=30.0,
amount=30.0,
amount_requested=30.0,
fee_open=fee.return_value,
fee_close=fee.return_value,
open_rate=1.0,
close_rate=1.1,
close_profit=10.0,
close_profit_abs=9.8425,
exchange='binance',
is_open=False,
strategy='StrategyTestV2',
timeframe=5,
sell_reason='roi',
open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=20),
close_date=datetime.now(tz=timezone.utc),
)
o = Order.parse_from_ccxt_object(mock_order_usdt_3(), 'XRP/USDT', 'buy')
trade.orders.append(o)
o = Order.parse_from_ccxt_object(mock_order_usdt_3_sell(), 'XRP/USDT', 'sell')
trade.orders.append(o)
return trade
def mock_order_usdt_4():
return {
'id': 'prod_buy_12345',
'symbol': 'ETC/USDT',
'status': 'open',
'side': 'buy',
'type': 'limit',
'price': 2.0,
'amount': 10.0,
'filled': 0.0,
'remaining': 30.0,
}
def mock_trade_usdt_4(fee):
"""
Simulate prod entry
"""
trade = Trade(
pair='ETC/USDT',
stake_amount=20.0,
amount=10.0,
amount_requested=10.01,
fee_open=fee.return_value,
fee_close=fee.return_value,
open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=14),
is_open=True,
open_rate=2.0,
exchange='binance',
open_order_id='prod_buy_12345',
strategy='StrategyTestV2',
timeframe=5,
)
o = Order.parse_from_ccxt_object(mock_order_usdt_4(), 'ETC/USDT', 'buy')
trade.orders.append(o)
return trade
def mock_order_usdt_5():
return {
'id': 'prod_buy_3455',
'symbol': 'XRP/USDT',
'status': 'closed',
'side': 'buy',
'type': 'limit',
'price': 2.0,
'amount': 10.0,
'filled': 10.0,
'remaining': 0.0,
}
def mock_order_usdt_5_stoploss():
return {
'id': 'prod_stoploss_3455',
'symbol': 'XRP/USDT',
'status': 'open',
'side': 'sell',
'type': 'stop_loss_limit',
'price': 2.0,
'amount': 10.0,
'filled': 0.0,
'remaining': 30.0,
}
def mock_trade_usdt_5(fee):
"""
Simulate prod entry with stoploss
"""
trade = Trade(
pair='XRP/USDT',
stake_amount=20.0,
amount=10.0,
amount_requested=10.01,
fee_open=fee.return_value,
fee_close=fee.return_value,
open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=12),
is_open=True,
open_rate=2.0,
exchange='binance',
strategy='SampleStrategy',
stoploss_order_id='prod_stoploss_3455',
timeframe=5,
)
o = Order.parse_from_ccxt_object(mock_order_usdt_5(), 'XRP/USDT', 'buy')
trade.orders.append(o)
o = Order.parse_from_ccxt_object(mock_order_usdt_5_stoploss(), 'XRP/USDT', 'stoploss')
trade.orders.append(o)
return trade
def mock_order_usdt_6():
return {
'id': 'prod_buy_6',
'symbol': 'LTC/USDT',
'status': 'closed',
'side': 'buy',
'type': 'limit',
'price': 10.0,
'amount': 2.0,
'filled': 2.0,
'remaining': 0.0,
}
def mock_order_usdt_6_sell():
return {
'id': 'prod_sell_6',
'symbol': 'LTC/USDT',
'status': 'open',
'side': 'sell',
'type': 'limit',
'price': 12.0,
'amount': 2.0,
'filled': 0.0,
'remaining': 2.0,
}
def mock_trade_usdt_6(fee):
"""
Simulate prod entry with open sell order
"""
trade = Trade(
pair='LTC/USDT',
stake_amount=20.0,
amount=2.0,
amount_requested=2.0,
open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=5),
fee_open=fee.return_value,
fee_close=fee.return_value,
is_open=True,
open_rate=10.0,
exchange='binance',
strategy='SampleStrategy',
open_order_id="prod_sell_6",
timeframe=5,
)
o = Order.parse_from_ccxt_object(mock_order_usdt_6(), 'LTC/USDT', 'buy')
trade.orders.append(o)
o = Order.parse_from_ccxt_object(mock_order_usdt_6_sell(), 'LTC/USDT', 'sell')
trade.orders.append(o)
return trade

View File

@ -1003,7 +1003,7 @@ def test_rpc_blacklist(mocker, default_conf) -> None:
assert len(ret['blacklist']) == 4 assert len(ret['blacklist']) == 4
assert ret['blacklist'] == default_conf['exchange']['pair_blacklist'] assert ret['blacklist'] == default_conf['exchange']['pair_blacklist']
assert ret['blacklist'] == ['DOGE/BTC', 'HOT/BTC', 'ETH/BTC', 'XRP/.*'] assert ret['blacklist'] == ['DOGE/BTC', 'HOT/BTC', 'ETH/BTC', 'XRP/.*']
assert ret['blacklist_expanded'] == ['ETH/BTC', 'XRP/BTC'] assert ret['blacklist_expanded'] == ['ETH/BTC', 'XRP/BTC', 'XRP/USDT']
assert 'errors' in ret assert 'errors' in ret
assert isinstance(ret['errors'], dict) assert isinstance(ret['errors'], dict)

View File

@ -937,7 +937,7 @@ def test_api_blacklist(botclient, mocker):
data='{"blacklist": ["XRP/.*"]}') data='{"blacklist": ["XRP/.*"]}')
assert_response(rc) assert_response(rc)
assert rc.json() == {"blacklist": ["DOGE/BTC", "HOT/BTC", "ETH/BTC", "XRP/.*"], assert rc.json() == {"blacklist": ["DOGE/BTC", "HOT/BTC", "ETH/BTC", "XRP/.*"],
"blacklist_expanded": ["ETH/BTC", "XRP/BTC"], "blacklist_expanded": ["ETH/BTC", "XRP/BTC", "XRP/USDT"],
"length": 4, "length": 4,
"method": ["StaticPairList"], "method": ["StaticPairList"],
"errors": {}, "errors": {},

File diff suppressed because it is too large Load Diff