Convert limit orders to market orders if they cross a threshold

closes #7786
This commit is contained in:
Matthias
2023-02-16 20:20:06 +01:00
parent 9600039686
commit 22700527ac
2 changed files with 31 additions and 13 deletions

View File

@@ -850,7 +850,7 @@ class Exchange:
'remaining': _amount,
'datetime': arrow.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
'timestamp': arrow.utcnow().int_timestamp * 1000,
'status': "closed" if ordertype == "market" and not stop_loss else "open",
'status': "open",
'fee': None,
'info': {},
'leverage': leverage
@@ -863,6 +863,14 @@ class Exchange:
orderbook: Optional[OrderBook] = None
if self.exchange_has('fetchL2OrderBook'):
orderbook = self.fetch_l2_order_book(pair, 20)
if ordertype == "limit" and orderbook:
# Allow a 3% price difference
allowed_diff = 0.03
if self._dry_is_price_crossed(pair, side, rate, orderbook, allowed_diff):
logger.info(
f"Converted order {pair} to market order due to price {rate} crossing spread "
f"by more than {allowed_diff:.2%}.")
dry_order["type"] = "market"
if dry_order["type"] == "market" and not dry_order.get("ft_order_type"):
# Update market order pricing
@@ -871,6 +879,7 @@ class Exchange:
'average': average,
'filled': _amount,
'remaining': 0.0,
'status': "closed",
'cost': (dry_order['amount'] * average) / leverage
})
# market orders will always incurr taker fees
@@ -943,7 +952,7 @@ class Exchange:
return rate
def _dry_is_price_crossed(self, pair: str, side: str, limit: float,
orderbook: Optional[OrderBook] = None) -> bool:
orderbook: Optional[OrderBook] = None, offset: float = 0.0) -> bool:
if not self.exchange_has('fetchL2OrderBook'):
return True
if not orderbook:
@@ -951,11 +960,11 @@ class Exchange:
try:
if side == 'buy':
price = orderbook['asks'][0][0]
if limit >= price:
if limit * (1 - offset) >= price:
return True
else:
price = orderbook['bids'][0][0]
if limit <= price:
if limit * (1 + offset) <= price:
return True
except IndexError:
# Ignore empty orderbooks when filling - can be filled with the next iteration.