def _get_stop_loss_price(self, symbol_market, starting_price, now_selling): if now_selling: return trading_personal_data.adapt_price( symbol_market, starting_price * (1 - self.STOP_LOSS_DELTA_FROM_OWN_PRICE)) return trading_personal_data.adapt_price( symbol_market, starting_price * (1 + self.STOP_LOSS_DELTA_FROM_OWN_PRICE))
async def create_buy_order(self, symbol, timeout, volume_weight, price_weight): current_order = None try: current_symbol_holding, current_market_holding, market_quantity, price, symbol_market = \ await trading_personal_data.get_pre_order_data(self.exchange_manager, symbol=symbol, timeout=timeout) base, _ = symbol_util.split_symbol(symbol) created_orders = [] quantity = await self._get_buy_quantity_from_weight(volume_weight, market_quantity, base) limit_price = trading_personal_data.adapt_price(symbol_market, self.get_limit_price(price)) for order_quantity, order_price in trading_personal_data.check_and_adapt_order_details_if_necessary( quantity, limit_price, symbol_market): current_order = trading_personal_data.create_order_instance(trader=self.exchange_manager.trader, order_type=trading_enums.TraderOrderType.BUY_LIMIT, symbol=symbol, current_price=price, quantity=order_quantity, price=order_price) created_order = await self.exchange_manager.trader.create_order(current_order) created_orders.append(created_order) self._register_buy_order(created_order.order_id, price_weight) if created_orders: return created_orders raise trading_errors.MissingMinimalExchangeTradeVolume() except (trading_errors.MissingFunds, trading_errors.MissingMinimalExchangeTradeVolume): raise except Exception as e: self.logger.error(f"Failed to create order : {e}. Order: " f"{current_order.get_string_info() if current_order else None}") self.logger.exception(e, False) return []
async def create_new_orders(self, symbol, final_note, state, **kwargs): current_order = None try: base, market = symbol_util.split_symbol(symbol) if market != self.exchange_manager.exchange_personal_data.portfolio_manager.reference_market: self.logger.warning(f"Ignored DCA order creation on {symbol} : it's not a reference market pair.") return [] current_symbol_holding, current_market_holding, market_quantity, price, symbol_market = \ await trading_personal_data.get_pre_order_data(self.exchange_manager, symbol=symbol, timeout=trading_constants.ORDER_DATA_FETCHING_TIMEOUT) created_orders = [] quantity = self.order_quantity_of_ref_market / price limit_price = trading_personal_data.adapt_price(symbol_market, price * (1 - self.ORDER_PRICE_DISTANCE)) for order_quantity, order_price in trading_personal_data.check_and_adapt_order_details_if_necessary( quantity, limit_price, symbol_market): current_order = trading_personal_data.create_order_instance(trader=self.exchange_manager.trader, order_type=trading_enums.TraderOrderType.BUY_LIMIT, symbol=symbol, current_price=price, quantity=order_quantity, price=order_price) created_order = await self.exchange_manager.trader.create_order(current_order) created_orders.append(created_order) if created_orders: return created_orders raise trading_errors.MissingMinimalExchangeTradeVolume() except (trading_errors.MissingFunds, trading_errors.MissingMinimalExchangeTradeVolume): raise except Exception as e: self.logger.error(f"Failed to create order : {e}. Order: " f"{current_order if current_order else None}") self.logger.exception(e, False) return []
async def create_new_orders(self, symbol, final_note, state, **kwargs): current_order = None timeout = kwargs.pop("timeout", trading_constants.ORDER_DATA_FETCHING_TIMEOUT) try: current_symbol_holding, current_market_holding, market_quantity, price, symbol_market = \ await trading_personal_data.get_pre_order_data(self.exchange_manager, symbol=symbol, timeout=timeout) quote, _ = symbol_util.split_symbol(symbol) created_orders = [] if state == trading_enums.EvaluatorStates.VERY_SHORT.value and not self.DISABLE_SELL_ORDERS: quantity = self._get_market_quantity_from_risk( final_note, current_symbol_holding, quote, True) quantity = trading_personal_data.add_dusts_to_quantity_if_necessary( quantity, price, symbol_market, current_symbol_holding) for order_quantity, order_price in self._check_and_adapt_order_details_if_necessary( quantity, price, symbol_market): current_order = trading_personal_data.create_order_instance( trader=self.trader, order_type=trading_enums.TraderOrderType.SELL_MARKET, symbol=symbol, current_price=float(order_price), quantity=float(order_quantity), price=float(order_price)) await self.trader.create_order(current_order) created_orders.append(current_order) elif state == trading_enums.EvaluatorStates.SHORT.value and not self.DISABLE_SELL_ORDERS: quantity = await self._get_sell_limit_quantity_from_risk( final_note, current_symbol_holding, quote) quantity = trading_personal_data.add_dusts_to_quantity_if_necessary( quantity, price, symbol_market, current_symbol_holding) limit_price = trading_personal_data.adapt_price( symbol_market, price * self._get_limit_price_from_risk(final_note)) for order_quantity, order_price in self._check_and_adapt_order_details_if_necessary( quantity, limit_price, symbol_market): current_order = trading_personal_data.create_order_instance( trader=self.trader, order_type=trading_enums.TraderOrderType.SELL_LIMIT, symbol=symbol, current_price=price, quantity=float(order_quantity), price=float(order_price)) updated_limit = await self.trader.create_order( current_order) created_orders.append(updated_limit) if self.USE_STOP_ORDERS: stop_price = trading_personal_data.adapt_price( symbol_market, price * self._get_stop_price_from_risk()) current_order = trading_personal_data.create_order_instance( trader=self.trader, order_type=trading_enums.TraderOrderType.STOP_LOSS, symbol=symbol, current_price=price, quantity=float(order_quantity), price=stop_price, linked_to=updated_limit) await self.trader.create_order(current_order) elif state == trading_enums.EvaluatorStates.NEUTRAL.value: return [] # TODO : stop loss elif state == trading_enums.EvaluatorStates.LONG.value and not self.DISABLE_BUY_ORDERS: quantity = self._get_buy_limit_quantity_from_risk( final_note, market_quantity, quote) quantity = quantity * await self._get_quantity_ratio(quote) limit_price = trading_personal_data.adapt_price( symbol_market, price * self._get_limit_price_from_risk(final_note)) for order_quantity, order_price in self._check_and_adapt_order_details_if_necessary( quantity, limit_price, symbol_market): current_order = trading_personal_data.create_order_instance( trader=self.trader, order_type=trading_enums.TraderOrderType.BUY_LIMIT, symbol=symbol, current_price=price, quantity=float(order_quantity), price=float(order_price)) await self.trader.create_order(current_order) created_orders.append(current_order) elif state == trading_enums.EvaluatorStates.VERY_LONG.value and not self.DISABLE_BUY_ORDERS: quantity = self._get_market_quantity_from_risk( final_note, market_quantity, quote) quantity = quantity * await self._get_quantity_ratio(quote) for order_quantity, order_price in self._check_and_adapt_order_details_if_necessary( quantity, price, symbol_market): current_order = trading_personal_data.create_order_instance( trader=self.trader, order_type=trading_enums.TraderOrderType.BUY_MARKET, symbol=symbol, current_price=float(order_price), quantity=float(order_quantity), price=float(order_price)) await self.trader.create_order(current_order) created_orders.append(current_order) if created_orders: return created_orders raise trading_errors.MissingMinimalExchangeTradeVolume() except (trading_errors.MissingFunds, trading_errors.MissingMinimalExchangeTradeVolume): raise except asyncio.TimeoutError as e: self.logger.error( f"Impossible to create order for {symbol} on {self.exchange_manager.exchange_name}: {e} " f"and is necessary to compute the order details.") return [] except Exception as e: self.logger.exception(e, True, f"Failed to create order : {e}.") return []
async def test_adapt_price(): # will use symbol market symbol_market = {Ecmsc.PRECISION.value: {Ecmsc.PRECISION_PRICE.value: 4}} assert personal_data.adapt_price(symbol_market, 0.0001) == 0.0001 assert personal_data.adapt_price(symbol_market, 0.00015) == 0.0001 assert personal_data.adapt_price(symbol_market, 0.005) == 0.005 assert personal_data.adapt_price(symbol_market, 1) == 1 assert personal_data.adapt_price(symbol_market, 56.5128597145) == 56.5128 assert personal_data.adapt_price(symbol_market, 1251.0000014576121234854513) == 1251.0000 # will use default (CURRENCY_DEFAULT_MAX_PRICE_DIGITS) symbol_market = {Ecmsc.PRECISION.value: {}} assert personal_data.adapt_price(symbol_market, 0.0001) == 0.0001 assert personal_data.adapt_price(symbol_market, 0.00015) == 0.00014999 assert personal_data.adapt_price(symbol_market, 0.005) == 0.005 assert personal_data.adapt_price(symbol_market, 1) == 1.0000000000000000000000001 assert personal_data.adapt_price(symbol_market, 1) == 1 assert personal_data.adapt_price(symbol_market, 56.5128597145) == 56.51285971 assert personal_data.adapt_price( symbol_market, 1251.0000014576121234854513) == 1251.00000145