Skip to content

Commit 134e5c6

Browse files
committed
[Orders] handle MissingMinimalExchangeTradeVolume
1 parent ed3cda5 commit 134e5c6

File tree

3 files changed

+63
-43
lines changed

3 files changed

+63
-43
lines changed

octobot_trading/exchanges/traders/trader.py

Lines changed: 52 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -489,17 +489,22 @@ async def _sell_everything(self, symbol, inverted, timeout=None):
489489
quantity = 0
490490
else:
491491
quantity = current_symbol_holding
492-
for order_quantity, order_price in decimal_order_adapter.decimal_check_and_adapt_order_details_if_necessary(
493-
quantity, price,
494-
symbol_market):
495-
current_order = order_factory.create_order_instance(trader=self,
496-
order_type=order_type,
497-
symbol=symbol,
498-
current_price=order_price,
499-
quantity=order_quantity,
500-
price=order_price)
501-
created_orders.append(
502-
await self.create_order(current_order))
492+
try:
493+
for order_quantity, order_price in decimal_order_adapter.decimal_check_and_adapt_order_details_if_necessary(
494+
quantity, price,
495+
symbol_market):
496+
current_order = order_factory.create_order_instance(trader=self,
497+
order_type=order_type,
498+
symbol=symbol,
499+
current_price=order_price,
500+
quantity=order_quantity,
501+
price=order_price)
502+
created_orders.append(
503+
await self.create_order(current_order))
504+
except errors.MissingMinimalExchangeTradeVolume as error:
505+
self.logger.exception(
506+
error, True,
507+
f"Failed to sell everything - error: {error}")
503508
return created_orders
504509

505510
async def sell_all(self, currencies_to_sell=None, timeout=None):
@@ -559,35 +564,42 @@ async def close_position(self, position, limit_price=None, timeout=1, emit_tradi
559564
_, _, _, price, symbol_market = await order_util.get_pre_order_data(self.exchange_manager,
560565
position.symbol,
561566
timeout=timeout)
562-
for order_quantity, order_price in decimal_order_adapter.decimal_check_and_adapt_order_details_if_necessary(
563-
position.get_quantity_to_close().copy_abs(), price, symbol_market):
564-
565-
if limit_price is not None:
566-
order_type = enums.TraderOrderType.SELL_LIMIT \
567-
if position.is_long() else enums.TraderOrderType.BUY_LIMIT
568-
else:
569-
order_type = enums.TraderOrderType.SELL_MARKET \
570-
if position.is_long() else enums.TraderOrderType.BUY_MARKET
571-
572-
current_order = order_factory.create_order_instance(trader=self,
573-
order_type=order_type,
574-
symbol=position.symbol,
575-
current_price=order_price,
576-
quantity=order_quantity,
577-
price=limit_price
578-
if limit_price is not None else order_price,
579-
reduce_only=True,
580-
close_position=True)
581-
async with signals.remote_signal_publisher(self.exchange_manager, current_order.symbol,
582-
emit_trading_signals):
583-
order = await signals.create_order(
584-
self.exchange_manager,
585-
emit_trading_signals and signals.should_emit_trading_signal(self.exchange_manager),
586-
current_order,
587-
wait_for_creation=wait_for_creation,
588-
creation_timeout=creation_timeout
589-
)
590-
created_orders.append(order)
567+
try:
568+
for order_quantity, order_price in decimal_order_adapter.decimal_check_and_adapt_order_details_if_necessary(
569+
position.get_quantity_to_close().copy_abs(), price, symbol_market):
570+
571+
if limit_price is not None:
572+
order_type = enums.TraderOrderType.SELL_LIMIT \
573+
if position.is_long() else enums.TraderOrderType.BUY_LIMIT
574+
else:
575+
order_type = enums.TraderOrderType.SELL_MARKET \
576+
if position.is_long() else enums.TraderOrderType.BUY_MARKET
577+
578+
current_order = order_factory.create_order_instance(trader=self,
579+
order_type=order_type,
580+
symbol=position.symbol,
581+
current_price=order_price,
582+
quantity=order_quantity,
583+
price=limit_price
584+
if limit_price is not None else order_price,
585+
reduce_only=True,
586+
close_position=True)
587+
async with signals.remote_signal_publisher(self.exchange_manager, current_order.symbol,
588+
emit_trading_signals):
589+
order = await signals.create_order(
590+
self.exchange_manager,
591+
emit_trading_signals and signals.should_emit_trading_signal(self.exchange_manager),
592+
current_order,
593+
wait_for_creation=wait_for_creation,
594+
creation_timeout=creation_timeout
595+
)
596+
created_orders.append(order)
597+
except errors.MissingMinimalExchangeTradeVolume as error:
598+
# this error should never happen as you are
599+
# able to always close a position
600+
self.logger.exception(
601+
error, True,
602+
f"Failed close position - error: {error}")
591603
return created_orders
592604

593605
async def withdraw(self, amount, currency):

octobot_trading/personal_data/orders/decimal_order_adapter.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,11 @@ def decimal_check_and_adapt_order_details_if_necessary(quantity, price, symbol_m
188188

189189
# check total_order_price not < min_cost
190190
if not personal_data.check_cost(float(total_order_price), min_cost):
191-
return []
191+
symbol = f"{symbol_market['symbol']} - " if 'symbol' in symbol_market else ""
192+
raise errors.MissingMinimalExchangeTradeVolume(
193+
f"Order value ({symbol}value: "
194+
f"{total_order_price}) must be at least {min_cost} to open a order "
195+
)
192196

193197
# check total_order_price not > max_cost and valid_quantity not > max_quantity
194198
elif (max_cost is not None and total_order_price > max_cost) or \

tests/personal_data/orders/test_decimal_order_adapter.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from octobot_trading.enums import ExchangeConstantsMarketStatusColumns as Ecmsc
2121
import octobot_trading.personal_data as personal_data
2222
import octobot_trading.constants as constants
23+
import octobot_trading.errors as errors
2324
from tests import event_loop
2425

2526
# All test coroutines will be treated as marked.
@@ -170,8 +171,11 @@ async def test_decimal_check_and_adapt_order_details_if_necessary():
170171
# invalid cost <
171172
quantity = decimal.Decimal(str(0.5))
172173
price = decimal.Decimal(str(1))
173-
assert personal_data.decimal_check_and_adapt_order_details_if_necessary(quantity, price, symbol_market) == []
174-
174+
try:
175+
personal_data.decimal_check_and_adapt_order_details_if_necessary(quantity, price, symbol_market)
176+
assert False
177+
except errors.MissingMinimalExchangeTradeVolume:
178+
assert True
175179
# invalid cost >
176180
quantity = decimal.Decimal(str(10))
177181
price = decimal.Decimal(str(49))

0 commit comments

Comments
 (0)