draft for partial sell
This commit is contained in:
parent
a77c11c7e0
commit
1de5c0412c
@ -478,9 +478,9 @@ class FreqtradeBot(LoggingMixin):
|
||||
|
||||
if stake_amount is not None and stake_amount < 0.0:
|
||||
# We should decrease our position
|
||||
# TODO: Selling part of the trade not implemented yet.
|
||||
logger.error(f"Unable to decrease trade position / sell partially"
|
||||
f" for pair {trade.pair}, feature not implemented.")
|
||||
proposed_exit_rate = self.exchange.get_rate(pair, refresh=True, side="buy")
|
||||
self.execute_trade_exit(trade, proposed_exit_rate, sell_reason=SellCheckTuple(
|
||||
sell_type=SellType.CUSTOM_SELL), partial=stake_amount)
|
||||
|
||||
def _check_depth_of_market_buy(self, pair: str, conf: Dict) -> bool:
|
||||
"""
|
||||
@ -620,7 +620,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
# Updating wallets
|
||||
self.wallets.update()
|
||||
|
||||
self._notify_enter(trade, order, order_type)
|
||||
self._notify_enter(trade, order, order_type, partial=pos_adjust)
|
||||
|
||||
if pos_adjust:
|
||||
if order_status == 'closed':
|
||||
@ -677,7 +677,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
return enter_limit_requested, stake_amount
|
||||
|
||||
def _notify_enter(self, trade: Trade, order: Dict, order_type: Optional[str] = None,
|
||||
fill: bool = False) -> None:
|
||||
fill: bool = False, partial: bool = False) -> None:
|
||||
"""
|
||||
Sends rpc notification when a buy occurred.
|
||||
"""
|
||||
@ -693,7 +693,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
'trade_id': trade.id,
|
||||
'type': RPCMessageType.BUY_FILL if fill else RPCMessageType.BUY,
|
||||
'buy_tag': trade.buy_tag,
|
||||
'exchange': self.exchange.name.capitalize(),
|
||||
'exchange': trade.exchange.capitalize(),
|
||||
'pair': trade.pair,
|
||||
'limit': open_rate, # Deprecated (?)
|
||||
'open_rate': open_rate,
|
||||
@ -704,6 +704,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
'amount': safe_value_fallback(order, 'filled', 'amount') or trade.amount,
|
||||
'open_date': trade.open_date or datetime.utcnow(),
|
||||
'current_rate': current_rate,
|
||||
'partial': partial,
|
||||
}
|
||||
|
||||
# Send the message
|
||||
@ -1153,6 +1154,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
*,
|
||||
exit_tag: Optional[str] = None,
|
||||
ordertype: Optional[str] = None,
|
||||
partial: float = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Executes a trade exit for the given trade and limit
|
||||
@ -1225,7 +1227,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
self.strategy.lock_pair(trade.pair, datetime.now(timezone.utc),
|
||||
reason='Auto lock')
|
||||
|
||||
self._notify_exit(trade, order_type)
|
||||
self._notify_exit(trade, order_type, partial=bool(partial))
|
||||
# In case of market sell orders the order can be closed immediately
|
||||
if order.get('status', 'unknown') in ('closed', 'expired'):
|
||||
self.update_trade_state(trade, trade.open_order_id, order)
|
||||
@ -1233,7 +1235,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
|
||||
return True
|
||||
|
||||
def _notify_exit(self, trade: Trade, order_type: str, fill: bool = False) -> None:
|
||||
def _notify_exit(self, trade: Trade, order_type: str, fill: bool = False, partial: bool = False) -> None:
|
||||
"""
|
||||
Sends rpc notification when a sell occurred.
|
||||
"""
|
||||
@ -1264,8 +1266,10 @@ class FreqtradeBot(LoggingMixin):
|
||||
'sell_reason': trade.sell_reason,
|
||||
'open_date': trade.open_date,
|
||||
'close_date': trade.close_date or datetime.utcnow(),
|
||||
'stake_amount': trade.stake_amount,
|
||||
'stake_currency': self.config['stake_currency'],
|
||||
'fiat_currency': self.config.get('fiat_display_currency', None),
|
||||
'partial': partial,
|
||||
}
|
||||
|
||||
if 'fiat_display_currency' in self.config:
|
||||
|
@ -476,6 +476,17 @@ class LocalTrade():
|
||||
elif order_type in ('market', 'limit') and order['side'] == 'sell':
|
||||
if self.is_open:
|
||||
logger.info(f'{order_type.upper()}_SELL has been fulfilled for {self}.')
|
||||
self.open_order_id = None
|
||||
if partial:
|
||||
orders=(self.select_filled_orders('buy'))
|
||||
lbuy=orders[-2]
|
||||
lamount = (lbuy.filled or lbuy.amount)
|
||||
lbuy.average=(lbuy.average * lamount - self.calc_profit2(orders[-1].rate, order.rate, order.filled or order.amount))/lamount
|
||||
Order.query.session.commit()
|
||||
self.orders.remove(orders[-1])
|
||||
self.recalc_trade_from_orders()
|
||||
Trade.commit()
|
||||
else:
|
||||
self.close(safe_value_fallback(order, 'average', 'price'))
|
||||
elif order_type in ('stop_loss_limit', 'stop-loss', 'stop-loss-limit', 'stop'):
|
||||
self.stoploss_order_id = None
|
||||
@ -488,6 +499,8 @@ class LocalTrade():
|
||||
raise ValueError(f'Unknown order type: {order_type}')
|
||||
Trade.commit()
|
||||
|
||||
def calc_profit2(self, open_rate: float, close_rate: float, amount: Float) ->float:
|
||||
return Decimal(self.amount) *( (1-self.fee_close)* Decimal(close_rate) -(1+self.fee_open)* Decimal(open_rate) )
|
||||
def close(self, rate: float, *, show_msg: bool = True) -> None:
|
||||
"""
|
||||
Sets close_rate to the given rate, calculates total profit
|
||||
|
@ -235,13 +235,26 @@ class Telegram(RPCHandler):
|
||||
|
||||
if msg['type'] == RPCMessageType.BUY_FILL:
|
||||
message += f"*Open Rate:* `{msg['open_rate']:.8f}`\n"
|
||||
total = msg['amount'] * msg['open_rate']
|
||||
|
||||
elif msg['type'] == RPCMessageType.BUY:
|
||||
message += f"*Open Rate:* `{msg['limit']:.8f}`\n"\
|
||||
f"*Current Rate:* `{msg['current_rate']:.8f}`\n"
|
||||
|
||||
total = msg['amount'] * msg['limit']
|
||||
if self._rpc._fiat_converter:
|
||||
total_fiat = self._rpc._fiat_converter.convert_amount(
|
||||
total, msg['stake_currency'], msg['fiat_currency'])
|
||||
else:
|
||||
total_fiat = 0
|
||||
message += f"*Total:* `({round_coin_value(msg['stake_amount'], msg['stake_currency'])}"
|
||||
|
||||
if msg.get('fiat_currency', None):
|
||||
message += f", {round_coin_value(total, msg['fiat_currency'])}"
|
||||
|
||||
message += ")`\n"
|
||||
if msg['partial']:
|
||||
message += f"*Balance:* `({round_coin_value(msg['stake_amount'], msg['stake_currency'])}"
|
||||
|
||||
if msg.get('fiat_currency', None):
|
||||
message += f", {round_coin_value(msg['stake_amount_fiat'], msg['fiat_currency'])}"
|
||||
|
||||
@ -287,7 +300,18 @@ class Telegram(RPCHandler):
|
||||
|
||||
elif msg['type'] == RPCMessageType.SELL_FILL:
|
||||
message += f"*Close Rate:* `{msg['close_rate']:.8f}`"
|
||||
if self._rpc._fiat_converter:
|
||||
msg['stake_amount_fiat'] = self._rpc._fiat_converter.convert_amount(
|
||||
msg['stake_amount'], msg['stake_currency'], msg['fiat_currency'])
|
||||
else:
|
||||
msg['stake_amount_fiat'] = 0
|
||||
if msg['partial']:
|
||||
message += f"*Balance:* `({round_coin_value(msg['stake_amount'], msg['stake_currency'])}"
|
||||
|
||||
if msg.get('fiat_currency', None):
|
||||
message += f", {round_coin_value(msg['stake_amount_fiat'], msg['fiat_currency'])}"
|
||||
|
||||
message += ")`"
|
||||
return message
|
||||
|
||||
def compose_message(self, msg: Dict[str, Any], msg_type: RPCMessageType) -> str:
|
||||
|
Loading…
Reference in New Issue
Block a user