def test_rpc_stop(mocker, default_conf) -> None: """ Test rpc_stop() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) mocker.patch('freqtrade.rpc.rpc_manager.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_ticker=MagicMock() ) freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://')) rpc = RPC(freqtradebot) freqtradebot.state = State.RUNNING (error, result) = rpc.rpc_stop() assert not error assert '`Stopping trader ...`' in result assert freqtradebot.state == State.STOPPED (error, result) = rpc.rpc_stop() assert error assert '*Status:* `already stopped`' in result assert freqtradebot.state == State.STOPPED
def test_rpc_count(mocker, default_conf, ticker) -> None: """ Test rpc_count() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) mocker.patch('freqtrade.rpc.rpc_manager.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_balances=MagicMock(return_value=ticker), get_ticker=ticker ) freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://')) rpc = RPC(freqtradebot) (error, trades) = rpc.rpc_count() nb_trades = len(trades) assert not error assert nb_trades == 0 # Create some test data freqtradebot.create_trade() (error, trades) = rpc.rpc_count() nb_trades = len(trades) assert not error assert nb_trades == 1
def test_rpc_count(mocker, default_conf, ticker, fee, markets) -> None: """ Test rpc_count() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', validate_pairs=MagicMock(), get_balances=MagicMock(return_value=ticker), get_ticker=ticker, get_fee=fee, get_markets=markets ) freqtradebot = FreqtradeBot(default_conf) rpc = RPC(freqtradebot) trades = rpc._rpc_count() nb_trades = len(trades) assert nb_trades == 0 # Create some test data freqtradebot.create_trade() trades = rpc._rpc_count() nb_trades = len(trades) assert nb_trades == 1
def test_rpc_status_table(default_conf, ticker, mocker) -> None: """ Test rpc_status_table() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) mocker.patch('freqtrade.rpc.rpc_manager.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_ticker=ticker ) freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://')) rpc = RPC(freqtradebot) freqtradebot.state = State.STOPPED (error, result) = rpc.rpc_status_table() assert error assert '*Status:* `trader is not running`' in result freqtradebot.state = State.RUNNING (error, result) = rpc.rpc_status_table() assert error assert '*Status:* `no active order`' in result freqtradebot.create_trade() (error, result) = rpc.rpc_status_table() assert 'just now' in result['Since'].all() assert 'BTC_ETH' in result['Pair'].all() assert '-0.59%' in result['Profit'].all()
def test_rpc_trade_statistics( default_conf, ticker, ticker_sell_up, limit_buy_order, limit_sell_order, mocker) -> None: """ Test rpc_trade_statistics() method """ patch_get_signal(mocker, (True, False)) mocker.patch.multiple( 'freqtrade.fiat_convert.Market', ticker=MagicMock(return_value={'price_usd': 15000.0}), ) mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0) mocker.patch('freqtrade.rpc.rpc_manager.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_ticker=ticker ) freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://')) stake_currency = default_conf['stake_currency'] fiat_display_currency = default_conf['fiat_display_currency'] rpc = RPC(freqtradebot) (error, stats) = rpc.rpc_trade_statistics(stake_currency, fiat_display_currency) assert error assert stats.find('no closed trade') >= 0 # Create some test data freqtradebot.create_trade() trade = Trade.query.first() # Simulate fulfilled LIMIT_BUY order for trade trade.update(limit_buy_order) # Update the ticker with a market going up mocker.patch.multiple( 'freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_ticker=ticker_sell_up ) trade.update(limit_sell_order) trade.close_date = datetime.utcnow() trade.is_open = False (error, stats) = rpc.rpc_trade_statistics(stake_currency, fiat_display_currency) assert not error assert prec_satoshi(stats['profit_closed_coin'], 6.217e-05) assert prec_satoshi(stats['profit_closed_percent'], 6.2) assert prec_satoshi(stats['profit_closed_fiat'], 0.93255) assert prec_satoshi(stats['profit_all_coin'], 6.217e-05) assert prec_satoshi(stats['profit_all_percent'], 6.2) assert prec_satoshi(stats['profit_all_fiat'], 0.93255) assert stats['trade_count'] == 1 assert stats['first_trade_date'] == 'just now' assert stats['latest_trade_date'] == 'just now' assert stats['avg_duration'] == '0:00:00' assert stats['best_pair'] == 'BTC_ETH' assert prec_satoshi(stats['best_rate'], 6.2)
def test_rpc_trade_statistics_closed(mocker, default_conf, ticker, fee, markets, ticker_sell_up, limit_buy_order, limit_sell_order): """ Test rpc_trade_statistics() method """ patch_get_signal(mocker, (True, False)) mocker.patch.multiple( 'freqtrade.fiat_convert.Market', ticker=MagicMock(return_value={'price_usd': 15000.0}), ) mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', validate_pairs=MagicMock(), get_ticker=ticker, get_fee=fee, get_markets=markets ) freqtradebot = FreqtradeBot(default_conf) stake_currency = default_conf['stake_currency'] fiat_display_currency = default_conf['fiat_display_currency'] rpc = RPC(freqtradebot) # Create some test data freqtradebot.create_trade() trade = Trade.query.first() # Simulate fulfilled LIMIT_BUY order for trade trade.update(limit_buy_order) # Update the ticker with a market going up mocker.patch.multiple( 'freqtrade.exchange.Exchange', validate_pairs=MagicMock(), get_ticker=ticker_sell_up, get_fee=fee ) trade.update(limit_sell_order) trade.close_date = datetime.utcnow() trade.is_open = False for trade in Trade.query.order_by(Trade.id).all(): trade.open_rate = None stats = rpc._rpc_trade_statistics(stake_currency, fiat_display_currency) assert prec_satoshi(stats['profit_closed_coin'], 0) assert prec_satoshi(stats['profit_closed_percent'], 0) assert prec_satoshi(stats['profit_closed_fiat'], 0) assert prec_satoshi(stats['profit_all_coin'], 0) assert prec_satoshi(stats['profit_all_percent'], 0) assert prec_satoshi(stats['profit_all_fiat'], 0) assert stats['trade_count'] == 1 assert stats['first_trade_date'] == 'just now' assert stats['latest_trade_date'] == 'just now' assert stats['avg_duration'] == '0:00:00' assert stats['best_pair'] == 'ETH/BTC' assert prec_satoshi(stats['best_rate'], 6.2)
def test_rpc_daily_profit(default_conf, update, ticker, limit_buy_order, limit_sell_order, mocker)\ -> None: """ Test rpc_daily_profit() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker, value={'price_usd': 15000.0}) mocker.patch('freqtrade.rpc.rpc_manager.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_ticker=ticker ) freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://')) stake_currency = default_conf['stake_currency'] fiat_display_currency = default_conf['fiat_display_currency'] rpc = RPC(freqtradebot) # Create some test data freqtradebot.create_trade() trade = Trade.query.first() assert trade # Simulate buy & sell trade.update(limit_buy_order) trade.update(limit_sell_order) trade.close_date = datetime.utcnow() trade.is_open = False # Try valid data update.message.text = '/daily 2' (error, days) = rpc.rpc_daily_profit(7, stake_currency, fiat_display_currency) assert not error assert len(days) == 7 for day in days: # [datetime.date(2018, 1, 11), '0.00000000 BTC', '0.000 USD'] assert (day[1] == '0.00000000 BTC' or day[1] == '0.00006217 BTC') assert (day[2] == '0.000 USD' or day[2] == '0.933 USD') # ensure first day is current date assert str(days[0][0]) == str(datetime.utcnow().date()) # Try invalid data (error, days) = rpc.rpc_daily_profit(0, stake_currency, fiat_display_currency) assert error assert days.find('must be an integer greater than 0') >= 0
def test_rpc_balance_handle(default_conf, mocker): """ Test rpc_balance() method """ mock_balance = [ { 'Currency': 'BTC', 'Balance': 10.0, 'Available': 12.0, 'Pending': 0.0, 'CryptoAddress': 'XXXX', }, { 'Currency': 'ETH', 'Balance': 0.0, 'Available': 0.0, 'Pending': 0.0, 'CryptoAddress': 'XXXX', } ] patch_get_signal(mocker, (True, False)) mocker.patch.multiple( 'freqtrade.fiat_convert.Market', ticker=MagicMock(return_value={'price_usd': 15000.0}), ) mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0) mocker.patch('freqtrade.rpc.rpc_manager.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_balances=MagicMock(return_value=mock_balance) ) freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://')) rpc = RPC(freqtradebot) (error, res) = rpc.rpc_balance(default_conf['fiat_display_currency']) assert not error (trade, x, y, z) = res assert prec_satoshi(x, 10) assert prec_satoshi(z, 150000) assert 'USD' in y assert len(trade) == 1 assert 'BTC' in trade[0]['currency'] assert prec_satoshi(trade[0]['available'], 12) assert prec_satoshi(trade[0]['balance'], 10) assert prec_satoshi(trade[0]['pending'], 0) assert prec_satoshi(trade[0]['est_btc'], 10)
def _analysed_history(self): """ Handler for /pair_history. Returns the dataframe of a given timerange Takes the following get arguments: get: parameters: - pair: Pair - timeframe: Timeframe to get data for (should be aligned to strategy.timeframe) - strategy: Strategy to use - Must exist in configured strategy-path! - timerange: timerange in the format YYYYMMDD-YYYYMMDD (YYYYMMDD- or (-YYYYMMDD)) are als possible. If omitted uses all available data. """ pair = request.args.get("pair") timeframe = request.args.get("timeframe") timerange = request.args.get("timerange") strategy = request.args.get("strategy") if not pair or not timeframe or not timerange or not strategy: return self.rest_error("Mandatory parameter missing.", 400) config = deepcopy(self._config) config.update({ 'strategy': strategy, }) results = RPC._rpc_analysed_history_full(config, pair, timeframe, timerange) return jsonify(results)
def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, mocker) -> None: """ Tests workflow """ default_conf['max_open_trades'] = 5 default_conf['forcebuy_enable'] = True default_conf['stake_amount'] = 'unlimited' default_conf['exchange']['name'] = 'binance' default_conf['telegram']['enabled'] = True mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch('freqtrade.wallets.Wallets.get_free', MagicMock( side_effect=[1000, 800, 600, 400, 200] )) mocker.patch.multiple( 'freqtrade.exchange.Exchange', get_ticker=ticker, get_fee=fee, symbol_amount_prec=lambda s, x, y: y, symbol_price_prec=lambda s, x, y: y, ) mocker.patch.multiple( 'freqtrade.freqtradebot.FreqtradeBot', create_stoploss_order=MagicMock(return_value=True), update_trade_state=MagicMock(), _notify_sell=MagicMock(), ) freqtrade = get_patched_freqtradebot(mocker, default_conf) rpc = RPC(freqtrade) freqtrade.strategy.order_types['stoploss_on_exchange'] = True # Switch ordertype to market to close trade immediately freqtrade.strategy.order_types['sell'] = 'market' patch_get_signal(freqtrade) # Create 4 trades freqtrade.create_trades() trades = Trade.query.all() assert len(trades) == 4 rpc._rpc_forcebuy('TKN/BTC', None) trades = Trade.query.all() assert len(trades) == 5 for trade in trades: assert trade.stake_amount == 200
def test_rpc_trade_status(default_conf, ticker, mocker) -> None: """ Test rpc_trade_status() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) mocker.patch('freqtrade.rpc.rpc_manager.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_ticker=ticker ) freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://')) rpc = RPC(freqtradebot) freqtradebot.state = State.STOPPED (error, result) = rpc.rpc_trade_status() assert error assert 'trader is not running' in result freqtradebot.state = State.RUNNING (error, result) = rpc.rpc_trade_status() assert error assert 'no active trade' in result freqtradebot.create_trade() (error, result) = rpc.rpc_trade_status() assert not error trade = result[0] result_message = [ '*Trade ID:* `1`\n' '*Current Pair:* ' '[BTC_ETH](https://www.bittrex.com/Market/Index?MarketName=BTC-ETH)\n' '*Open Since:* `just now`\n' '*Amount:* `90.99181074`\n' '*Open Rate:* `0.00001099`\n' '*Close Rate:* `None`\n' '*Current Rate:* `0.00001098`\n' '*Close Profit:* `None`\n' '*Current Profit:* `-0.59%`\n' '*Open Order:* `(LIMIT_BUY rem=0.00000000)`' ] assert result == result_message assert trade.find('[BTC_ETH]') >= 0
def test_rpc_status_table(default_conf, ticker, fee, markets, mocker) -> None: """ Test rpc_status_table() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', validate_pairs=MagicMock(), get_ticker=ticker, get_fee=fee, get_markets=markets ) freqtradebot = FreqtradeBot(default_conf) rpc = RPC(freqtradebot) freqtradebot.state = State.STOPPED with pytest.raises(RPCException, match=r'.*\*Status:\* `trader is not running``*'): rpc._rpc_status_table() freqtradebot.state = State.RUNNING with pytest.raises(RPCException, match=r'.*\*Status:\* `no active order`*'): rpc._rpc_status_table() freqtradebot.create_trade() result = rpc._rpc_status_table() assert 'just now' in result['Since'].all() assert 'ETH/BTC' in result['Pair'].all() assert '-0.59%' in result['Profit'].all()
def _get_logs(self): """ Returns latest logs get: param: limit: Only get a certain number of records """ limit = int(request.args.get('limit', 0)) or None return jsonify(RPC._rpc_get_logs(limit))
def test_rpc_balance_handle(default_conf, mocker): """ Test rpc_balance() method """ mock_balance = { 'BTC': { 'free': 10.0, 'total': 12.0, 'used': 2.0, }, 'ETH': { 'free': 0.0, 'total': 0.0, 'used': 0.0, } } patch_get_signal(mocker, (True, False)) mocker.patch.multiple( 'freqtrade.fiat_convert.Market', ticker=MagicMock(return_value={'price_usd': 15000.0}), ) mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', validate_pairs=MagicMock(), get_balances=MagicMock(return_value=mock_balance) ) freqtradebot = FreqtradeBot(default_conf) rpc = RPC(freqtradebot) output, total, symbol, value = rpc._rpc_balance(default_conf['fiat_display_currency']) assert prec_satoshi(total, 12) assert prec_satoshi(value, 180000) assert 'USD' in symbol assert len(output) == 1 assert 'BTC' in output[0]['currency'] assert prec_satoshi(output[0]['available'], 10) assert prec_satoshi(output[0]['balance'], 12) assert prec_satoshi(output[0]['pending'], 2) assert prec_satoshi(output[0]['est_btc'], 12)
def test_performance_handle(default_conf, ticker, limit_buy_order, fee, limit_sell_order, markets, mocker) -> None: """ Test rpc_performance() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', validate_pairs=MagicMock(), get_balances=MagicMock(return_value=ticker), get_ticker=ticker, get_fee=fee, get_markets=markets ) freqtradebot = FreqtradeBot(default_conf) rpc = RPC(freqtradebot) # Create some test data freqtradebot.create_trade() 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_performance() 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_stop(mocker, default_conf) -> None: """ Test rpc_stop() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', validate_pairs=MagicMock(), get_ticker=MagicMock() ) freqtradebot = FreqtradeBot(default_conf) rpc = RPC(freqtradebot) freqtradebot.state = State.RUNNING result = rpc._rpc_stop() assert '`Stopping trader ...`' in result assert freqtradebot.state == State.STOPPED result = rpc._rpc_stop() assert '*Status:* `already stopped`' in result assert freqtradebot.state == State.STOPPED
def test_rpc_trade_status(default_conf, ticker, fee, markets, mocker) -> None: """ Test rpc_trade_status() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', validate_pairs=MagicMock(), get_ticker=ticker, get_fee=fee, get_markets=markets ) freqtradebot = FreqtradeBot(default_conf) rpc = RPC(freqtradebot) freqtradebot.state = State.STOPPED with pytest.raises(RPCException, match=r'.*trader is not running*'): rpc._rpc_trade_status() freqtradebot.state = State.RUNNING with pytest.raises(RPCException, match=r'.*no active trade*'): rpc._rpc_trade_status() freqtradebot.create_trade() trades = rpc._rpc_trade_status() trade = trades[0] result_message = [ '*Trade ID:* `1`\n' '*Current Pair:* ' '[ETH/BTC](https://bittrex.com/Market/Index?MarketName=BTC-ETH)\n' '*Open Since:* `just now`\n' '*Amount:* `90.99181074`\n' '*Open Rate:* `0.00001099`\n' '*Close Rate:* `None`\n' '*Current Rate:* `0.00001098`\n' '*Close Profit:* `None`\n' '*Current Profit:* `-0.59%`\n' '*Open Order:* `(limit buy rem=0.00000000)`' ] assert trades == result_message assert trade.find('[ETH/BTC]') >= 0
def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, mocker, balance_ratio, result1) -> None: """ Tests workflow unlimited stake-amount Buy 4 trades, forcebuy a 5th trade Sell one trade, calculated stake amount should now be lower than before since one trade was sold at a loss. """ default_conf['max_open_trades'] = 5 default_conf['forcebuy_enable'] = True default_conf['stake_amount'] = 'unlimited' default_conf['tradable_balance_ratio'] = balance_ratio default_conf['dry_run_wallet'] = 1000 default_conf['exchange']['name'] = 'binance' default_conf['telegram']['enabled'] = True mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', fetch_ticker=ticker, get_fee=fee, amount_to_precision=lambda s, x, y: y, price_to_precision=lambda s, x, y: y, ) mocker.patch.multiple( 'freqtrade.freqtradebot.FreqtradeBot', create_stoploss_order=MagicMock(return_value=True), update_trade_state=MagicMock(), _notify_sell=MagicMock(), ) should_sell_mock = MagicMock(side_effect=[ SellCheckTuple(sell_flag=False, sell_type=SellType.NONE), SellCheckTuple(sell_flag=True, sell_type=SellType.SELL_SIGNAL), SellCheckTuple(sell_flag=False, sell_type=SellType.NONE), SellCheckTuple(sell_flag=False, sell_type=SellType.NONE), SellCheckTuple(sell_flag=None, sell_type=SellType.NONE) ]) mocker.patch("freqtrade.strategy.interface.IStrategy.should_sell", should_sell_mock) freqtrade = get_patched_freqtradebot(mocker, default_conf) rpc = RPC(freqtrade) freqtrade.strategy.order_types['stoploss_on_exchange'] = True # Switch ordertype to market to close trade immediately freqtrade.strategy.order_types['sell'] = 'market' patch_get_signal(freqtrade) # Create 4 trades n = freqtrade.enter_positions() assert n == 4 trades = Trade.query.all() assert len(trades) == 4 assert freqtrade.get_trade_stake_amount('XRP/BTC') == result1 rpc._rpc_forcebuy('TKN/BTC', None) trades = Trade.query.all() assert len(trades) == 5 for trade in trades: assert trade.stake_amount == result1 # Reset trade open order id's trade.open_order_id = None trades = Trade.get_open_trades() assert len(trades) == 5 bals = freqtrade.wallets.get_all_balances() n = freqtrade.exit_positions(trades) assert n == 1 trades = Trade.get_open_trades() # One trade sold assert len(trades) == 4 # stake-amount should now be reduced, since one trade was sold at a loss. assert freqtrade.get_trade_stake_amount('XRP/BTC') < result1 # Validate that balance of sold trade is not in dry-run balances anymore. bals2 = freqtrade.wallets.get_all_balances() assert bals != bals2 assert len(bals) == 6 assert len(bals2) == 5 assert 'LTC' in bals assert 'LTC' not in bals2
def _show_config(self): """ Prints the bot's version """ return jsonify( RPC._rpc_show_config(self._config, self._freqtrade.state))
def test_rpc_forcesell(default_conf, ticker, fee, mocker, markets) -> None: """ Test rpc_forcesell() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) cancel_order_mock = MagicMock() mocker.patch.multiple( 'freqtrade.exchange.Exchange', validate_pairs=MagicMock(), get_ticker=ticker, cancel_order=cancel_order_mock, get_order=MagicMock( return_value={ 'status': 'closed', 'type': 'limit', 'side': 'buy' } ), get_fee=fee, get_markets=markets ) freqtradebot = FreqtradeBot(default_conf) rpc = RPC(freqtradebot) freqtradebot.state = State.STOPPED with pytest.raises(RPCException, match=r'.*`trader is not running`*'): rpc._rpc_forcesell(None) freqtradebot.state = State.RUNNING with pytest.raises(RPCException, match=r'.*Invalid argument.*'): rpc._rpc_forcesell(None) rpc._rpc_forcesell('all') freqtradebot.create_trade() rpc._rpc_forcesell('all') rpc._rpc_forcesell('1') freqtradebot.state = State.STOPPED with pytest.raises(RPCException, match=r'.*`trader is not running`*'): rpc._rpc_forcesell(None) with pytest.raises(RPCException, match=r'.*`trader is not running`*'): rpc._rpc_forcesell('all') freqtradebot.state = State.RUNNING assert cancel_order_mock.call_count == 0 # make an limit-buy open trade trade = Trade.query.filter(Trade.id == '1').first() filled_amount = trade.amount / 2 mocker.patch( 'freqtrade.exchange.Exchange.get_order', return_value={ 'status': 'open', 'type': 'limit', 'side': 'buy', 'filled': filled_amount } ) # check that the trade is called, which is done by ensuring exchange.cancel_order is called # and trade amount is updated rpc._rpc_forcesell('1') assert cancel_order_mock.call_count == 1 assert trade.amount == filled_amount freqtradebot.create_trade() trade = Trade.query.filter(Trade.id == '2').first() amount = trade.amount # make an limit-buy open trade, if there is no 'filled', don't sell it mocker.patch( 'freqtrade.exchange.Exchange.get_order', return_value={ 'status': 'open', 'type': 'limit', 'side': 'buy', 'filled': None } ) # check that the trade is called, which is done by ensuring exchange.cancel_order is called rpc._rpc_forcesell('2') assert cancel_order_mock.call_count == 2 assert trade.amount == amount freqtradebot.create_trade() # make an limit-sell open trade mocker.patch( 'freqtrade.exchange.Exchange.get_order', return_value={ 'status': 'open', 'type': 'limit', 'side': 'sell' } ) rpc._rpc_forcesell('3') # status quo, no exchange calls assert cancel_order_mock.call_count == 2
def test_rpc_forcesell(default_conf, ticker, mocker) -> None: """ Test rpc_forcesell() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) mocker.patch('freqtrade.rpc.rpc_manager.Telegram', MagicMock()) cancel_order_mock = MagicMock() mocker.patch.multiple( 'freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_ticker=ticker, cancel_order=cancel_order_mock, get_order=MagicMock( return_value={ 'closed': True, 'type': 'LIMIT_BUY', } ) ) freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://')) rpc = RPC(freqtradebot) freqtradebot.state = State.STOPPED (error, res) = rpc.rpc_forcesell(None) assert error assert res == '`trader is not running`' freqtradebot.state = State.RUNNING (error, res) = rpc.rpc_forcesell(None) assert error assert res == 'Invalid argument.' (error, res) = rpc.rpc_forcesell('all') assert not error assert res == '' freqtradebot.create_trade() (error, res) = rpc.rpc_forcesell('all') assert not error assert res == '' (error, res) = rpc.rpc_forcesell('1') assert not error assert res == '' freqtradebot.state = State.STOPPED (error, res) = rpc.rpc_forcesell(None) assert error assert res == '`trader is not running`' (error, res) = rpc.rpc_forcesell('all') assert error assert res == '`trader is not running`' freqtradebot.state = State.RUNNING assert cancel_order_mock.call_count == 0 # make an limit-buy open trade mocker.patch( 'freqtrade.freqtradebot.exchange.get_order', return_value={ 'closed': None, 'type': 'LIMIT_BUY' } ) # check that the trade is called, which is done # by ensuring exchange.cancel_order is called (error, res) = rpc.rpc_forcesell('1') assert not error assert res == '' assert cancel_order_mock.call_count == 1 freqtradebot.create_trade() # make an limit-sell open trade mocker.patch( 'freqtrade.freqtradebot.exchange.get_order', return_value={ 'closed': None, 'type': 'LIMIT_SELL' } ) (error, res) = rpc.rpc_forcesell('2') assert not error assert res == '' # status quo, no exchange calls assert cancel_order_mock.call_count == 1