Attempt to support limit orders for position adjustment.

This commit is contained in:
Reigo Reinmets 2021-12-11 18:25:05 +02:00
parent 7d42f42405
commit 71147d2899
2 changed files with 36 additions and 7 deletions

View File

@ -469,15 +469,14 @@ class FreqtradeBot(LoggingMixin):
def adjust_trade_position(self, trade: Trade): def adjust_trade_position(self, trade: Trade):
""" """
Check the implemented trading strategy for adjustment command. Check the implemented trading strategy for adjustment command.
If the strategy triggers the adjustment a new buy/sell-order gets issued. If the strategy triggers the adjustment, a new order gets issued.
Once that completes, the existing trade is modified to match new data. Once that completes, the existing trade is modified to match new data.
""" """
logger.debug(f"adjust_trade_position for pair {trade.pair}")
for order in trade.orders: for order in trade.orders:
if order.ft_is_open: if order.ft_is_open:
logger.debug(f"Order {order} is still open, skipping pair.")
return return
logger.debug(f"adjust_trade_position for pair {trade.pair}")
sell_rate = self.exchange.get_rate(trade.pair, refresh=True, side="sell") sell_rate = self.exchange.get_rate(trade.pair, refresh=True, side="sell")
current_profit = trade.calc_profit_ratio(sell_rate) current_profit = trade.calc_profit_ratio(sell_rate)
stake_to_adjust = strategy_safe_wrapper(self.strategy.adjust_trade_position, default_retval=None)( stake_to_adjust = strategy_safe_wrapper(self.strategy.adjust_trade_position, default_retval=None)(
@ -491,6 +490,7 @@ class FreqtradeBot(LoggingMixin):
if stake_to_adjust != None and stake_to_adjust < 0.0: if stake_to_adjust != None and stake_to_adjust < 0.0:
# We should decrease our position # We should decrease our position
# TODO: Selling part of the trade not implemented yet. # TODO: Selling part of the trade not implemented yet.
logger.error(f"Unable to decrease trade position / sell partially for pair {trade.pair}, feature not implemented.")
return return
return return
@ -528,7 +528,7 @@ class FreqtradeBot(LoggingMixin):
logger.debug(f'Executing additional order: amount={amount}, stake={stake_amount}, price={enter_limit_requested}') logger.debug(f'Executing additional order: amount={amount}, stake={stake_amount}, price={enter_limit_requested}')
order_type = 'market' order_type = self.strategy.order_types['buy']
order = self.exchange.create_order(pair=pair, ordertype=order_type, side="buy", order = self.exchange.create_order(pair=pair, ordertype=order_type, side="buy",
amount=amount, rate=enter_limit_requested, amount=amount, rate=enter_limit_requested,
time_in_force=time_in_force) time_in_force=time_in_force)
@ -573,7 +573,7 @@ class FreqtradeBot(LoggingMixin):
# Updating wallets # Updating wallets
self.wallets.update() self.wallets.update()
self._notify_enter(trade, order_type) self._notify_additional_buy(trade, order_obj, order_type)
return True return True
@ -729,6 +729,31 @@ class FreqtradeBot(LoggingMixin):
return True return True
def _notify_additional_buy(self, trade: Trade, order: Order, order_type: Optional[str] = None,
fill: bool = False) -> None:
"""
Sends rpc notification when a buy occurred.
"""
msg = {
'trade_id': trade.id,
'type': RPCMessageType.BUY_FILL if fill else RPCMessageType.BUY,
'buy_tag': "adjust_trade_position",
'exchange': self.exchange.name.capitalize(),
'pair': trade.pair,
'limit': order.price, # Deprecated (?)
'open_rate': order.price,
'order_type': order_type,
'stake_amount': order.cost,
'stake_currency': self.config['stake_currency'],
'fiat_currency': self.config.get('fiat_display_currency', None),
'amount': order.amount,
'open_date': order.order_filled_date or datetime.utcnow(),
'current_rate': order.price,
}
# Send the message
self.rpc.send_msg(msg)
def _notify_enter(self, trade: Trade, order_type: Optional[str] = None, def _notify_enter(self, trade: Trade, order_type: Optional[str] = None,
fill: bool = False) -> None: fill: bool = False) -> None:
""" """

View File

@ -568,8 +568,13 @@ class LocalTrade():
profit_ratio = (close_trade_value / self.open_trade_value) - 1 profit_ratio = (close_trade_value / self.open_trade_value) - 1
return float(f"{profit_ratio:.8f}") return float(f"{profit_ratio:.8f}")
def recalc_trade_from_orders(self): def recalc_trade_from_orders(self):
# We need at least 2 orders for averaging amounts and rates.
if len(self.orders) < 2:
# Just in case, still recalc open trade value
self.recalc_open_trade_value()
return
total_amount = 0.0 total_amount = 0.0
total_stake = 0.0 total_stake = 0.0
for temp_order in self.orders: for temp_order in self.orders:
@ -590,7 +595,6 @@ class LocalTrade():
if self.stop_loss_pct is not None and self.open_rate is not None: if self.stop_loss_pct is not None and self.open_rate is not None:
self.adjust_stop_loss(self.open_rate, self.stop_loss_pct) self.adjust_stop_loss(self.open_rate, self.stop_loss_pct)
def select_order(self, order_side: str, is_open: Optional[bool]) -> Optional[Order]: def select_order(self, order_side: str, is_open: Optional[bool]) -> Optional[Order]:
""" """
Finds latest order for this orderside and status Finds latest order for this orderside and status