test cases added: force_stoploss by Edge
This commit is contained in:
parent
b57d9edda8
commit
06d75a8bad
@ -649,7 +649,7 @@ class FreqtradeBot(object):
|
|||||||
|
|
||||||
if should_sell.sell_flag:
|
if should_sell.sell_flag:
|
||||||
self.execute_sell(trade, sell_rate, should_sell.sell_type)
|
self.execute_sell(trade, sell_rate, should_sell.sell_type)
|
||||||
logger.info('excuted sell')
|
logger.info('executed sell, reason: %s', should_sell.sell_type)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ from telegram import Chat, Message, Update
|
|||||||
|
|
||||||
from freqtrade.exchange.exchange_helpers import parse_ticker_dataframe
|
from freqtrade.exchange.exchange_helpers import parse_ticker_dataframe
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange
|
||||||
|
from freqtrade.edge import Edge
|
||||||
from freqtrade.freqtradebot import FreqtradeBot
|
from freqtrade.freqtradebot import FreqtradeBot
|
||||||
|
|
||||||
logging.getLogger('').setLevel(logging.INFO)
|
logging.getLogger('').setLevel(logging.INFO)
|
||||||
@ -42,6 +43,25 @@ def get_patched_exchange(mocker, config, api_mock=None) -> Exchange:
|
|||||||
return exchange
|
return exchange
|
||||||
|
|
||||||
|
|
||||||
|
def patch_edge(mocker) -> None:
|
||||||
|
# "ETH/BTC",
|
||||||
|
# "LTC/BTC",
|
||||||
|
# "XRP/BTC",
|
||||||
|
# "NEO/BTC"
|
||||||
|
mocker.patch('freqtrade.edge.Edge._cached_pairs', mocker.PropertyMock(
|
||||||
|
return_value=[
|
||||||
|
['NEO/BTC', -0.20, 0.66, 3.71, 0.50, 1.71],
|
||||||
|
['LTC/BTC', -0.21, 0.66, 3.71, 0.50, 1.71],
|
||||||
|
]
|
||||||
|
))
|
||||||
|
mocker.patch('freqtrade.edge.Edge.stoploss', MagicMock(return_value=-0.20))
|
||||||
|
mocker.patch('freqtrade.edge.Edge.calculate', MagicMock(return_value=True))
|
||||||
|
|
||||||
|
def get_patched_edge(mocker, config) -> Edge:
|
||||||
|
patch_edge(mocker)
|
||||||
|
edge = Edge(config)
|
||||||
|
return edge
|
||||||
|
|
||||||
# Functions for recurrent object patching
|
# Functions for recurrent object patching
|
||||||
def get_patched_freqtradebot(mocker, config) -> FreqtradeBot:
|
def get_patched_freqtradebot(mocker, config) -> FreqtradeBot:
|
||||||
"""
|
"""
|
||||||
|
@ -130,6 +130,8 @@ def test_process_expectancy(mocker, default_conf):
|
|||||||
final = edge._process_expectancy(trades_df)
|
final = edge._process_expectancy(trades_df)
|
||||||
assert len(final) == 1
|
assert len(final) == 1
|
||||||
|
|
||||||
|
# TODO: check expectancy + win rate etc
|
||||||
|
|
||||||
|
|
||||||
def test_three_complete_trades(mocker, default_conf):
|
def test_three_complete_trades(mocker, default_conf):
|
||||||
exchange = get_patched_exchange(mocker, default_conf)
|
exchange = get_patched_exchange(mocker, default_conf)
|
||||||
|
@ -18,7 +18,7 @@ from freqtrade.persistence import Trade
|
|||||||
from freqtrade.rpc import RPCMessageType
|
from freqtrade.rpc import RPCMessageType
|
||||||
from freqtrade.state import State
|
from freqtrade.state import State
|
||||||
from freqtrade.strategy.interface import SellType, SellCheckTuple
|
from freqtrade.strategy.interface import SellType, SellCheckTuple
|
||||||
from freqtrade.tests.conftest import log_has, patch_exchange
|
from freqtrade.tests.conftest import log_has, patch_exchange, patch_edge
|
||||||
|
|
||||||
|
|
||||||
# Functions for recurrent object patching
|
# Functions for recurrent object patching
|
||||||
@ -251,6 +251,100 @@ def test_get_trade_stake_amount_unlimited_amount(default_conf,
|
|||||||
assert result is None
|
assert result is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_edge_overrides_stake_amount(mocker, default_conf) -> None:
|
||||||
|
default_conf['edge']['enabled'] = True
|
||||||
|
patch_RPCManager(mocker)
|
||||||
|
patch_exchange(mocker)
|
||||||
|
patch_edge(mocker)
|
||||||
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
|
|
||||||
|
# strategy stoploss should be ignored
|
||||||
|
freqtrade.strategy.stoploss = -0.05
|
||||||
|
|
||||||
|
with pytest.raises(IndexError):
|
||||||
|
freqtrade._get_trade_stake_amount('ETH/BTC')
|
||||||
|
|
||||||
|
assert freqtrade._get_trade_stake_amount('NEO/BTC') == 0.025
|
||||||
|
assert freqtrade._get_trade_stake_amount('LTC/BTC') == 0.02381
|
||||||
|
|
||||||
|
|
||||||
|
def test_edge_overrides_stoploss(limit_buy_order, fee, markets, caplog, mocker, default_conf) -> None:
|
||||||
|
default_conf['edge']['enabled'] = True
|
||||||
|
patch_RPCManager(mocker)
|
||||||
|
patch_exchange(mocker)
|
||||||
|
patch_edge(mocker)
|
||||||
|
|
||||||
|
# Strategy stoploss is -0.1 but Edge imposes a stoploss at -0.2
|
||||||
|
# Thus, if price falls 21%, stoploss should be triggered
|
||||||
|
#
|
||||||
|
# mocking the ticker: price is falling ...
|
||||||
|
buy_price = limit_buy_order['price']
|
||||||
|
mocker.patch.multiple(
|
||||||
|
'freqtrade.exchange.Exchange',
|
||||||
|
get_ticker=MagicMock(return_value={
|
||||||
|
'bid': buy_price * 0.79,
|
||||||
|
'ask': buy_price * 0.79,
|
||||||
|
'last': buy_price * 0.79
|
||||||
|
}),
|
||||||
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
|
get_fee=fee,
|
||||||
|
get_markets=markets,
|
||||||
|
)
|
||||||
|
#############################################
|
||||||
|
|
||||||
|
# Create a trade with "limit_buy_order" price
|
||||||
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
|
patch_get_signal(freqtrade)
|
||||||
|
freqtrade.strategy.min_roi_reached = lambda trade, current_profit, current_time: False
|
||||||
|
freqtrade.create_trade()
|
||||||
|
trade = Trade.query.first()
|
||||||
|
trade.update(limit_buy_order)
|
||||||
|
#############################################
|
||||||
|
|
||||||
|
# stoploss shoud be hit
|
||||||
|
assert freqtrade.handle_trade(trade) is True
|
||||||
|
|
||||||
|
assert log_has('executed sell, reason: SellType.STOP_LOSS', caplog.record_tuples)
|
||||||
|
assert trade.sell_reason == SellType.STOP_LOSS.value
|
||||||
|
|
||||||
|
|
||||||
|
def test_edge_should_ignore_strategy_stoploss(limit_buy_order, fee, markets,
|
||||||
|
mocker, default_conf) -> None:
|
||||||
|
default_conf['edge']['enabled'] = True
|
||||||
|
patch_RPCManager(mocker)
|
||||||
|
patch_exchange(mocker)
|
||||||
|
patch_edge(mocker)
|
||||||
|
|
||||||
|
# Strategy stoploss is -0.1 but Edge imposes a stoploss at -0.2
|
||||||
|
# Thus, if price falls 15%, stoploss should not be triggered
|
||||||
|
#
|
||||||
|
# mocking the ticker: price is falling ...
|
||||||
|
buy_price = limit_buy_order['price']
|
||||||
|
mocker.patch.multiple(
|
||||||
|
'freqtrade.exchange.Exchange',
|
||||||
|
get_ticker=MagicMock(return_value={
|
||||||
|
'bid': buy_price * 0.85,
|
||||||
|
'ask': buy_price * 0.85,
|
||||||
|
'last': buy_price * 0.85
|
||||||
|
}),
|
||||||
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
|
get_fee=fee,
|
||||||
|
get_markets=markets,
|
||||||
|
)
|
||||||
|
#############################################
|
||||||
|
|
||||||
|
# Create a trade with "limit_buy_order" price
|
||||||
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
|
patch_get_signal(freqtrade)
|
||||||
|
freqtrade.strategy.min_roi_reached = lambda trade, current_profit, current_time: False
|
||||||
|
freqtrade.create_trade()
|
||||||
|
trade = Trade.query.first()
|
||||||
|
trade.update(limit_buy_order)
|
||||||
|
#############################################
|
||||||
|
|
||||||
|
# stoploss shoud be hit
|
||||||
|
assert freqtrade.handle_trade(trade) is False
|
||||||
|
|
||||||
def test_get_min_pair_stake_amount(mocker, default_conf) -> None:
|
def test_get_min_pair_stake_amount(mocker, default_conf) -> None:
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
|
Loading…
Reference in New Issue
Block a user