From 7d77aff2894d864f3f32417434a58606da2b05da Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 21 Nov 2021 09:24:20 +0100 Subject: [PATCH 1/4] Add some compatibility around buy_tag --- docs/strategy-advanced.md | 6 +++--- docs/strategy-customization.md | 2 +- docs/webhook-config.md | 6 +++--- freqtrade/freqtradebot.py | 5 +++++ freqtrade/persistence/models.py | 1 + freqtrade/rpc/api_server/api_schemas.py | 1 + freqtrade/rpc/telegram.py | 8 ++++---- tests/test_persistence.py | 2 ++ 8 files changed, 20 insertions(+), 11 deletions(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index 573d184ff..908165fc7 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -77,7 +77,7 @@ class AwesomeStrategy(IStrategy): *** -## Buy Tag +## Enter Tag When your strategy has multiple buy signals, you can name the signal that triggered. Then you can access you buy signal on `custom_sell` @@ -89,7 +89,7 @@ def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: (dataframe['rsi'] < 35) & (dataframe['volume'] > 0) ), - ['buy', 'buy_tag']] = (1, 'buy_signal_rsi') + ['buy', 'enter_tag']] = (1, 'buy_signal_rsi') return dataframe @@ -104,7 +104,7 @@ def custom_sell(self, pair: str, trade: Trade, current_time: datetime, current_r ``` !!! Note - `buy_tag` is limited to 100 characters, remaining data will be truncated. + `enter_tag` is limited to 100 characters, remaining data will be truncated. ## Exit tag diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index 178ed108b..e90d87c4a 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -498,7 +498,7 @@ for more information. & (dataframe['volume'] > 0) ), - ['buy', 'buy_tag']] = (1, 'buy_signal_rsi') + ['buy', 'enter_tag']] = (1, 'buy_signal_rsi') return dataframe ``` diff --git a/docs/webhook-config.md b/docs/webhook-config.md index ec944cb50..43aa0502c 100644 --- a/docs/webhook-config.md +++ b/docs/webhook-config.md @@ -83,7 +83,7 @@ Possible parameters are: * `fiat_currency` * `order_type` * `current_rate` -* `buy_tag` +* `enter_tag` ### Webhookbuycancel @@ -101,7 +101,7 @@ Possible parameters are: * `fiat_currency` * `order_type` * `current_rate` -* `buy_tag` +* `enter_tag` ### Webhookbuyfill @@ -117,7 +117,7 @@ Possible parameters are: * `stake_amount` * `stake_currency` * `fiat_currency` -* `buy_tag` +* `enter_tag` ### Webhooksell diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index d234ebb07..237c07060 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -755,6 +755,7 @@ class FreqtradeBot(LoggingMixin): 'trade_id': trade.id, 'type': RPCMessageType.SHORT if trade.is_short else RPCMessageType.BUY, 'buy_tag': trade.buy_tag, + 'enter_tag': trade.buy_tag, 'exchange': self.exchange.name.capitalize(), 'pair': trade.pair, 'limit': trade.open_rate, @@ -780,6 +781,7 @@ class FreqtradeBot(LoggingMixin): 'trade_id': trade.id, 'type': msg_type, 'buy_tag': trade.buy_tag, + 'enter_tag': trade.buy_tag, 'exchange': self.exchange.name.capitalize(), 'pair': trade.pair, 'limit': trade.open_rate, @@ -802,6 +804,7 @@ class FreqtradeBot(LoggingMixin): 'trade_id': trade.id, 'type': msg_type, 'buy_tag': trade.buy_tag, + 'enter_tag': trade.buy_tag, 'exchange': self.exchange.name.capitalize(), 'pair': trade.pair, 'open_rate': trade.open_rate, @@ -1384,6 +1387,7 @@ class FreqtradeBot(LoggingMixin): 'current_rate': current_rate, 'profit_amount': profit_trade, 'profit_ratio': profit_ratio, + 'enter_tag': trade.buy_tag, 'buy_tag': trade.buy_tag, 'sell_reason': trade.sell_reason, 'open_date': trade.open_date, @@ -1428,6 +1432,7 @@ class FreqtradeBot(LoggingMixin): 'current_rate': current_rate, 'profit_amount': profit_trade, 'profit_ratio': profit_ratio, + 'enter_tag': trade.buy_tag, 'buy_tag': trade.buy_tag, 'sell_reason': trade.sell_reason, 'open_date': trade.open_date, diff --git a/freqtrade/persistence/models.py b/freqtrade/persistence/models.py index f9df45111..f73edbe02 100644 --- a/freqtrade/persistence/models.py +++ b/freqtrade/persistence/models.py @@ -390,6 +390,7 @@ class LocalTrade(): 'stake_amount': round(self.stake_amount, 8), 'strategy': self.strategy, 'buy_tag': self.buy_tag, + 'enter_tag': self.buy_tag, 'timeframe': self.timeframe, 'fee_open': self.fee_open, diff --git a/freqtrade/rpc/api_server/api_schemas.py b/freqtrade/rpc/api_server/api_schemas.py index d6a861011..db4378a51 100644 --- a/freqtrade/rpc/api_server/api_schemas.py +++ b/freqtrade/rpc/api_server/api_schemas.py @@ -185,6 +185,7 @@ class TradeSchema(BaseModel): stake_amount: float strategy: str buy_tag: Optional[str] + enter_tag: Optional[str] timeframe: int fee_open: Optional[float] fee_open_cost: Optional[float] diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 0e1a6fe27..3bcc6adf2 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -226,7 +226,7 @@ class Telegram(RPCHandler): f"{emoji} *{msg['exchange']}:* {'Bought' if is_fill else 'Buying'} {msg['pair']}" f" (#{msg['trade_id']})\n" ) - message += f"*Buy Tag:* `{msg['buy_tag']}`\n" if msg.get('buy_tag', None) else "" + message += f"*Enter Tag:* `{msg['enter_tag']}`\n" if msg.get('enter_tag', None) else "" message += f"*Amount:* `{msg['amount']:.8f}`\n" if msg['type'] == RPCMessageType.BUY_FILL: @@ -251,7 +251,7 @@ class Telegram(RPCHandler): microsecond=0) - msg['open_date'].replace(microsecond=0) msg['duration_min'] = msg['duration'].total_seconds() / 60 - msg['buy_tag'] = msg['buy_tag'] if "buy_tag" in msg.keys() else None + msg['enter_tag'] = msg['enter_tag'] if "enter_tag" in msg.keys() else None msg['emoji'] = self._get_sell_emoji(msg) # Check if all sell properties are available. @@ -397,7 +397,7 @@ class Telegram(RPCHandler): "*Trade ID:* `{trade_id}` `(since {open_date_hum})`", "*Current Pair:* {pair}", "*Amount:* `{amount} ({stake_amount} {base_currency})`", - "*Buy Tag:* `{buy_tag}`" if r['buy_tag'] else "", + "*Enter Tag:* `{enter_tag}`" if r['enter_tag'] else "", "*Open Rate:* `{open_rate:.8f}`", "*Close Rate:* `{close_rate}`" if r['close_rate'] else "", "*Current Rate:* `{current_rate:.8f}`", @@ -989,7 +989,7 @@ class Telegram(RPCHandler): output = "Buy Tag Performance:\n" for i, trade in enumerate(trades): stat_line = ( - f"{i+1}.\t {trade['buy_tag']}\t" + f"{i+1}.\t {trade['enter_tag']}\t" f"{round_coin_value(trade['profit_abs'], self._config['stake_currency'])} " f"({trade['profit_ratio']:.2%}) " f"({trade['count']})\n") diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 2f5f61a15..9df4f511a 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -1602,6 +1602,7 @@ def test_to_json(default_conf, fee): 'max_rate': None, 'strategy': None, 'buy_tag': None, + 'enter_tag': None, 'timeframe': None, 'exchange': 'binance', 'leverage': None, @@ -1675,6 +1676,7 @@ def test_to_json(default_conf, fee): 'sell_order_status': None, 'strategy': None, 'buy_tag': 'buys_signal_001', + 'enter_tag': 'buys_signal_001', 'timeframe': None, 'exchange': 'binance', 'leverage': None, From 36deced00bbef878e5858fdfd7da26d2dbdd1fd5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 21 Nov 2021 09:51:16 +0100 Subject: [PATCH 2/4] Remove more buy_tag references --- docs/deprecated.md | 21 ++++++++++++++ docs/strategy-advanced.md | 2 +- freqtrade/data/btanalysis.py | 2 +- freqtrade/freqtradebot.py | 23 ++++++++-------- freqtrade/optimize/backtesting.py | 2 +- freqtrade/persistence/migrations.py | 6 ++-- freqtrade/persistence/models.py | 38 ++++++++++++++++---------- freqtrade/rpc/rpc.py | 4 +-- freqtrade/rpc/telegram.py | 14 ++++++---- tests/conftest.py | 2 -- tests/conftest_trades.py | 6 ++-- tests/optimize/test_backtest_detail.py | 2 +- tests/optimize/test_backtesting.py | 2 +- tests/rpc/test_rpc.py | 30 ++++++++++---------- tests/rpc/test_rpc_apiserver.py | 2 ++ tests/rpc/test_rpc_telegram.py | 26 ++++++++++-------- tests/test_freqtradebot.py | 5 ++++ tests/test_persistence.py | 6 ++-- 18 files changed, 117 insertions(+), 76 deletions(-) diff --git a/docs/deprecated.md b/docs/deprecated.md index d86a7ac7a..be1d51837 100644 --- a/docs/deprecated.md +++ b/docs/deprecated.md @@ -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. 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. diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index 908165fc7..560b4dcb6 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -97,7 +97,7 @@ def custom_sell(self, pair: str, trade: Trade, current_time: datetime, current_r current_profit: float, **kwargs): dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) 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 None diff --git a/freqtrade/data/btanalysis.py b/freqtrade/data/btanalysis.py index e8d878838..48b58f193 100644 --- a/freqtrade/data/btanalysis.py +++ b/freqtrade/data/btanalysis.py @@ -30,7 +30,7 @@ BT_DATA_COLUMNS = ['pair', 'stake_amount', 'amount', 'open_date', 'close_date', 'fee_open', 'fee_close', 'trade_duration', 'profit_ratio', 'profit_abs', 'sell_reason', '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?, ...?) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 237c07060..bcef984dd 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -721,8 +721,7 @@ class FreqtradeBot(LoggingMixin): exchange=self.exchange.id, open_order_id=order_id, strategy=self.strategy.get_strategy_name(), - # TODO-lev: compatibility layer for buy_tag (!) - buy_tag=enter_tag, + enter_tag=enter_tag, timeframe=timeframe_to_minutes(self.config['timeframe']), leverage=leverage, is_short=is_short, @@ -754,8 +753,8 @@ class FreqtradeBot(LoggingMixin): msg = { 'trade_id': trade.id, 'type': RPCMessageType.SHORT if trade.is_short else RPCMessageType.BUY, - 'buy_tag': trade.buy_tag, - 'enter_tag': trade.buy_tag, + 'buy_tag': trade.enter_tag, + 'enter_tag': trade.enter_tag, 'exchange': self.exchange.name.capitalize(), 'pair': trade.pair, 'limit': trade.open_rate, @@ -780,8 +779,8 @@ class FreqtradeBot(LoggingMixin): msg = { 'trade_id': trade.id, 'type': msg_type, - 'buy_tag': trade.buy_tag, - 'enter_tag': trade.buy_tag, + 'buy_tag': trade.enter_tag, + 'enter_tag': trade.enter_tag, 'exchange': self.exchange.name.capitalize(), 'pair': trade.pair, 'limit': trade.open_rate, @@ -803,8 +802,8 @@ class FreqtradeBot(LoggingMixin): msg = { 'trade_id': trade.id, 'type': msg_type, - 'buy_tag': trade.buy_tag, - 'enter_tag': trade.buy_tag, + 'buy_tag': trade.enter_tag, + 'enter_tag': trade.enter_tag, 'exchange': self.exchange.name.capitalize(), 'pair': trade.pair, 'open_rate': trade.open_rate, @@ -1387,8 +1386,8 @@ class FreqtradeBot(LoggingMixin): 'current_rate': current_rate, 'profit_amount': profit_trade, 'profit_ratio': profit_ratio, - 'enter_tag': trade.buy_tag, - 'buy_tag': trade.buy_tag, + 'buy_tag': trade.enter_tag, + 'enter_tag': trade.enter_tag, 'sell_reason': trade.sell_reason, 'open_date': trade.open_date, 'close_date': trade.close_date or datetime.utcnow(), @@ -1432,8 +1431,8 @@ class FreqtradeBot(LoggingMixin): 'current_rate': current_rate, 'profit_amount': profit_trade, 'profit_ratio': profit_ratio, - 'enter_tag': trade.buy_tag, - 'buy_tag': trade.buy_tag, + 'buy_tag': trade.enter_tag, + 'enter_tag': trade.enter_tag, 'sell_reason': trade.sell_reason, 'open_date': trade.open_date, 'close_date': trade.close_date or datetime.now(timezone.utc), diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 0f4d17fd8..a18d14cbe 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -478,7 +478,7 @@ class Backtesting: fee_open=self.fee, fee_close=self.fee, 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, is_short=(direction == 'short'), ) diff --git a/freqtrade/persistence/migrations.py b/freqtrade/persistence/migrations.py index 2b1d10bc1..212499df3 100644 --- a/freqtrade/persistence/migrations.py +++ b/freqtrade/persistence/migrations.py @@ -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') sell_reason = get_column_def(cols, 'sell_reason', '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') @@ -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, stop_loss, stop_loss_pct, initial_stop_loss, initial_stop_loss_pct, 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, trading_mode, leverage, isolated_liq, is_short, 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, {max_rate} max_rate, {min_rate} min_rate, {sell_reason} sell_reason, {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, {trading_mode} trading_mode, {leverage} leverage, {isolated_liq} isolated_liq, {is_short} is_short, {interest_rate} interest_rate, diff --git a/freqtrade/persistence/models.py b/freqtrade/persistence/models.py index f73edbe02..3314f8204 100644 --- a/freqtrade/persistence/models.py +++ b/freqtrade/persistence/models.py @@ -264,7 +264,7 @@ class LocalTrade(): sell_reason: str = '' sell_order_status: str = '' strategy: str = '' - buy_tag: Optional[str] = None + enter_tag: Optional[str] = None timeframe: Optional[int] = None trading_mode: TradingMode = TradingMode.SPOT @@ -280,6 +280,14 @@ class LocalTrade(): # Futures properties 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 def has_no_leverage(self) -> bool: """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, 'stake_amount': round(self.stake_amount, 8), 'strategy': self.strategy, - 'buy_tag': self.buy_tag, - 'enter_tag': self.buy_tag, + 'buy_tag': self.enter_tag, + 'enter_tag': self.enter_tag, 'timeframe': self.timeframe, 'fee_open': self.fee_open, @@ -929,7 +937,7 @@ class Trade(_DECL_BASE, LocalTrade): sell_reason = Column(String(100), nullable=True) sell_order_status = 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) trading_mode = Column(Enum(TradingMode), nullable=True) @@ -1100,7 +1108,7 @@ class Trade(_DECL_BASE, LocalTrade): ] @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 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): filters.append(Trade.pair == pair) - buy_tag_perf = Trade.query.with_entities( - Trade.buy_tag, + enter_tag_perf = Trade.query.with_entities( + Trade.enter_tag, func.sum(Trade.close_profit).label('profit_sum'), func.sum(Trade.close_profit_abs).label('profit_sum_abs'), func.count(Trade.pair).label('count') ).filter(*filters)\ - .group_by(Trade.buy_tag) \ + .group_by(Trade.enter_tag) \ .order_by(desc('profit_sum_abs')) \ .all() 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_pct': round(profit * 100, 2), 'profit_abs': profit_abs, '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 @@ -1179,7 +1187,7 @@ class Trade(_DECL_BASE, LocalTrade): mix_tag_perf = Trade.query.with_entities( Trade.id, - Trade.buy_tag, + Trade.enter_tag, Trade.sell_reason, func.sum(Trade.close_profit).label('profit_sum'), func.sum(Trade.close_profit_abs).label('profit_sum_abs'), @@ -1190,12 +1198,12 @@ class Trade(_DECL_BASE, LocalTrade): .all() return_list: List[Dict] = [] - for id, buy_tag, sell_reason, profit, profit_abs, count in mix_tag_perf: - buy_tag = buy_tag if buy_tag is not None else "Other" + for id, enter_tag, sell_reason, profit, profit_abs, count in mix_tag_perf: + enter_tag = enter_tag if enter_tag 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): - mix_tag = buy_tag + " " + sell_reason + if(sell_reason is not None and enter_tag is not None): + mix_tag = enter_tag + " " + sell_reason i = 0 if not any(item["mix_tag"] == mix_tag for item in return_list): return_list.append({'mix_tag': mix_tag, diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 9a47cd112..2a1445e1a 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -782,12 +782,12 @@ class RPC: 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. 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 diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 3bcc6adf2..35811e1be 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -154,7 +154,7 @@ class Telegram(RPCHandler): CommandHandler('trades', self._trades), CommandHandler('delete', self._delete_trade), CommandHandler('performance', self._performance), - CommandHandler('buys', self._buy_tag_performance), + CommandHandler(['buys', 'entries'], self._enter_tag_performance), CommandHandler('sells', self._sell_reason_performance), CommandHandler('mix_tags', self._mix_tag_performance), CommandHandler('stats', self._stats), @@ -182,7 +182,8 @@ class Telegram(RPCHandler): CallbackQueryHandler(self._profit, pattern='update_profit'), CallbackQueryHandler(self._balance, pattern='update_balance'), 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, pattern='update_sell_reason_performance'), CallbackQueryHandler(self._mix_tag_performance, pattern='update_mix_tag_performance'), @@ -972,7 +973,7 @@ class Telegram(RPCHandler): self._send_msg(str(e)) @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 . Shows a performance statistic from finished trades @@ -985,7 +986,7 @@ class Telegram(RPCHandler): if context.args and isinstance(context.args[0], str): pair = context.args[0] - trades = self._rpc._rpc_buy_tag_performance(pair) + trades = self._rpc._rpc_enter_tag_performance(pair) output = "Buy Tag Performance:\n" for i, trade in enumerate(trades): stat_line = ( @@ -1001,7 +1002,7 @@ class Telegram(RPCHandler): output += stat_line 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) except RPCException as e: self._send_msg(str(e)) @@ -1277,7 +1278,8 @@ class Telegram(RPCHandler): " *table :* `will display trades in a table`\n" " `pending buy orders are marked with an asterisk (*)`\n" " `pending sell orders are marked with a double asterisk (**)`\n" - "*/buys :* `Shows the buy_tag performance`\n" + # TODO-lev: Update commands and help (?) + "*/buys :* `Shows the enter_tag performance`\n" "*/sells :* `Shows the sell reason performance`\n" "*/mix_tags :* `Shows combined buy tag + sell reason performance`\n" "*/trades [limit]:* `Lists last closed trades (limited to 10 by default)`\n" diff --git a/tests/conftest.py b/tests/conftest.py index e184903d1..6a85f5de2 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -215,8 +215,6 @@ def patch_get_signal( ) -> None: """ :param mocker: mocker to patch IStrategy class - :param value: which value IStrategy.get_signal() must return - (buy, sell, buy_tag) :return: None """ # returns (Signal-direction, signaname) diff --git a/tests/conftest_trades.py b/tests/conftest_trades.py index 0ad01e72f..a245033b9 100644 --- a/tests/conftest_trades.py +++ b/tests/conftest_trades.py @@ -102,7 +102,7 @@ def mock_trade_2(fee, is_short: bool): open_order_id=f'dry_run_sell_{direc(is_short)}_12345', strategy='StrategyTestV3', timeframe=5, - buy_tag='TEST1', + enter_tag='TEST1', sell_reason='sell_signal', open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=20), 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, exchange='binance', strategy='SampleStrategy', - buy_tag='TEST1', + enter_tag='TEST1', stoploss_order_id=f'prod_stoploss_{direc(is_short)}_3455', timeframe=5, is_short=is_short @@ -314,7 +314,7 @@ def mock_trade_6(fee, is_short: bool): open_rate=0.15, exchange='binance', strategy='SampleStrategy', - buy_tag='TEST2', + enter_tag='TEST2', open_order_id=f"prod_sell_{direc(is_short)}_6", timeframe=5, is_short=is_short diff --git a/tests/optimize/test_backtest_detail.py b/tests/optimize/test_backtest_detail.py index 599450b57..6db88d123 100644 --- a/tests/optimize/test_backtest_detail.py +++ b/tests/optimize/test_backtest_detail.py @@ -621,6 +621,6 @@ def test_backtest_results(default_conf, fee, mocker, caplog, data) -> None: for c, trade in enumerate(data.trades): res = results.iloc[c] 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.close_date == _get_frame_time_from_offset(trade.close_tick) diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py index 19aa56ef4..e50c88b46 100644 --- a/tests/optimize/test_backtesting.py +++ b/tests/optimize/test_backtesting.py @@ -698,7 +698,7 @@ def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None: 'min_rate': [0.10370188, 0.10300000000000001], 'max_rate': [0.10501, 0.1038888], 'is_open': [False, False], - 'buy_tag': [None, None] + 'enter_tag': [None, None] }) pd.testing.assert_frame_equal(results, expected) data_pair = processed[pair] diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index 9821c9468..5996fc1f7 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -70,6 +70,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: 'max_rate': ANY, 'strategy': ANY, 'buy_tag': ANY, + 'enter_tag': ANY, 'timeframe': 5, 'open_order_id': ANY, 'close_date': None, @@ -143,6 +144,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None: 'max_rate': ANY, 'strategy': ANY, 'buy_tag': ANY, + 'enter_tag': ANY, 'timeframe': ANY, 'open_order_id': ANY, '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) -def test_buy_tag_performance_handle(default_conf, ticker, limit_buy_order, fee, - limit_sell_order, mocker) -> None: +def test_enter_tag_performance_handle(default_conf, ticker, limit_buy_order, fee, + limit_sell_order, mocker) -> None: mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( '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.is_open = False - res = rpc._rpc_buy_tag_performance(None) + res = rpc._rpc_enter_tag_performance(None) assert len(res) == 1 - assert res[0]['buy_tag'] == 'Other' + assert res[0]['enter_tag'] == 'Other' assert res[0]['count'] == 1 assert prec_satoshi(res[0]['profit_pct'], 6.2) - trade.buy_tag = "TEST_TAG" - res = rpc._rpc_buy_tag_performance(None) + trade.enter_tag = "TEST_TAG" + res = rpc._rpc_enter_tag_performance(None) assert len(res) == 1 - assert res[0]['buy_tag'] == 'TEST_TAG' + assert res[0]['enter_tag'] == 'TEST_TAG' assert res[0]['count'] == 1 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.multiple( 'freqtrade.exchange.Exchange', @@ -896,21 +898,21 @@ def test_buy_tag_performance_handle_2(mocker, default_conf, markets, fee): create_mock_trades(fee) rpc = RPC(freqtradebot) - res = rpc._rpc_buy_tag_performance(None) + res = rpc._rpc_enter_tag_performance(None) assert len(res) == 2 - assert res[0]['buy_tag'] == 'TEST1' + assert res[0]['enter_tag'] == 'TEST1' assert res[0]['count'] == 1 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 prec_satoshi(res[1]['profit_pct'], 1.0) # 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 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) @@ -1020,7 +1022,7 @@ def test_mix_tag_performance_handle(default_conf, ticker, limit_buy_order, fee, assert res[0]['count'] == 1 assert prec_satoshi(res[0]['profit_pct'], 6.2) - trade.buy_tag = "TESTBUY" + trade.enter_tag = "TESTBUY" trade.sell_reason = "TESTSELL" res = rpc._rpc_mix_tag_performance(None) diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index f2096c0c0..332478c64 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -957,6 +957,7 @@ def test_api_status(botclient, mocker, ticker, fee, markets, is_short, 'sell_order_status': None, 'strategy': CURRENT_TEST_STRATEGY, 'buy_tag': None, + 'enter_tag': None, 'timeframe': 5, 'exchange': 'binance', } @@ -1115,6 +1116,7 @@ def test_api_forcebuy(botclient, mocker, fee): 'sell_order_status': None, 'strategy': CURRENT_TEST_STRATEGY, 'buy_tag': None, + 'enter_tag': None, 'timeframe': 5, 'exchange': 'binance', } diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index f64f05ddd..c01820599 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -189,6 +189,7 @@ def test_telegram_status(default_conf, update, mocker) -> None: 'amount': 90.99181074, 'stake_amount': 90.99181074, 'buy_tag': None, + 'enter_tag': None, 'close_profit_ratio': None, 'profit': -0.0059, 'profit_ratio': -0.0059, @@ -954,6 +955,7 @@ def test_telegram_forcesell_handle(default_conf, update, ticker, fee, 'stake_currency': 'BTC', 'fiat_currency': 'USD', 'buy_tag': ANY, + 'enter_tag': ANY, 'sell_reason': SellType.FORCE_SELL.value, 'open_date': ANY, 'close_date': ANY, @@ -1018,6 +1020,7 @@ def test_telegram_forcesell_down_handle(default_conf, update, ticker, fee, 'stake_currency': 'BTC', 'fiat_currency': 'USD', 'buy_tag': ANY, + 'enter_tag': ANY, 'sell_reason': SellType.FORCE_SELL.value, 'open_date': ANY, 'close_date': ANY, @@ -1072,6 +1075,7 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, mocker) -> None 'stake_currency': 'BTC', 'fiat_currency': 'USD', 'buy_tag': ANY, + 'enter_tag': ANY, 'sell_reason': SellType.FORCE_SELL.value, 'open_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 trade.update(limit_buy_order) - trade.buy_tag = "TESTBUY" + trade.enter_tag = "TESTBUY" # Simulate fulfilled LIMIT_SELL order for trade trade.update(limit_sell_order) trade.close_date = datetime.utcnow() 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 'Buy Tag Performance' in msg_mock.call_args_list[0][0][0] assert 'TESTBUY\t0.00006217 BTC (6.20%) (1)' 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 trade.update(limit_buy_order) - trade.buy_tag = "TESTBUY" + trade.enter_tag = "TESTBUY" trade.sell_reason = "TESTSELL" # Simulate fulfilled LIMIT_SELL order for trade @@ -1598,7 +1602,7 @@ def test_send_msg_buy_notification(default_conf, mocker, caplog) -> None: msg = { 'type': RPCMessageType.BUY, 'trade_id': 1, - 'buy_tag': 'buy_signal_01', + 'enter_tag': 'buy_signal_01', 'exchange': 'Binance', 'pair': 'ETH/BTC', 'limit': 1.099e-05, @@ -1616,7 +1620,7 @@ def test_send_msg_buy_notification(default_conf, mocker, caplog) -> None: telegram.send_msg(msg) 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' \ '*Open 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({ 'type': RPCMessageType.BUY_FILL, 'trade_id': 1, - 'buy_tag': 'buy_signal_01', + 'enter_tag': 'buy_signal_01', 'exchange': 'Binance', 'pair': 'ETH/BTC', '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] \ == '\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' \ '*Open Rate:* `0.00001099`\n' \ '*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({ 'type': RPCMessageType.BUY, - 'buy_tag': 'buy_signal_01', + 'enter_tag': 'buy_signal_01', 'trade_id': 1, 'exchange': 'Binance', '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) }) 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' '*Open 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, 'stake_currency': 'ETH', 'fiat_currency': 'USD', - 'buy_tag': 'buy_signal1', + 'enter_tag': 'buy_signal1', 'sell_reason': SellType.STOP_LOSS.value, 'open_date': arrow.utcnow().shift(hours=-2, minutes=-35, seconds=-3), 'close_date': arrow.utcnow(), }) assert msg_mock.call_args[0][0] == ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH (#1)\n' '*Unrealized Profit:* `-57.41%`\n' - '*Buy Tag:* `buy_signal1`\n' + '*Enter Tag:* `buy_signal1`\n' '*Sell Reason:* `stop_loss`\n' '*Duration:* `2:35:03 (155.1 min)`\n' '*Amount:* `1333.33333333`\n' diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 08b2801f7..54d3a95a0 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -2858,6 +2858,7 @@ def test_execute_trade_exit_up(default_conf_usdt, ticker_usdt, fee, ticker_usdt_ 'amount': amt, 'order_type': 'limit', 'buy_tag': None, + 'enter_tag': None, 'open_rate': open_rate, 'current_rate': 2.01 if is_short else 2.3, '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, 'order_type': 'limit', 'buy_tag': None, + 'enter_tag': None, 'open_rate': 2.02 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, @@ -2991,6 +2993,7 @@ def test_execute_trade_exit_custom_exit_price( 'amount': amount, 'order_type': 'limit', 'buy_tag': None, + 'enter_tag': None, 'open_rate': open_rate, 'current_rate': current_rate, '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, 'order_type': 'limit', 'buy_tag': None, + 'enter_tag': None, 'open_rate': 2.02 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, @@ -3308,6 +3312,7 @@ def test_execute_trade_exit_market_order( 'amount': round(amount, 9), 'order_type': 'market', 'buy_tag': None, + 'enter_tag': None, 'open_rate': open_rate, 'current_rate': current_rate, 'profit_amount': profit_amount, diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 9df4f511a..f1401eef1 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -1551,7 +1551,7 @@ def test_to_json(default_conf, fee): open_date=arrow.utcnow().shift(hours=-2).datetime, open_rate=0.123, exchange='binance', - buy_tag=None, + enter_tag=None, open_order_id='dry_run_buy_12345' ) result = trade.to_json() @@ -1625,7 +1625,7 @@ def test_to_json(default_conf, fee): close_date=arrow.utcnow().shift(hours=-1).datetime, open_rate=0.123, close_rate=0.125, - buy_tag='buys_signal_001', + enter_tag='buys_signal_001', exchange='binance', ) result = trade.to_json() @@ -2118,7 +2118,7 @@ def test_Trade_object_idem(): 'get_open_order_trades', 'get_trades', 'get_sell_reason_performance', - 'get_buy_tag_performance', + 'get_enter_tag_performance', 'get_mix_tag_performance', ) From 2a84526f04718c84872ce46007d310efb45e0272 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 21 Nov 2021 10:05:56 +0100 Subject: [PATCH 3/4] Remove more buy_tag references --- freqtrade/rpc/api_server/api_schemas.py | 2 +- freqtrade/rpc/rpc.py | 10 +++------- freqtrade/rpc/telegram.py | 2 +- tests/rpc/test_rpc_telegram.py | 16 ++++++++-------- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/freqtrade/rpc/api_server/api_schemas.py b/freqtrade/rpc/api_server/api_schemas.py index db4378a51..cc92cb81e 100644 --- a/freqtrade/rpc/api_server/api_schemas.py +++ b/freqtrade/rpc/api_server/api_schemas.py @@ -184,7 +184,7 @@ class TradeSchema(BaseModel): amount_requested: float stake_amount: float strategy: str - buy_tag: Optional[str] + buy_tag: Optional[str] # Deprecated enter_tag: Optional[str] timeframe: int fee_open: Optional[float] diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 2a1445e1a..7242bec2a 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -787,22 +787,18 @@ class RPC: Handler for buy tag performance. Shows a performance statistic from finished trades """ - buy_tags = Trade.get_enter_tag_performance(pair) - - return buy_tags + return Trade.get_enter_tag_performance(pair) def _rpc_sell_reason_performance(self, pair: Optional[str]) -> List[Dict[str, Any]]: """ Handler for sell reason performance. Shows a performance statistic from finished trades """ - sell_reasons = Trade.get_sell_reason_performance(pair) - - return sell_reasons + return Trade.get_sell_reason_performance(pair) def _rpc_mix_tag_performance(self, pair: Optional[str]) -> List[Dict[str, Any]]: """ - Handler for mix tag (buy_tag + sell_reason) performance. + Handler for mix tag (enter_tag + sell_reason) performance. Shows a performance statistic from finished trades """ mix_tags = Trade.get_mix_tag_performance(pair) diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 35811e1be..3e7332db7 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -272,7 +272,7 @@ class Telegram(RPCHandler): f"{'Sold' if is_fill else 'Selling'} {msg['pair']} (#{msg['trade_id']})\n" f"*{'Profit' if is_fill else 'Unrealized Profit'}:* " f"`{msg['profit_ratio']:.2%}{msg['profit_extra']}`\n" - f"*Buy Tag:* `{msg['buy_tag']}`\n" + f"*Enter Tag:* `{msg['enter_tag']}`\n" f"*Sell Reason:* `{msg['sell_reason']}`\n" f"*Duration:* `{msg['duration']} ({msg['duration_min']:.1f} min)`\n" f"*Amount:* `{msg['amount']:.8f}`\n") diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index c01820599..35d7b365f 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -93,7 +93,7 @@ def test_telegram_init(default_conf, mocker, caplog) -> None: message_str = ("rpc.telegram is listening for following commands: [['status'], ['profit'], " "['balance'], ['start'], ['stop'], ['forcesell'], ['forcebuy'], ['trades'], " - "['delete'], ['performance'], ['buys'], ['sells'], ['mix_tags'], " + "['delete'], ['performance'], ['buys', 'entries'], ['sells'], ['mix_tags'], " "['stats'], ['daily'], ['weekly'], ['monthly'], " "['count'], ['locks'], ['unlock', 'delete_locks'], " "['reload_config', 'reload_conf'], ['show_config', 'show_conf'], " @@ -1648,7 +1648,7 @@ def test_send_msg_buy_cancel_notification(default_conf, mocker) -> None: telegram.send_msg({ 'type': RPCMessageType.BUY_CANCEL, - 'buy_tag': 'buy_signal_01', + 'enter_tag': 'buy_signal_01', 'trade_id': 1, 'exchange': 'Binance', 'pair': 'ETH/BTC', @@ -1736,7 +1736,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None: 'profit_ratio': -0.57405275, 'stake_currency': 'ETH', 'fiat_currency': 'USD', - 'buy_tag': 'buy_signal1', + 'enter_tag': 'buy_signal1', 'sell_reason': SellType.STOP_LOSS.value, 'open_date': arrow.utcnow().shift(hours=-1), 'close_date': arrow.utcnow(), @@ -1744,7 +1744,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None: assert msg_mock.call_args[0][0] \ == ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH (#1)\n' '*Unrealized Profit:* `-57.41% (loss: -0.05746268 ETH / -24.812 USD)`\n' - '*Buy Tag:* `buy_signal1`\n' + '*Enter Tag:* `buy_signal1`\n' '*Sell Reason:* `stop_loss`\n' '*Duration:* `1:00:00 (60.0 min)`\n' '*Amount:* `1333.33333333`\n' @@ -1768,7 +1768,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None: 'profit_amount': -0.05746268, 'profit_ratio': -0.57405275, 'stake_currency': 'ETH', - 'buy_tag': 'buy_signal1', + 'enter_tag': 'buy_signal1', 'sell_reason': SellType.STOP_LOSS.value, 'open_date': arrow.utcnow().shift(days=-1, hours=-2, minutes=-30), 'close_date': arrow.utcnow(), @@ -1776,7 +1776,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None: assert msg_mock.call_args[0][0] \ == ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH (#1)\n' '*Unrealized Profit:* `-57.41%`\n' - '*Buy Tag:* `buy_signal1`\n' + '*Enter Tag:* `buy_signal1`\n' '*Sell Reason:* `stop_loss`\n' '*Duration:* `1 day, 2:30:00 (1590.0 min)`\n' '*Amount:* `1333.33333333`\n' @@ -1839,7 +1839,7 @@ def test_send_msg_sell_fill_notification(default_conf, mocker) -> None: 'profit_amount': -0.05746268, 'profit_ratio': -0.57405275, 'stake_currency': 'ETH', - 'buy_tag': 'buy_signal1', + 'enter_tag': 'buy_signal1', 'sell_reason': SellType.STOP_LOSS.value, 'open_date': arrow.utcnow().shift(days=-1, hours=-2, minutes=-30), 'close_date': arrow.utcnow(), @@ -1847,7 +1847,7 @@ def test_send_msg_sell_fill_notification(default_conf, mocker) -> None: assert msg_mock.call_args[0][0] \ == ('\N{WARNING SIGN} *Binance:* Sold KEY/ETH (#1)\n' '*Profit:* `-57.41%`\n' - '*Buy Tag:* `buy_signal1`\n' + '*Enter Tag:* `buy_signal1`\n' '*Sell Reason:* `stop_loss`\n' '*Duration:* `1 day, 2:30:00 (1590.0 min)`\n' '*Amount:* `1333.33333333`\n' From 192ac88314f6b3d7f14862b7da82b65b1b761f68 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 21 Nov 2021 10:16:18 +0100 Subject: [PATCH 4/4] Update optimize-reports to enter_tag wording --- freqtrade/optimize/optimize_reports.py | 16 +++++++++------- freqtrade/persistence/migrations.py | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index c4002fcbe..2a1309548 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -422,8 +422,8 @@ def generate_strategy_stats(btdata: Dict[str, DataFrame], starting_balance=starting_balance, results=results, skip_nan=False) - buy_tag_results = generate_tag_metrics("buy_tag", starting_balance=starting_balance, - results=results, skip_nan=False) + enter_tag_results = generate_tag_metrics("enter_tag", starting_balance=starting_balance, + results=results, skip_nan=False) sell_reason_stats = generate_sell_reason_stats(max_open_trades=max_open_trades, results=results) @@ -448,7 +448,7 @@ def generate_strategy_stats(btdata: Dict[str, DataFrame], 'best_pair': best_pair, 'worst_pair': worst_pair, 'results_per_pair': pair_results, - 'results_per_buy_tag': buy_tag_results, + 'results_per_enter_tag': enter_tag_results, 'sell_reason_summary': sell_reason_stats, 'left_open_trades': left_open_results, # 'days_breakdown_stats': days_breakdown_stats, @@ -628,7 +628,7 @@ def text_table_tags(tag_type: str, tag_results: List[Dict[str, Any]], stake_curr :param stake_currency: stake-currency - used to correctly name headers :return: pretty printed table with tabulate as string """ - if(tag_type == "buy_tag"): + if(tag_type == "enter_tag"): headers = _get_line_header("TAG", stake_currency) else: headers = _get_line_header_sell("TAG", stake_currency) @@ -797,10 +797,12 @@ def show_backtest_result(strategy: str, results: Dict[str, Any], stake_currency: print(' BACKTESTING REPORT '.center(len(table.splitlines()[0]), '=')) print(table) - if results.get('results_per_buy_tag') is not None: + if (results.get('results_per_enter_tag') is not None + or results.get('results_per_buy_tag') is not None): + # results_per_buy_tag is deprecated and should be removed 2 versions after short golive. table = text_table_tags( - "buy_tag", - results['results_per_buy_tag'], + "enter_tag", + results.get('results_per_enter_tag', results.get('results_per_buy_tag')), stake_currency=stake_currency) if isinstance(table, str) and len(table) > 0: diff --git a/freqtrade/persistence/migrations.py b/freqtrade/persistence/migrations.py index 212499df3..99b8f0925 100644 --- a/freqtrade/persistence/migrations.py +++ b/freqtrade/persistence/migrations.py @@ -180,7 +180,7 @@ def check_migrate(engine, decl_base, previous_tables) -> None: table_back_name = get_backup_name(tabs, 'trades_bak') # Check for latest column - if not has_column(cols, 'funding_fees'): + if not has_column(cols, 'enter_tag'): logger.info(f'Running database migration for trades - backup: {table_back_name}') migrate_trades_table(decl_base, inspector, engine, table_back_name, cols) # Reread columns - the above recreated the table!