use Order object to update trade
This commit is contained in:
		| @@ -16,7 +16,7 @@ from freqtrade.data.dataprovider import DataProvider | |||||||
| from freqtrade.edge import Edge | from freqtrade.edge import Edge | ||||||
| from freqtrade.enums import RPCMessageType, RunMode, SellType, State | from freqtrade.enums import RPCMessageType, RunMode, SellType, State | ||||||
| from freqtrade.exceptions import (DependencyException, ExchangeError, InsufficientFundsError, | from freqtrade.exceptions import (DependencyException, ExchangeError, InsufficientFundsError, | ||||||
|                                   InvalidOrderException, PricingError) |                                   InvalidOrderException, OperationalException, PricingError) | ||||||
| from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds | from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds | ||||||
| from freqtrade.misc import safe_value_fallback, safe_value_fallback2 | from freqtrade.misc import safe_value_fallback, safe_value_fallback2 | ||||||
| from freqtrade.mixins import LoggingMixin | from freqtrade.mixins import LoggingMixin | ||||||
| @@ -1358,8 +1358,11 @@ class FreqtradeBot(LoggingMixin): | |||||||
|             return True |             return True | ||||||
|  |  | ||||||
|         order = self.handle_order_fee(trade, order) |         order = self.handle_order_fee(trade, order) | ||||||
|  |         order_obj = trade.select_order_by_order_id(order['id']) | ||||||
|         trade.update(order) |         if not order_obj: | ||||||
|  |             # TODO: this can't happen! | ||||||
|  |             raise OperationalException("order-obj not found!") | ||||||
|  |         trade.update(order_obj) | ||||||
|         trade.recalc_trade_from_orders() |         trade.recalc_trade_from_orders() | ||||||
|         Trade.commit() |         Trade.commit() | ||||||
|  |  | ||||||
|   | |||||||
| @@ -113,14 +113,15 @@ class Order(_DECL_BASE): | |||||||
|  |  | ||||||
|     trade = relationship("Trade", back_populates="orders") |     trade = relationship("Trade", back_populates="orders") | ||||||
|  |  | ||||||
|     ft_order_side = Column(String(25), nullable=False) |     # order_side can only be 'buy', 'sell' or 'stoploss' | ||||||
|     ft_pair = Column(String(25), nullable=False) |     ft_order_side: str = Column(String(25), nullable=False) | ||||||
|  |     ft_pair: str = Column(String(25), nullable=False) | ||||||
|     ft_is_open = Column(Boolean, nullable=False, default=True, index=True) |     ft_is_open = Column(Boolean, nullable=False, default=True, index=True) | ||||||
|  |  | ||||||
|     order_id = Column(String(255), nullable=False, index=True) |     order_id = Column(String(255), nullable=False, index=True) | ||||||
|     status = Column(String(255), nullable=True) |     status = Column(String(255), nullable=True) | ||||||
|     symbol = Column(String(25), nullable=True) |     symbol = Column(String(25), nullable=True) | ||||||
|     order_type = Column(String(50), nullable=True) |     order_type: str = Column(String(50), nullable=True) | ||||||
|     side = Column(String(25), nullable=True) |     side = Column(String(25), nullable=True) | ||||||
|     price = Column(Float, nullable=True) |     price = Column(Float, nullable=True) | ||||||
|     average = Column(Float, nullable=True) |     average = Column(Float, nullable=True) | ||||||
| @@ -133,9 +134,18 @@ class Order(_DECL_BASE): | |||||||
|     order_update_date = Column(DateTime, nullable=True) |     order_update_date = Column(DateTime, nullable=True) | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def order_date_utc(self): |     def order_date_utc(self) -> datetime: | ||||||
|  |         """ Order-date with UTC timezoneinfo""" | ||||||
|         return self.order_date.replace(tzinfo=timezone.utc) |         return self.order_date.replace(tzinfo=timezone.utc) | ||||||
|  |  | ||||||
|  |     @property | ||||||
|  |     def safe_price(self) -> float: | ||||||
|  |         return self.average or self.price | ||||||
|  |  | ||||||
|  |     @property | ||||||
|  |     def safe_filled(self) -> float: | ||||||
|  |         return self.filled or self.amount | ||||||
|  |  | ||||||
|     def __repr__(self): |     def __repr__(self): | ||||||
|  |  | ||||||
|         return (f'Order(id={self.id}, order_id={self.order_id}, trade_id={self.ft_trade_id}, ' |         return (f'Order(id={self.id}, order_id={self.order_id}, trade_id={self.ft_trade_id}, ' | ||||||
| @@ -452,40 +462,39 @@ class LocalTrade(): | |||||||
|             f"Trailing stoploss saved us: " |             f"Trailing stoploss saved us: " | ||||||
|             f"{float(self.stop_loss) - float(self.initial_stop_loss):.8f}.") |             f"{float(self.stop_loss) - float(self.initial_stop_loss):.8f}.") | ||||||
|  |  | ||||||
|     def update(self, order: Dict) -> None: |     def update(self, order: Order) -> None: | ||||||
|         """ |         """ | ||||||
|         Updates this entity with amount and actual open/close rates. |         Updates this entity with amount and actual open/close rates. | ||||||
|         :param order: order retrieved by exchange.fetch_order() |         :param order: order retrieved by exchange.fetch_order() | ||||||
|         :return: None |         :return: None | ||||||
|         """ |         """ | ||||||
|         order_type = order['type'] |  | ||||||
|         # Ignore open and cancelled orders |         # Ignore open and cancelled orders | ||||||
|         if order['status'] == 'open' or safe_value_fallback(order, 'average', 'price') is None: |         if order.status == 'open' or safe_value_fallback(order, 'average', 'price') is None: | ||||||
|             return |             return | ||||||
|  |  | ||||||
|         logger.info('Updating trade (id=%s) ...', self.id) |         logger.info(f'Updating trade (id={self.id}) ...') | ||||||
|  |  | ||||||
|         if order_type in ('market', 'limit') and order['side'] == 'buy': |         if order.ft_order_side == 'buy': | ||||||
|             # Update open rate and actual amount |             # Update open rate and actual amount | ||||||
|             self.open_rate = float(safe_value_fallback(order, 'average', 'price')) |             self.open_rate = order.safe_price | ||||||
|             self.amount = float(safe_value_fallback(order, 'filled', 'amount')) |             self.amount = order.safe_filled | ||||||
|             if self.is_open: |             if self.is_open: | ||||||
|                 logger.info(f'{order_type.upper()}_BUY has been fulfilled for {self}.') |                 logger.info(f'{order.order_type.upper()}_BUY has been fulfilled for {self}.') | ||||||
|             self.open_order_id = None |             self.open_order_id = None | ||||||
|             self.recalc_trade_from_orders() |             self.recalc_trade_from_orders() | ||||||
|         elif order_type in ('market', 'limit') and order['side'] == 'sell': |         elif order.ft_order_side == 'sell': | ||||||
|             if self.is_open: |             if self.is_open: | ||||||
|                 logger.info(f'{order_type.upper()}_SELL has been fulfilled for {self}.') |                 logger.info(f'{order.order_type.upper()}_SELL has been fulfilled for {self}.') | ||||||
|             self.close(safe_value_fallback(order, 'average', 'price')) |             self.close(order.safe_price) | ||||||
|         elif order_type in ('stop_loss_limit', 'stop-loss', 'stop-loss-limit', 'stop'): |         elif order.ft_order_side == 'stoploss': | ||||||
|             self.stoploss_order_id = None |             self.stoploss_order_id = None | ||||||
|             self.close_rate_requested = self.stop_loss |             self.close_rate_requested = self.stop_loss | ||||||
|             self.sell_reason = SellType.STOPLOSS_ON_EXCHANGE.value |             self.sell_reason = SellType.STOPLOSS_ON_EXCHANGE.value | ||||||
|             if self.is_open: |             if self.is_open: | ||||||
|                 logger.info(f'{order_type.upper()} is hit for {self}.') |                 logger.info(f'{order.order_type.upper()} is hit for {self}.') | ||||||
|             self.close(safe_value_fallback(order, 'average', 'price')) |             self.close(order.safe_price) | ||||||
|         else: |         else: | ||||||
|             raise ValueError(f'Unknown order type: {order_type}') |             raise ValueError(f'Unknown order type: {order.order_type}') | ||||||
|         Trade.commit() |         Trade.commit() | ||||||
|  |  | ||||||
|     def close(self, rate: float, *, show_msg: bool = True) -> None: |     def close(self, rate: float, *, show_msg: bool = True) -> None: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user