Remove more buy_tag references

This commit is contained in:
Matthias 2021-11-21 09:51:16 +01:00
parent 7d77aff289
commit 36deced00b
18 changed files with 117 additions and 76 deletions

View File

@ -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.

View File

@ -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

View File

@ -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?, ...?)

View File

@ -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),

View File

@ -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'),
)

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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 = "<b>Buy Tag Performance:</b>\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 <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"
"*/mix_tags <pair|none>:* `Shows combined buy tag + sell reason performance`\n"
"*/trades [limit]:* `Lists last closed trades (limited to 10 by default)`\n"

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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]

View File

@ -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)

View File

@ -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',
}

View File

@ -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 '<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
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'

View File

@ -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,

View File

@ -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',
)