Merge branch 'feat/short' into funding-fee-backtesting
This commit is contained in:
@@ -754,6 +754,46 @@ def test_download_data_no_pairs(mocker, caplog):
|
||||
start_download_data(pargs)
|
||||
|
||||
|
||||
def test_download_data_all_pairs(mocker, markets):
|
||||
|
||||
mocker.patch.object(Path, "exists", MagicMock(return_value=False))
|
||||
|
||||
dl_mock = mocker.patch('freqtrade.commands.data_commands.refresh_backtest_ohlcv_data',
|
||||
MagicMock(return_value=["ETH/BTC", "XRP/BTC"]))
|
||||
patch_exchange(mocker)
|
||||
mocker.patch(
|
||||
'freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets)
|
||||
)
|
||||
args = [
|
||||
"download-data",
|
||||
"--exchange",
|
||||
"binance",
|
||||
"--pairs",
|
||||
".*/USDT"
|
||||
]
|
||||
pargs = get_args(args)
|
||||
pargs['config'] = None
|
||||
start_download_data(pargs)
|
||||
expected = set(['ETH/USDT', 'XRP/USDT', 'NEO/USDT', 'TKN/USDT'])
|
||||
assert set(dl_mock.call_args_list[0][1]['pairs']) == expected
|
||||
assert dl_mock.call_count == 1
|
||||
|
||||
dl_mock.reset_mock()
|
||||
args = [
|
||||
"download-data",
|
||||
"--exchange",
|
||||
"binance",
|
||||
"--pairs",
|
||||
".*/USDT",
|
||||
"--include-inactive-pairs",
|
||||
]
|
||||
pargs = get_args(args)
|
||||
pargs['config'] = None
|
||||
start_download_data(pargs)
|
||||
expected = set(['ETH/USDT', 'LTC/USDT', 'XRP/USDT', 'NEO/USDT', 'TKN/USDT'])
|
||||
assert set(dl_mock.call_args_list[0][1]['pairs']) == expected
|
||||
|
||||
|
||||
def test_download_data_trades(mocker, caplog):
|
||||
dl_mock = mocker.patch('freqtrade.commands.data_commands.refresh_backtest_trades_data',
|
||||
MagicMock(return_value=[]))
|
||||
@@ -903,7 +943,7 @@ def test_hyperopt_list(mocker, capsys, caplog, saved_hyperopt_results, tmpdir):
|
||||
mocker.patch(
|
||||
'freqtrade.optimize.hyperopt_tools.HyperoptTools._test_hyperopt_results_exist',
|
||||
return_value=True
|
||||
)
|
||||
)
|
||||
|
||||
def fake_iterator(*args, **kwargs):
|
||||
yield from [saved_hyperopt_results]
|
||||
@@ -1309,9 +1349,10 @@ def test_start_list_data(testdatadir, capsys):
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_persistence")
|
||||
# TODO-lev: Short trades?
|
||||
def test_show_trades(mocker, fee, capsys, caplog):
|
||||
mocker.patch("freqtrade.persistence.init_db")
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, False)
|
||||
args = [
|
||||
"show-trades",
|
||||
"--db-url",
|
||||
|
||||
@@ -209,8 +209,14 @@ def get_patched_worker(mocker, config) -> Worker:
|
||||
return Worker(args=None, config=config)
|
||||
|
||||
|
||||
def patch_get_signal(freqtrade: FreqtradeBot, enter_long=True, exit_long=False,
|
||||
enter_short=False, exit_short=False, enter_tag: Optional[str] = None) -> None:
|
||||
def patch_get_signal(
|
||||
freqtrade: FreqtradeBot,
|
||||
enter_long=True,
|
||||
exit_long=False,
|
||||
enter_short=False,
|
||||
exit_short=False,
|
||||
enter_tag: Optional[str] = None
|
||||
) -> None:
|
||||
"""
|
||||
:param mocker: mocker to patch IStrategy class
|
||||
:param value: which value IStrategy.get_signal() must return
|
||||
@@ -241,7 +247,7 @@ def patch_get_signal(freqtrade: FreqtradeBot, enter_long=True, exit_long=False,
|
||||
freqtrade.exchange.refresh_latest_ohlcv = lambda p: None
|
||||
|
||||
|
||||
def create_mock_trades(fee, use_db: bool = True):
|
||||
def create_mock_trades(fee, is_short: bool, use_db: bool = True):
|
||||
"""
|
||||
Create some fake trades ...
|
||||
"""
|
||||
@@ -252,26 +258,26 @@ def create_mock_trades(fee, use_db: bool = True):
|
||||
LocalTrade.add_bt_trade(trade)
|
||||
|
||||
# Simulate dry_run entries
|
||||
trade = mock_trade_1(fee)
|
||||
trade = mock_trade_1(fee, is_short)
|
||||
add_trade(trade)
|
||||
|
||||
trade = mock_trade_2(fee)
|
||||
trade = mock_trade_2(fee, is_short)
|
||||
add_trade(trade)
|
||||
|
||||
trade = mock_trade_3(fee)
|
||||
trade = mock_trade_3(fee, is_short)
|
||||
add_trade(trade)
|
||||
|
||||
trade = mock_trade_4(fee)
|
||||
trade = mock_trade_4(fee, is_short)
|
||||
add_trade(trade)
|
||||
|
||||
trade = mock_trade_5(fee)
|
||||
trade = mock_trade_5(fee, is_short)
|
||||
add_trade(trade)
|
||||
|
||||
trade = mock_trade_6(fee)
|
||||
trade = mock_trade_6(fee, is_short)
|
||||
add_trade(trade)
|
||||
|
||||
if use_db:
|
||||
Trade.query.session.flush()
|
||||
Trade.commit()
|
||||
|
||||
|
||||
def create_mock_trades_with_leverage(fee, use_db: bool = True):
|
||||
@@ -285,22 +291,22 @@ def create_mock_trades_with_leverage(fee, use_db: bool = True):
|
||||
LocalTrade.add_bt_trade(trade)
|
||||
|
||||
# Simulate dry_run entries
|
||||
trade = mock_trade_1(fee)
|
||||
trade = mock_trade_1(fee, False)
|
||||
add_trade(trade)
|
||||
|
||||
trade = mock_trade_2(fee)
|
||||
trade = mock_trade_2(fee, False)
|
||||
add_trade(trade)
|
||||
|
||||
trade = mock_trade_3(fee)
|
||||
trade = mock_trade_3(fee, False)
|
||||
add_trade(trade)
|
||||
|
||||
trade = mock_trade_4(fee)
|
||||
trade = mock_trade_4(fee, False)
|
||||
add_trade(trade)
|
||||
|
||||
trade = mock_trade_5(fee)
|
||||
trade = mock_trade_5(fee, False)
|
||||
add_trade(trade)
|
||||
|
||||
trade = mock_trade_6(fee)
|
||||
trade = mock_trade_6(fee, False)
|
||||
add_trade(trade)
|
||||
|
||||
trade = short_trade(fee)
|
||||
@@ -323,7 +329,7 @@ def create_mock_trades_usdt(fee, use_db: bool = True):
|
||||
else:
|
||||
LocalTrade.add_bt_trade(trade)
|
||||
|
||||
# Simulate dry_run entries
|
||||
# Simulate dry_run entries
|
||||
trade = mock_trade_usdt_1(fee)
|
||||
add_trade(trade)
|
||||
|
||||
@@ -343,7 +349,7 @@ def create_mock_trades_usdt(fee, use_db: bool = True):
|
||||
add_trade(trade)
|
||||
|
||||
if use_db:
|
||||
Trade.query.session.flush()
|
||||
Trade.commit()
|
||||
|
||||
|
||||
def get_sides(is_short: bool) -> Tuple[str, str]:
|
||||
@@ -2295,6 +2301,7 @@ def limit_sell_order_usdt_open():
|
||||
'timestamp': arrow.utcnow().int_timestamp,
|
||||
'price': 2.20,
|
||||
'amount': 30.0,
|
||||
'cost': 66.0,
|
||||
'filled': 0.0,
|
||||
'remaining': 30.0,
|
||||
'status': 'open'
|
||||
@@ -2340,3 +2347,27 @@ def market_sell_order_usdt():
|
||||
'remaining': 0.0,
|
||||
'status': 'closed'
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def limit_order(limit_buy_order_usdt, limit_sell_order_usdt):
|
||||
return {
|
||||
'buy': limit_buy_order_usdt,
|
||||
'sell': limit_sell_order_usdt
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def market_order(market_buy_order_usdt, market_sell_order_usdt):
|
||||
return {
|
||||
'buy': market_buy_order_usdt,
|
||||
'sell': market_sell_order_usdt
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def limit_order_open(limit_buy_order_usdt_open, limit_sell_order_usdt_open):
|
||||
return {
|
||||
'buy': limit_buy_order_usdt_open,
|
||||
'sell': limit_sell_order_usdt_open
|
||||
}
|
||||
|
||||
@@ -6,12 +6,24 @@ from freqtrade.persistence.models import Order, Trade
|
||||
MOCK_TRADE_COUNT = 6
|
||||
|
||||
|
||||
def mock_order_1():
|
||||
def enter_side(is_short: bool):
|
||||
return "sell" if is_short else "buy"
|
||||
|
||||
|
||||
def exit_side(is_short: bool):
|
||||
return "buy" if is_short else "sell"
|
||||
|
||||
|
||||
def direc(is_short: bool):
|
||||
return "short" if is_short else "long"
|
||||
|
||||
|
||||
def mock_order_1(is_short: bool):
|
||||
return {
|
||||
'id': '1234',
|
||||
'id': f'1234_{direc(is_short)}',
|
||||
'symbol': 'ETH/BTC',
|
||||
'status': 'closed',
|
||||
'side': 'buy',
|
||||
'side': enter_side(is_short),
|
||||
'type': 'limit',
|
||||
'price': 0.123,
|
||||
'amount': 123.0,
|
||||
@@ -20,7 +32,7 @@ def mock_order_1():
|
||||
}
|
||||
|
||||
|
||||
def mock_trade_1(fee):
|
||||
def mock_trade_1(fee, is_short: bool):
|
||||
trade = Trade(
|
||||
pair='ETH/BTC',
|
||||
stake_amount=0.001,
|
||||
@@ -32,21 +44,22 @@ def mock_trade_1(fee):
|
||||
open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=17),
|
||||
open_rate=0.123,
|
||||
exchange='binance',
|
||||
open_order_id='dry_run_buy_12345',
|
||||
open_order_id=f'dry_run_buy_{direc(is_short)}_12345',
|
||||
strategy='StrategyTestV3',
|
||||
timeframe=5,
|
||||
is_short=is_short
|
||||
)
|
||||
o = Order.parse_from_ccxt_object(mock_order_1(), 'ETH/BTC', 'buy')
|
||||
o = Order.parse_from_ccxt_object(mock_order_1(is_short), 'ETH/BTC', enter_side(is_short))
|
||||
trade.orders.append(o)
|
||||
return trade
|
||||
|
||||
|
||||
def mock_order_2():
|
||||
def mock_order_2(is_short: bool):
|
||||
return {
|
||||
'id': '1235',
|
||||
'id': f'1235_{direc(is_short)}',
|
||||
'symbol': 'ETC/BTC',
|
||||
'status': 'closed',
|
||||
'side': 'buy',
|
||||
'side': enter_side(is_short),
|
||||
'type': 'limit',
|
||||
'price': 0.123,
|
||||
'amount': 123.0,
|
||||
@@ -55,12 +68,12 @@ def mock_order_2():
|
||||
}
|
||||
|
||||
|
||||
def mock_order_2_sell():
|
||||
def mock_order_2_sell(is_short: bool):
|
||||
return {
|
||||
'id': '12366',
|
||||
'id': f'12366_{direc(is_short)}',
|
||||
'symbol': 'ETC/BTC',
|
||||
'status': 'closed',
|
||||
'side': 'sell',
|
||||
'side': exit_side(is_short),
|
||||
'type': 'limit',
|
||||
'price': 0.128,
|
||||
'amount': 123.0,
|
||||
@@ -69,7 +82,7 @@ def mock_order_2_sell():
|
||||
}
|
||||
|
||||
|
||||
def mock_trade_2(fee):
|
||||
def mock_trade_2(fee, is_short: bool):
|
||||
"""
|
||||
Closed trade...
|
||||
"""
|
||||
@@ -82,30 +95,31 @@ def mock_trade_2(fee):
|
||||
fee_close=fee.return_value,
|
||||
open_rate=0.123,
|
||||
close_rate=0.128,
|
||||
close_profit=0.005,
|
||||
close_profit_abs=0.000584127,
|
||||
close_profit=-0.005 if is_short else 0.005,
|
||||
close_profit_abs=-0.005584127 if is_short else 0.000584127,
|
||||
exchange='binance',
|
||||
is_open=False,
|
||||
open_order_id='dry_run_sell_12345',
|
||||
open_order_id=f'dry_run_sell_{direc(is_short)}_12345',
|
||||
strategy='StrategyTestV3',
|
||||
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),
|
||||
is_short=is_short
|
||||
)
|
||||
o = Order.parse_from_ccxt_object(mock_order_2(), 'ETC/BTC', 'buy')
|
||||
o = Order.parse_from_ccxt_object(mock_order_2(is_short), 'ETC/BTC', enter_side(is_short))
|
||||
trade.orders.append(o)
|
||||
o = Order.parse_from_ccxt_object(mock_order_2_sell(), 'ETC/BTC', 'sell')
|
||||
o = Order.parse_from_ccxt_object(mock_order_2_sell(is_short), 'ETC/BTC', exit_side(is_short))
|
||||
trade.orders.append(o)
|
||||
return trade
|
||||
|
||||
|
||||
def mock_order_3():
|
||||
def mock_order_3(is_short: bool):
|
||||
return {
|
||||
'id': '41231a12a',
|
||||
'id': f'41231a12a_{direc(is_short)}',
|
||||
'symbol': 'XRP/BTC',
|
||||
'status': 'closed',
|
||||
'side': 'buy',
|
||||
'side': enter_side(is_short),
|
||||
'type': 'limit',
|
||||
'price': 0.05,
|
||||
'amount': 123.0,
|
||||
@@ -114,12 +128,12 @@ def mock_order_3():
|
||||
}
|
||||
|
||||
|
||||
def mock_order_3_sell():
|
||||
def mock_order_3_sell(is_short: bool):
|
||||
return {
|
||||
'id': '41231a666a',
|
||||
'id': f'41231a666a_{direc(is_short)}',
|
||||
'symbol': 'XRP/BTC',
|
||||
'status': 'closed',
|
||||
'side': 'sell',
|
||||
'side': exit_side(is_short),
|
||||
'type': 'stop_loss_limit',
|
||||
'price': 0.06,
|
||||
'average': 0.06,
|
||||
@@ -129,7 +143,7 @@ def mock_order_3_sell():
|
||||
}
|
||||
|
||||
|
||||
def mock_trade_3(fee):
|
||||
def mock_trade_3(fee, is_short: bool):
|
||||
"""
|
||||
Closed trade
|
||||
"""
|
||||
@@ -142,8 +156,8 @@ def mock_trade_3(fee):
|
||||
fee_close=fee.return_value,
|
||||
open_rate=0.05,
|
||||
close_rate=0.06,
|
||||
close_profit=0.01,
|
||||
close_profit_abs=0.000155,
|
||||
close_profit=-0.01 if is_short else 0.01,
|
||||
close_profit_abs=-0.001155 if is_short else 0.000155,
|
||||
exchange='binance',
|
||||
is_open=False,
|
||||
strategy='StrategyTestV3',
|
||||
@@ -151,20 +165,21 @@ def mock_trade_3(fee):
|
||||
sell_reason='roi',
|
||||
open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=20),
|
||||
close_date=datetime.now(tz=timezone.utc),
|
||||
is_short=is_short
|
||||
)
|
||||
o = Order.parse_from_ccxt_object(mock_order_3(), 'XRP/BTC', 'buy')
|
||||
o = Order.parse_from_ccxt_object(mock_order_3(is_short), 'XRP/BTC', enter_side(is_short))
|
||||
trade.orders.append(o)
|
||||
o = Order.parse_from_ccxt_object(mock_order_3_sell(), 'XRP/BTC', 'sell')
|
||||
o = Order.parse_from_ccxt_object(mock_order_3_sell(is_short), 'XRP/BTC', exit_side(is_short))
|
||||
trade.orders.append(o)
|
||||
return trade
|
||||
|
||||
|
||||
def mock_order_4():
|
||||
def mock_order_4(is_short: bool):
|
||||
return {
|
||||
'id': 'prod_buy_12345',
|
||||
'id': f'prod_buy_{direc(is_short)}_12345',
|
||||
'symbol': 'ETC/BTC',
|
||||
'status': 'open',
|
||||
'side': 'buy',
|
||||
'side': enter_side(is_short),
|
||||
'type': 'limit',
|
||||
'price': 0.123,
|
||||
'amount': 123.0,
|
||||
@@ -173,7 +188,7 @@ def mock_order_4():
|
||||
}
|
||||
|
||||
|
||||
def mock_trade_4(fee):
|
||||
def mock_trade_4(fee, is_short: bool):
|
||||
"""
|
||||
Simulate prod entry
|
||||
"""
|
||||
@@ -188,21 +203,22 @@ def mock_trade_4(fee):
|
||||
is_open=True,
|
||||
open_rate=0.123,
|
||||
exchange='binance',
|
||||
open_order_id='prod_buy_12345',
|
||||
open_order_id=f'prod_buy_{direc(is_short)}_12345',
|
||||
strategy='StrategyTestV3',
|
||||
timeframe=5,
|
||||
is_short=is_short
|
||||
)
|
||||
o = Order.parse_from_ccxt_object(mock_order_4(), 'ETC/BTC', 'buy')
|
||||
o = Order.parse_from_ccxt_object(mock_order_4(is_short), 'ETC/BTC', enter_side(is_short))
|
||||
trade.orders.append(o)
|
||||
return trade
|
||||
|
||||
|
||||
def mock_order_5():
|
||||
def mock_order_5(is_short: bool):
|
||||
return {
|
||||
'id': 'prod_buy_3455',
|
||||
'id': f'prod_buy_{direc(is_short)}_3455',
|
||||
'symbol': 'XRP/BTC',
|
||||
'status': 'closed',
|
||||
'side': 'buy',
|
||||
'side': enter_side(is_short),
|
||||
'type': 'limit',
|
||||
'price': 0.123,
|
||||
'amount': 123.0,
|
||||
@@ -211,12 +227,12 @@ def mock_order_5():
|
||||
}
|
||||
|
||||
|
||||
def mock_order_5_stoploss():
|
||||
def mock_order_5_stoploss(is_short: bool):
|
||||
return {
|
||||
'id': 'prod_stoploss_3455',
|
||||
'id': f'prod_stoploss_{direc(is_short)}_3455',
|
||||
'symbol': 'XRP/BTC',
|
||||
'status': 'open',
|
||||
'side': 'sell',
|
||||
'side': exit_side(is_short),
|
||||
'type': 'stop_loss_limit',
|
||||
'price': 0.123,
|
||||
'amount': 123.0,
|
||||
@@ -225,7 +241,7 @@ def mock_order_5_stoploss():
|
||||
}
|
||||
|
||||
|
||||
def mock_trade_5(fee):
|
||||
def mock_trade_5(fee, is_short: bool):
|
||||
"""
|
||||
Simulate prod entry with stoploss
|
||||
"""
|
||||
@@ -241,22 +257,23 @@ def mock_trade_5(fee):
|
||||
open_rate=0.123,
|
||||
exchange='binance',
|
||||
strategy='SampleStrategy',
|
||||
stoploss_order_id='prod_stoploss_3455',
|
||||
stoploss_order_id=f'prod_stoploss_{direc(is_short)}_3455',
|
||||
timeframe=5,
|
||||
is_short=is_short
|
||||
)
|
||||
o = Order.parse_from_ccxt_object(mock_order_5(), 'XRP/BTC', 'buy')
|
||||
o = Order.parse_from_ccxt_object(mock_order_5(is_short), 'XRP/BTC', enter_side(is_short))
|
||||
trade.orders.append(o)
|
||||
o = Order.parse_from_ccxt_object(mock_order_5_stoploss(), 'XRP/BTC', 'stoploss')
|
||||
o = Order.parse_from_ccxt_object(mock_order_5_stoploss(is_short), 'XRP/BTC', 'stoploss')
|
||||
trade.orders.append(o)
|
||||
return trade
|
||||
|
||||
|
||||
def mock_order_6():
|
||||
def mock_order_6(is_short: bool):
|
||||
return {
|
||||
'id': 'prod_buy_6',
|
||||
'id': f'prod_buy_{direc(is_short)}_6',
|
||||
'symbol': 'LTC/BTC',
|
||||
'status': 'closed',
|
||||
'side': 'buy',
|
||||
'side': enter_side(is_short),
|
||||
'type': 'limit',
|
||||
'price': 0.15,
|
||||
'amount': 2.0,
|
||||
@@ -265,23 +282,23 @@ def mock_order_6():
|
||||
}
|
||||
|
||||
|
||||
def mock_order_6_sell():
|
||||
def mock_order_6_sell(is_short: bool):
|
||||
return {
|
||||
'id': 'prod_sell_6',
|
||||
'id': f'prod_sell_{direc(is_short)}_6',
|
||||
'symbol': 'LTC/BTC',
|
||||
'status': 'open',
|
||||
'side': 'sell',
|
||||
'side': exit_side(is_short),
|
||||
'type': 'limit',
|
||||
'price': 0.20,
|
||||
'price': 0.15 if is_short else 0.20,
|
||||
'amount': 2.0,
|
||||
'filled': 0.0,
|
||||
'remaining': 2.0,
|
||||
}
|
||||
|
||||
|
||||
def mock_trade_6(fee):
|
||||
def mock_trade_6(fee, is_short: bool):
|
||||
"""
|
||||
Simulate prod entry with open sell order
|
||||
Simulate prod entry with open exit order
|
||||
"""
|
||||
trade = Trade(
|
||||
pair='LTC/BTC',
|
||||
@@ -295,12 +312,12 @@ def mock_trade_6(fee):
|
||||
open_rate=0.15,
|
||||
exchange='binance',
|
||||
strategy='SampleStrategy',
|
||||
open_order_id="prod_sell_6",
|
||||
open_order_id=f"prod_sell_{direc(is_short)}_6",
|
||||
timeframe=5,
|
||||
)
|
||||
o = Order.parse_from_ccxt_object(mock_order_6(), 'LTC/BTC', 'buy')
|
||||
o = Order.parse_from_ccxt_object(mock_order_6(is_short), 'LTC/BTC', enter_side(is_short))
|
||||
trade.orders.append(o)
|
||||
o = Order.parse_from_ccxt_object(mock_order_6_sell(), 'LTC/BTC', 'sell')
|
||||
o = Order.parse_from_ccxt_object(mock_order_6_sell(is_short), 'LTC/BTC', exit_side(is_short))
|
||||
trade.orders.append(o)
|
||||
return trade
|
||||
|
||||
|
||||
@@ -111,9 +111,10 @@ def test_load_backtest_data_multi(testdatadir):
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_persistence")
|
||||
def test_load_trades_from_db(default_conf, fee, mocker):
|
||||
@pytest.mark.parametrize('is_short', [False, True])
|
||||
def test_load_trades_from_db(default_conf, fee, is_short, mocker):
|
||||
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, is_short)
|
||||
# remove init so it does not init again
|
||||
init_mock = mocker.patch('freqtrade.data.btanalysis.init_db', MagicMock())
|
||||
|
||||
|
||||
@@ -3248,6 +3248,33 @@ def test_validate_trading_mode_and_collateral(
|
||||
exchange.validate_trading_mode_and_collateral(trading_mode, collateral)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("exchange_name,trading_mode,ccxt_config", [
|
||||
("binance", "spot", {}),
|
||||
("binance", "margin", {"options": {"defaultType": "margin"}}),
|
||||
("binance", "futures", {"options": {"defaultType": "future"}}),
|
||||
("kraken", "spot", {}),
|
||||
("kraken", "margin", {}),
|
||||
("kraken", "futures", {}),
|
||||
("ftx", "spot", {}),
|
||||
("ftx", "margin", {}),
|
||||
("ftx", "futures", {}),
|
||||
("bittrex", "spot", {}),
|
||||
("bittrex", "margin", {}),
|
||||
("bittrex", "futures", {}),
|
||||
])
|
||||
def test__ccxt_config(
|
||||
default_conf,
|
||||
mocker,
|
||||
exchange_name,
|
||||
trading_mode,
|
||||
ccxt_config
|
||||
):
|
||||
default_conf['trading_mode'] = trading_mode
|
||||
default_conf['collateral'] = 'isolated'
|
||||
exchange = get_patched_exchange(mocker, default_conf, id=exchange_name)
|
||||
assert exchange._ccxt_config == ccxt_config
|
||||
|
||||
|
||||
def test_get_mark_price():
|
||||
return
|
||||
|
||||
|
||||
@@ -164,6 +164,8 @@ def test_get_balances_prod(default_conf, mocker):
|
||||
ccxt_exceptionhandlers(mocker, default_conf, api_mock, "kraken",
|
||||
"get_balances", "fetch_balance")
|
||||
|
||||
# TODO-lev: All these stoploss tests with shorts
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ordertype', ['market', 'limit'])
|
||||
@pytest.mark.parametrize('side,adjustedprice', [
|
||||
|
||||
@@ -705,7 +705,7 @@ def test_simplified_interface_roi_stoploss(mocker, hyperopt_conf, capsys) -> Non
|
||||
assert hasattr(hyperopt, "position_stacking")
|
||||
|
||||
|
||||
def test_simplified_interface_all_failed(mocker, hyperopt_conf) -> None:
|
||||
def test_simplified_interface_all_failed(mocker, hyperopt_conf, caplog) -> None:
|
||||
mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
||||
mocker.patch('freqtrade.optimize.hyperopt.file_dump_json')
|
||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
||||
@@ -727,7 +727,13 @@ def test_simplified_interface_all_failed(mocker, hyperopt_conf) -> None:
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
with pytest.raises(OperationalException, match=r"The 'protection' space is included into *"):
|
||||
hyperopt.start()
|
||||
hyperopt.init_spaces()
|
||||
|
||||
hyperopt.config['hyperopt_ignore_missing_space'] = True
|
||||
caplog.clear()
|
||||
hyperopt.init_spaces()
|
||||
assert log_has_re(r"The 'protection' space is included into *", caplog)
|
||||
assert hyperopt.protection_space == []
|
||||
|
||||
|
||||
def test_simplified_interface_buy(mocker, hyperopt_conf, capsys) -> None:
|
||||
|
||||
@@ -415,10 +415,10 @@ def test_VolumePairList_refresh_empty(mocker, markets_empty, whitelist_conf):
|
||||
# SpreadFilter only
|
||||
([{"method": "SpreadFilter", "max_spread_ratio": 0.005}],
|
||||
"BTC", 'filter_at_the_beginning'), # OperationalException expected
|
||||
# Static Pairlist after VolumePairList, on a non-first position
|
||||
([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"},
|
||||
# Static Pairlist after VolumePairList, on a non-first position (appends pairs)
|
||||
([{"method": "VolumePairList", "number_assets": 2, "sort_key": "quoteVolume"},
|
||||
{"method": "StaticPairList"}],
|
||||
"BTC", 'static_in_the_middle'),
|
||||
"BTC", ['ETH/BTC', 'TKN/BTC', 'TRST/BTC', 'SWT/BTC', 'BCC/BTC', 'HOT/BTC']),
|
||||
([{"method": "VolumePairList", "number_assets": 20, "sort_key": "quoteVolume"},
|
||||
{"method": "PriceFilter", "low_price_ratio": 0.02}],
|
||||
"USDT", ['ETH/USDT', 'NANO/USDT']),
|
||||
@@ -469,13 +469,6 @@ def test_VolumePairList_whitelist_gen(mocker, whitelist_conf, shitcoinmarkets, t
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||
|
||||
if whitelist_result == 'static_in_the_middle':
|
||||
with pytest.raises(OperationalException,
|
||||
match=r"StaticPairList can only be used in the first position "
|
||||
r"in the list of Pairlist Handlers."):
|
||||
freqtrade = get_patched_freqtradebot(mocker, whitelist_conf)
|
||||
return
|
||||
|
||||
freqtrade = get_patched_freqtradebot(mocker, whitelist_conf)
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
get_tickers=tickers,
|
||||
@@ -665,11 +658,11 @@ def test_PerformanceFilter_error(mocker, whitelist_conf, caplog) -> None:
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_persistence")
|
||||
def test_PerformanceFilter_lookback(mocker, whitelist_conf, fee) -> None:
|
||||
def test_PerformanceFilter_lookback(mocker, whitelist_conf, fee, caplog) -> None:
|
||||
whitelist_conf['exchange']['pair_whitelist'].append('XRP/BTC')
|
||||
whitelist_conf['pairlists'] = [
|
||||
{"method": "StaticPairList"},
|
||||
{"method": "PerformanceFilter", "minutes": 60}
|
||||
{"method": "PerformanceFilter", "minutes": 60, "min_profit": 0.01}
|
||||
]
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||
exchange = get_patched_exchange(mocker, whitelist_conf)
|
||||
@@ -679,9 +672,10 @@ def test_PerformanceFilter_lookback(mocker, whitelist_conf, fee) -> None:
|
||||
assert pm.whitelist == ['ETH/BTC', 'TKN/BTC', 'XRP/BTC']
|
||||
|
||||
with time_machine.travel("2021-09-01 05:00:00 +00:00") as t:
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, False)
|
||||
pm.refresh_pairlist()
|
||||
assert pm.whitelist == ['XRP/BTC', 'ETH/BTC', 'TKN/BTC']
|
||||
assert pm.whitelist == ['XRP/BTC']
|
||||
assert log_has_re(r'Removing pair .* since .* is below .*', caplog)
|
||||
|
||||
# Move to "outside" of lookback window, so original sorting is restored.
|
||||
t.move_to("2021-09-01 07:00:00 +00:00")
|
||||
|
||||
@@ -289,7 +289,8 @@ def test_rpc_daily_profit(default_conf, update, ticker, fee,
|
||||
rpc._rpc_daily_profit(0, stake_currency, fiat_display_currency)
|
||||
|
||||
|
||||
def test_rpc_trade_history(mocker, default_conf, markets, fee):
|
||||
@pytest.mark.parametrize('is_short', [True, False])
|
||||
def test_rpc_trade_history(mocker, default_conf, markets, fee, is_short):
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
@@ -297,7 +298,7 @@ def test_rpc_trade_history(mocker, default_conf, markets, fee):
|
||||
)
|
||||
|
||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, is_short)
|
||||
rpc = RPC(freqtradebot)
|
||||
rpc._fiat_converter = CryptoToFiatConverter()
|
||||
trades = rpc._rpc_trade_history(2)
|
||||
@@ -314,7 +315,8 @@ def test_rpc_trade_history(mocker, default_conf, markets, fee):
|
||||
assert trades['trades'][0]['pair'] == 'XRP/BTC'
|
||||
|
||||
|
||||
def test_rpc_delete_trade(mocker, default_conf, fee, markets, caplog):
|
||||
@pytest.mark.parametrize('is_short', [True, False])
|
||||
def test_rpc_delete_trade(mocker, default_conf, fee, markets, caplog, is_short):
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
stoploss_mock = MagicMock()
|
||||
cancel_mock = MagicMock()
|
||||
@@ -327,7 +329,7 @@ def test_rpc_delete_trade(mocker, default_conf, fee, markets, caplog):
|
||||
|
||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||
freqtradebot.strategy.order_types['stoploss_on_exchange'] = True
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, is_short)
|
||||
rpc = RPC(freqtradebot)
|
||||
with pytest.raises(RPCException, match='invalid argument'):
|
||||
rpc._rpc_delete('200')
|
||||
|
||||
@@ -95,7 +95,7 @@ def test_api_not_found(botclient):
|
||||
assert rc.json() == {"detail": "Not Found"}
|
||||
|
||||
|
||||
def test_api_ui_fallback(botclient):
|
||||
def test_api_ui_fallback(botclient, mocker):
|
||||
ftbot, client = botclient
|
||||
|
||||
rc = client_get(client, "/favicon.ico")
|
||||
@@ -109,9 +109,16 @@ def test_api_ui_fallback(botclient):
|
||||
rc = client_get(client, "/something")
|
||||
assert rc.status_code == 200
|
||||
|
||||
# Test directory traversal
|
||||
# Test directory traversal without mock
|
||||
rc = client_get(client, '%2F%2F%2Fetc/passwd')
|
||||
assert rc.status_code == 200
|
||||
# Allow both fallback or real UI
|
||||
assert '`freqtrade install-ui`' in rc.text or '<!DOCTYPE html>' in rc.text
|
||||
|
||||
mocker.patch.object(Path, 'is_file', MagicMock(side_effect=[True, False]))
|
||||
rc = client_get(client, '%2F%2F%2Fetc/passwd')
|
||||
assert rc.status_code == 200
|
||||
|
||||
assert '`freqtrade install-ui`' in rc.text
|
||||
|
||||
|
||||
@@ -451,7 +458,8 @@ def test_api_balance(botclient, mocker, rpc_balance, tickers):
|
||||
assert 'starting_capital_ratio' in response
|
||||
|
||||
|
||||
def test_api_count(botclient, mocker, ticker, fee, markets):
|
||||
@pytest.mark.parametrize('is_short', [True, False])
|
||||
def test_api_count(botclient, mocker, ticker, fee, markets, is_short):
|
||||
ftbot, client = botclient
|
||||
patch_get_signal(ftbot)
|
||||
mocker.patch.multiple(
|
||||
@@ -468,7 +476,7 @@ def test_api_count(botclient, mocker, ticker, fee, markets):
|
||||
assert rc.json()["max"] == 1
|
||||
|
||||
# Create some test data
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, is_short)
|
||||
rc = client_get(client, f"{BASE_URI}/count")
|
||||
assert_response(rc)
|
||||
assert rc.json()["current"] == 4
|
||||
@@ -549,7 +557,8 @@ def test_api_daily(botclient, mocker, ticker, fee, markets):
|
||||
assert rc.json()['data'][0]['date'] == str(datetime.utcnow().date())
|
||||
|
||||
|
||||
def test_api_trades(botclient, mocker, fee, markets):
|
||||
@pytest.mark.parametrize('is_short', [True, False])
|
||||
def test_api_trades(botclient, mocker, fee, markets, is_short):
|
||||
ftbot, client = botclient
|
||||
patch_get_signal(ftbot)
|
||||
mocker.patch.multiple(
|
||||
@@ -562,7 +571,7 @@ def test_api_trades(botclient, mocker, fee, markets):
|
||||
assert rc.json()['trades_count'] == 0
|
||||
assert rc.json()['total_trades'] == 0
|
||||
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, is_short)
|
||||
Trade.query.session.flush()
|
||||
|
||||
rc = client_get(client, f"{BASE_URI}/trades")
|
||||
@@ -577,6 +586,7 @@ def test_api_trades(botclient, mocker, fee, markets):
|
||||
assert rc.json()['total_trades'] == 2
|
||||
|
||||
|
||||
# TODO-lev: @pytest.mark.parametrize('is_short', [True, False])
|
||||
def test_api_trade_single(botclient, mocker, fee, ticker, markets):
|
||||
ftbot, client = botclient
|
||||
patch_get_signal(ftbot)
|
||||
@@ -589,7 +599,7 @@ def test_api_trade_single(botclient, mocker, fee, ticker, markets):
|
||||
assert_response(rc, 404)
|
||||
assert rc.json()['detail'] == 'Trade not found.'
|
||||
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, False)
|
||||
Trade.query.session.flush()
|
||||
|
||||
rc = client_get(client, f"{BASE_URI}/trade/3")
|
||||
@@ -597,6 +607,7 @@ def test_api_trade_single(botclient, mocker, fee, ticker, markets):
|
||||
assert rc.json()['trade_id'] == 3
|
||||
|
||||
|
||||
# TODO-lev: @pytest.mark.parametrize('is_short', [True, False])
|
||||
def test_api_delete_trade(botclient, mocker, fee, markets):
|
||||
ftbot, client = botclient
|
||||
patch_get_signal(ftbot)
|
||||
@@ -612,11 +623,12 @@ def test_api_delete_trade(botclient, mocker, fee, markets):
|
||||
# Error - trade won't exist yet.
|
||||
assert_response(rc, 502)
|
||||
|
||||
create_mock_trades(fee)
|
||||
Trade.query.session.flush()
|
||||
create_mock_trades(fee, False)
|
||||
|
||||
ftbot.strategy.order_types['stoploss_on_exchange'] = True
|
||||
trades = Trade.query.all()
|
||||
trades[1].stoploss_order_id = '1234'
|
||||
Trade.commit()
|
||||
assert len(trades) > 2
|
||||
|
||||
rc = client_delete(client, f"{BASE_URI}/trades/1")
|
||||
@@ -686,7 +698,7 @@ def test_api_edge_disabled(botclient, mocker, ticker, fee, markets):
|
||||
assert rc.json() == {"error": "Error querying /api/v1/edge: Edge is not enabled."}
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_persistence")
|
||||
# TODO-lev: @pytest.mark.parametrize('is_short', [True, False])
|
||||
def test_api_profit(botclient, mocker, ticker, fee, markets):
|
||||
ftbot, client = botclient
|
||||
patch_get_signal(ftbot)
|
||||
@@ -702,7 +714,7 @@ def test_api_profit(botclient, mocker, ticker, fee, markets):
|
||||
assert_response(rc, 200)
|
||||
assert rc.json()['trade_count'] == 0
|
||||
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, False)
|
||||
# Simulate fulfilled LIMIT_BUY order for trade
|
||||
|
||||
rc = client_get(client, f"{BASE_URI}/profit")
|
||||
@@ -737,7 +749,7 @@ def test_api_profit(botclient, mocker, ticker, fee, markets):
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_persistence")
|
||||
# TODO-lev: @pytest.mark.parametrize('is_short', [True, False])
|
||||
def test_api_stats(botclient, mocker, ticker, fee, markets,):
|
||||
ftbot, client = botclient
|
||||
patch_get_signal(ftbot)
|
||||
@@ -754,7 +766,7 @@ def test_api_stats(botclient, mocker, ticker, fee, markets,):
|
||||
assert 'durations' in rc.json()
|
||||
assert 'sell_reasons' in rc.json()
|
||||
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, False)
|
||||
|
||||
rc = client_get(client, f"{BASE_URI}/stats")
|
||||
assert_response(rc, 200)
|
||||
@@ -803,7 +815,7 @@ def test_api_performance(botclient, fee):
|
||||
trade.close_profit_abs = trade.calc_profit()
|
||||
|
||||
Trade.query.session.add(trade)
|
||||
Trade.query.session.flush()
|
||||
Trade.commit()
|
||||
|
||||
rc = client_get(client, f"{BASE_URI}/performance")
|
||||
assert_response(rc)
|
||||
@@ -812,6 +824,10 @@ def test_api_performance(botclient, fee):
|
||||
{'count': 1, 'pair': 'XRP/ETH', 'profit': -5.57, 'profit_abs': -0.1150375}]
|
||||
|
||||
|
||||
# TODO-lev: @pytest.mark.parametrize('is_short,side', [
|
||||
# (True, "short"),
|
||||
# (False, "long")
|
||||
# ])
|
||||
def test_api_status(botclient, mocker, ticker, fee, markets):
|
||||
ftbot, client = botclient
|
||||
patch_get_signal(ftbot)
|
||||
@@ -827,7 +843,7 @@ def test_api_status(botclient, mocker, ticker, fee, markets):
|
||||
rc = client_get(client, f"{BASE_URI}/status")
|
||||
assert_response(rc, 200)
|
||||
assert rc.json() == []
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, False)
|
||||
|
||||
rc = client_get(client, f"{BASE_URI}/status")
|
||||
assert_response(rc)
|
||||
@@ -880,7 +896,7 @@ def test_api_status(botclient, mocker, ticker, fee, markets):
|
||||
'is_open': True,
|
||||
'max_rate': ANY,
|
||||
'min_rate': ANY,
|
||||
'open_order_id': 'dry_run_buy_12345',
|
||||
'open_order_id': 'dry_run_buy_long_12345',
|
||||
'open_rate_requested': ANY,
|
||||
'open_trade_value': 15.1668225,
|
||||
'sell_reason': None,
|
||||
|
||||
@@ -33,6 +33,7 @@ class DummyCls(Telegram):
|
||||
"""
|
||||
Dummy class for testing the Telegram @authorized_only decorator
|
||||
"""
|
||||
|
||||
def __init__(self, rpc: RPC, config) -> None:
|
||||
super().__init__(rpc, config)
|
||||
self.state = {'called': False}
|
||||
@@ -479,8 +480,9 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee,
|
||||
assert '*Best Performing:* `ETH/BTC: 6.20%`' in msg_mock.call_args_list[-1][0][0]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('is_short', [True, False])
|
||||
def test_telegram_stats(default_conf, update, ticker, ticker_sell_up, fee,
|
||||
limit_buy_order, limit_sell_order, mocker) -> None:
|
||||
limit_buy_order, limit_sell_order, mocker, is_short) -> None:
|
||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
@@ -496,7 +498,7 @@ def test_telegram_stats(default_conf, update, ticker, ticker_sell_up, fee,
|
||||
msg_mock.reset_mock()
|
||||
|
||||
# Create some test data
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, is_short)
|
||||
|
||||
telegram._stats(update=update, context=MagicMock())
|
||||
assert msg_mock.call_count == 1
|
||||
@@ -997,9 +999,9 @@ def test_count_handle(default_conf, update, ticker, fee, mocker) -> None:
|
||||
|
||||
msg = ('<pre> current max total stake\n--------- ----- -------------\n'
|
||||
' 1 {} {}</pre>').format(
|
||||
default_conf['max_open_trades'],
|
||||
default_conf['stake_amount']
|
||||
)
|
||||
default_conf['max_open_trades'],
|
||||
default_conf['stake_amount']
|
||||
)
|
||||
assert msg in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
|
||||
@@ -1159,6 +1161,7 @@ def test_edge_enabled(edge_conf, update, mocker) -> None:
|
||||
assert 'Winrate' not in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
|
||||
# TODO-lev: @pytest.mark.parametrize('is_short', [True, False])
|
||||
def test_telegram_trades(mocker, update, default_conf, fee):
|
||||
|
||||
telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
@@ -1177,7 +1180,7 @@ def test_telegram_trades(mocker, update, default_conf, fee):
|
||||
assert "<pre>" not in msg_mock.call_args_list[0][0][0]
|
||||
msg_mock.reset_mock()
|
||||
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, False)
|
||||
|
||||
context = MagicMock()
|
||||
context.args = [5]
|
||||
@@ -1191,6 +1194,7 @@ def test_telegram_trades(mocker, update, default_conf, fee):
|
||||
msg_mock.call_args_list[0][0][0]))
|
||||
|
||||
|
||||
# TODO-lev: @pytest.mark.parametrize('is_short', [True, False])
|
||||
def test_telegram_delete_trade(mocker, update, default_conf, fee):
|
||||
|
||||
telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
@@ -1201,7 +1205,7 @@ def test_telegram_delete_trade(mocker, update, default_conf, fee):
|
||||
assert "Trade-id not set." in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
msg_mock.reset_mock()
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, False)
|
||||
|
||||
context = MagicMock()
|
||||
context.args = [1]
|
||||
|
||||
@@ -47,8 +47,8 @@ def test_returns_latest_signal(ohlcv_history):
|
||||
mocked_history.loc[1, 'exit_long'] = 0
|
||||
mocked_history.loc[1, 'enter_long'] = 1
|
||||
|
||||
assert _STRATEGY.get_entry_signal('ETH/BTC', '5m', mocked_history
|
||||
) == (SignalDirection.LONG, None)
|
||||
assert _STRATEGY.get_entry_signal(
|
||||
'ETH/BTC', '5m', mocked_history) == (SignalDirection.LONG, None)
|
||||
assert _STRATEGY.get_exit_signal('ETH/BTC', '5m', mocked_history) == (True, False)
|
||||
assert _STRATEGY.get_exit_signal('ETH/BTC', '5m', mocked_history, True) == (False, False)
|
||||
mocked_history.loc[1, 'exit_long'] = 0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1514,11 +1514,12 @@ def test_adjust_min_max_rates(fee):
|
||||
|
||||
@pytest.mark.usefixtures("init_persistence")
|
||||
@pytest.mark.parametrize('use_db', [True, False])
|
||||
def test_get_open(fee, use_db):
|
||||
@pytest.mark.parametrize('is_short', [True, False])
|
||||
def test_get_open(fee, is_short, use_db):
|
||||
Trade.use_db = use_db
|
||||
Trade.reset_trades()
|
||||
|
||||
create_mock_trades(fee, use_db)
|
||||
create_mock_trades(fee, is_short, use_db)
|
||||
assert len(Trade.get_open_trades()) == 4
|
||||
|
||||
Trade.use_db = True
|
||||
@@ -1874,14 +1875,15 @@ def test_fee_updated(fee):
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_persistence")
|
||||
@pytest.mark.parametrize('is_short', [True, False])
|
||||
@pytest.mark.parametrize('use_db', [True, False])
|
||||
def test_total_open_trades_stakes(fee, use_db):
|
||||
def test_total_open_trades_stakes(fee, is_short, use_db):
|
||||
|
||||
Trade.use_db = use_db
|
||||
Trade.reset_trades()
|
||||
res = Trade.total_open_trades_stakes()
|
||||
assert res == 0
|
||||
create_mock_trades(fee, use_db)
|
||||
create_mock_trades(fee, is_short, use_db)
|
||||
res = Trade.total_open_trades_stakes()
|
||||
assert res == 0.004
|
||||
|
||||
@@ -1889,6 +1891,7 @@ def test_total_open_trades_stakes(fee, use_db):
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_persistence")
|
||||
# TODO-lev: @pytest.mark.parametrize('is_short', [True, False])
|
||||
@pytest.mark.parametrize('use_db', [True, False])
|
||||
def test_get_total_closed_profit(fee, use_db):
|
||||
|
||||
@@ -1896,7 +1899,7 @@ def test_get_total_closed_profit(fee, use_db):
|
||||
Trade.reset_trades()
|
||||
res = Trade.get_total_closed_profit()
|
||||
assert res == 0
|
||||
create_mock_trades(fee, use_db)
|
||||
create_mock_trades(fee, False, use_db)
|
||||
res = Trade.get_total_closed_profit()
|
||||
assert res == 0.000739127
|
||||
|
||||
@@ -1904,11 +1907,12 @@ def test_get_total_closed_profit(fee, use_db):
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_persistence")
|
||||
# TODO-lev: @pytest.mark.parametrize('is_short', [True, False])
|
||||
@pytest.mark.parametrize('use_db', [True, False])
|
||||
def test_get_trades_proxy(fee, use_db):
|
||||
Trade.use_db = use_db
|
||||
Trade.reset_trades()
|
||||
create_mock_trades(fee, use_db)
|
||||
create_mock_trades(fee, False, use_db)
|
||||
trades = Trade.get_trades_proxy()
|
||||
assert len(trades) == 6
|
||||
|
||||
@@ -1937,9 +1941,10 @@ def test_get_trades_backtest():
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_persistence")
|
||||
# @pytest.mark.parametrize('is_short', [True, False])
|
||||
def test_get_overall_performance(fee):
|
||||
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, False)
|
||||
res = Trade.get_overall_performance()
|
||||
|
||||
assert len(res) == 2
|
||||
@@ -1949,12 +1954,13 @@ def test_get_overall_performance(fee):
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_persistence")
|
||||
# TODO-lev: @pytest.mark.parametrize('is_short', [True, False])
|
||||
def test_get_best_pair(fee):
|
||||
|
||||
res = Trade.get_best_pair()
|
||||
assert res is None
|
||||
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, False)
|
||||
res = Trade.get_best_pair()
|
||||
assert len(res) == 2
|
||||
assert res[0] == 'XRP/BTC'
|
||||
@@ -2036,8 +2042,9 @@ def test_update_order_from_ccxt(caplog):
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_persistence")
|
||||
# TODO-lev: @pytest.mark.parametrize('is_short', [True, False])
|
||||
def test_select_order(fee):
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, False)
|
||||
|
||||
trades = Trade.get_trades().all()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user