Repository: freqtrade/freqtrade

Issue:
MIN_TRADE_REQUIREMENT_NOT_MET
"stake_amount": 0.0005

Traceback (most recent call last):
  File "./freqtrade/main.py", line 70, in _process
    trade = create_trade(float(_CONF['stake_amount']))
  File "./freqtrade/main.py", line 213, in create_trade
    order_id = exchange.buy(pair, buy_limit, amount)
  File "/vagrant/freqtrade/freqtrade/exchange/__init__.py", line 100, in buy
    return _API.buy(pair, rate, amount)
  File "/vagrant/freqtrade/freqtrade/exchange/bittrex.py", line 53, in buy
    amount=amount))
RuntimeError: MIN_TRADE_REQUIREMENT_NOT_MET params=(BTC_CLUB, 0.00067, 0.7444029850746269)


Discussion:
Bittrex requires a minimum amount of 50k satoshi
 0.00067 is more than 50k satoshi, the stake_amount was set to 0.0005
I encountered this as well. The program crashes and the bot stops. Is there anyway to handle this properly rather than just stopping the bot?
I think this may happen in the following scenario:
1. Price drops to a certain point
2. Bot wants to buy X coins for price Y, that is 0.0005 BTC
3. Price drops even lower
4. The buy order is set but price is less than Y, that being less than 0.0005 BTC

That would be fixed by forcing min price to  0.0007 or even 0.001 I believe.
@alxnegrila 0.00067 is the rate at which it tried to buy CLUB it's not the amount.

Indeed, 0.0005 BTC should actually be fine.
The scenario was
Place LIMIT_BUY order to get 0.74440298 CLUB's for 0.0005 BTC at a rate of  0.00067 BTC/CLUB.

@hftcrypto Did you encounter the exact same traceback? As far as I can see the bot didn't crash at this point (the RuntimeError got catched in _process). It should stop, give you a telegram message about what failed and then you can /start it again.

Errors reported from bittrex are already catched, but they require human intervention.
Right now there is no reliable way to handle that because of several reasons:
* There is no public documentation which contains a complete list of all error codes
* You cannot just ignore these errors because it could mask a configuration problem and could lead to a banned account.

@alxnegrila it would be possible to require a minimum `stake_amount` but that would be very specific to BTC on bittrex.

I think I spotted the place where it misbehaves, it is somewhere within the fee calculation:
```
>>> 0.00067 * 0.7444029850746269
0.0004987500000000001
```
It acutally tried to create LIMIT_BUY order for 0.00049875 BTC


Resolving patch:
diff --git a/freqtrade/main.py b/freqtrade/main.py
--- a/freqtrade/main.py
+++ b/freqtrade/main.py
@@ -204,10 +204,9 @@ def create_trade(stake_amount: float) -> bool:
     else:
         return False
 
-    # Calculate amount and subtract fee
-    fee = exchange.get_fee()
+    # Calculate amount
     buy_limit = get_target_bid(exchange.get_ticker(pair))
-    amount = (1 - fee) * stake_amount / buy_limit
+    amount = stake_amount / buy_limit
 
     order_id = exchange.buy(pair, buy_limit, amount)
     # Create trade entity and return
@@ -222,7 +221,7 @@ def create_trade(stake_amount: float) -> bool:
         pair=pair,
         stake_amount=stake_amount,
         amount=amount,
-        fee=fee * 2,
+        fee=exchange.get_fee() * 2,
         open_rate=buy_limit,
         open_date=datetime.utcnow(),
         exchange=exchange.get_name().upper(),


Test patch:
diff --git a/freqtrade/tests/test_main.py b/freqtrade/tests/test_main.py
--- a/freqtrade/tests/test_main.py
+++ b/freqtrade/tests/test_main.py
@@ -41,7 +41,7 @@ def test_process_trade_creation(default_conf, ticker, health, mocker):
     assert trade.open_date is not None
     assert trade.exchange == Exchanges.BITTREX.name
     assert trade.open_rate == 0.072661
-    assert trade.amount == 0.6864067381401302
+    assert trade.amount == 0.6881270557795791
 
 
 def test_process_exchange_failures(default_conf, ticker, health, mocker):
@@ -133,6 +133,21 @@ def test_create_trade(default_conf, ticker, limit_buy_order, mocker):
     assert whitelist == default_conf['exchange']['pair_whitelist']
 
 
+def test_create_trade_minimal_amount(default_conf, ticker, mocker):
+    mocker.patch.dict('freqtrade.main._CONF', default_conf)
+    mocker.patch.multiple('freqtrade.rpc', init=MagicMock(), send_msg=MagicMock())
+    mocker.patch('freqtrade.main.get_signal', side_effect=lambda s, t: True)
+    buy_mock = mocker.patch('freqtrade.main.exchange.buy', MagicMock(return_value='mocked_limit_buy'))
+    mocker.patch.multiple('freqtrade.main.exchange',
+                          validate_pairs=MagicMock(),
+                          get_ticker=ticker)
+    init(default_conf, create_engine('sqlite://'))
+    min_stake_amount = 0.0005
+    create_trade(min_stake_amount)
+    rate, amount = buy_mock.call_args[0][1], buy_mock.call_args[0][2]
+    assert rate * amount >= min_stake_amount
+
+
 def test_create_trade_no_stake_amount(default_conf, ticker, mocker):
     mocker.patch.dict('freqtrade.main._CONF', default_conf)
     mocker.patch('freqtrade.main.get_signal', side_effect=lambda s, t: True)