Update order structure to ccxt generic structure instead of bittrex specific
This commit is contained in:
parent
4810d87044
commit
0ae5b75f33
@ -388,22 +388,22 @@ class FreqtradeBot(object):
|
|||||||
|
|
||||||
for trade in Trade.query.filter(Trade.open_order_id.isnot(None)).all():
|
for trade in Trade.query.filter(Trade.open_order_id.isnot(None)).all():
|
||||||
try:
|
try:
|
||||||
order = exchange.get_order(trade.open_order_id)
|
order = exchange.get_order(trade.open_order_id, trade.pair)
|
||||||
except requests.exceptions.RequestException:
|
except requests.exceptions.RequestException:
|
||||||
self.logger.info(
|
self.logger.info(
|
||||||
'Cannot query order for %s due to %s',
|
'Cannot query order for %s due to %s',
|
||||||
trade,
|
trade,
|
||||||
traceback.format_exc())
|
traceback.format_exc())
|
||||||
continue
|
continue
|
||||||
ordertime = arrow.get(order['opened'])
|
ordertime = arrow.get(order['datetime']).datetime
|
||||||
|
|
||||||
# Check if trade is still actually open
|
# Check if trade is still actually open
|
||||||
if int(order['remaining']) == 0:
|
if int(order['remaining']) == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if order['type'] == "LIMIT_BUY" and ordertime < timeoutthreashold:
|
if order['side'] == 'buy' and ordertime < timeoutthreashold:
|
||||||
self.handle_timedout_limit_buy(trade, order)
|
self.handle_timedout_limit_buy(trade, order)
|
||||||
elif order['type'] == "LIMIT_SELL" and ordertime < timeoutthreashold:
|
elif order['side'] == 'sell' and ordertime < timeoutthreashold:
|
||||||
self.handle_timedout_limit_sell(trade, order)
|
self.handle_timedout_limit_sell(trade, order)
|
||||||
|
|
||||||
# FIX: 20180110, why is cancel.order unconditionally here, whereas
|
# FIX: 20180110, why is cancel.order unconditionally here, whereas
|
||||||
@ -465,7 +465,7 @@ class FreqtradeBot(object):
|
|||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
# Execute sell and update trade record
|
# Execute sell and update trade record
|
||||||
order_id = exchange.sell(str(trade.pair), limit, trade.amount)
|
order_id = exchange.sell(str(trade.pair), limit, trade.amount)['id']
|
||||||
trade.open_order_id = order_id
|
trade.open_order_id = order_id
|
||||||
|
|
||||||
fmt_exp_profit = round(trade.calc_profit_percent(rate=limit) * 100, 2)
|
fmt_exp_profit = round(trade.calc_profit_percent(rate=limit) * 100, 2)
|
||||||
|
@ -111,20 +111,20 @@ class Trade(_DECL_BASE):
|
|||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
# Ignore open and cancelled orders
|
# Ignore open and cancelled orders
|
||||||
if not order['closed'] or order['rate'] is None:
|
if order['status'] == 'open' or order['price'] is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
logger.info('Updating trade (id=%d) ...', self.id)
|
logger.info('Updating trade (id=%d) ...', self.id)
|
||||||
|
|
||||||
getcontext().prec = 8 # Bittrex do not go above 8 decimal
|
getcontext().prec = 8 # Bittrex do not go above 8 decimal
|
||||||
if order['type'] == 'LIMIT_BUY':
|
if order['type'] == 'limit' and order['side'] == 'buy':
|
||||||
# Update open rate and actual amount
|
# Update open rate and actual amount
|
||||||
self.open_rate = Decimal(order['rate'])
|
self.open_rate = Decimal(order['price'])
|
||||||
self.amount = Decimal(order['amount'])
|
self.amount = Decimal(order['amount'])
|
||||||
logger.info('LIMIT_BUY has been fulfilled for %s.', self)
|
logger.info('LIMIT_BUY has been fulfilled for %s.', self)
|
||||||
self.open_order_id = None
|
self.open_order_id = None
|
||||||
elif order['type'] == 'LIMIT_SELL':
|
elif order['type'] == 'limit' and order['side'] == 'sell':
|
||||||
self.close(order['rate'])
|
self.close(order['price'])
|
||||||
else:
|
else:
|
||||||
raise ValueError('Unknown order type: {}'.format(order['type']))
|
raise ValueError('Unknown order type: {}'.format(order['type']))
|
||||||
cleanup()
|
cleanup()
|
||||||
|
@ -50,7 +50,7 @@ class RPC(object):
|
|||||||
for trade in trades:
|
for trade in trades:
|
||||||
order = None
|
order = None
|
||||||
if trade.open_order_id:
|
if trade.open_order_id:
|
||||||
order = exchange.get_order(trade.open_order_id)
|
order = exchange.get_order(trade.open_order_id, trade.pair)
|
||||||
# calculate profit and send message to user
|
# calculate profit and send message to user
|
||||||
current_rate = exchange.get_ticker(trade.pair, False)['bid']
|
current_rate = exchange.get_ticker(trade.pair, False)['bid']
|
||||||
current_profit = trade.calc_profit_percent(current_rate)
|
current_profit = trade.calc_profit_percent(current_rate)
|
||||||
@ -78,8 +78,8 @@ class RPC(object):
|
|||||||
amount=round(trade.amount, 8),
|
amount=round(trade.amount, 8),
|
||||||
close_profit=fmt_close_profit,
|
close_profit=fmt_close_profit,
|
||||||
current_profit=round(current_profit * 100, 2),
|
current_profit=round(current_profit * 100, 2),
|
||||||
open_order='({} rem={:.8f})'.format(
|
open_order='({} {} rem={:.8f})'.format(
|
||||||
order['type'], order['remaining']
|
order['type'], order['side'], order['remaining']
|
||||||
) if order else None,
|
) if order else None,
|
||||||
)
|
)
|
||||||
result.append(message)
|
result.append(message)
|
||||||
@ -311,17 +311,21 @@ class RPC(object):
|
|||||||
def _exec_forcesell(trade: Trade) -> None:
|
def _exec_forcesell(trade: Trade) -> None:
|
||||||
# Check if there is there is an open order
|
# Check if there is there is an open order
|
||||||
if trade.open_order_id:
|
if trade.open_order_id:
|
||||||
order = exchange.get_order(trade.open_order_id)
|
order = exchange.get_order(trade.open_order_id, trade.pair)
|
||||||
|
|
||||||
# Cancel open LIMIT_BUY orders and close trade
|
# Cancel open LIMIT_BUY orders and close trade
|
||||||
if order and not order['closed'] and order['type'] == 'LIMIT_BUY':
|
if order and order['status'] == 'open' \
|
||||||
exchange.cancel_order(trade.open_order_id)
|
and order['type'] == 'limit' \
|
||||||
trade.close(order.get('rate') or trade.open_rate)
|
and order['side'] == 'buy':
|
||||||
|
exchange.cancel_order(trade.open_order_id, trade.pair)
|
||||||
|
trade.close(order.get('price') or trade.open_rate)
|
||||||
# TODO: sell amount which has been bought already
|
# TODO: sell amount which has been bought already
|
||||||
return
|
return
|
||||||
|
|
||||||
# Ignore trades with an attached LIMIT_SELL order
|
# Ignore trades with an attached LIMIT_SELL order
|
||||||
if order and not order['closed'] and order['type'] == 'LIMIT_SELL':
|
if order and order['status'] == 'open' \
|
||||||
|
and order['type'] == 'limit' \
|
||||||
|
and order['side'] == 'sell':
|
||||||
return
|
return
|
||||||
|
|
||||||
# Get current rate and execute sell
|
# Get current rate and execute sell
|
||||||
|
@ -67,7 +67,7 @@ def test_rpc_trade_status(default_conf, ticker, mocker) -> None:
|
|||||||
'*Current Rate:* `0.00001098`\n'
|
'*Current Rate:* `0.00001098`\n'
|
||||||
'*Close Profit:* `None`\n'
|
'*Close Profit:* `None`\n'
|
||||||
'*Current Profit:* `-0.59%`\n'
|
'*Current Profit:* `-0.59%`\n'
|
||||||
'*Open Order:* `(LIMIT_BUY rem=0.00000000)`'
|
'*Open Order:* `(limit buy rem=0.00000000)`'
|
||||||
]
|
]
|
||||||
assert result == result_message
|
assert result == result_message
|
||||||
assert trade.find('[ETH/BTC]') >= 0
|
assert trade.find('[ETH/BTC]') >= 0
|
||||||
@ -401,8 +401,9 @@ def test_rpc_forcesell(default_conf, ticker, mocker) -> None:
|
|||||||
cancel_order=cancel_order_mock,
|
cancel_order=cancel_order_mock,
|
||||||
get_order=MagicMock(
|
get_order=MagicMock(
|
||||||
return_value={
|
return_value={
|
||||||
'closed': True,
|
'status': 'closed',
|
||||||
'type': 'LIMIT_BUY',
|
'type': 'limit',
|
||||||
|
'side': 'buy'
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -448,8 +449,9 @@ def test_rpc_forcesell(default_conf, ticker, mocker) -> None:
|
|||||||
mocker.patch(
|
mocker.patch(
|
||||||
'freqtrade.freqtradebot.exchange.get_order',
|
'freqtrade.freqtradebot.exchange.get_order',
|
||||||
return_value={
|
return_value={
|
||||||
'closed': None,
|
'status': 'open',
|
||||||
'type': 'LIMIT_BUY'
|
'type': 'limit',
|
||||||
|
'side': 'buy'
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
# check that the trade is called, which is done
|
# check that the trade is called, which is done
|
||||||
@ -464,8 +466,9 @@ def test_rpc_forcesell(default_conf, ticker, mocker) -> None:
|
|||||||
mocker.patch(
|
mocker.patch(
|
||||||
'freqtrade.freqtradebot.exchange.get_order',
|
'freqtrade.freqtradebot.exchange.get_order',
|
||||||
return_value={
|
return_value={
|
||||||
'closed': None,
|
'status': 'open',
|
||||||
'type': 'LIMIT_SELL'
|
'type': 'limit',
|
||||||
|
'side': 'sell'
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
(error, res) = rpc.rpc_forcesell('2')
|
(error, res) = rpc.rpc_forcesell('2')
|
||||||
|
@ -191,7 +191,7 @@ def test_update_open_order(limit_buy_order):
|
|||||||
assert trade.close_profit is None
|
assert trade.close_profit is None
|
||||||
assert trade.close_date is None
|
assert trade.close_date is None
|
||||||
|
|
||||||
limit_buy_order['closed'] = False
|
limit_buy_order['status'] = 'open'
|
||||||
trade.update(limit_buy_order)
|
trade.update(limit_buy_order)
|
||||||
|
|
||||||
assert trade.open_order_id is None
|
assert trade.open_order_id is None
|
||||||
|
Loading…
Reference in New Issue
Block a user