add get_real_amount and tests
This commit is contained in:
parent
1332ab397f
commit
11d8f7d522
@ -362,6 +362,53 @@ class FreqtradeBot(object):
|
|||||||
return self.handle_trade(trade)
|
return self.handle_trade(trade)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def get_real_amount(self, order: Trade) -> float:
|
||||||
|
"""
|
||||||
|
Get real amount for the trade
|
||||||
|
This is needed for exchanges which charge fees in target currency (binance)
|
||||||
|
"""
|
||||||
|
|
||||||
|
trades = exchange.get_trades_for_order(
|
||||||
|
order.open_order_id, order.pair, order.open_date)
|
||||||
|
|
||||||
|
if len(trades) == 0:
|
||||||
|
raise OperationalException("get_real_amount: no trade found")
|
||||||
|
amount = 0
|
||||||
|
fee = 0
|
||||||
|
for trade in trades:
|
||||||
|
amount += trade["amount"]
|
||||||
|
if "fee" in trade:
|
||||||
|
if order.pair.startswith(trade["fee"]["currency"]):
|
||||||
|
fee += trade["fee"]["cost"]
|
||||||
|
|
||||||
|
# TODO: create order using amount_lots would be better
|
||||||
|
if amount != order.amount:
|
||||||
|
self.logger.warning("amount {} does not match amount {}".format(amount, order.amount))
|
||||||
|
raise OperationalException("Half bought? Amounts don't match")
|
||||||
|
real_amount = amount - fee
|
||||||
|
return real_amount
|
||||||
|
|
||||||
|
def maybe_update_real_amount(self, trade: Trade) -> bool:
|
||||||
|
"""
|
||||||
|
Updates trade-amount with real amount
|
||||||
|
:return: True if real-amount has been changed.
|
||||||
|
"""
|
||||||
|
if trade.is_open and trade.open_order_id is None:
|
||||||
|
# Trade is not open anymore
|
||||||
|
self.logger.warning("could not open trade amount - Trade is not open anymore")
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
new_amount = self.get_real_amount(trade)
|
||||||
|
except OperationalException as exception:
|
||||||
|
self.logger.warning("could not update trade amount: %s", exception)
|
||||||
|
return False
|
||||||
|
# updating amount
|
||||||
|
self.logger.info("Updating amount for Trade {} from {} to {}".format(
|
||||||
|
trade, trade.amount, new_amount))
|
||||||
|
trade.amount = new_amount
|
||||||
|
Trade.session.flush()
|
||||||
|
return True
|
||||||
|
|
||||||
def handle_trade(self, trade: Trade) -> bool:
|
def handle_trade(self, trade: Trade) -> bool:
|
||||||
"""
|
"""
|
||||||
Sells the current pair if the threshold is reached and updates the trade record.
|
Sells the current pair if the threshold is reached and updates the trade record.
|
||||||
|
@ -1281,3 +1281,196 @@ def test_sell_profit_only_disable_loss(default_conf, limit_buy_order, mocker) ->
|
|||||||
trade.update(limit_buy_order)
|
trade.update(limit_buy_order)
|
||||||
patch_get_signal(mocker, value=(False, True))
|
patch_get_signal(mocker, value=(False, True))
|
||||||
assert freqtrade.handle_trade(trade) is True
|
assert freqtrade.handle_trade(trade) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_real_amount_quote(default_conf, trades_for_order, mocker):
|
||||||
|
"""
|
||||||
|
Test get_real_amount
|
||||||
|
"""
|
||||||
|
|
||||||
|
rv = [{'info': {'id': 34567,
|
||||||
|
'orderId': 123456,
|
||||||
|
'price': '0.24544100',
|
||||||
|
'qty': '8.00000000',
|
||||||
|
'commission': '0.00800000',
|
||||||
|
'commissionAsset': 'LTC',
|
||||||
|
'time': 1521663363189,
|
||||||
|
'isBuyer': True,
|
||||||
|
'isMaker': False,
|
||||||
|
'isBestMatch': True},
|
||||||
|
'timestamp': 1521663363189,
|
||||||
|
'datetime': '2018-03-21T20:16:03.189Z',
|
||||||
|
'symbol': 'LTC/ETH',
|
||||||
|
'id': '34567',
|
||||||
|
'order': '123456',
|
||||||
|
'type': None,
|
||||||
|
'side': 'buy',
|
||||||
|
'price': 0.245441,
|
||||||
|
'cost': 1.963528,
|
||||||
|
'amount': 8.0,
|
||||||
|
'fee': {'cost': 0.008, 'currency': 'LTC'}}]
|
||||||
|
mocker.patch('freqtrade.exchange.get_trades_for_order', return_value=rv)
|
||||||
|
|
||||||
|
patch_get_signal(mocker)
|
||||||
|
patch_RPCManager(mocker)
|
||||||
|
patch_coinmarketcap(mocker)
|
||||||
|
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
|
||||||
|
trade = Trade(
|
||||||
|
pair='LTC/ETH',
|
||||||
|
amount=8,
|
||||||
|
exchange='binance',
|
||||||
|
open_order_id="123456"
|
||||||
|
)
|
||||||
|
freqtrade = FreqtradeBot(default_conf, create_engine('sqlite://'))
|
||||||
|
# Amount - cost
|
||||||
|
assert freqtrade.get_real_amount(trade) == 7.992
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_real_amount_stake(default_conf, mocker):
|
||||||
|
"""
|
||||||
|
Test get_real_amount
|
||||||
|
"""
|
||||||
|
|
||||||
|
rv = [{'info': {'id': 34567,
|
||||||
|
'orderId': 123456,
|
||||||
|
'price': '0.24544100',
|
||||||
|
'qty': '8.00000000',
|
||||||
|
'commission': '0.00800000',
|
||||||
|
'commissionAsset': 'LTC',
|
||||||
|
'time': 1521663363189,
|
||||||
|
'isBuyer': True,
|
||||||
|
'isMaker': False,
|
||||||
|
'isBestMatch': True},
|
||||||
|
'timestamp': 1521663363189,
|
||||||
|
'datetime': '2018-03-21T20:16:03.189Z',
|
||||||
|
'symbol': 'LTC/ETH',
|
||||||
|
'id': '34567',
|
||||||
|
'order': '123456',
|
||||||
|
'type': None,
|
||||||
|
'side': 'buy',
|
||||||
|
'price': 0.245441,
|
||||||
|
'cost': 1.963528,
|
||||||
|
'amount': 8.0,
|
||||||
|
'fee': {'cost': 0.008, 'currency': 'ETH'}}]
|
||||||
|
mocker.patch('freqtrade.exchange.get_trades_for_order', return_value=rv)
|
||||||
|
|
||||||
|
patch_get_signal(mocker)
|
||||||
|
patch_RPCManager(mocker)
|
||||||
|
patch_coinmarketcap(mocker)
|
||||||
|
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
|
||||||
|
trade = Trade(
|
||||||
|
pair='IOTA/ETH',
|
||||||
|
amount=8,
|
||||||
|
exchange='binance',
|
||||||
|
open_order_id="123456"
|
||||||
|
)
|
||||||
|
freqtrade = FreqtradeBot(default_conf, create_engine('sqlite://'))
|
||||||
|
# Amount - cost
|
||||||
|
assert freqtrade.get_real_amount(trade) == 8
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_real_amount_BNB(default_conf, mocker):
|
||||||
|
"""
|
||||||
|
Test get_real_amount
|
||||||
|
"""
|
||||||
|
|
||||||
|
rv = [{'info': {'id': 34567,
|
||||||
|
'orderId': 123456,
|
||||||
|
'price': '0.24544100',
|
||||||
|
'qty': '8.00000000',
|
||||||
|
'commission': '0.00800000',
|
||||||
|
'commissionAsset': 'LTC',
|
||||||
|
'time': 1521663363189,
|
||||||
|
'isBuyer': True,
|
||||||
|
'isMaker': False,
|
||||||
|
'isBestMatch': True},
|
||||||
|
'timestamp': 1521663363189,
|
||||||
|
'datetime': '2018-03-21T20:16:03.189Z',
|
||||||
|
'symbol': 'LTC/ETH',
|
||||||
|
'id': '34567',
|
||||||
|
'order': '123456',
|
||||||
|
'type': None,
|
||||||
|
'side': 'buy',
|
||||||
|
'price': 0.245441,
|
||||||
|
'cost': 1.963528,
|
||||||
|
'amount': 8.0,
|
||||||
|
'fee': {'cost': 0.00094518, 'currency': 'BNB'}}]
|
||||||
|
mocker.patch('freqtrade.exchange.get_trades_for_order', return_value=rv)
|
||||||
|
|
||||||
|
patch_get_signal(mocker)
|
||||||
|
patch_RPCManager(mocker)
|
||||||
|
patch_coinmarketcap(mocker)
|
||||||
|
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
|
||||||
|
trade = Trade(
|
||||||
|
pair='IOTA/ETH',
|
||||||
|
amount=8,
|
||||||
|
exchange='binance',
|
||||||
|
open_order_id="123456"
|
||||||
|
)
|
||||||
|
freqtrade = FreqtradeBot(default_conf, create_engine('sqlite://'))
|
||||||
|
# Amount - cost
|
||||||
|
assert freqtrade.get_real_amount(trade) == 8
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_real_amount_multi(default_conf, mocker):
|
||||||
|
"""
|
||||||
|
Test get_real_amount
|
||||||
|
"""
|
||||||
|
|
||||||
|
rv = [{'info': {'id': 34567,
|
||||||
|
'orderId': 123456,
|
||||||
|
'price': '0.24544100',
|
||||||
|
'qty': '8.00000000',
|
||||||
|
'commission': '0.00800000',
|
||||||
|
'commissionAsset': 'LTC',
|
||||||
|
'time': 1521663363189,
|
||||||
|
'isBuyer': True,
|
||||||
|
'isMaker': False,
|
||||||
|
'isBestMatch': True},
|
||||||
|
'timestamp': 1521663363189,
|
||||||
|
'datetime': '2018-03-21T20:16:03.189Z',
|
||||||
|
'symbol': 'LTC/ETH',
|
||||||
|
'id': '34567',
|
||||||
|
'order': '123456',
|
||||||
|
'type': None,
|
||||||
|
'side': 'buy',
|
||||||
|
'price': 0.245441,
|
||||||
|
'cost': 1.963528,
|
||||||
|
'amount': 4.0,
|
||||||
|
'fee': {'cost': 0.004, 'currency': 'LTC'}},
|
||||||
|
{'info': {'id': 34567,
|
||||||
|
'orderId': 123456,
|
||||||
|
'price': '0.24544100',
|
||||||
|
'qty': '8.00000000',
|
||||||
|
'commission': '0.00800000',
|
||||||
|
'commissionAsset': 'LTC',
|
||||||
|
'time': 1521663363189,
|
||||||
|
'isBuyer': True,
|
||||||
|
'isMaker': False,
|
||||||
|
'isBestMatch': True},
|
||||||
|
'timestamp': 1521663363189,
|
||||||
|
'datetime': '2018-03-21T20:16:03.189Z',
|
||||||
|
'symbol': 'LTC/ETH',
|
||||||
|
'id': '34567',
|
||||||
|
'order': '123456',
|
||||||
|
'type': None,
|
||||||
|
'side': 'buy',
|
||||||
|
'price': 0.245441,
|
||||||
|
'cost': 1.963528,
|
||||||
|
'amount': 4.0,
|
||||||
|
'fee': {'cost': 0.004, 'currency': 'LTC'}}]
|
||||||
|
mocker.patch('freqtrade.exchange.get_trades_for_order', return_value=rv)
|
||||||
|
|
||||||
|
patch_get_signal(mocker)
|
||||||
|
patch_RPCManager(mocker)
|
||||||
|
patch_coinmarketcap(mocker)
|
||||||
|
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
|
||||||
|
trade = Trade(
|
||||||
|
pair='LTC/ETH',
|
||||||
|
amount=8,
|
||||||
|
exchange='binance',
|
||||||
|
open_order_id="123456"
|
||||||
|
)
|
||||||
|
freqtrade = FreqtradeBot(default_conf, create_engine('sqlite://'))
|
||||||
|
# Amount - cost
|
||||||
|
assert freqtrade.get_real_amount(trade) == 7.992
|
||||||
|
Loading…
Reference in New Issue
Block a user