Remove more buy_tag references
This commit is contained in:
parent
7d77aff289
commit
36deced00b
@ -43,3 +43,24 @@ As this does however increase risk and provides no benefit, it's been removed fo
|
|||||||
|
|
||||||
Using separate hyperopt files was deprecated in 2021.4 and was removed in 2021.9.
|
Using separate hyperopt files was deprecated in 2021.4 and was removed in 2021.9.
|
||||||
Please switch to the new [Parametrized Strategies](hyperopt.md) to benefit from the new hyperopt interface.
|
Please switch to the new [Parametrized Strategies](hyperopt.md) to benefit from the new hyperopt interface.
|
||||||
|
|
||||||
|
## Margin / short changes
|
||||||
|
|
||||||
|
// TODO-lev: update version here
|
||||||
|
|
||||||
|
## Strategy changes
|
||||||
|
|
||||||
|
As strategies now have to support multiple different signal types, some things had to change.
|
||||||
|
|
||||||
|
Columns:
|
||||||
|
|
||||||
|
* `buy` -> `enter_long`
|
||||||
|
* `sell` -> `exit_long`
|
||||||
|
* `buy_tag` -> `enter_tag`
|
||||||
|
|
||||||
|
New columns are `enter_short` and `exit_short`, which will initiate short trades (requires additional configuration!)
|
||||||
|
|
||||||
|
### webhooks - `buy_tag` has been renamed to `enter_tag`
|
||||||
|
|
||||||
|
This should apply only to your strategy and potentially to webhooks.
|
||||||
|
We will keep a compatibility layer for 1-2 versions (so both `buy_tag` and `enter_tag` will still work), but support for this in webhooks will disappear after that.
|
||||||
|
@ -97,7 +97,7 @@ def custom_sell(self, pair: str, trade: Trade, current_time: datetime, current_r
|
|||||||
current_profit: float, **kwargs):
|
current_profit: float, **kwargs):
|
||||||
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
|
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
|
||||||
last_candle = dataframe.iloc[-1].squeeze()
|
last_candle = dataframe.iloc[-1].squeeze()
|
||||||
if trade.buy_tag == 'buy_signal_rsi' and last_candle['rsi'] > 80:
|
if trade.enter_tag == 'buy_signal_rsi' and last_candle['rsi'] > 80:
|
||||||
return 'sell_signal_rsi'
|
return 'sell_signal_rsi'
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ BT_DATA_COLUMNS = ['pair', 'stake_amount', 'amount', 'open_date', 'close_date',
|
|||||||
'fee_open', 'fee_close', 'trade_duration',
|
'fee_open', 'fee_close', 'trade_duration',
|
||||||
'profit_ratio', 'profit_abs', 'sell_reason',
|
'profit_ratio', 'profit_abs', 'sell_reason',
|
||||||
'initial_stop_loss_abs', 'initial_stop_loss_ratio', 'stop_loss_abs',
|
'initial_stop_loss_abs', 'initial_stop_loss_ratio', 'stop_loss_abs',
|
||||||
'stop_loss_ratio', 'min_rate', 'max_rate', 'is_open', 'buy_tag']
|
'stop_loss_ratio', 'min_rate', 'max_rate', 'is_open', 'enter_tag']
|
||||||
# TODO-lev: usage of the above might need compatibility code (buy_tag, is_short?, ...?)
|
# TODO-lev: usage of the above might need compatibility code (buy_tag, is_short?, ...?)
|
||||||
|
|
||||||
|
|
||||||
|
@ -721,8 +721,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
exchange=self.exchange.id,
|
exchange=self.exchange.id,
|
||||||
open_order_id=order_id,
|
open_order_id=order_id,
|
||||||
strategy=self.strategy.get_strategy_name(),
|
strategy=self.strategy.get_strategy_name(),
|
||||||
# TODO-lev: compatibility layer for buy_tag (!)
|
enter_tag=enter_tag,
|
||||||
buy_tag=enter_tag,
|
|
||||||
timeframe=timeframe_to_minutes(self.config['timeframe']),
|
timeframe=timeframe_to_minutes(self.config['timeframe']),
|
||||||
leverage=leverage,
|
leverage=leverage,
|
||||||
is_short=is_short,
|
is_short=is_short,
|
||||||
@ -754,8 +753,8 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
msg = {
|
msg = {
|
||||||
'trade_id': trade.id,
|
'trade_id': trade.id,
|
||||||
'type': RPCMessageType.SHORT if trade.is_short else RPCMessageType.BUY,
|
'type': RPCMessageType.SHORT if trade.is_short else RPCMessageType.BUY,
|
||||||
'buy_tag': trade.buy_tag,
|
'buy_tag': trade.enter_tag,
|
||||||
'enter_tag': trade.buy_tag,
|
'enter_tag': trade.enter_tag,
|
||||||
'exchange': self.exchange.name.capitalize(),
|
'exchange': self.exchange.name.capitalize(),
|
||||||
'pair': trade.pair,
|
'pair': trade.pair,
|
||||||
'limit': trade.open_rate,
|
'limit': trade.open_rate,
|
||||||
@ -780,8 +779,8 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
msg = {
|
msg = {
|
||||||
'trade_id': trade.id,
|
'trade_id': trade.id,
|
||||||
'type': msg_type,
|
'type': msg_type,
|
||||||
'buy_tag': trade.buy_tag,
|
'buy_tag': trade.enter_tag,
|
||||||
'enter_tag': trade.buy_tag,
|
'enter_tag': trade.enter_tag,
|
||||||
'exchange': self.exchange.name.capitalize(),
|
'exchange': self.exchange.name.capitalize(),
|
||||||
'pair': trade.pair,
|
'pair': trade.pair,
|
||||||
'limit': trade.open_rate,
|
'limit': trade.open_rate,
|
||||||
@ -803,8 +802,8 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
msg = {
|
msg = {
|
||||||
'trade_id': trade.id,
|
'trade_id': trade.id,
|
||||||
'type': msg_type,
|
'type': msg_type,
|
||||||
'buy_tag': trade.buy_tag,
|
'buy_tag': trade.enter_tag,
|
||||||
'enter_tag': trade.buy_tag,
|
'enter_tag': trade.enter_tag,
|
||||||
'exchange': self.exchange.name.capitalize(),
|
'exchange': self.exchange.name.capitalize(),
|
||||||
'pair': trade.pair,
|
'pair': trade.pair,
|
||||||
'open_rate': trade.open_rate,
|
'open_rate': trade.open_rate,
|
||||||
@ -1387,8 +1386,8 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
'current_rate': current_rate,
|
'current_rate': current_rate,
|
||||||
'profit_amount': profit_trade,
|
'profit_amount': profit_trade,
|
||||||
'profit_ratio': profit_ratio,
|
'profit_ratio': profit_ratio,
|
||||||
'enter_tag': trade.buy_tag,
|
'buy_tag': trade.enter_tag,
|
||||||
'buy_tag': trade.buy_tag,
|
'enter_tag': trade.enter_tag,
|
||||||
'sell_reason': trade.sell_reason,
|
'sell_reason': trade.sell_reason,
|
||||||
'open_date': trade.open_date,
|
'open_date': trade.open_date,
|
||||||
'close_date': trade.close_date or datetime.utcnow(),
|
'close_date': trade.close_date or datetime.utcnow(),
|
||||||
@ -1432,8 +1431,8 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
'current_rate': current_rate,
|
'current_rate': current_rate,
|
||||||
'profit_amount': profit_trade,
|
'profit_amount': profit_trade,
|
||||||
'profit_ratio': profit_ratio,
|
'profit_ratio': profit_ratio,
|
||||||
'enter_tag': trade.buy_tag,
|
'buy_tag': trade.enter_tag,
|
||||||
'buy_tag': trade.buy_tag,
|
'enter_tag': trade.enter_tag,
|
||||||
'sell_reason': trade.sell_reason,
|
'sell_reason': trade.sell_reason,
|
||||||
'open_date': trade.open_date,
|
'open_date': trade.open_date,
|
||||||
'close_date': trade.close_date or datetime.now(timezone.utc),
|
'close_date': trade.close_date or datetime.now(timezone.utc),
|
||||||
|
@ -478,7 +478,7 @@ class Backtesting:
|
|||||||
fee_open=self.fee,
|
fee_open=self.fee,
|
||||||
fee_close=self.fee,
|
fee_close=self.fee,
|
||||||
is_open=True,
|
is_open=True,
|
||||||
buy_tag=row[ENTER_TAG_IDX] if has_enter_tag else None,
|
enter_tag=row[ENTER_TAG_IDX] if has_enter_tag else None,
|
||||||
exchange=self._exchange_name,
|
exchange=self._exchange_name,
|
||||||
is_short=(direction == 'short'),
|
is_short=(direction == 'short'),
|
||||||
)
|
)
|
||||||
|
@ -47,7 +47,7 @@ def migrate_trades_table(decl_base, inspector, engine, table_back_name: str, col
|
|||||||
min_rate = get_column_def(cols, 'min_rate', 'null')
|
min_rate = get_column_def(cols, 'min_rate', 'null')
|
||||||
sell_reason = get_column_def(cols, 'sell_reason', 'null')
|
sell_reason = get_column_def(cols, 'sell_reason', 'null')
|
||||||
strategy = get_column_def(cols, 'strategy', 'null')
|
strategy = get_column_def(cols, 'strategy', 'null')
|
||||||
buy_tag = get_column_def(cols, 'buy_tag', 'null')
|
enter_tag = get_column_def(cols, 'buy_tag', get_column_def(cols, 'enter_tag', 'null'))
|
||||||
|
|
||||||
trading_mode = get_column_def(cols, 'trading_mode', 'null')
|
trading_mode = get_column_def(cols, 'trading_mode', 'null')
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ def migrate_trades_table(decl_base, inspector, engine, table_back_name: str, col
|
|||||||
stake_amount, amount, amount_requested, open_date, close_date, open_order_id,
|
stake_amount, amount, amount_requested, open_date, close_date, open_order_id,
|
||||||
stop_loss, stop_loss_pct, initial_stop_loss, initial_stop_loss_pct,
|
stop_loss, stop_loss_pct, initial_stop_loss, initial_stop_loss_pct,
|
||||||
stoploss_order_id, stoploss_last_update,
|
stoploss_order_id, stoploss_last_update,
|
||||||
max_rate, min_rate, sell_reason, sell_order_status, strategy, buy_tag,
|
max_rate, min_rate, sell_reason, sell_order_status, strategy, enter_tag,
|
||||||
timeframe, open_trade_value, close_profit_abs,
|
timeframe, open_trade_value, close_profit_abs,
|
||||||
trading_mode, leverage, isolated_liq, is_short,
|
trading_mode, leverage, isolated_liq, is_short,
|
||||||
interest_rate, funding_fees
|
interest_rate, funding_fees
|
||||||
@ -116,7 +116,7 @@ def migrate_trades_table(decl_base, inspector, engine, table_back_name: str, col
|
|||||||
{stoploss_order_id} stoploss_order_id, {stoploss_last_update} stoploss_last_update,
|
{stoploss_order_id} stoploss_order_id, {stoploss_last_update} stoploss_last_update,
|
||||||
{max_rate} max_rate, {min_rate} min_rate, {sell_reason} sell_reason,
|
{max_rate} max_rate, {min_rate} min_rate, {sell_reason} sell_reason,
|
||||||
{sell_order_status} sell_order_status,
|
{sell_order_status} sell_order_status,
|
||||||
{strategy} strategy, {buy_tag} buy_tag, {timeframe} timeframe,
|
{strategy} strategy, {enter_tag} enter_tag, {timeframe} timeframe,
|
||||||
{open_trade_value} open_trade_value, {close_profit_abs} close_profit_abs,
|
{open_trade_value} open_trade_value, {close_profit_abs} close_profit_abs,
|
||||||
{trading_mode} trading_mode, {leverage} leverage, {isolated_liq} isolated_liq,
|
{trading_mode} trading_mode, {leverage} leverage, {isolated_liq} isolated_liq,
|
||||||
{is_short} is_short, {interest_rate} interest_rate,
|
{is_short} is_short, {interest_rate} interest_rate,
|
||||||
|
@ -264,7 +264,7 @@ class LocalTrade():
|
|||||||
sell_reason: str = ''
|
sell_reason: str = ''
|
||||||
sell_order_status: str = ''
|
sell_order_status: str = ''
|
||||||
strategy: str = ''
|
strategy: str = ''
|
||||||
buy_tag: Optional[str] = None
|
enter_tag: Optional[str] = None
|
||||||
timeframe: Optional[int] = None
|
timeframe: Optional[int] = None
|
||||||
|
|
||||||
trading_mode: TradingMode = TradingMode.SPOT
|
trading_mode: TradingMode = TradingMode.SPOT
|
||||||
@ -280,6 +280,14 @@ class LocalTrade():
|
|||||||
# Futures properties
|
# Futures properties
|
||||||
funding_fees: Optional[float] = None
|
funding_fees: Optional[float] = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def buy_tag(self) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
Compatibility between buy_tag (old) and enter_tag (new)
|
||||||
|
Consider buy_tag deprecated
|
||||||
|
"""
|
||||||
|
return self.enter_tag
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def has_no_leverage(self) -> bool:
|
def has_no_leverage(self) -> bool:
|
||||||
"""Returns true if this is a non-leverage, non-short trade"""
|
"""Returns true if this is a non-leverage, non-short trade"""
|
||||||
@ -389,8 +397,8 @@ class LocalTrade():
|
|||||||
'amount_requested': round(self.amount_requested, 8) if self.amount_requested else None,
|
'amount_requested': round(self.amount_requested, 8) if self.amount_requested else None,
|
||||||
'stake_amount': round(self.stake_amount, 8),
|
'stake_amount': round(self.stake_amount, 8),
|
||||||
'strategy': self.strategy,
|
'strategy': self.strategy,
|
||||||
'buy_tag': self.buy_tag,
|
'buy_tag': self.enter_tag,
|
||||||
'enter_tag': self.buy_tag,
|
'enter_tag': self.enter_tag,
|
||||||
'timeframe': self.timeframe,
|
'timeframe': self.timeframe,
|
||||||
|
|
||||||
'fee_open': self.fee_open,
|
'fee_open': self.fee_open,
|
||||||
@ -929,7 +937,7 @@ class Trade(_DECL_BASE, LocalTrade):
|
|||||||
sell_reason = Column(String(100), nullable=True)
|
sell_reason = Column(String(100), nullable=True)
|
||||||
sell_order_status = Column(String(100), nullable=True)
|
sell_order_status = Column(String(100), nullable=True)
|
||||||
strategy = Column(String(100), nullable=True)
|
strategy = Column(String(100), nullable=True)
|
||||||
buy_tag = Column(String(100), nullable=True)
|
enter_tag = Column(String(100), nullable=True)
|
||||||
timeframe = Column(Integer, nullable=True)
|
timeframe = Column(Integer, nullable=True)
|
||||||
|
|
||||||
trading_mode = Column(Enum(TradingMode), nullable=True)
|
trading_mode = Column(Enum(TradingMode), nullable=True)
|
||||||
@ -1100,7 +1108,7 @@ class Trade(_DECL_BASE, LocalTrade):
|
|||||||
]
|
]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_buy_tag_performance(pair: Optional[str]) -> List[Dict[str, Any]]:
|
def get_enter_tag_performance(pair: Optional[str]) -> List[Dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
Returns List of dicts containing all Trades, based on buy tag performance
|
Returns List of dicts containing all Trades, based on buy tag performance
|
||||||
Can either be average for all pairs or a specific pair provided
|
Can either be average for all pairs or a specific pair provided
|
||||||
@ -1111,25 +1119,25 @@ class Trade(_DECL_BASE, LocalTrade):
|
|||||||
if(pair is not None):
|
if(pair is not None):
|
||||||
filters.append(Trade.pair == pair)
|
filters.append(Trade.pair == pair)
|
||||||
|
|
||||||
buy_tag_perf = Trade.query.with_entities(
|
enter_tag_perf = Trade.query.with_entities(
|
||||||
Trade.buy_tag,
|
Trade.enter_tag,
|
||||||
func.sum(Trade.close_profit).label('profit_sum'),
|
func.sum(Trade.close_profit).label('profit_sum'),
|
||||||
func.sum(Trade.close_profit_abs).label('profit_sum_abs'),
|
func.sum(Trade.close_profit_abs).label('profit_sum_abs'),
|
||||||
func.count(Trade.pair).label('count')
|
func.count(Trade.pair).label('count')
|
||||||
).filter(*filters)\
|
).filter(*filters)\
|
||||||
.group_by(Trade.buy_tag) \
|
.group_by(Trade.enter_tag) \
|
||||||
.order_by(desc('profit_sum_abs')) \
|
.order_by(desc('profit_sum_abs')) \
|
||||||
.all()
|
.all()
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
'buy_tag': buy_tag if buy_tag is not None else "Other",
|
'enter_tag': enter_tag if enter_tag is not None else "Other",
|
||||||
'profit_ratio': profit,
|
'profit_ratio': profit,
|
||||||
'profit_pct': round(profit * 100, 2),
|
'profit_pct': round(profit * 100, 2),
|
||||||
'profit_abs': profit_abs,
|
'profit_abs': profit_abs,
|
||||||
'count': count
|
'count': count
|
||||||
}
|
}
|
||||||
for buy_tag, profit, profit_abs, count in buy_tag_perf
|
for enter_tag, profit, profit_abs, count in enter_tag_perf
|
||||||
]
|
]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -1179,7 +1187,7 @@ class Trade(_DECL_BASE, LocalTrade):
|
|||||||
|
|
||||||
mix_tag_perf = Trade.query.with_entities(
|
mix_tag_perf = Trade.query.with_entities(
|
||||||
Trade.id,
|
Trade.id,
|
||||||
Trade.buy_tag,
|
Trade.enter_tag,
|
||||||
Trade.sell_reason,
|
Trade.sell_reason,
|
||||||
func.sum(Trade.close_profit).label('profit_sum'),
|
func.sum(Trade.close_profit).label('profit_sum'),
|
||||||
func.sum(Trade.close_profit_abs).label('profit_sum_abs'),
|
func.sum(Trade.close_profit_abs).label('profit_sum_abs'),
|
||||||
@ -1190,12 +1198,12 @@ class Trade(_DECL_BASE, LocalTrade):
|
|||||||
.all()
|
.all()
|
||||||
|
|
||||||
return_list: List[Dict] = []
|
return_list: List[Dict] = []
|
||||||
for id, buy_tag, sell_reason, profit, profit_abs, count in mix_tag_perf:
|
for id, enter_tag, sell_reason, profit, profit_abs, count in mix_tag_perf:
|
||||||
buy_tag = buy_tag if buy_tag is not None else "Other"
|
enter_tag = enter_tag if enter_tag is not None else "Other"
|
||||||
sell_reason = sell_reason if sell_reason is not None else "Other"
|
sell_reason = sell_reason if sell_reason is not None else "Other"
|
||||||
|
|
||||||
if(sell_reason is not None and buy_tag is not None):
|
if(sell_reason is not None and enter_tag is not None):
|
||||||
mix_tag = buy_tag + " " + sell_reason
|
mix_tag = enter_tag + " " + sell_reason
|
||||||
i = 0
|
i = 0
|
||||||
if not any(item["mix_tag"] == mix_tag for item in return_list):
|
if not any(item["mix_tag"] == mix_tag for item in return_list):
|
||||||
return_list.append({'mix_tag': mix_tag,
|
return_list.append({'mix_tag': mix_tag,
|
||||||
|
@ -782,12 +782,12 @@ class RPC:
|
|||||||
|
|
||||||
return pair_rates
|
return pair_rates
|
||||||
|
|
||||||
def _rpc_buy_tag_performance(self, pair: Optional[str]) -> List[Dict[str, Any]]:
|
def _rpc_enter_tag_performance(self, pair: Optional[str]) -> List[Dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
Handler for buy tag performance.
|
Handler for buy tag performance.
|
||||||
Shows a performance statistic from finished trades
|
Shows a performance statistic from finished trades
|
||||||
"""
|
"""
|
||||||
buy_tags = Trade.get_buy_tag_performance(pair)
|
buy_tags = Trade.get_enter_tag_performance(pair)
|
||||||
|
|
||||||
return buy_tags
|
return buy_tags
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ class Telegram(RPCHandler):
|
|||||||
CommandHandler('trades', self._trades),
|
CommandHandler('trades', self._trades),
|
||||||
CommandHandler('delete', self._delete_trade),
|
CommandHandler('delete', self._delete_trade),
|
||||||
CommandHandler('performance', self._performance),
|
CommandHandler('performance', self._performance),
|
||||||
CommandHandler('buys', self._buy_tag_performance),
|
CommandHandler(['buys', 'entries'], self._enter_tag_performance),
|
||||||
CommandHandler('sells', self._sell_reason_performance),
|
CommandHandler('sells', self._sell_reason_performance),
|
||||||
CommandHandler('mix_tags', self._mix_tag_performance),
|
CommandHandler('mix_tags', self._mix_tag_performance),
|
||||||
CommandHandler('stats', self._stats),
|
CommandHandler('stats', self._stats),
|
||||||
@ -182,7 +182,8 @@ class Telegram(RPCHandler):
|
|||||||
CallbackQueryHandler(self._profit, pattern='update_profit'),
|
CallbackQueryHandler(self._profit, pattern='update_profit'),
|
||||||
CallbackQueryHandler(self._balance, pattern='update_balance'),
|
CallbackQueryHandler(self._balance, pattern='update_balance'),
|
||||||
CallbackQueryHandler(self._performance, pattern='update_performance'),
|
CallbackQueryHandler(self._performance, pattern='update_performance'),
|
||||||
CallbackQueryHandler(self._buy_tag_performance, pattern='update_buy_tag_performance'),
|
CallbackQueryHandler(self._enter_tag_performance,
|
||||||
|
pattern='update_enter_tag_performance'),
|
||||||
CallbackQueryHandler(self._sell_reason_performance,
|
CallbackQueryHandler(self._sell_reason_performance,
|
||||||
pattern='update_sell_reason_performance'),
|
pattern='update_sell_reason_performance'),
|
||||||
CallbackQueryHandler(self._mix_tag_performance, pattern='update_mix_tag_performance'),
|
CallbackQueryHandler(self._mix_tag_performance, pattern='update_mix_tag_performance'),
|
||||||
@ -972,7 +973,7 @@ class Telegram(RPCHandler):
|
|||||||
self._send_msg(str(e))
|
self._send_msg(str(e))
|
||||||
|
|
||||||
@authorized_only
|
@authorized_only
|
||||||
def _buy_tag_performance(self, update: Update, context: CallbackContext) -> None:
|
def _enter_tag_performance(self, update: Update, context: CallbackContext) -> None:
|
||||||
"""
|
"""
|
||||||
Handler for /buys PAIR .
|
Handler for /buys PAIR .
|
||||||
Shows a performance statistic from finished trades
|
Shows a performance statistic from finished trades
|
||||||
@ -985,7 +986,7 @@ class Telegram(RPCHandler):
|
|||||||
if context.args and isinstance(context.args[0], str):
|
if context.args and isinstance(context.args[0], str):
|
||||||
pair = context.args[0]
|
pair = context.args[0]
|
||||||
|
|
||||||
trades = self._rpc._rpc_buy_tag_performance(pair)
|
trades = self._rpc._rpc_enter_tag_performance(pair)
|
||||||
output = "<b>Buy Tag Performance:</b>\n"
|
output = "<b>Buy Tag Performance:</b>\n"
|
||||||
for i, trade in enumerate(trades):
|
for i, trade in enumerate(trades):
|
||||||
stat_line = (
|
stat_line = (
|
||||||
@ -1001,7 +1002,7 @@ class Telegram(RPCHandler):
|
|||||||
output += stat_line
|
output += stat_line
|
||||||
|
|
||||||
self._send_msg(output, parse_mode=ParseMode.HTML,
|
self._send_msg(output, parse_mode=ParseMode.HTML,
|
||||||
reload_able=True, callback_path="update_buy_tag_performance",
|
reload_able=True, callback_path="update_enter_tag_performance",
|
||||||
query=update.callback_query)
|
query=update.callback_query)
|
||||||
except RPCException as e:
|
except RPCException as e:
|
||||||
self._send_msg(str(e))
|
self._send_msg(str(e))
|
||||||
@ -1277,7 +1278,8 @@ class Telegram(RPCHandler):
|
|||||||
" *table :* `will display trades in a table`\n"
|
" *table :* `will display trades in a table`\n"
|
||||||
" `pending buy orders are marked with an asterisk (*)`\n"
|
" `pending buy orders are marked with an asterisk (*)`\n"
|
||||||
" `pending sell orders are marked with a double asterisk (**)`\n"
|
" `pending sell orders are marked with a double asterisk (**)`\n"
|
||||||
"*/buys <pair|none>:* `Shows the buy_tag performance`\n"
|
# TODO-lev: Update commands and help (?)
|
||||||
|
"*/buys <pair|none>:* `Shows the enter_tag performance`\n"
|
||||||
"*/sells <pair|none>:* `Shows the sell reason performance`\n"
|
"*/sells <pair|none>:* `Shows the sell reason performance`\n"
|
||||||
"*/mix_tags <pair|none>:* `Shows combined buy tag + sell reason performance`\n"
|
"*/mix_tags <pair|none>:* `Shows combined buy tag + sell reason performance`\n"
|
||||||
"*/trades [limit]:* `Lists last closed trades (limited to 10 by default)`\n"
|
"*/trades [limit]:* `Lists last closed trades (limited to 10 by default)`\n"
|
||||||
|
@ -215,8 +215,6 @@ def patch_get_signal(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
:param mocker: mocker to patch IStrategy class
|
:param mocker: mocker to patch IStrategy class
|
||||||
:param value: which value IStrategy.get_signal() must return
|
|
||||||
(buy, sell, buy_tag)
|
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
# returns (Signal-direction, signaname)
|
# returns (Signal-direction, signaname)
|
||||||
|
@ -102,7 +102,7 @@ def mock_trade_2(fee, is_short: bool):
|
|||||||
open_order_id=f'dry_run_sell_{direc(is_short)}_12345',
|
open_order_id=f'dry_run_sell_{direc(is_short)}_12345',
|
||||||
strategy='StrategyTestV3',
|
strategy='StrategyTestV3',
|
||||||
timeframe=5,
|
timeframe=5,
|
||||||
buy_tag='TEST1',
|
enter_tag='TEST1',
|
||||||
sell_reason='sell_signal',
|
sell_reason='sell_signal',
|
||||||
open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=20),
|
open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=20),
|
||||||
close_date=datetime.now(tz=timezone.utc) - timedelta(minutes=2),
|
close_date=datetime.now(tz=timezone.utc) - timedelta(minutes=2),
|
||||||
@ -258,7 +258,7 @@ def mock_trade_5(fee, is_short: bool):
|
|||||||
open_rate=0.123,
|
open_rate=0.123,
|
||||||
exchange='binance',
|
exchange='binance',
|
||||||
strategy='SampleStrategy',
|
strategy='SampleStrategy',
|
||||||
buy_tag='TEST1',
|
enter_tag='TEST1',
|
||||||
stoploss_order_id=f'prod_stoploss_{direc(is_short)}_3455',
|
stoploss_order_id=f'prod_stoploss_{direc(is_short)}_3455',
|
||||||
timeframe=5,
|
timeframe=5,
|
||||||
is_short=is_short
|
is_short=is_short
|
||||||
@ -314,7 +314,7 @@ def mock_trade_6(fee, is_short: bool):
|
|||||||
open_rate=0.15,
|
open_rate=0.15,
|
||||||
exchange='binance',
|
exchange='binance',
|
||||||
strategy='SampleStrategy',
|
strategy='SampleStrategy',
|
||||||
buy_tag='TEST2',
|
enter_tag='TEST2',
|
||||||
open_order_id=f"prod_sell_{direc(is_short)}_6",
|
open_order_id=f"prod_sell_{direc(is_short)}_6",
|
||||||
timeframe=5,
|
timeframe=5,
|
||||||
is_short=is_short
|
is_short=is_short
|
||||||
|
@ -621,6 +621,6 @@ def test_backtest_results(default_conf, fee, mocker, caplog, data) -> None:
|
|||||||
for c, trade in enumerate(data.trades):
|
for c, trade in enumerate(data.trades):
|
||||||
res = results.iloc[c]
|
res = results.iloc[c]
|
||||||
assert res.sell_reason == trade.sell_reason.value
|
assert res.sell_reason == trade.sell_reason.value
|
||||||
assert res.buy_tag == trade.enter_tag
|
assert res.enter_tag == trade.enter_tag
|
||||||
assert res.open_date == _get_frame_time_from_offset(trade.open_tick)
|
assert res.open_date == _get_frame_time_from_offset(trade.open_tick)
|
||||||
assert res.close_date == _get_frame_time_from_offset(trade.close_tick)
|
assert res.close_date == _get_frame_time_from_offset(trade.close_tick)
|
||||||
|
@ -698,7 +698,7 @@ def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None:
|
|||||||
'min_rate': [0.10370188, 0.10300000000000001],
|
'min_rate': [0.10370188, 0.10300000000000001],
|
||||||
'max_rate': [0.10501, 0.1038888],
|
'max_rate': [0.10501, 0.1038888],
|
||||||
'is_open': [False, False],
|
'is_open': [False, False],
|
||||||
'buy_tag': [None, None]
|
'enter_tag': [None, None]
|
||||||
})
|
})
|
||||||
pd.testing.assert_frame_equal(results, expected)
|
pd.testing.assert_frame_equal(results, expected)
|
||||||
data_pair = processed[pair]
|
data_pair = processed[pair]
|
||||||
|
@ -70,6 +70,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
|
|||||||
'max_rate': ANY,
|
'max_rate': ANY,
|
||||||
'strategy': ANY,
|
'strategy': ANY,
|
||||||
'buy_tag': ANY,
|
'buy_tag': ANY,
|
||||||
|
'enter_tag': ANY,
|
||||||
'timeframe': 5,
|
'timeframe': 5,
|
||||||
'open_order_id': ANY,
|
'open_order_id': ANY,
|
||||||
'close_date': None,
|
'close_date': None,
|
||||||
@ -143,6 +144,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
|
|||||||
'max_rate': ANY,
|
'max_rate': ANY,
|
||||||
'strategy': ANY,
|
'strategy': ANY,
|
||||||
'buy_tag': ANY,
|
'buy_tag': ANY,
|
||||||
|
'enter_tag': ANY,
|
||||||
'timeframe': ANY,
|
'timeframe': ANY,
|
||||||
'open_order_id': ANY,
|
'open_order_id': ANY,
|
||||||
'close_date': None,
|
'close_date': None,
|
||||||
@ -842,8 +844,8 @@ def test_performance_handle(default_conf, ticker, limit_buy_order, fee,
|
|||||||
assert prec_satoshi(res[0]['profit_pct'], 6.2)
|
assert prec_satoshi(res[0]['profit_pct'], 6.2)
|
||||||
|
|
||||||
|
|
||||||
def test_buy_tag_performance_handle(default_conf, ticker, limit_buy_order, fee,
|
def test_enter_tag_performance_handle(default_conf, ticker, limit_buy_order, fee,
|
||||||
limit_sell_order, mocker) -> None:
|
limit_sell_order, mocker) -> None:
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
@ -869,23 +871,23 @@ def test_buy_tag_performance_handle(default_conf, ticker, limit_buy_order, fee,
|
|||||||
|
|
||||||
trade.close_date = datetime.utcnow()
|
trade.close_date = datetime.utcnow()
|
||||||
trade.is_open = False
|
trade.is_open = False
|
||||||
res = rpc._rpc_buy_tag_performance(None)
|
res = rpc._rpc_enter_tag_performance(None)
|
||||||
|
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0]['buy_tag'] == 'Other'
|
assert res[0]['enter_tag'] == 'Other'
|
||||||
assert res[0]['count'] == 1
|
assert res[0]['count'] == 1
|
||||||
assert prec_satoshi(res[0]['profit_pct'], 6.2)
|
assert prec_satoshi(res[0]['profit_pct'], 6.2)
|
||||||
|
|
||||||
trade.buy_tag = "TEST_TAG"
|
trade.enter_tag = "TEST_TAG"
|
||||||
res = rpc._rpc_buy_tag_performance(None)
|
res = rpc._rpc_enter_tag_performance(None)
|
||||||
|
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0]['buy_tag'] == 'TEST_TAG'
|
assert res[0]['enter_tag'] == 'TEST_TAG'
|
||||||
assert res[0]['count'] == 1
|
assert res[0]['count'] == 1
|
||||||
assert prec_satoshi(res[0]['profit_pct'], 6.2)
|
assert prec_satoshi(res[0]['profit_pct'], 6.2)
|
||||||
|
|
||||||
|
|
||||||
def test_buy_tag_performance_handle_2(mocker, default_conf, markets, fee):
|
def test_enter_tag_performance_handle_2(mocker, default_conf, markets, fee):
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
@ -896,21 +898,21 @@ def test_buy_tag_performance_handle_2(mocker, default_conf, markets, fee):
|
|||||||
create_mock_trades(fee)
|
create_mock_trades(fee)
|
||||||
rpc = RPC(freqtradebot)
|
rpc = RPC(freqtradebot)
|
||||||
|
|
||||||
res = rpc._rpc_buy_tag_performance(None)
|
res = rpc._rpc_enter_tag_performance(None)
|
||||||
|
|
||||||
assert len(res) == 2
|
assert len(res) == 2
|
||||||
assert res[0]['buy_tag'] == 'TEST1'
|
assert res[0]['enter_tag'] == 'TEST1'
|
||||||
assert res[0]['count'] == 1
|
assert res[0]['count'] == 1
|
||||||
assert prec_satoshi(res[0]['profit_pct'], 0.5)
|
assert prec_satoshi(res[0]['profit_pct'], 0.5)
|
||||||
assert res[1]['buy_tag'] == 'Other'
|
assert res[1]['enter_tag'] == 'Other'
|
||||||
assert res[1]['count'] == 1
|
assert res[1]['count'] == 1
|
||||||
assert prec_satoshi(res[1]['profit_pct'], 1.0)
|
assert prec_satoshi(res[1]['profit_pct'], 1.0)
|
||||||
|
|
||||||
# Test for a specific pair
|
# Test for a specific pair
|
||||||
res = rpc._rpc_buy_tag_performance('ETC/BTC')
|
res = rpc._rpc_enter_tag_performance('ETC/BTC')
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0]['count'] == 1
|
assert res[0]['count'] == 1
|
||||||
assert res[0]['buy_tag'] == 'TEST1'
|
assert res[0]['enter_tag'] == 'TEST1'
|
||||||
assert prec_satoshi(res[0]['profit_pct'], 0.5)
|
assert prec_satoshi(res[0]['profit_pct'], 0.5)
|
||||||
|
|
||||||
|
|
||||||
@ -1020,7 +1022,7 @@ def test_mix_tag_performance_handle(default_conf, ticker, limit_buy_order, fee,
|
|||||||
assert res[0]['count'] == 1
|
assert res[0]['count'] == 1
|
||||||
assert prec_satoshi(res[0]['profit_pct'], 6.2)
|
assert prec_satoshi(res[0]['profit_pct'], 6.2)
|
||||||
|
|
||||||
trade.buy_tag = "TESTBUY"
|
trade.enter_tag = "TESTBUY"
|
||||||
trade.sell_reason = "TESTSELL"
|
trade.sell_reason = "TESTSELL"
|
||||||
res = rpc._rpc_mix_tag_performance(None)
|
res = rpc._rpc_mix_tag_performance(None)
|
||||||
|
|
||||||
|
@ -957,6 +957,7 @@ def test_api_status(botclient, mocker, ticker, fee, markets, is_short,
|
|||||||
'sell_order_status': None,
|
'sell_order_status': None,
|
||||||
'strategy': CURRENT_TEST_STRATEGY,
|
'strategy': CURRENT_TEST_STRATEGY,
|
||||||
'buy_tag': None,
|
'buy_tag': None,
|
||||||
|
'enter_tag': None,
|
||||||
'timeframe': 5,
|
'timeframe': 5,
|
||||||
'exchange': 'binance',
|
'exchange': 'binance',
|
||||||
}
|
}
|
||||||
@ -1115,6 +1116,7 @@ def test_api_forcebuy(botclient, mocker, fee):
|
|||||||
'sell_order_status': None,
|
'sell_order_status': None,
|
||||||
'strategy': CURRENT_TEST_STRATEGY,
|
'strategy': CURRENT_TEST_STRATEGY,
|
||||||
'buy_tag': None,
|
'buy_tag': None,
|
||||||
|
'enter_tag': None,
|
||||||
'timeframe': 5,
|
'timeframe': 5,
|
||||||
'exchange': 'binance',
|
'exchange': 'binance',
|
||||||
}
|
}
|
||||||
|
@ -189,6 +189,7 @@ def test_telegram_status(default_conf, update, mocker) -> None:
|
|||||||
'amount': 90.99181074,
|
'amount': 90.99181074,
|
||||||
'stake_amount': 90.99181074,
|
'stake_amount': 90.99181074,
|
||||||
'buy_tag': None,
|
'buy_tag': None,
|
||||||
|
'enter_tag': None,
|
||||||
'close_profit_ratio': None,
|
'close_profit_ratio': None,
|
||||||
'profit': -0.0059,
|
'profit': -0.0059,
|
||||||
'profit_ratio': -0.0059,
|
'profit_ratio': -0.0059,
|
||||||
@ -954,6 +955,7 @@ def test_telegram_forcesell_handle(default_conf, update, ticker, fee,
|
|||||||
'stake_currency': 'BTC',
|
'stake_currency': 'BTC',
|
||||||
'fiat_currency': 'USD',
|
'fiat_currency': 'USD',
|
||||||
'buy_tag': ANY,
|
'buy_tag': ANY,
|
||||||
|
'enter_tag': ANY,
|
||||||
'sell_reason': SellType.FORCE_SELL.value,
|
'sell_reason': SellType.FORCE_SELL.value,
|
||||||
'open_date': ANY,
|
'open_date': ANY,
|
||||||
'close_date': ANY,
|
'close_date': ANY,
|
||||||
@ -1018,6 +1020,7 @@ def test_telegram_forcesell_down_handle(default_conf, update, ticker, fee,
|
|||||||
'stake_currency': 'BTC',
|
'stake_currency': 'BTC',
|
||||||
'fiat_currency': 'USD',
|
'fiat_currency': 'USD',
|
||||||
'buy_tag': ANY,
|
'buy_tag': ANY,
|
||||||
|
'enter_tag': ANY,
|
||||||
'sell_reason': SellType.FORCE_SELL.value,
|
'sell_reason': SellType.FORCE_SELL.value,
|
||||||
'open_date': ANY,
|
'open_date': ANY,
|
||||||
'close_date': ANY,
|
'close_date': ANY,
|
||||||
@ -1072,6 +1075,7 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, mocker) -> None
|
|||||||
'stake_currency': 'BTC',
|
'stake_currency': 'BTC',
|
||||||
'fiat_currency': 'USD',
|
'fiat_currency': 'USD',
|
||||||
'buy_tag': ANY,
|
'buy_tag': ANY,
|
||||||
|
'enter_tag': ANY,
|
||||||
'sell_reason': SellType.FORCE_SELL.value,
|
'sell_reason': SellType.FORCE_SELL.value,
|
||||||
'open_date': ANY,
|
'open_date': ANY,
|
||||||
'close_date': ANY,
|
'close_date': ANY,
|
||||||
@ -1235,14 +1239,14 @@ def test_buy_tag_performance_handle(default_conf, update, ticker, fee,
|
|||||||
# Simulate fulfilled LIMIT_BUY order for trade
|
# Simulate fulfilled LIMIT_BUY order for trade
|
||||||
trade.update(limit_buy_order)
|
trade.update(limit_buy_order)
|
||||||
|
|
||||||
trade.buy_tag = "TESTBUY"
|
trade.enter_tag = "TESTBUY"
|
||||||
# Simulate fulfilled LIMIT_SELL order for trade
|
# Simulate fulfilled LIMIT_SELL order for trade
|
||||||
trade.update(limit_sell_order)
|
trade.update(limit_sell_order)
|
||||||
|
|
||||||
trade.close_date = datetime.utcnow()
|
trade.close_date = datetime.utcnow()
|
||||||
trade.is_open = False
|
trade.is_open = False
|
||||||
|
|
||||||
telegram._buy_tag_performance(update=update, context=MagicMock())
|
telegram._enter_tag_performance(update=update, context=MagicMock())
|
||||||
assert msg_mock.call_count == 1
|
assert msg_mock.call_count == 1
|
||||||
assert 'Buy Tag Performance' in msg_mock.call_args_list[0][0][0]
|
assert 'Buy Tag Performance' in msg_mock.call_args_list[0][0][0]
|
||||||
assert '<code>TESTBUY\t0.00006217 BTC (6.20%) (1)</code>' in msg_mock.call_args_list[0][0][0]
|
assert '<code>TESTBUY\t0.00006217 BTC (6.20%) (1)</code>' in msg_mock.call_args_list[0][0][0]
|
||||||
@ -1297,7 +1301,7 @@ def test_mix_tag_performance_handle(default_conf, update, ticker, fee,
|
|||||||
# Simulate fulfilled LIMIT_BUY order for trade
|
# Simulate fulfilled LIMIT_BUY order for trade
|
||||||
trade.update(limit_buy_order)
|
trade.update(limit_buy_order)
|
||||||
|
|
||||||
trade.buy_tag = "TESTBUY"
|
trade.enter_tag = "TESTBUY"
|
||||||
trade.sell_reason = "TESTSELL"
|
trade.sell_reason = "TESTSELL"
|
||||||
|
|
||||||
# Simulate fulfilled LIMIT_SELL order for trade
|
# Simulate fulfilled LIMIT_SELL order for trade
|
||||||
@ -1598,7 +1602,7 @@ def test_send_msg_buy_notification(default_conf, mocker, caplog) -> None:
|
|||||||
msg = {
|
msg = {
|
||||||
'type': RPCMessageType.BUY,
|
'type': RPCMessageType.BUY,
|
||||||
'trade_id': 1,
|
'trade_id': 1,
|
||||||
'buy_tag': 'buy_signal_01',
|
'enter_tag': 'buy_signal_01',
|
||||||
'exchange': 'Binance',
|
'exchange': 'Binance',
|
||||||
'pair': 'ETH/BTC',
|
'pair': 'ETH/BTC',
|
||||||
'limit': 1.099e-05,
|
'limit': 1.099e-05,
|
||||||
@ -1616,7 +1620,7 @@ def test_send_msg_buy_notification(default_conf, mocker, caplog) -> None:
|
|||||||
telegram.send_msg(msg)
|
telegram.send_msg(msg)
|
||||||
assert msg_mock.call_args[0][0] \
|
assert msg_mock.call_args[0][0] \
|
||||||
== '\N{LARGE BLUE CIRCLE} *Binance:* Buying ETH/BTC (#1)\n' \
|
== '\N{LARGE BLUE CIRCLE} *Binance:* Buying ETH/BTC (#1)\n' \
|
||||||
'*Buy Tag:* `buy_signal_01`\n' \
|
'*Enter Tag:* `buy_signal_01`\n' \
|
||||||
'*Amount:* `1333.33333333`\n' \
|
'*Amount:* `1333.33333333`\n' \
|
||||||
'*Open Rate:* `0.00001099`\n' \
|
'*Open Rate:* `0.00001099`\n' \
|
||||||
'*Current Rate:* `0.00001099`\n' \
|
'*Current Rate:* `0.00001099`\n' \
|
||||||
@ -1691,7 +1695,7 @@ def test_send_msg_buy_fill_notification(default_conf, mocker) -> None:
|
|||||||
telegram.send_msg({
|
telegram.send_msg({
|
||||||
'type': RPCMessageType.BUY_FILL,
|
'type': RPCMessageType.BUY_FILL,
|
||||||
'trade_id': 1,
|
'trade_id': 1,
|
||||||
'buy_tag': 'buy_signal_01',
|
'enter_tag': 'buy_signal_01',
|
||||||
'exchange': 'Binance',
|
'exchange': 'Binance',
|
||||||
'pair': 'ETH/BTC',
|
'pair': 'ETH/BTC',
|
||||||
'stake_amount': 0.001,
|
'stake_amount': 0.001,
|
||||||
@ -1705,7 +1709,7 @@ def test_send_msg_buy_fill_notification(default_conf, mocker) -> None:
|
|||||||
|
|
||||||
assert msg_mock.call_args[0][0] \
|
assert msg_mock.call_args[0][0] \
|
||||||
== '\N{CHECK MARK} *Binance:* Bought ETH/BTC (#1)\n' \
|
== '\N{CHECK MARK} *Binance:* Bought ETH/BTC (#1)\n' \
|
||||||
'*Buy Tag:* `buy_signal_01`\n' \
|
'*Enter Tag:* `buy_signal_01`\n' \
|
||||||
'*Amount:* `1333.33333333`\n' \
|
'*Amount:* `1333.33333333`\n' \
|
||||||
'*Open Rate:* `0.00001099`\n' \
|
'*Open Rate:* `0.00001099`\n' \
|
||||||
'*Total:* `(0.00100000 BTC, 12.345 USD)`'
|
'*Total:* `(0.00100000 BTC, 12.345 USD)`'
|
||||||
@ -1893,7 +1897,7 @@ def test_send_msg_buy_notification_no_fiat(default_conf, mocker) -> None:
|
|||||||
|
|
||||||
telegram.send_msg({
|
telegram.send_msg({
|
||||||
'type': RPCMessageType.BUY,
|
'type': RPCMessageType.BUY,
|
||||||
'buy_tag': 'buy_signal_01',
|
'enter_tag': 'buy_signal_01',
|
||||||
'trade_id': 1,
|
'trade_id': 1,
|
||||||
'exchange': 'Binance',
|
'exchange': 'Binance',
|
||||||
'pair': 'ETH/BTC',
|
'pair': 'ETH/BTC',
|
||||||
@ -1908,7 +1912,7 @@ def test_send_msg_buy_notification_no_fiat(default_conf, mocker) -> None:
|
|||||||
'open_date': arrow.utcnow().shift(hours=-1)
|
'open_date': arrow.utcnow().shift(hours=-1)
|
||||||
})
|
})
|
||||||
assert msg_mock.call_args[0][0] == ('\N{LARGE BLUE CIRCLE} *Binance:* Buying ETH/BTC (#1)\n'
|
assert msg_mock.call_args[0][0] == ('\N{LARGE BLUE CIRCLE} *Binance:* Buying ETH/BTC (#1)\n'
|
||||||
'*Buy Tag:* `buy_signal_01`\n'
|
'*Enter Tag:* `buy_signal_01`\n'
|
||||||
'*Amount:* `1333.33333333`\n'
|
'*Amount:* `1333.33333333`\n'
|
||||||
'*Open Rate:* `0.00001099`\n'
|
'*Open Rate:* `0.00001099`\n'
|
||||||
'*Current Rate:* `0.00001099`\n'
|
'*Current Rate:* `0.00001099`\n'
|
||||||
@ -1934,14 +1938,14 @@ def test_send_msg_sell_notification_no_fiat(default_conf, mocker) -> None:
|
|||||||
'profit_ratio': -0.57405275,
|
'profit_ratio': -0.57405275,
|
||||||
'stake_currency': 'ETH',
|
'stake_currency': 'ETH',
|
||||||
'fiat_currency': 'USD',
|
'fiat_currency': 'USD',
|
||||||
'buy_tag': 'buy_signal1',
|
'enter_tag': 'buy_signal1',
|
||||||
'sell_reason': SellType.STOP_LOSS.value,
|
'sell_reason': SellType.STOP_LOSS.value,
|
||||||
'open_date': arrow.utcnow().shift(hours=-2, minutes=-35, seconds=-3),
|
'open_date': arrow.utcnow().shift(hours=-2, minutes=-35, seconds=-3),
|
||||||
'close_date': arrow.utcnow(),
|
'close_date': arrow.utcnow(),
|
||||||
})
|
})
|
||||||
assert msg_mock.call_args[0][0] == ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH (#1)\n'
|
assert msg_mock.call_args[0][0] == ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH (#1)\n'
|
||||||
'*Unrealized Profit:* `-57.41%`\n'
|
'*Unrealized Profit:* `-57.41%`\n'
|
||||||
'*Buy Tag:* `buy_signal1`\n'
|
'*Enter Tag:* `buy_signal1`\n'
|
||||||
'*Sell Reason:* `stop_loss`\n'
|
'*Sell Reason:* `stop_loss`\n'
|
||||||
'*Duration:* `2:35:03 (155.1 min)`\n'
|
'*Duration:* `2:35:03 (155.1 min)`\n'
|
||||||
'*Amount:* `1333.33333333`\n'
|
'*Amount:* `1333.33333333`\n'
|
||||||
|
@ -2858,6 +2858,7 @@ def test_execute_trade_exit_up(default_conf_usdt, ticker_usdt, fee, ticker_usdt_
|
|||||||
'amount': amt,
|
'amount': amt,
|
||||||
'order_type': 'limit',
|
'order_type': 'limit',
|
||||||
'buy_tag': None,
|
'buy_tag': None,
|
||||||
|
'enter_tag': None,
|
||||||
'open_rate': open_rate,
|
'open_rate': open_rate,
|
||||||
'current_rate': 2.01 if is_short else 2.3,
|
'current_rate': 2.01 if is_short else 2.3,
|
||||||
'profit_amount': 0.29554455 if is_short else 5.685,
|
'profit_amount': 0.29554455 if is_short else 5.685,
|
||||||
@ -2914,6 +2915,7 @@ def test_execute_trade_exit_down(default_conf_usdt, ticker_usdt, fee, ticker_usd
|
|||||||
'amount': 29.70297029 if is_short else 30.0,
|
'amount': 29.70297029 if is_short else 30.0,
|
||||||
'order_type': 'limit',
|
'order_type': 'limit',
|
||||||
'buy_tag': None,
|
'buy_tag': None,
|
||||||
|
'enter_tag': None,
|
||||||
'open_rate': 2.02 if is_short else 2.0,
|
'open_rate': 2.02 if is_short else 2.0,
|
||||||
'current_rate': 2.2 if is_short else 2.0,
|
'current_rate': 2.2 if is_short else 2.0,
|
||||||
'profit_amount': -5.65990099 if is_short else -0.00075,
|
'profit_amount': -5.65990099 if is_short else -0.00075,
|
||||||
@ -2991,6 +2993,7 @@ def test_execute_trade_exit_custom_exit_price(
|
|||||||
'amount': amount,
|
'amount': amount,
|
||||||
'order_type': 'limit',
|
'order_type': 'limit',
|
||||||
'buy_tag': None,
|
'buy_tag': None,
|
||||||
|
'enter_tag': None,
|
||||||
'open_rate': open_rate,
|
'open_rate': open_rate,
|
||||||
'current_rate': current_rate,
|
'current_rate': current_rate,
|
||||||
'profit_amount': profit_amount,
|
'profit_amount': profit_amount,
|
||||||
@ -3055,6 +3058,7 @@ def test_execute_trade_exit_down_stoploss_on_exchange_dry_run(
|
|||||||
'amount': 29.70297029 if is_short else 30.0,
|
'amount': 29.70297029 if is_short else 30.0,
|
||||||
'order_type': 'limit',
|
'order_type': 'limit',
|
||||||
'buy_tag': None,
|
'buy_tag': None,
|
||||||
|
'enter_tag': None,
|
||||||
'open_rate': 2.02 if is_short else 2.0,
|
'open_rate': 2.02 if is_short else 2.0,
|
||||||
'current_rate': 2.2 if is_short else 2.0,
|
'current_rate': 2.2 if is_short else 2.0,
|
||||||
'profit_amount': -0.3 if is_short else -0.8985,
|
'profit_amount': -0.3 if is_short else -0.8985,
|
||||||
@ -3308,6 +3312,7 @@ def test_execute_trade_exit_market_order(
|
|||||||
'amount': round(amount, 9),
|
'amount': round(amount, 9),
|
||||||
'order_type': 'market',
|
'order_type': 'market',
|
||||||
'buy_tag': None,
|
'buy_tag': None,
|
||||||
|
'enter_tag': None,
|
||||||
'open_rate': open_rate,
|
'open_rate': open_rate,
|
||||||
'current_rate': current_rate,
|
'current_rate': current_rate,
|
||||||
'profit_amount': profit_amount,
|
'profit_amount': profit_amount,
|
||||||
|
@ -1551,7 +1551,7 @@ def test_to_json(default_conf, fee):
|
|||||||
open_date=arrow.utcnow().shift(hours=-2).datetime,
|
open_date=arrow.utcnow().shift(hours=-2).datetime,
|
||||||
open_rate=0.123,
|
open_rate=0.123,
|
||||||
exchange='binance',
|
exchange='binance',
|
||||||
buy_tag=None,
|
enter_tag=None,
|
||||||
open_order_id='dry_run_buy_12345'
|
open_order_id='dry_run_buy_12345'
|
||||||
)
|
)
|
||||||
result = trade.to_json()
|
result = trade.to_json()
|
||||||
@ -1625,7 +1625,7 @@ def test_to_json(default_conf, fee):
|
|||||||
close_date=arrow.utcnow().shift(hours=-1).datetime,
|
close_date=arrow.utcnow().shift(hours=-1).datetime,
|
||||||
open_rate=0.123,
|
open_rate=0.123,
|
||||||
close_rate=0.125,
|
close_rate=0.125,
|
||||||
buy_tag='buys_signal_001',
|
enter_tag='buys_signal_001',
|
||||||
exchange='binance',
|
exchange='binance',
|
||||||
)
|
)
|
||||||
result = trade.to_json()
|
result = trade.to_json()
|
||||||
@ -2118,7 +2118,7 @@ def test_Trade_object_idem():
|
|||||||
'get_open_order_trades',
|
'get_open_order_trades',
|
||||||
'get_trades',
|
'get_trades',
|
||||||
'get_sell_reason_performance',
|
'get_sell_reason_performance',
|
||||||
'get_buy_tag_performance',
|
'get_enter_tag_performance',
|
||||||
'get_mix_tag_performance',
|
'get_mix_tag_performance',
|
||||||
|
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user