Add minimal pair stake amount check
This commit is contained in:
parent
708320318c
commit
eb909068c5
@ -98,6 +98,13 @@ class Analyze(object):
|
|||||||
"""
|
"""
|
||||||
return self.strategy.ticker_interval
|
return self.strategy.ticker_interval
|
||||||
|
|
||||||
|
def get_stoploss(self) -> float:
|
||||||
|
"""
|
||||||
|
Return stoploss to use
|
||||||
|
:return: Strategy stoploss value to use
|
||||||
|
"""
|
||||||
|
return self.strategy.stoploss
|
||||||
|
|
||||||
def analyze_ticker(self, ticker_history: List[Dict]) -> DataFrame:
|
def analyze_ticker(self, ticker_history: List[Dict]) -> DataFrame:
|
||||||
"""
|
"""
|
||||||
Parses the given ticker history and returns a populated DataFrame
|
Parses the given ticker history and returns a populated DataFrame
|
||||||
|
@ -254,13 +254,7 @@ class FreqtradeBot(object):
|
|||||||
if open_trades >= self.config['max_open_trades']:
|
if open_trades >= self.config['max_open_trades']:
|
||||||
logger.warning('Can\'t open a new trade: max number of trades is reached')
|
logger.warning('Can\'t open a new trade: max number of trades is reached')
|
||||||
return None
|
return None
|
||||||
trade_stake_amount = avaliable_amount / (self.config['max_open_trades'] - open_trades)
|
return avaliable_amount / (self.config['max_open_trades'] - open_trades)
|
||||||
if trade_stake_amount < 0.0005:
|
|
||||||
raise DependencyException(
|
|
||||||
'Available balance(%f %s) is lower than minimal' % (
|
|
||||||
avaliable_amount, self.config['stake_currency'])
|
|
||||||
)
|
|
||||||
return trade_stake_amount
|
|
||||||
|
|
||||||
# Check if stake_amount is fulfilled
|
# Check if stake_amount is fulfilled
|
||||||
if avaliable_amount < stake_amount:
|
if avaliable_amount < stake_amount:
|
||||||
@ -272,6 +266,34 @@ class FreqtradeBot(object):
|
|||||||
|
|
||||||
return stake_amount
|
return stake_amount
|
||||||
|
|
||||||
|
def _get_min_pair_stake_amount(self, pair: str, price: float) -> Optional[float]:
|
||||||
|
markets = exchange.get_markets()
|
||||||
|
markets = [m for m in markets if m['symbol'] == pair]
|
||||||
|
if not markets:
|
||||||
|
raise ValueError(f'Can\'t get market information for symbol {pair}')
|
||||||
|
|
||||||
|
market = markets[0]
|
||||||
|
|
||||||
|
if 'limits' not in market:
|
||||||
|
return None
|
||||||
|
|
||||||
|
min_stake_amounts = []
|
||||||
|
if 'cost' in market['limits'] and 'min' in market['limits']['cost']:
|
||||||
|
min_stake_amounts.append(market['limits']['cost']['min'])
|
||||||
|
|
||||||
|
if 'amount' in market['limits'] and 'min' in market['limits']['amount']:
|
||||||
|
min_stake_amounts.append(market['limits']['amount']['min'] * price)
|
||||||
|
|
||||||
|
if not min_stake_amounts:
|
||||||
|
return None
|
||||||
|
|
||||||
|
amount_reserve_percent = 1 - 0.05 # reserve 5% + stoploss
|
||||||
|
if self.analyze.get_stoploss() is not None:
|
||||||
|
amount_reserve_percent += self.analyze.get_stoploss()
|
||||||
|
# it should not be more than 50%
|
||||||
|
amount_reserve_percent = max(amount_reserve_percent, 0.5)
|
||||||
|
return min(min_stake_amounts)/amount_reserve_percent
|
||||||
|
|
||||||
def create_trade(self) -> bool:
|
def create_trade(self) -> bool:
|
||||||
"""
|
"""
|
||||||
Checks the implemented trading indicator(s) for a randomly picked pair,
|
Checks the implemented trading indicator(s) for a randomly picked pair,
|
||||||
@ -314,8 +336,16 @@ class FreqtradeBot(object):
|
|||||||
pair_url = exchange.get_pair_detail_url(pair)
|
pair_url = exchange.get_pair_detail_url(pair)
|
||||||
# Calculate amount
|
# Calculate amount
|
||||||
buy_limit = self.get_target_bid(exchange.get_ticker(pair))
|
buy_limit = self.get_target_bid(exchange.get_ticker(pair))
|
||||||
amount = stake_amount / buy_limit
|
|
||||||
|
|
||||||
|
min_stake_amount = self._get_min_pair_stake_amount(pair_s, buy_limit)
|
||||||
|
if min_stake_amount is not None and min_stake_amount > stake_amount:
|
||||||
|
logger.warning(
|
||||||
|
f'Can\'t open a new trade for {pair_s}: stake amount'
|
||||||
|
f' is too small ({stake_amount} < {min_stake_amount})'
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
amount = stake_amount / buy_limit
|
||||||
order_id = exchange.buy(pair, buy_limit, amount)['id']
|
order_id = exchange.buy(pair, buy_limit, amount)['id']
|
||||||
|
|
||||||
stake_amount_fiat = self.fiat_converter.convert_amount(
|
stake_amount_fiat = self.fiat_converter.convert_amount(
|
||||||
|
@ -174,7 +174,10 @@ def markets():
|
|||||||
'max': 1000,
|
'max': 1000,
|
||||||
},
|
},
|
||||||
'price': 500000,
|
'price': 500000,
|
||||||
'cost': 500000,
|
'cost': {
|
||||||
|
'min': 1,
|
||||||
|
'max': 500000,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'info': '',
|
'info': '',
|
||||||
},
|
},
|
||||||
@ -196,7 +199,10 @@ def markets():
|
|||||||
'max': 1000,
|
'max': 1000,
|
||||||
},
|
},
|
||||||
'price': 500000,
|
'price': 500000,
|
||||||
'cost': 500000,
|
'cost': {
|
||||||
|
'min': 1,
|
||||||
|
'max': 500000,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'info': '',
|
'info': '',
|
||||||
},
|
},
|
||||||
@ -218,7 +224,85 @@ def markets():
|
|||||||
'max': 1000,
|
'max': 1000,
|
||||||
},
|
},
|
||||||
'price': 500000,
|
'price': 500000,
|
||||||
'cost': 500000,
|
'cost': {
|
||||||
|
'min': 1,
|
||||||
|
'max': 500000,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'info': '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 'ltcbtc',
|
||||||
|
'symbol': 'LTC/BTC',
|
||||||
|
'base': 'LTC',
|
||||||
|
'quote': 'BTC',
|
||||||
|
'active': False,
|
||||||
|
'precision': {
|
||||||
|
'price': 8,
|
||||||
|
'amount': 8,
|
||||||
|
'cost': 8,
|
||||||
|
},
|
||||||
|
'lot': 0.00000001,
|
||||||
|
'limits': {
|
||||||
|
'amount': {
|
||||||
|
'min': 0.01,
|
||||||
|
'max': 1000,
|
||||||
|
},
|
||||||
|
'price': 500000,
|
||||||
|
'cost': {
|
||||||
|
'min': 1,
|
||||||
|
'max': 500000,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'info': '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 'xrpbtc',
|
||||||
|
'symbol': 'XRP/BTC',
|
||||||
|
'base': 'XRP',
|
||||||
|
'quote': 'BTC',
|
||||||
|
'active': False,
|
||||||
|
'precision': {
|
||||||
|
'price': 8,
|
||||||
|
'amount': 8,
|
||||||
|
'cost': 8,
|
||||||
|
},
|
||||||
|
'lot': 0.00000001,
|
||||||
|
'limits': {
|
||||||
|
'amount': {
|
||||||
|
'min': 0.01,
|
||||||
|
'max': 1000,
|
||||||
|
},
|
||||||
|
'price': 500000,
|
||||||
|
'cost': {
|
||||||
|
'min': 1,
|
||||||
|
'max': 500000,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'info': '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 'neobtc',
|
||||||
|
'symbol': 'NEO/BTC',
|
||||||
|
'base': 'NEO',
|
||||||
|
'quote': 'BTC',
|
||||||
|
'active': False,
|
||||||
|
'precision': {
|
||||||
|
'price': 8,
|
||||||
|
'amount': 8,
|
||||||
|
'cost': 8,
|
||||||
|
},
|
||||||
|
'lot': 0.00000001,
|
||||||
|
'limits': {
|
||||||
|
'amount': {
|
||||||
|
'min': 0.01,
|
||||||
|
'max': 1000,
|
||||||
|
},
|
||||||
|
'price': 500000,
|
||||||
|
'cost': {
|
||||||
|
'min': 1,
|
||||||
|
'max': 500000,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'info': '',
|
'info': '',
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ def prec_satoshi(a, b) -> float:
|
|||||||
|
|
||||||
|
|
||||||
# Unit tests
|
# Unit tests
|
||||||
def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
|
def test_rpc_trade_status(default_conf, ticker, fee, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test rpc_trade_status() method
|
Test rpc_trade_status() method
|
||||||
"""
|
"""
|
||||||
@ -34,7 +34,8 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
|
|||||||
'freqtrade.freqtradebot.exchange',
|
'freqtrade.freqtradebot.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = FreqtradeBot(default_conf)
|
||||||
@ -72,7 +73,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
|
|||||||
assert trade.find('[ETH/BTC]') >= 0
|
assert trade.find('[ETH/BTC]') >= 0
|
||||||
|
|
||||||
|
|
||||||
def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
|
def test_rpc_status_table(default_conf, ticker, fee, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test rpc_status_table() method
|
Test rpc_status_table() method
|
||||||
"""
|
"""
|
||||||
@ -83,7 +84,8 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
|
|||||||
'freqtrade.freqtradebot.exchange',
|
'freqtrade.freqtradebot.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = FreqtradeBot(default_conf)
|
||||||
@ -107,7 +109,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_rpc_daily_profit(default_conf, update, ticker, fee,
|
def test_rpc_daily_profit(default_conf, update, ticker, fee,
|
||||||
limit_buy_order, limit_sell_order, mocker) -> None:
|
limit_buy_order, limit_sell_order, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test rpc_daily_profit() method
|
Test rpc_daily_profit() method
|
||||||
"""
|
"""
|
||||||
@ -118,7 +120,8 @@ def test_rpc_daily_profit(default_conf, update, ticker, fee,
|
|||||||
'freqtrade.freqtradebot.exchange',
|
'freqtrade.freqtradebot.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = FreqtradeBot(default_conf)
|
||||||
@ -160,7 +163,7 @@ def test_rpc_daily_profit(default_conf, update, ticker, fee,
|
|||||||
|
|
||||||
|
|
||||||
def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee,
|
def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee,
|
||||||
limit_buy_order, limit_sell_order, mocker) -> None:
|
limit_buy_order, limit_sell_order, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test rpc_trade_statistics() method
|
Test rpc_trade_statistics() method
|
||||||
"""
|
"""
|
||||||
@ -175,7 +178,8 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee,
|
|||||||
'freqtrade.freqtradebot.exchange',
|
'freqtrade.freqtradebot.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = FreqtradeBot(default_conf)
|
||||||
@ -237,7 +241,7 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee,
|
|||||||
|
|
||||||
# Test that rpc_trade_statistics can handle trades that lacks
|
# Test that rpc_trade_statistics can handle trades that lacks
|
||||||
# trade.open_rate (it is set to None)
|
# trade.open_rate (it is set to None)
|
||||||
def test_rpc_trade_statistics_closed(mocker, default_conf, ticker, fee,
|
def test_rpc_trade_statistics_closed(mocker, default_conf, ticker, fee, markets,
|
||||||
ticker_sell_up, limit_buy_order, limit_sell_order):
|
ticker_sell_up, limit_buy_order, limit_sell_order):
|
||||||
"""
|
"""
|
||||||
Test rpc_trade_statistics() method
|
Test rpc_trade_statistics() method
|
||||||
@ -253,7 +257,8 @@ def test_rpc_trade_statistics_closed(mocker, default_conf, ticker, fee,
|
|||||||
'freqtrade.freqtradebot.exchange',
|
'freqtrade.freqtradebot.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = FreqtradeBot(default_conf)
|
||||||
@ -400,7 +405,7 @@ def test_rpc_stop(mocker, default_conf) -> None:
|
|||||||
assert freqtradebot.state == State.STOPPED
|
assert freqtradebot.state == State.STOPPED
|
||||||
|
|
||||||
|
|
||||||
def test_rpc_forcesell(default_conf, ticker, fee, mocker) -> None:
|
def test_rpc_forcesell(default_conf, ticker, fee, mocker, markets) -> None:
|
||||||
"""
|
"""
|
||||||
Test rpc_forcesell() method
|
Test rpc_forcesell() method
|
||||||
"""
|
"""
|
||||||
@ -422,6 +427,7 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker) -> None:
|
|||||||
}
|
}
|
||||||
),
|
),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = FreqtradeBot(default_conf)
|
||||||
@ -519,7 +525,7 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_performance_handle(default_conf, ticker, limit_buy_order, fee,
|
def test_performance_handle(default_conf, ticker, limit_buy_order, fee,
|
||||||
limit_sell_order, mocker) -> None:
|
limit_sell_order, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test rpc_performance() method
|
Test rpc_performance() method
|
||||||
"""
|
"""
|
||||||
@ -531,7 +537,8 @@ def test_performance_handle(default_conf, ticker, limit_buy_order, fee,
|
|||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_balances=MagicMock(return_value=ticker),
|
get_balances=MagicMock(return_value=ticker),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = FreqtradeBot(default_conf)
|
||||||
@ -558,7 +565,7 @@ def test_performance_handle(default_conf, ticker, limit_buy_order, fee,
|
|||||||
assert prec_satoshi(res[0]['profit'], 6.2)
|
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, markets) -> None:
|
||||||
"""
|
"""
|
||||||
Test rpc_count() method
|
Test rpc_count() method
|
||||||
"""
|
"""
|
||||||
@ -571,6 +578,7 @@ def test_rpc_count(mocker, default_conf, ticker, fee) -> None:
|
|||||||
get_balances=MagicMock(return_value=ticker),
|
get_balances=MagicMock(return_value=ticker),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = FreqtradeBot(default_conf)
|
||||||
|
@ -233,7 +233,7 @@ def test_authorized_only_exception(default_conf, mocker, caplog) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_status(default_conf, update, mocker, fee, ticker) -> None:
|
def test_status(default_conf, update, mocker, fee, ticker, markets) -> None:
|
||||||
"""
|
"""
|
||||||
Test _status() method
|
Test _status() method
|
||||||
"""
|
"""
|
||||||
@ -250,6 +250,7 @@ def test_status(default_conf, update, mocker, fee, ticker) -> None:
|
|||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_pair_detail_url=MagicMock(),
|
get_pair_detail_url=MagicMock(),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
msg_mock = MagicMock()
|
msg_mock = MagicMock()
|
||||||
status_table = MagicMock()
|
status_table = MagicMock()
|
||||||
@ -278,7 +279,7 @@ def test_status(default_conf, update, mocker, fee, ticker) -> None:
|
|||||||
assert status_table.call_count == 1
|
assert status_table.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
def test_status_handle(default_conf, update, ticker, fee, mocker) -> None:
|
def test_status_handle(default_conf, update, ticker, fee, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test _status() method
|
Test _status() method
|
||||||
"""
|
"""
|
||||||
@ -289,6 +290,7 @@ def test_status_handle(default_conf, update, ticker, fee, mocker) -> None:
|
|||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
msg_mock = MagicMock()
|
msg_mock = MagicMock()
|
||||||
status_table = MagicMock()
|
status_table = MagicMock()
|
||||||
@ -324,7 +326,7 @@ def test_status_handle(default_conf, update, ticker, fee, mocker) -> None:
|
|||||||
assert '[ETH/BTC]' in msg_mock.call_args_list[0][0][0]
|
assert '[ETH/BTC]' in msg_mock.call_args_list[0][0][0]
|
||||||
|
|
||||||
|
|
||||||
def test_status_table_handle(default_conf, update, ticker, fee, mocker) -> None:
|
def test_status_table_handle(default_conf, update, ticker, fee, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test _status_table() method
|
Test _status_table() method
|
||||||
"""
|
"""
|
||||||
@ -336,6 +338,7 @@ def test_status_table_handle(default_conf, update, ticker, fee, mocker) -> None:
|
|||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
buy=MagicMock(return_value={'id': 'mocked_order_id'}),
|
buy=MagicMock(return_value={'id': 'mocked_order_id'}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
msg_mock = MagicMock()
|
msg_mock = MagicMock()
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
@ -377,7 +380,7 @@ def test_status_table_handle(default_conf, update, ticker, fee, mocker) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee,
|
def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee,
|
||||||
limit_sell_order, mocker) -> None:
|
limit_sell_order, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test _daily() method
|
Test _daily() method
|
||||||
"""
|
"""
|
||||||
@ -391,7 +394,8 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee,
|
|||||||
'freqtrade.freqtradebot.exchange',
|
'freqtrade.freqtradebot.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
msg_mock = MagicMock()
|
msg_mock = MagicMock()
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
@ -489,7 +493,7 @@ def test_daily_wrong_input(default_conf, update, ticker, mocker) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee,
|
def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee,
|
||||||
limit_buy_order, limit_sell_order, mocker) -> None:
|
limit_buy_order, limit_sell_order, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test _profit() method
|
Test _profit() method
|
||||||
"""
|
"""
|
||||||
@ -500,7 +504,8 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee,
|
|||||||
'freqtrade.freqtradebot.exchange',
|
'freqtrade.freqtradebot.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
msg_mock = MagicMock()
|
msg_mock = MagicMock()
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
@ -768,7 +773,8 @@ def test_reload_conf_handle(default_conf, update, mocker) -> None:
|
|||||||
assert 'Reloading config' in msg_mock.call_args_list[0][0][0]
|
assert 'Reloading config' in msg_mock.call_args_list[0][0][0]
|
||||||
|
|
||||||
|
|
||||||
def test_forcesell_handle(default_conf, update, ticker, fee, ticker_sell_up, mocker) -> None:
|
def test_forcesell_handle(default_conf, update, ticker, fee,
|
||||||
|
ticker_sell_up, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test _forcesell() method
|
Test _forcesell() method
|
||||||
"""
|
"""
|
||||||
@ -781,7 +787,8 @@ def test_forcesell_handle(default_conf, update, ticker, fee, ticker_sell_up, moc
|
|||||||
'freqtrade.freqtradebot.exchange',
|
'freqtrade.freqtradebot.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = FreqtradeBot(default_conf)
|
||||||
@ -808,7 +815,8 @@ def test_forcesell_handle(default_conf, update, ticker, fee, ticker_sell_up, moc
|
|||||||
assert '0.919 USD' in rpc_mock.call_args_list[-1][0][0]
|
assert '0.919 USD' in rpc_mock.call_args_list[-1][0][0]
|
||||||
|
|
||||||
|
|
||||||
def test_forcesell_down_handle(default_conf, update, ticker, fee, ticker_sell_down, mocker) -> None:
|
def test_forcesell_down_handle(default_conf, update, ticker, fee,
|
||||||
|
ticker_sell_down, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test _forcesell() method
|
Test _forcesell() method
|
||||||
"""
|
"""
|
||||||
@ -821,7 +829,8 @@ def test_forcesell_down_handle(default_conf, update, ticker, fee, ticker_sell_do
|
|||||||
'freqtrade.freqtradebot.exchange',
|
'freqtrade.freqtradebot.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = FreqtradeBot(default_conf)
|
||||||
@ -852,7 +861,7 @@ def test_forcesell_down_handle(default_conf, update, ticker, fee, ticker_sell_do
|
|||||||
assert '-0.824 USD' in rpc_mock.call_args_list[-1][0][0]
|
assert '-0.824 USD' in rpc_mock.call_args_list[-1][0][0]
|
||||||
|
|
||||||
|
|
||||||
def test_forcesell_all_handle(default_conf, update, ticker, fee, mocker) -> None:
|
def test_forcesell_all_handle(default_conf, update, ticker, fee, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test _forcesell() method
|
Test _forcesell() method
|
||||||
"""
|
"""
|
||||||
@ -866,7 +875,8 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, mocker) -> None
|
|||||||
'freqtrade.freqtradebot.exchange',
|
'freqtrade.freqtradebot.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = FreqtradeBot(default_conf)
|
||||||
@ -930,7 +940,7 @@ def test_forcesell_handle_invalid(default_conf, update, mocker) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_performance_handle(default_conf, update, ticker, fee,
|
def test_performance_handle(default_conf, update, ticker, fee,
|
||||||
limit_buy_order, limit_sell_order, mocker) -> None:
|
limit_buy_order, limit_sell_order, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test _performance() method
|
Test _performance() method
|
||||||
"""
|
"""
|
||||||
@ -946,7 +956,8 @@ def test_performance_handle(default_conf, update, ticker, fee,
|
|||||||
'freqtrade.freqtradebot.exchange',
|
'freqtrade.freqtradebot.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = FreqtradeBot(default_conf)
|
||||||
@ -994,7 +1005,7 @@ def test_performance_handle_invalid(default_conf, update, mocker) -> None:
|
|||||||
assert 'not running' in msg_mock.call_args_list[0][0][0]
|
assert 'not running' 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, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test _count() method
|
Test _count() method
|
||||||
"""
|
"""
|
||||||
@ -1010,7 +1021,8 @@ def test_count_handle(default_conf, update, ticker, fee, mocker) -> None:
|
|||||||
'freqtrade.freqtradebot.exchange',
|
'freqtrade.freqtradebot.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
buy=MagicMock(return_value={'id': 'mocked_order_id'})
|
buy=MagicMock(return_value={'id': 'mocked_order_id'}),
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
mocker.patch('freqtrade.optimize.backtesting.exchange.get_fee', fee)
|
mocker.patch('freqtrade.optimize.backtesting.exchange.get_fee', fee)
|
||||||
freqtradebot = FreqtradeBot(default_conf)
|
freqtradebot = FreqtradeBot(default_conf)
|
||||||
|
@ -255,20 +255,12 @@ def test_get_trade_stake_amount_no_stake_amount(default_conf,
|
|||||||
with pytest.raises(DependencyException, match=r'.*stake amount.*'):
|
with pytest.raises(DependencyException, match=r'.*stake amount.*'):
|
||||||
freqtrade._get_trade_stake_amount()
|
freqtrade._get_trade_stake_amount()
|
||||||
|
|
||||||
# test UNLIMITED_STAKE_AMOUNT
|
|
||||||
conf = deepcopy(default_conf)
|
|
||||||
conf['stake_amount'] = constants.UNLIMITED_STAKE_AMOUNT
|
|
||||||
conf['max_open_trades'] = 2
|
|
||||||
freqtrade = FreqtradeBot(conf)
|
|
||||||
|
|
||||||
with pytest.raises(DependencyException, match=r'.*is lower than minimal.*'):
|
|
||||||
freqtrade._get_trade_stake_amount()
|
|
||||||
|
|
||||||
|
|
||||||
def test_get_trade_stake_amount_unlimited_amount(default_conf,
|
def test_get_trade_stake_amount_unlimited_amount(default_conf,
|
||||||
ticker,
|
ticker,
|
||||||
limit_buy_order,
|
limit_buy_order,
|
||||||
fee,
|
fee,
|
||||||
|
markets,
|
||||||
mocker) -> None:
|
mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test get_trade_stake_amount() method
|
Test get_trade_stake_amount() method
|
||||||
@ -283,6 +275,7 @@ def test_get_trade_stake_amount_unlimited_amount(default_conf,
|
|||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_balance=MagicMock(return_value=default_conf['stake_amount']),
|
get_balance=MagicMock(return_value=default_conf['stake_amount']),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
conf = deepcopy(default_conf)
|
conf = deepcopy(default_conf)
|
||||||
@ -314,28 +307,119 @@ def test_get_trade_stake_amount_unlimited_amount(default_conf,
|
|||||||
assert result is None
|
assert result is None
|
||||||
|
|
||||||
|
|
||||||
def test_create_trade_no_stake_amount(default_conf, ticker, limit_buy_order, fee, mocker) -> None:
|
def test_get_min_pair_stake_amount(mocker, default_conf) -> None:
|
||||||
"""
|
"""
|
||||||
Test create_trade() method
|
Test get_trade_stake_amount() method
|
||||||
"""
|
"""
|
||||||
patch_get_signal(mocker)
|
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_coinmarketcap(mocker)
|
mocker.patch('freqtrade.freqtradebot.exchange.validate_pairs', MagicMock())
|
||||||
mocker.patch.multiple(
|
mocker.patch('freqtrade.freqtradebot.Analyze.get_stoploss', MagicMock(return_value=-0.05))
|
||||||
'freqtrade.freqtradebot.exchange',
|
|
||||||
validate_pairs=MagicMock(),
|
|
||||||
get_ticker=ticker,
|
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
|
||||||
get_balance=MagicMock(return_value=default_conf['stake_amount'] * 0.5),
|
|
||||||
get_fee=fee,
|
|
||||||
)
|
|
||||||
freqtrade = FreqtradeBot(default_conf)
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
|
|
||||||
with pytest.raises(DependencyException, match=r'.*stake amount.*'):
|
# no pair found
|
||||||
freqtrade.create_trade()
|
mocker.patch(
|
||||||
|
'freqtrade.freqtradebot.exchange.get_markets',
|
||||||
|
MagicMock(return_value=[{
|
||||||
|
'symbol': 'ETH/BTC'
|
||||||
|
}])
|
||||||
|
)
|
||||||
|
with pytest.raises(ValueError, match=r'.*get market information.*'):
|
||||||
|
freqtrade._get_min_pair_stake_amount('BNB/BTC', 1)
|
||||||
|
|
||||||
|
# no 'limits' section
|
||||||
|
mocker.patch(
|
||||||
|
'freqtrade.freqtradebot.exchange.get_markets',
|
||||||
|
MagicMock(return_value=[{
|
||||||
|
'symbol': 'ETH/BTC'
|
||||||
|
}])
|
||||||
|
)
|
||||||
|
result = freqtrade._get_min_pair_stake_amount('ETH/BTC', 1)
|
||||||
|
assert result is None
|
||||||
|
|
||||||
|
# empty 'limits' section
|
||||||
|
mocker.patch(
|
||||||
|
'freqtrade.freqtradebot.exchange.get_markets',
|
||||||
|
MagicMock(return_value=[{
|
||||||
|
'symbol': 'ETH/BTC',
|
||||||
|
'limits': {}
|
||||||
|
}])
|
||||||
|
)
|
||||||
|
result = freqtrade._get_min_pair_stake_amount('ETH/BTC', 1)
|
||||||
|
assert result is None
|
||||||
|
|
||||||
|
# empty 'cost'/'amount' section
|
||||||
|
mocker.patch(
|
||||||
|
'freqtrade.freqtradebot.exchange.get_markets',
|
||||||
|
MagicMock(return_value=[{
|
||||||
|
'symbol': 'ETH/BTC',
|
||||||
|
'limits': {
|
||||||
|
'cost': {},
|
||||||
|
'amount': {}
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
)
|
||||||
|
result = freqtrade._get_min_pair_stake_amount('ETH/BTC', 1)
|
||||||
|
assert result is None
|
||||||
|
|
||||||
|
# min cost is set
|
||||||
|
mocker.patch(
|
||||||
|
'freqtrade.freqtradebot.exchange.get_markets',
|
||||||
|
MagicMock(return_value=[{
|
||||||
|
'symbol': 'ETH/BTC',
|
||||||
|
'limits': {
|
||||||
|
'cost': {'min': 2},
|
||||||
|
'amount': {}
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
)
|
||||||
|
result = freqtrade._get_min_pair_stake_amount('ETH/BTC', 1)
|
||||||
|
assert result == 2 / 0.9
|
||||||
|
|
||||||
|
# min amount is set
|
||||||
|
mocker.patch(
|
||||||
|
'freqtrade.freqtradebot.exchange.get_markets',
|
||||||
|
MagicMock(return_value=[{
|
||||||
|
'symbol': 'ETH/BTC',
|
||||||
|
'limits': {
|
||||||
|
'cost': {},
|
||||||
|
'amount': {'min': 2}
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
)
|
||||||
|
result = freqtrade._get_min_pair_stake_amount('ETH/BTC', 2)
|
||||||
|
assert result == 2 * 2 / 0.9
|
||||||
|
|
||||||
|
# min amount and cost are set (cost is minimal)
|
||||||
|
mocker.patch(
|
||||||
|
'freqtrade.freqtradebot.exchange.get_markets',
|
||||||
|
MagicMock(return_value=[{
|
||||||
|
'symbol': 'ETH/BTC',
|
||||||
|
'limits': {
|
||||||
|
'cost': {'min': 2},
|
||||||
|
'amount': {'min': 2}
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
)
|
||||||
|
result = freqtrade._get_min_pair_stake_amount('ETH/BTC', 2)
|
||||||
|
assert result == min(2, 2 * 2) / 0.9
|
||||||
|
|
||||||
|
# min amount and cost are set (amount is minial)
|
||||||
|
mocker.patch(
|
||||||
|
'freqtrade.freqtradebot.exchange.get_markets',
|
||||||
|
MagicMock(return_value=[{
|
||||||
|
'symbol': 'ETH/BTC',
|
||||||
|
'limits': {
|
||||||
|
'cost': {'min': 8},
|
||||||
|
'amount': {'min': 2}
|
||||||
|
}
|
||||||
|
}])
|
||||||
|
)
|
||||||
|
result = freqtrade._get_min_pair_stake_amount('ETH/BTC', 2)
|
||||||
|
assert result == min(8, 2 * 2) / 0.9
|
||||||
|
|
||||||
|
|
||||||
def test_create_trade(default_conf, ticker, limit_buy_order, fee, mocker) -> None:
|
def test_create_trade(default_conf, ticker, limit_buy_order, fee, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test create_trade() method
|
Test create_trade() method
|
||||||
"""
|
"""
|
||||||
@ -348,6 +432,7 @@ def test_create_trade(default_conf, ticker, limit_buy_order, fee, mocker) -> Non
|
|||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
# Save state of current whitelist
|
# Save state of current whitelist
|
||||||
@ -371,7 +456,31 @@ def test_create_trade(default_conf, ticker, limit_buy_order, fee, mocker) -> Non
|
|||||||
assert whitelist == default_conf['exchange']['pair_whitelist']
|
assert whitelist == default_conf['exchange']['pair_whitelist']
|
||||||
|
|
||||||
|
|
||||||
def test_create_trade_minimal_amount(default_conf, ticker, limit_buy_order, fee, mocker) -> None:
|
def test_create_trade_no_stake_amount(default_conf, ticker, limit_buy_order,
|
||||||
|
fee, markets, mocker) -> None:
|
||||||
|
"""
|
||||||
|
Test create_trade() method
|
||||||
|
"""
|
||||||
|
patch_get_signal(mocker)
|
||||||
|
patch_RPCManager(mocker)
|
||||||
|
patch_coinmarketcap(mocker)
|
||||||
|
mocker.patch.multiple(
|
||||||
|
'freqtrade.freqtradebot.exchange',
|
||||||
|
validate_pairs=MagicMock(),
|
||||||
|
get_ticker=ticker,
|
||||||
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
|
get_balance=MagicMock(return_value=default_conf['stake_amount'] * 0.5),
|
||||||
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
|
)
|
||||||
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
|
|
||||||
|
with pytest.raises(DependencyException, match=r'.*stake amount.*'):
|
||||||
|
freqtrade.create_trade()
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_trade_minimal_amount(default_conf, ticker, limit_buy_order,
|
||||||
|
fee, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test create_trade() method
|
Test create_trade() method
|
||||||
"""
|
"""
|
||||||
@ -385,6 +494,7 @@ def test_create_trade_minimal_amount(default_conf, ticker, limit_buy_order, fee,
|
|||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
buy=buy_mock,
|
buy=buy_mock,
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
conf = deepcopy(default_conf)
|
conf = deepcopy(default_conf)
|
||||||
@ -396,7 +506,34 @@ def test_create_trade_minimal_amount(default_conf, ticker, limit_buy_order, fee,
|
|||||||
assert rate * amount >= conf['stake_amount']
|
assert rate * amount >= conf['stake_amount']
|
||||||
|
|
||||||
|
|
||||||
def test_create_trade_limit_reached(default_conf, ticker, limit_buy_order, fee, mocker) -> None:
|
def test_create_trade_too_small_stake_amount(default_conf, ticker, limit_buy_order,
|
||||||
|
fee, markets, mocker) -> None:
|
||||||
|
"""
|
||||||
|
Test create_trade() method
|
||||||
|
"""
|
||||||
|
patch_get_signal(mocker)
|
||||||
|
patch_RPCManager(mocker)
|
||||||
|
patch_coinmarketcap(mocker)
|
||||||
|
buy_mock = MagicMock(return_value={'id': limit_buy_order['id']})
|
||||||
|
mocker.patch.multiple(
|
||||||
|
'freqtrade.freqtradebot.exchange',
|
||||||
|
validate_pairs=MagicMock(),
|
||||||
|
get_ticker=ticker,
|
||||||
|
buy=buy_mock,
|
||||||
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
|
)
|
||||||
|
|
||||||
|
conf = deepcopy(default_conf)
|
||||||
|
conf['stake_amount'] = 0.000000005
|
||||||
|
freqtrade = FreqtradeBot(conf)
|
||||||
|
|
||||||
|
result = freqtrade.create_trade()
|
||||||
|
assert result is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_trade_limit_reached(default_conf, ticker, limit_buy_order,
|
||||||
|
fee, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test create_trade() method
|
Test create_trade() method
|
||||||
"""
|
"""
|
||||||
@ -410,6 +547,7 @@ def test_create_trade_limit_reached(default_conf, ticker, limit_buy_order, fee,
|
|||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_balance=MagicMock(return_value=default_conf['stake_amount']),
|
get_balance=MagicMock(return_value=default_conf['stake_amount']),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
conf = deepcopy(default_conf)
|
conf = deepcopy(default_conf)
|
||||||
conf['max_open_trades'] = 0
|
conf['max_open_trades'] = 0
|
||||||
@ -421,7 +559,7 @@ def test_create_trade_limit_reached(default_conf, ticker, limit_buy_order, fee,
|
|||||||
assert freqtrade._get_trade_stake_amount() is None
|
assert freqtrade._get_trade_stake_amount() is None
|
||||||
|
|
||||||
|
|
||||||
def test_create_trade_no_pairs(default_conf, ticker, limit_buy_order, fee, mocker) -> None:
|
def test_create_trade_no_pairs(default_conf, ticker, limit_buy_order, fee, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test create_trade() method
|
Test create_trade() method
|
||||||
"""
|
"""
|
||||||
@ -434,6 +572,7 @@ def test_create_trade_no_pairs(default_conf, ticker, limit_buy_order, fee, mocke
|
|||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
conf = deepcopy(default_conf)
|
conf = deepcopy(default_conf)
|
||||||
@ -448,7 +587,7 @@ def test_create_trade_no_pairs(default_conf, ticker, limit_buy_order, fee, mocke
|
|||||||
|
|
||||||
|
|
||||||
def test_create_trade_no_pairs_after_blacklist(default_conf, ticker,
|
def test_create_trade_no_pairs_after_blacklist(default_conf, ticker,
|
||||||
limit_buy_order, fee, mocker) -> None:
|
limit_buy_order, fee, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test create_trade() method
|
Test create_trade() method
|
||||||
"""
|
"""
|
||||||
@ -461,6 +600,7 @@ def test_create_trade_no_pairs_after_blacklist(default_conf, ticker,
|
|||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
conf = deepcopy(default_conf)
|
conf = deepcopy(default_conf)
|
||||||
@ -736,7 +876,8 @@ def test_process_maybe_execute_sell_exception(mocker, default_conf,
|
|||||||
assert log_has('Unable to sell trade: ', caplog.record_tuples)
|
assert log_has('Unable to sell trade: ', caplog.record_tuples)
|
||||||
|
|
||||||
|
|
||||||
def test_handle_trade(default_conf, limit_buy_order, limit_sell_order, fee, mocker) -> None:
|
def test_handle_trade(default_conf, limit_buy_order, limit_sell_order,
|
||||||
|
fee, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test check_handle() method
|
Test check_handle() method
|
||||||
"""
|
"""
|
||||||
@ -752,7 +893,8 @@ def test_handle_trade(default_conf, limit_buy_order, limit_sell_order, fee, mock
|
|||||||
}),
|
}),
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
sell=MagicMock(return_value={'id': limit_sell_order['id']}),
|
sell=MagicMock(return_value={'id': limit_sell_order['id']}),
|
||||||
get_fee=fee
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
patch_coinmarketcap(mocker, value={'price_usd': 15000.0})
|
patch_coinmarketcap(mocker, value={'price_usd': 15000.0})
|
||||||
|
|
||||||
@ -780,7 +922,8 @@ def test_handle_trade(default_conf, limit_buy_order, limit_sell_order, fee, mock
|
|||||||
assert trade.close_date is not None
|
assert trade.close_date is not None
|
||||||
|
|
||||||
|
|
||||||
def test_handle_overlpapping_signals(default_conf, ticker, limit_buy_order, fee, mocker) -> None:
|
def test_handle_overlpapping_signals(default_conf, ticker, limit_buy_order,
|
||||||
|
fee, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test check_handle() method
|
Test check_handle() method
|
||||||
"""
|
"""
|
||||||
@ -797,6 +940,7 @@ def test_handle_overlpapping_signals(default_conf, ticker, limit_buy_order, fee,
|
|||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
freqtrade = FreqtradeBot(conf)
|
freqtrade = FreqtradeBot(conf)
|
||||||
@ -838,7 +982,8 @@ def test_handle_overlpapping_signals(default_conf, ticker, limit_buy_order, fee,
|
|||||||
assert freqtrade.handle_trade(trades[0]) is True
|
assert freqtrade.handle_trade(trades[0]) is True
|
||||||
|
|
||||||
|
|
||||||
def test_handle_trade_roi(default_conf, ticker, limit_buy_order, fee, mocker, caplog) -> None:
|
def test_handle_trade_roi(default_conf, ticker, limit_buy_order,
|
||||||
|
fee, mocker, markets, caplog) -> None:
|
||||||
"""
|
"""
|
||||||
Test check_handle() method
|
Test check_handle() method
|
||||||
"""
|
"""
|
||||||
@ -855,6 +1000,7 @@ def test_handle_trade_roi(default_conf, ticker, limit_buy_order, fee, mocker, ca
|
|||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
mocker.patch('freqtrade.freqtradebot.Analyze.min_roi_reached', return_value=True)
|
mocker.patch('freqtrade.freqtradebot.Analyze.min_roi_reached', return_value=True)
|
||||||
@ -875,7 +1021,7 @@ def test_handle_trade_roi(default_conf, ticker, limit_buy_order, fee, mocker, ca
|
|||||||
|
|
||||||
|
|
||||||
def test_handle_trade_experimental(
|
def test_handle_trade_experimental(
|
||||||
default_conf, ticker, limit_buy_order, fee, mocker, caplog) -> None:
|
default_conf, ticker, limit_buy_order, fee, mocker, markets, caplog) -> None:
|
||||||
"""
|
"""
|
||||||
Test check_handle() method
|
Test check_handle() method
|
||||||
"""
|
"""
|
||||||
@ -892,6 +1038,7 @@ def test_handle_trade_experimental(
|
|||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
mocker.patch('freqtrade.freqtradebot.Analyze.min_roi_reached', return_value=False)
|
mocker.patch('freqtrade.freqtradebot.Analyze.min_roi_reached', return_value=False)
|
||||||
|
|
||||||
@ -909,7 +1056,8 @@ def test_handle_trade_experimental(
|
|||||||
assert log_has('Sell signal received. Selling..', caplog.record_tuples)
|
assert log_has('Sell signal received. Selling..', caplog.record_tuples)
|
||||||
|
|
||||||
|
|
||||||
def test_close_trade(default_conf, ticker, limit_buy_order, limit_sell_order, fee, mocker) -> None:
|
def test_close_trade(default_conf, ticker, limit_buy_order, limit_sell_order,
|
||||||
|
fee, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test check_handle() method
|
Test check_handle() method
|
||||||
"""
|
"""
|
||||||
@ -922,6 +1070,7 @@ def test_close_trade(default_conf, ticker, limit_buy_order, limit_sell_order, fe
|
|||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
freqtrade = FreqtradeBot(default_conf)
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
|
|
||||||
@ -1160,7 +1309,7 @@ def test_handle_timedout_limit_sell(mocker, default_conf) -> None:
|
|||||||
assert cancel_order_mock.call_count == 1
|
assert cancel_order_mock.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, mocker) -> None:
|
def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test execute_sell() method with a ticker going UP
|
Test execute_sell() method with a ticker going UP
|
||||||
"""
|
"""
|
||||||
@ -1171,7 +1320,8 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, mocker) -> N
|
|||||||
'freqtrade.freqtradebot.exchange',
|
'freqtrade.freqtradebot.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0)
|
mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||||
freqtrade = FreqtradeBot(default_conf)
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
@ -1201,7 +1351,7 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, mocker) -> N
|
|||||||
assert '0.919 USD' in rpc_mock.call_args_list[-1][0][0]
|
assert '0.919 USD' in rpc_mock.call_args_list[-1][0][0]
|
||||||
|
|
||||||
|
|
||||||
def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, mocker) -> None:
|
def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test execute_sell() method with a ticker going DOWN
|
Test execute_sell() method with a ticker going DOWN
|
||||||
"""
|
"""
|
||||||
@ -1213,7 +1363,8 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, mocker)
|
|||||||
'freqtrade.freqtradebot.exchange',
|
'freqtrade.freqtradebot.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
freqtrade = FreqtradeBot(default_conf)
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
|
|
||||||
@ -1242,7 +1393,7 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, mocker)
|
|||||||
|
|
||||||
|
|
||||||
def test_execute_sell_without_conf_sell_up(default_conf, ticker, fee,
|
def test_execute_sell_without_conf_sell_up(default_conf, ticker, fee,
|
||||||
ticker_sell_up, mocker) -> None:
|
ticker_sell_up, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test execute_sell() method with a ticker going DOWN and with a bot config empty
|
Test execute_sell() method with a ticker going DOWN and with a bot config empty
|
||||||
"""
|
"""
|
||||||
@ -1253,7 +1404,8 @@ def test_execute_sell_without_conf_sell_up(default_conf, ticker, fee,
|
|||||||
'freqtrade.freqtradebot.exchange',
|
'freqtrade.freqtradebot.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
freqtrade = FreqtradeBot(default_conf)
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
|
|
||||||
@ -1283,7 +1435,7 @@ def test_execute_sell_without_conf_sell_up(default_conf, ticker, fee,
|
|||||||
|
|
||||||
|
|
||||||
def test_execute_sell_without_conf_sell_down(default_conf, ticker, fee,
|
def test_execute_sell_without_conf_sell_down(default_conf, ticker, fee,
|
||||||
ticker_sell_down, mocker) -> None:
|
ticker_sell_down, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test execute_sell() method with a ticker going DOWN and with a bot config empty
|
Test execute_sell() method with a ticker going DOWN and with a bot config empty
|
||||||
"""
|
"""
|
||||||
@ -1294,7 +1446,8 @@ def test_execute_sell_without_conf_sell_down(default_conf, ticker, fee,
|
|||||||
'freqtrade.freqtradebot.exchange',
|
'freqtrade.freqtradebot.exchange',
|
||||||
validate_pairs=MagicMock(),
|
validate_pairs=MagicMock(),
|
||||||
get_ticker=ticker,
|
get_ticker=ticker,
|
||||||
get_fee=fee
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
freqtrade = FreqtradeBot(default_conf)
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
|
|
||||||
@ -1321,7 +1474,8 @@ def test_execute_sell_without_conf_sell_down(default_conf, ticker, fee,
|
|||||||
assert 'loss: -5.48%, -0.00005492' in rpc_mock.call_args_list[-1][0][0]
|
assert 'loss: -5.48%, -0.00005492' in rpc_mock.call_args_list[-1][0][0]
|
||||||
|
|
||||||
|
|
||||||
def test_sell_profit_only_enable_profit(default_conf, limit_buy_order, fee, mocker) -> None:
|
def test_sell_profit_only_enable_profit(default_conf, limit_buy_order,
|
||||||
|
fee, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test sell_profit_only feature when enabled
|
Test sell_profit_only feature when enabled
|
||||||
"""
|
"""
|
||||||
@ -1339,6 +1493,7 @@ def test_sell_profit_only_enable_profit(default_conf, limit_buy_order, fee, mock
|
|||||||
}),
|
}),
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
conf = deepcopy(default_conf)
|
conf = deepcopy(default_conf)
|
||||||
conf['experimental'] = {
|
conf['experimental'] = {
|
||||||
@ -1354,7 +1509,8 @@ def test_sell_profit_only_enable_profit(default_conf, limit_buy_order, fee, mock
|
|||||||
assert freqtrade.handle_trade(trade) is True
|
assert freqtrade.handle_trade(trade) is True
|
||||||
|
|
||||||
|
|
||||||
def test_sell_profit_only_disable_profit(default_conf, limit_buy_order, fee, mocker) -> None:
|
def test_sell_profit_only_disable_profit(default_conf, limit_buy_order,
|
||||||
|
fee, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test sell_profit_only feature when disabled
|
Test sell_profit_only feature when disabled
|
||||||
"""
|
"""
|
||||||
@ -1372,6 +1528,7 @@ def test_sell_profit_only_disable_profit(default_conf, limit_buy_order, fee, moc
|
|||||||
}),
|
}),
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
conf = deepcopy(default_conf)
|
conf = deepcopy(default_conf)
|
||||||
conf['experimental'] = {
|
conf['experimental'] = {
|
||||||
@ -1387,7 +1544,7 @@ def test_sell_profit_only_disable_profit(default_conf, limit_buy_order, fee, moc
|
|||||||
assert freqtrade.handle_trade(trade) is True
|
assert freqtrade.handle_trade(trade) is True
|
||||||
|
|
||||||
|
|
||||||
def test_sell_profit_only_enable_loss(default_conf, limit_buy_order, fee, mocker) -> None:
|
def test_sell_profit_only_enable_loss(default_conf, limit_buy_order, fee, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test sell_profit_only feature when enabled and we have a loss
|
Test sell_profit_only feature when enabled and we have a loss
|
||||||
"""
|
"""
|
||||||
@ -1405,6 +1562,7 @@ def test_sell_profit_only_enable_loss(default_conf, limit_buy_order, fee, mocker
|
|||||||
}),
|
}),
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
conf = deepcopy(default_conf)
|
conf = deepcopy(default_conf)
|
||||||
conf['experimental'] = {
|
conf['experimental'] = {
|
||||||
@ -1420,7 +1578,7 @@ def test_sell_profit_only_enable_loss(default_conf, limit_buy_order, fee, mocker
|
|||||||
assert freqtrade.handle_trade(trade) is False
|
assert freqtrade.handle_trade(trade) is False
|
||||||
|
|
||||||
|
|
||||||
def test_sell_profit_only_disable_loss(default_conf, limit_buy_order, fee, mocker) -> None:
|
def test_sell_profit_only_disable_loss(default_conf, limit_buy_order, fee, markets, mocker) -> None:
|
||||||
"""
|
"""
|
||||||
Test sell_profit_only feature when enabled and we have a loss
|
Test sell_profit_only feature when enabled and we have a loss
|
||||||
"""
|
"""
|
||||||
@ -1438,6 +1596,7 @@ def test_sell_profit_only_disable_loss(default_conf, limit_buy_order, fee, mocke
|
|||||||
}),
|
}),
|
||||||
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
|
get_markets=markets
|
||||||
)
|
)
|
||||||
|
|
||||||
conf = deepcopy(default_conf)
|
conf = deepcopy(default_conf)
|
||||||
|
Loading…
Reference in New Issue
Block a user