Fixed models and rpc performance functions, added skeletons for tests.
This commit is contained in:
parent
22dd2ca003
commit
b51f946ee0
@ -850,7 +850,8 @@ class Trade(_DECL_BASE, LocalTrade):
|
|||||||
.group_by(Trade.pair) \
|
.group_by(Trade.pair) \
|
||||||
.order_by(desc('profit_sum_abs')) \
|
.order_by(desc('profit_sum_abs')) \
|
||||||
.all()
|
.all()
|
||||||
return [
|
|
||||||
|
response = [
|
||||||
{
|
{
|
||||||
'pair': pair,
|
'pair': pair,
|
||||||
'profit': profit,
|
'profit': profit,
|
||||||
@ -859,6 +860,8 @@ class Trade(_DECL_BASE, LocalTrade):
|
|||||||
}
|
}
|
||||||
for pair, profit, profit_abs, count in pair_rates
|
for pair, profit, profit_abs, count in pair_rates
|
||||||
]
|
]
|
||||||
|
[x.update({'profit': round(x['profit'] * 100, 2)}) for x in response]
|
||||||
|
return response
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_buy_tag_performance(pair: Optional[str]) -> List[Dict[str, Any]]:
|
def get_buy_tag_performance(pair: Optional[str]) -> List[Dict[str, Any]]:
|
||||||
@ -868,36 +871,31 @@ class Trade(_DECL_BASE, LocalTrade):
|
|||||||
NOTE: Not supported in Backtesting.
|
NOTE: Not supported in Backtesting.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
filters = [Trade.is_open.is_(False)]
|
||||||
if(pair is not None):
|
if(pair is not None):
|
||||||
tag_perf = Trade.query.with_entities(
|
filters.append(Trade.pair == pair)
|
||||||
Trade.buy_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(Trade.is_open.is_(False))\
|
|
||||||
.filter(Trade.pair == pair) \
|
|
||||||
.order_by(desc('profit_sum_abs')) \
|
|
||||||
.all()
|
|
||||||
else:
|
|
||||||
tag_perf = Trade.query.with_entities(
|
|
||||||
Trade.buy_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(Trade.is_open.is_(False))\
|
|
||||||
.group_by(Trade.buy_tag) \
|
|
||||||
.order_by(desc('profit_sum_abs')) \
|
|
||||||
.all()
|
|
||||||
|
|
||||||
return [
|
buy_tag_perf = Trade.query.with_entities(
|
||||||
|
Trade.buy_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) \
|
||||||
|
.order_by(desc('profit_sum_abs')) \
|
||||||
|
.all()
|
||||||
|
|
||||||
|
response = [
|
||||||
{
|
{
|
||||||
'buy_tag': buy_tag if buy_tag is not None else "Other",
|
'buy_tag': buy_tag if buy_tag is not None else "Other",
|
||||||
'profit': profit,
|
'profit': profit,
|
||||||
'profit_abs': profit_abs,
|
'profit_abs': profit_abs,
|
||||||
'count': count
|
'count': count
|
||||||
}
|
}
|
||||||
for buy_tag, profit, profit_abs, count in tag_perf
|
for buy_tag, profit, profit_abs, count in buy_tag_perf
|
||||||
]
|
]
|
||||||
|
[x.update({'profit': round(x['profit'] * 100, 2)}) for x in response]
|
||||||
|
return response
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_sell_reason_performance(pair: Optional[str]) -> List[Dict[str, Any]]:
|
def get_sell_reason_performance(pair: Optional[str]) -> List[Dict[str, Any]]:
|
||||||
@ -906,36 +904,32 @@ class Trade(_DECL_BASE, LocalTrade):
|
|||||||
Can either be average for all pairs or a specific pair provided
|
Can either be average for all pairs or a specific pair provided
|
||||||
NOTE: Not supported in Backtesting.
|
NOTE: Not supported in Backtesting.
|
||||||
"""
|
"""
|
||||||
if(pair is not None):
|
|
||||||
tag_perf = Trade.query.with_entities(
|
|
||||||
Trade.sell_reason,
|
|
||||||
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(Trade.is_open.is_(False))\
|
|
||||||
.filter(Trade.pair == pair) \
|
|
||||||
.order_by(desc('profit_sum_abs')) \
|
|
||||||
.all()
|
|
||||||
else:
|
|
||||||
tag_perf = Trade.query.with_entities(
|
|
||||||
Trade.sell_reason,
|
|
||||||
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(Trade.is_open.is_(False))\
|
|
||||||
.group_by(Trade.sell_reason) \
|
|
||||||
.order_by(desc('profit_sum_abs')) \
|
|
||||||
.all()
|
|
||||||
|
|
||||||
return [
|
filters = [Trade.is_open.is_(False)]
|
||||||
|
if(pair is not None):
|
||||||
|
filters.append(Trade.pair == pair)
|
||||||
|
|
||||||
|
sell_tag_perf = Trade.query.with_entities(
|
||||||
|
Trade.sell_reason,
|
||||||
|
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.sell_reason) \
|
||||||
|
.order_by(desc('profit_sum_abs')) \
|
||||||
|
.all()
|
||||||
|
|
||||||
|
response = [
|
||||||
{
|
{
|
||||||
'sell_reason': sell_reason if sell_reason is not None else "Other",
|
'sell_reason': sell_reason if sell_reason is not None else "Other",
|
||||||
'profit': profit,
|
'profit': profit,
|
||||||
'profit_abs': profit_abs,
|
'profit_abs': profit_abs,
|
||||||
'count': count
|
'count': count
|
||||||
}
|
}
|
||||||
for sell_reason, profit, profit_abs, count in tag_perf
|
for sell_reason, profit, profit_abs, count in sell_tag_perf
|
||||||
]
|
]
|
||||||
|
[x.update({'profit': round(x['profit'] * 100, 2)}) for x in response]
|
||||||
|
return response
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_mix_tag_performance(pair: Optional[str]) -> List[Dict[str, Any]]:
|
def get_mix_tag_performance(pair: Optional[str]) -> List[Dict[str, Any]]:
|
||||||
@ -944,34 +938,25 @@ class Trade(_DECL_BASE, LocalTrade):
|
|||||||
Can either be average for all pairs or a specific pair provided
|
Can either be average for all pairs or a specific pair provided
|
||||||
NOTE: Not supported in Backtesting.
|
NOTE: Not supported in Backtesting.
|
||||||
"""
|
"""
|
||||||
if(pair is not None):
|
|
||||||
tag_perf = Trade.query.with_entities(
|
|
||||||
Trade.id,
|
|
||||||
Trade.buy_tag,
|
|
||||||
Trade.sell_reason,
|
|
||||||
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(Trade.is_open.is_(False))\
|
|
||||||
.filter(Trade.pair == pair) \
|
|
||||||
.order_by(desc('profit_sum_abs')) \
|
|
||||||
.all()
|
|
||||||
|
|
||||||
else:
|
filters = [Trade.is_open.is_(False)]
|
||||||
tag_perf = Trade.query.with_entities(
|
if(pair is not None):
|
||||||
Trade.id,
|
filters.append(Trade.pair == pair)
|
||||||
Trade.buy_tag,
|
|
||||||
Trade.sell_reason,
|
mix_tag_perf = Trade.query.with_entities(
|
||||||
func.sum(Trade.close_profit).label('profit_sum'),
|
Trade.id,
|
||||||
func.sum(Trade.close_profit_abs).label('profit_sum_abs'),
|
Trade.buy_tag,
|
||||||
func.count(Trade.pair).label('count')
|
Trade.sell_reason,
|
||||||
).filter(Trade.is_open.is_(False))\
|
func.sum(Trade.close_profit).label('profit_sum'),
|
||||||
.group_by(Trade.id) \
|
func.sum(Trade.close_profit_abs).label('profit_sum_abs'),
|
||||||
.order_by(desc('profit_sum_abs')) \
|
func.count(Trade.pair).label('count')
|
||||||
.all()
|
).filter(*filters)\
|
||||||
|
.group_by(Trade.id) \
|
||||||
|
.order_by(desc('profit_sum_abs')) \
|
||||||
|
.all()
|
||||||
|
|
||||||
return_list: List[Dict] = []
|
return_list: List[Dict] = []
|
||||||
for id, buy_tag, sell_reason, profit, profit_abs, count in tag_perf:
|
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"
|
buy_tag = buy_tag if buy_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"
|
||||||
|
|
||||||
@ -993,6 +978,7 @@ class Trade(_DECL_BASE, LocalTrade):
|
|||||||
'count': 1 + return_list[i]["count"]}
|
'count': 1 + return_list[i]["count"]}
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
[x.update({'profit': round(x['profit'] * 100, 2)}) for x in return_list]
|
||||||
return return_list
|
return return_list
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -685,8 +685,7 @@ class RPC:
|
|||||||
Shows a performance statistic from finished trades
|
Shows a performance statistic from finished trades
|
||||||
"""
|
"""
|
||||||
pair_rates = Trade.get_overall_performance()
|
pair_rates = Trade.get_overall_performance()
|
||||||
# Round and convert to %
|
|
||||||
[x.update({'profit': round(x['profit'] * 100, 2)}) for x in pair_rates]
|
|
||||||
return pair_rates
|
return pair_rates
|
||||||
|
|
||||||
def _rpc_buy_tag_performance(self, pair: Optional[str]) -> List[Dict[str, Any]]:
|
def _rpc_buy_tag_performance(self, pair: Optional[str]) -> List[Dict[str, Any]]:
|
||||||
@ -695,8 +694,7 @@ class RPC:
|
|||||||
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_buy_tag_performance(pair)
|
||||||
# Round and convert to %
|
|
||||||
[x.update({'profit': round(x['profit'] * 100, 2)}) for x in buy_tags]
|
|
||||||
return buy_tags
|
return buy_tags
|
||||||
|
|
||||||
def _rpc_sell_reason_performance(self, pair: Optional[str]) -> List[Dict[str, Any]]:
|
def _rpc_sell_reason_performance(self, pair: Optional[str]) -> List[Dict[str, Any]]:
|
||||||
@ -705,8 +703,7 @@ class RPC:
|
|||||||
Shows a performance statistic from finished trades
|
Shows a performance statistic from finished trades
|
||||||
"""
|
"""
|
||||||
sell_reasons = Trade.get_sell_reason_performance(pair)
|
sell_reasons = Trade.get_sell_reason_performance(pair)
|
||||||
# Round and convert to %
|
|
||||||
[x.update({'profit': round(x['profit'] * 100, 2)}) for x in sell_reasons]
|
|
||||||
return sell_reasons
|
return sell_reasons
|
||||||
|
|
||||||
def _rpc_mix_tag_performance(self, pair: Optional[str]) -> List[Dict[str, Any]]:
|
def _rpc_mix_tag_performance(self, pair: Optional[str]) -> List[Dict[str, Any]]:
|
||||||
@ -715,8 +712,7 @@ class RPC:
|
|||||||
Shows a performance statistic from finished trades
|
Shows a performance statistic from finished trades
|
||||||
"""
|
"""
|
||||||
mix_tags = Trade.get_mix_tag_performance(pair)
|
mix_tags = Trade.get_mix_tag_performance(pair)
|
||||||
# Round and convert to %
|
|
||||||
[x.update({'profit': round(x['profit'] * 100, 2)}) for x in mix_tags]
|
|
||||||
return mix_tags
|
return mix_tags
|
||||||
|
|
||||||
def _rpc_count(self) -> Dict[str, float]:
|
def _rpc_count(self) -> Dict[str, float]:
|
||||||
|
@ -827,6 +827,120 @@ def test_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'], 6.2)
|
assert prec_satoshi(res[0]['profit'], 6.2)
|
||||||
|
|
||||||
|
# TEST FOR TRADES WITH NO BUY TAG
|
||||||
|
# TEST TRADE WITH ONE BUY_TAG AND OTHER TWO TRADES WITH THE SAME TAG
|
||||||
|
# TEST THE SAME FOR A PAIR
|
||||||
|
|
||||||
|
|
||||||
|
def test_buy_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',
|
||||||
|
get_balances=MagicMock(return_value=ticker),
|
||||||
|
fetch_ticker=ticker,
|
||||||
|
get_fee=fee,
|
||||||
|
)
|
||||||
|
|
||||||
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
|
patch_get_signal(freqtradebot)
|
||||||
|
rpc = RPC(freqtradebot)
|
||||||
|
|
||||||
|
# Create some test data
|
||||||
|
freqtradebot.enter_positions()
|
||||||
|
trade = Trade.query.first()
|
||||||
|
assert trade
|
||||||
|
|
||||||
|
# Simulate fulfilled LIMIT_BUY order for trade
|
||||||
|
trade.update(limit_buy_order)
|
||||||
|
|
||||||
|
# Simulate fulfilled LIMIT_SELL order for trade
|
||||||
|
trade.update(limit_sell_order)
|
||||||
|
|
||||||
|
trade.close_date = datetime.utcnow()
|
||||||
|
trade.is_open = False
|
||||||
|
res = rpc._rpc_buy_tag_performance(None)
|
||||||
|
assert len(res) == 1
|
||||||
|
assert res[0]['pair'] == 'ETH/BTC'
|
||||||
|
assert res[0]['count'] == 1
|
||||||
|
assert prec_satoshi(res[0]['profit'], 6.2)
|
||||||
|
|
||||||
|
# TEST FOR TRADES WITH NO SELL REASON
|
||||||
|
# TEST TRADE WITH ONE SELL REASON AND OTHER TWO TRADES WITH THE SAME reason
|
||||||
|
# TEST THE SAME FOR A PAIR
|
||||||
|
|
||||||
|
|
||||||
|
def test_sell_reason_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',
|
||||||
|
get_balances=MagicMock(return_value=ticker),
|
||||||
|
fetch_ticker=ticker,
|
||||||
|
get_fee=fee,
|
||||||
|
)
|
||||||
|
|
||||||
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
|
patch_get_signal(freqtradebot)
|
||||||
|
rpc = RPC(freqtradebot)
|
||||||
|
|
||||||
|
# Create some test data
|
||||||
|
freqtradebot.enter_positions()
|
||||||
|
trade = Trade.query.first()
|
||||||
|
assert trade
|
||||||
|
|
||||||
|
# Simulate fulfilled LIMIT_BUY order for trade
|
||||||
|
trade.update(limit_buy_order)
|
||||||
|
|
||||||
|
# Simulate fulfilled LIMIT_SELL order for trade
|
||||||
|
trade.update(limit_sell_order)
|
||||||
|
|
||||||
|
trade.close_date = datetime.utcnow()
|
||||||
|
trade.is_open = False
|
||||||
|
res = rpc._rpc_sell_reason_performance(None)
|
||||||
|
assert len(res) == 1
|
||||||
|
assert res[0]['pair'] == 'ETH/BTC'
|
||||||
|
assert res[0]['count'] == 1
|
||||||
|
assert prec_satoshi(res[0]['profit'], 6.2)
|
||||||
|
|
||||||
|
# TEST FOR TRADES WITH NO TAGS
|
||||||
|
# TEST TRADE WITH ONE TAG MIX AND OTHER TWO TRADES WITH THE SAME TAG MIX
|
||||||
|
# TEST THE SAME FOR A PAIR
|
||||||
|
|
||||||
|
|
||||||
|
def test_mix_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',
|
||||||
|
get_balances=MagicMock(return_value=ticker),
|
||||||
|
fetch_ticker=ticker,
|
||||||
|
get_fee=fee,
|
||||||
|
)
|
||||||
|
|
||||||
|
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||||
|
patch_get_signal(freqtradebot)
|
||||||
|
rpc = RPC(freqtradebot)
|
||||||
|
|
||||||
|
# Create some test data
|
||||||
|
freqtradebot.enter_positions()
|
||||||
|
trade = Trade.query.first()
|
||||||
|
assert trade
|
||||||
|
|
||||||
|
# Simulate fulfilled LIMIT_BUY order for trade
|
||||||
|
trade.update(limit_buy_order)
|
||||||
|
|
||||||
|
# Simulate fulfilled LIMIT_SELL order for trade
|
||||||
|
trade.update(limit_sell_order)
|
||||||
|
|
||||||
|
trade.close_date = datetime.utcnow()
|
||||||
|
trade.is_open = False
|
||||||
|
res = rpc._rpc_mix_tag_performance(None)
|
||||||
|
assert len(res) == 1
|
||||||
|
assert res[0]['pair'] == 'ETH/BTC'
|
||||||
|
assert res[0]['count'] == 1
|
||||||
|
assert prec_satoshi(res[0]['profit'], 6.2)
|
||||||
|
|
||||||
|
|
||||||
def test_rpc_count(mocker, default_conf, ticker, fee) -> None:
|
def test_rpc_count(mocker, default_conf, ticker, fee) -> None:
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
|
@ -978,6 +978,105 @@ def test_performance_handle(default_conf, update, ticker, fee,
|
|||||||
assert 'Performance' in msg_mock.call_args_list[0][0][0]
|
assert 'Performance' in msg_mock.call_args_list[0][0][0]
|
||||||
assert '<code>ETH/BTC\t0.00006217 BTC (6.20%) (1)</code>' in msg_mock.call_args_list[0][0][0]
|
assert '<code>ETH/BTC\t0.00006217 BTC (6.20%) (1)</code>' in msg_mock.call_args_list[0][0][0]
|
||||||
|
|
||||||
|
# TEST FOR TRADES WITH NO BUY TAG
|
||||||
|
# TEST TRADE WITH ONE BUY_TAG AND OTHER TWO TRADES WITH THE SAME TAG
|
||||||
|
# TEST THE SAME FOR A PAIR
|
||||||
|
|
||||||
|
|
||||||
|
def test_buy_tag_performance_handle(default_conf, update, ticker, fee,
|
||||||
|
limit_buy_order, limit_sell_order, mocker) -> None:
|
||||||
|
mocker.patch.multiple(
|
||||||
|
'freqtrade.exchange.Exchange',
|
||||||
|
fetch_ticker=ticker,
|
||||||
|
get_fee=fee,
|
||||||
|
)
|
||||||
|
telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||||
|
patch_get_signal(freqtradebot)
|
||||||
|
|
||||||
|
# Create some test data
|
||||||
|
freqtradebot.enter_positions()
|
||||||
|
trade = Trade.query.first()
|
||||||
|
assert trade
|
||||||
|
|
||||||
|
# Simulate fulfilled LIMIT_BUY order for trade
|
||||||
|
trade.update(limit_buy_order)
|
||||||
|
|
||||||
|
# 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())
|
||||||
|
assert msg_mock.call_count == 1
|
||||||
|
assert 'Performance' in msg_mock.call_args_list[0][0][0]
|
||||||
|
assert '<code>ETH/BTC\t0.00006217 BTC (6.20%) (1)</code>' in msg_mock.call_args_list[0][0][0]
|
||||||
|
|
||||||
|
# TEST FOR TRADES WITH NO SELL REASON
|
||||||
|
# TEST TRADE WITH ONE SELL REASON AND OTHER TWO TRADES WITH THE SAME reason
|
||||||
|
# TEST THE SAME FOR A PAIR
|
||||||
|
|
||||||
|
|
||||||
|
def test_sell_reason_performance_handle(default_conf, update, ticker, fee,
|
||||||
|
limit_buy_order, limit_sell_order, mocker) -> None:
|
||||||
|
mocker.patch.multiple(
|
||||||
|
'freqtrade.exchange.Exchange',
|
||||||
|
fetch_ticker=ticker,
|
||||||
|
get_fee=fee,
|
||||||
|
)
|
||||||
|
telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||||
|
patch_get_signal(freqtradebot)
|
||||||
|
|
||||||
|
# Create some test data
|
||||||
|
freqtradebot.enter_positions()
|
||||||
|
trade = Trade.query.first()
|
||||||
|
assert trade
|
||||||
|
|
||||||
|
# Simulate fulfilled LIMIT_BUY order for trade
|
||||||
|
trade.update(limit_buy_order)
|
||||||
|
|
||||||
|
# Simulate fulfilled LIMIT_SELL order for trade
|
||||||
|
trade.update(limit_sell_order)
|
||||||
|
|
||||||
|
trade.close_date = datetime.utcnow()
|
||||||
|
trade.is_open = False
|
||||||
|
telegram._sell_reason_performance(update=update, context=MagicMock())
|
||||||
|
assert msg_mock.call_count == 1
|
||||||
|
assert 'Performance' in msg_mock.call_args_list[0][0][0]
|
||||||
|
assert '<code>ETH/BTC\t0.00006217 BTC (6.20%) (1)</code>' in msg_mock.call_args_list[0][0][0]
|
||||||
|
|
||||||
|
# TEST FOR TRADES WITH NO TAGS
|
||||||
|
# TEST TRADE WITH ONE TAG MIX AND OTHER TWO TRADES WITH THE SAME TAG MIX
|
||||||
|
# TEST THE SAME FOR A PAIR
|
||||||
|
|
||||||
|
|
||||||
|
def test_mix_tag_performance_handle(default_conf, update, ticker, fee,
|
||||||
|
limit_buy_order, limit_sell_order, mocker) -> None:
|
||||||
|
mocker.patch.multiple(
|
||||||
|
'freqtrade.exchange.Exchange',
|
||||||
|
fetch_ticker=ticker,
|
||||||
|
get_fee=fee,
|
||||||
|
)
|
||||||
|
telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||||
|
patch_get_signal(freqtradebot)
|
||||||
|
|
||||||
|
# Create some test data
|
||||||
|
freqtradebot.enter_positions()
|
||||||
|
trade = Trade.query.first()
|
||||||
|
assert trade
|
||||||
|
|
||||||
|
# Simulate fulfilled LIMIT_BUY order for trade
|
||||||
|
trade.update(limit_buy_order)
|
||||||
|
|
||||||
|
# Simulate fulfilled LIMIT_SELL order for trade
|
||||||
|
trade.update(limit_sell_order)
|
||||||
|
|
||||||
|
trade.close_date = datetime.utcnow()
|
||||||
|
trade.is_open = False
|
||||||
|
telegram._mix_tag_performance(update=update, context=MagicMock())
|
||||||
|
assert msg_mock.call_count == 1
|
||||||
|
assert 'Performance' in msg_mock.call_args_list[0][0][0]
|
||||||
|
assert '<code>ETH/BTC\t0.00006217 BTC (6.20%) (1)</code>' in msg_mock.call_args_list[0][0][0]
|
||||||
|
|
||||||
|
|
||||||
def test_count_handle(default_conf, update, ticker, fee, mocker) -> None:
|
def test_count_handle(default_conf, update, ticker, fee, mocker) -> None:
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
|
Loading…
Reference in New Issue
Block a user