modify trade life cycle (should fix #112)

This commit is contained in:
gcarq 2017-11-17 20:17:29 +01:00
parent 59d04d1d0c
commit 63c95a3546
3 changed files with 14 additions and 34 deletions

View File

@ -88,7 +88,7 @@ def _process(dynamic_whitelist: Optional[bool] = False) -> bool:
logger.info('Got open order for %s', trade)
trade.update(exchange.get_order(trade.open_order_id))
if not close_trade_if_fulfilled(trade):
if trade.is_open and trade.open_order_id is None:
# Check if we can sell our current pair
state_changed = handle_trade(trade) or state_changed
@ -109,27 +109,6 @@ def _process(dynamic_whitelist: Optional[bool] = False) -> bool:
return state_changed
def close_trade_if_fulfilled(trade: Trade) -> bool:
"""
Checks if the trade is closable, and if so it is being closed.
:param trade: Trade
:return: True if trade has been closed else False
"""
# If we don't have an open order and the close rate is already set,
# we can close this trade.
if trade.close_profit is not None \
and trade.close_date is not None \
and trade.close_rate is not None \
and trade.open_order_id is None:
trade.is_open = False
logger.info(
'Marking %s as closed as the trade is fulfilled and found no open orders for it.',
trade
)
return True
return False
def execute_sell(trade: Trade, limit: float) -> None:
"""
Executes a limit sell for the given trade and limit

View File

@ -85,20 +85,27 @@ class Trade(_DECL_BASE):
if not order['closed']:
return
logger.debug('Updating trade (id=%d) ...', self.id)
logger.info('Updating trade (id=%d) ...', self.id)
if order['type'] == 'LIMIT_BUY':
# Update open rate and actual amount
self.open_rate = order['rate']
self.amount = order['amount']
logger.info('LIMIT_BUY has been fulfilled for %s.', self)
elif order['type'] == 'LIMIT_SELL':
# Set close rate and set actual profit
self.close_rate = order['rate']
self.close_profit = self.calc_profit()
self.close_date = datetime.utcnow()
self.is_open = False
logger.info(
'Marking %s as closed as the trade is fulfilled and found no open orders for it.',
self
)
else:
raise ValueError('Unknown order type: {}'.format(order['type']))
self.open_order_id = None
Trade.session.flush()
def calc_profit(self, rate: Optional[float] = None) -> float:
"""

View File

@ -8,7 +8,7 @@ from sqlalchemy import create_engine
from freqtrade.exchange import Exchanges
from freqtrade.analyze import SignalType
from freqtrade.main import create_trade, handle_trade, close_trade_if_fulfilled, init, \
from freqtrade.main import create_trade, handle_trade, init, \
get_target_bid, _process
from freqtrade.misc import get_state, State, FreqtradeException
from freqtrade.persistence import Trade
@ -183,7 +183,6 @@ def test_handle_trade(default_conf, limit_buy_order, limit_sell_order, mocker):
handle_trade(trade)
assert trade.open_order_id == 'mocked_limit_sell'
assert close_trade_if_fulfilled(trade) is False
# Simulate fulfilled LIMIT_SELL order for trade
trade.update(limit_sell_order)
@ -205,20 +204,15 @@ def test_close_trade(default_conf, ticker, limit_buy_order, limit_sell_order, mo
# Create trade and sell it
init(default_conf, create_engine('sqlite://'))
trade = create_trade(15.0)
trade.update(limit_buy_order)
trade.update(limit_sell_order)
Trade.session.add(trade)
Trade.session.flush()
trade.update(limit_buy_order)
trade = Trade.query.filter(Trade.is_open.is_(True)).first()
assert trade
# Simulate that there is no open order
trade.open_order_id = None
trade.update(limit_sell_order)
trade = Trade.query.filter(Trade.is_open.is_(False)).first()
assert trade
closed = close_trade_if_fulfilled(trade)
assert closed
assert not trade.is_open
with pytest.raises(ValueError, match=r'.*closed trade.*'):
handle_trade(trade)