Merge branch 'freqtrade:develop' into develop

This commit is contained in:
hippocritical 2023-03-24 22:37:21 +01:00 committed by GitHub
commit efefcb240b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 36 additions and 36 deletions

View File

@ -1135,7 +1135,11 @@ class Exchange:
"sell" else (stop_price >= limit_rate)) "sell" else (stop_price >= limit_rate))
# Ensure rate is less than stop price # Ensure rate is less than stop price
if bad_stop_price: if bad_stop_price:
raise OperationalException( # This can for example happen if the stop / liquidation price is set to 0
# Which is possible if a market-order closes right away.
# The InvalidOrderException will bubble up to exit_positions, where it will be
# handled gracefully.
raise InvalidOrderException(
"In stoploss limit order, stop price should be more than limit price. " "In stoploss limit order, stop price should be more than limit price. "
f"Stop price: {stop_price}, Limit price: {limit_rate}, " f"Stop price: {stop_price}, Limit price: {limit_rate}, "
f"Limit Price pct: {limit_price_pct}" f"Limit Price pct: {limit_price_pct}"

View File

@ -594,7 +594,7 @@ class FreqtradeBot(LoggingMixin):
stake_available = self.wallets.get_available_stake_amount() stake_available = self.wallets.get_available_stake_amount()
logger.debug(f"Calling adjust_trade_position for pair {trade.pair}") logger.debug(f"Calling adjust_trade_position for pair {trade.pair}")
stake_amount = strategy_safe_wrapper(self.strategy.adjust_trade_position, stake_amount = strategy_safe_wrapper(self.strategy.adjust_trade_position,
default_retval=None)( default_retval=None, supress_error=True)(
trade=trade, trade=trade,
current_time=datetime.now(timezone.utc), current_rate=current_entry_rate, current_time=datetime.now(timezone.utc), current_rate=current_entry_rate,
current_profit=current_entry_profit, min_stake=min_entry_stake, current_profit=current_entry_profit, min_stake=min_entry_stake,
@ -810,6 +810,9 @@ class FreqtradeBot(LoggingMixin):
precision_mode=self.exchange.precisionMode, precision_mode=self.exchange.precisionMode,
contract_size=self.exchange.get_contract_size(pair), contract_size=self.exchange.get_contract_size(pair),
) )
stoploss = self.strategy.stoploss if not self.edge else self.edge.get_stoploss(pair)
trade.adjust_stop_loss(trade.open_rate, stoploss, initial=True)
else: else:
# This is additional buy, we reset fee_open_currency so timeout checking can work # This is additional buy, we reset fee_open_currency so timeout checking can work
trade.is_open = True trade.is_open = True
@ -1021,12 +1024,16 @@ class FreqtradeBot(LoggingMixin):
trades_closed = 0 trades_closed = 0
for trade in trades: for trade in trades:
try: try:
try:
if (self.strategy.order_types.get('stoploss_on_exchange') and if (self.strategy.order_types.get('stoploss_on_exchange') and
self.handle_stoploss_on_exchange(trade)): self.handle_stoploss_on_exchange(trade)):
trades_closed += 1 trades_closed += 1
Trade.commit() Trade.commit()
continue continue
except InvalidOrderException as exception:
logger.warning(
f'Unable to handle stoploss on exchange for {trade.pair}: {exception}')
# Check if we can sell our current pair # Check if we can sell our current pair
if trade.open_order_id is None and trade.is_open and self.handle_trade(trade): if trade.open_order_id is None and trade.is_open and self.handle_trade(trade):
trades_closed += 1 trades_closed += 1

View File

@ -522,7 +522,7 @@ class Backtesting:
max_stake = self.exchange.get_max_pair_stake_amount(trade.pair, current_rate) max_stake = self.exchange.get_max_pair_stake_amount(trade.pair, current_rate)
stake_available = self.wallets.get_available_stake_amount() stake_available = self.wallets.get_available_stake_amount()
stake_amount = strategy_safe_wrapper(self.strategy.adjust_trade_position, stake_amount = strategy_safe_wrapper(self.strategy.adjust_trade_position,
default_retval=None)( default_retval=None, supress_error=True)(
trade=trade, # type: ignore[arg-type] trade=trade, # type: ignore[arg-type]
current_time=current_date, current_rate=current_rate, current_time=current_date, current_rate=current_rate,
current_profit=current_profit, min_stake=min_stake, current_profit=current_profit, min_stake=min_stake,

View File

@ -52,7 +52,7 @@ def test_create_stoploss_order_binance(default_conf, mocker, limitratio, expecte
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance')
with pytest.raises(OperationalException): with pytest.raises(InvalidOrderException):
order = exchange.create_stoploss( order = exchange.create_stoploss(
pair='ETH/BTC', pair='ETH/BTC',
amount=1, amount=1,
@ -131,7 +131,7 @@ def test_create_stoploss_order_dry_run_binance(default_conf, mocker):
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance')
with pytest.raises(OperationalException): with pytest.raises(InvalidOrderException):
order = exchange.create_stoploss( order = exchange.create_stoploss(
pair='ETH/BTC', pair='ETH/BTC',
amount=1, amount=1,

View File

@ -4,7 +4,7 @@ from unittest.mock import MagicMock
import ccxt import ccxt
import pytest import pytest
from freqtrade.exceptions import DependencyException, InvalidOrderException, OperationalException from freqtrade.exceptions import DependencyException, InvalidOrderException
from tests.conftest import EXMS, get_patched_exchange from tests.conftest import EXMS, get_patched_exchange
from tests.exchange.test_exchange import ccxt_exceptionhandlers from tests.exchange.test_exchange import ccxt_exceptionhandlers
@ -31,7 +31,7 @@ def test_create_stoploss_order_huobi(default_conf, mocker, limitratio, expected,
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'huobi') exchange = get_patched_exchange(mocker, default_conf, api_mock, 'huobi')
with pytest.raises(OperationalException): with pytest.raises(InvalidOrderException):
order = exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=190, order = exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=190,
order_types={'stoploss_on_exchange_limit_ratio': 1.05}, order_types={'stoploss_on_exchange_limit_ratio': 1.05},
side=side, side=side,
@ -84,7 +84,7 @@ def test_create_stoploss_order_dry_run_huobi(default_conf, mocker):
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'huobi') exchange = get_patched_exchange(mocker, default_conf, api_mock, 'huobi')
with pytest.raises(OperationalException): with pytest.raises(InvalidOrderException):
order = exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=190, order = exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=190,
order_types={'stoploss_on_exchange_limit_ratio': 1.05}, order_types={'stoploss_on_exchange_limit_ratio': 1.05},
side='sell', leverage=1.0) side='sell', leverage=1.0)

View File

@ -4,7 +4,7 @@ from unittest.mock import MagicMock
import ccxt import ccxt
import pytest import pytest
from freqtrade.exceptions import DependencyException, InvalidOrderException, OperationalException from freqtrade.exceptions import DependencyException, InvalidOrderException
from tests.conftest import EXMS, get_patched_exchange from tests.conftest import EXMS, get_patched_exchange
from tests.exchange.test_exchange import ccxt_exceptionhandlers from tests.exchange.test_exchange import ccxt_exceptionhandlers
@ -31,7 +31,7 @@ def test_create_stoploss_order_kucoin(default_conf, mocker, limitratio, expected
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kucoin') exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kucoin')
if order_type == 'limit': if order_type == 'limit':
with pytest.raises(OperationalException): with pytest.raises(InvalidOrderException):
order = exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=190, order = exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=190,
order_types={ order_types={
'stoploss': order_type, 'stoploss': order_type,
@ -92,7 +92,7 @@ def test_stoploss_order_dry_run_kucoin(default_conf, mocker):
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kucoin') exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kucoin')
with pytest.raises(OperationalException): with pytest.raises(InvalidOrderException):
order = exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=190, order = exchange.create_stoploss(pair='ETH/BTC', amount=1, stop_price=190,
order_types={'stoploss': 'limit', order_types={'stoploss': 'limit',
'stoploss_on_exchange_limit_ratio': 1.05}, 'stoploss_on_exchange_limit_ratio': 1.05},

View File

@ -125,17 +125,6 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
'profit_pct': 0.0, 'profit_pct': 0.0,
'profit_abs': 0.0, 'profit_abs': 0.0,
'total_profit_abs': 0.0, 'total_profit_abs': 0.0,
'stop_loss_abs': 0.0,
'stop_loss_pct': None,
'stop_loss_ratio': None,
'stoploss_current_dist': -1.099e-05,
'stoploss_current_dist_ratio': -1.0,
'stoploss_current_dist_pct': pytest.approx(-100.0),
'stoploss_entry_dist': -0.0010025,
'stoploss_entry_dist_ratio': -1.0,
'initial_stop_loss_abs': 0.0,
'initial_stop_loss_pct': None,
'initial_stop_loss_ratio': None,
'open_order': '(limit buy rem=91.07468123)', 'open_order': '(limit buy rem=91.07468123)',
}) })
response_unfilled['orders'][0].update({ response_unfilled['orders'][0].update({

View File

@ -386,12 +386,12 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker)
assert trade.open_order_id is not None assert trade.open_order_id is not None
assert pytest.approx(trade.stake_amount) == 60 assert pytest.approx(trade.stake_amount) == 60
assert trade.open_rate == 1.96 assert trade.open_rate == 1.96
assert trade.stop_loss_pct is None assert trade.stop_loss_pct == -0.1
assert trade.stop_loss == 0.0 assert pytest.approx(trade.stop_loss) == trade.open_rate * (1 - 0.1 / leverage)
assert pytest.approx(trade.initial_stop_loss) == trade.open_rate * (1 - 0.1 / leverage)
assert trade.initial_stop_loss_pct == -0.1
assert trade.leverage == leverage assert trade.leverage == leverage
assert trade.stake_amount == 60 assert trade.stake_amount == 60
assert trade.initial_stop_loss == 0.0
assert trade.initial_stop_loss_pct is None
# No adjustment # No adjustment
freqtrade.process() freqtrade.process()
trade = Trade.get_trades().first() trade = Trade.get_trades().first()
@ -407,11 +407,11 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker)
assert trade.open_order_id is not None assert trade.open_order_id is not None
# Open rate is not adjusted yet # Open rate is not adjusted yet
assert trade.open_rate == 1.96 assert trade.open_rate == 1.96
assert trade.stop_loss_pct is None assert trade.stop_loss_pct == -0.1
assert trade.stop_loss == 0.0 assert pytest.approx(trade.stop_loss) == trade.open_rate * (1 - 0.1 / leverage)
assert pytest.approx(trade.initial_stop_loss) == trade.open_rate * (1 - 0.1 / leverage)
assert trade.stake_amount == 60 assert trade.stake_amount == 60
assert trade.initial_stop_loss == 0.0 assert trade.initial_stop_loss_pct == -0.1
assert trade.initial_stop_loss_pct is None
# Fill order # Fill order
mocker.patch(f'{EXMS}._dry_is_price_crossed', return_value=True) mocker.patch(f'{EXMS}._dry_is_price_crossed', return_value=True)
@ -424,7 +424,7 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker)
assert pytest.approx(trade.stake_amount) == 60 assert pytest.approx(trade.stake_amount) == 60
assert trade.stop_loss_pct == -0.1 assert trade.stop_loss_pct == -0.1
assert pytest.approx(trade.stop_loss) == 1.99 * (1 - 0.1 / leverage) assert pytest.approx(trade.stop_loss) == 1.99 * (1 - 0.1 / leverage)
assert pytest.approx(trade.initial_stop_loss) == 1.99 * (1 - 0.1 / leverage) assert pytest.approx(trade.initial_stop_loss) == 1.96 * (1 - 0.1 / leverage)
assert trade.initial_stop_loss_pct == -0.1 assert trade.initial_stop_loss_pct == -0.1
# 2nd order - not filling # 2nd order - not filling