force flush in create_trade and execute_sell (fixes #128)

This commit is contained in:
gcarq 2017-11-22 20:51:25 +01:00
parent 765a762ccf
commit 9136e64d89
3 changed files with 44 additions and 54 deletions

View File

@ -67,11 +67,8 @@ def _process(dynamic_whitelist: Optional[bool] = False) -> bool:
if len(trades) < _CONF['max_open_trades']: if len(trades) < _CONF['max_open_trades']:
try: try:
# Create entity and execute trade # Create entity and execute trade
trade = create_trade(float(_CONF['stake_amount'])) state_changed = create_trade(float(_CONF['stake_amount']))
if trade: if not state_changed:
Trade.session.add(trade)
state_changed = True
else:
logger.info( logger.info(
'Checked all whitelisted currencies. ' 'Checked all whitelisted currencies. '
'Found no suitable entry positions for buying. Will keep looking ...' 'Found no suitable entry positions for buying. Will keep looking ...'
@ -126,6 +123,7 @@ def execute_sell(trade: Trade, limit: float) -> None:
limit, limit,
fmt_exp_profit fmt_exp_profit
)) ))
Trade.session.flush()
def min_roi_reached(trade: Trade, current_rate: float, current_time: datetime) -> bool: def min_roi_reached(trade: Trade, current_rate: float, current_time: datetime) -> bool:
@ -172,11 +170,12 @@ def get_target_bid(ticker: Dict[str, float]) -> float:
return ticker['ask'] + balance * (ticker['last'] - ticker['ask']) return ticker['ask'] + balance * (ticker['last'] - ticker['ask'])
def create_trade(stake_amount: float) -> Optional[Trade]: def create_trade(stake_amount: float) -> bool:
""" """
Checks the implemented trading indicator(s) for a randomly picked pair, Checks the implemented trading indicator(s) for a randomly picked pair,
if one pair triggers the buy_signal a new trade record gets created if one pair triggers the buy_signal a new trade record gets created
:param stake_amount: amount of btc to spend :param stake_amount: amount of btc to spend
:return: True if a trade object has been created and persisted, False otherwise
""" """
logger.info( logger.info(
'Checking buy signals to create a new trade with stake_amount: %f ...', 'Checking buy signals to create a new trade with stake_amount: %f ...',
@ -203,7 +202,7 @@ def create_trade(stake_amount: float) -> Optional[Trade]:
pair = _pair pair = _pair
break break
else: else:
return None return False
# Calculate amount and subtract fee # Calculate amount and subtract fee
fee = exchange.get_fee() fee = exchange.get_fee()
@ -219,14 +218,19 @@ def create_trade(stake_amount: float) -> Optional[Trade]:
buy_limit buy_limit
)) ))
# Fee is applied twice because we make a LIMIT_BUY and LIMIT_SELL # Fee is applied twice because we make a LIMIT_BUY and LIMIT_SELL
return Trade(pair=pair, trade = Trade(
stake_amount=stake_amount, pair=pair,
amount=amount, stake_amount=stake_amount,
fee=fee * 2, amount=amount,
open_rate=buy_limit, fee=fee * 2,
open_date=datetime.utcnow(), open_rate=buy_limit,
exchange=exchange.get_name().upper(), open_date=datetime.utcnow(),
open_order_id=order_id) exchange=exchange.get_name().upper(),
open_order_id=order_id
)
Trade.session.add(trade)
Trade.session.flush()
return True
def init(config: dict, db_url: Optional[str] = None) -> None: def init(config: dict, db_url: Optional[str] = None) -> None:

View File

@ -115,9 +115,9 @@ def test_create_trade(default_conf, ticker, limit_buy_order, mocker):
whitelist = copy.deepcopy(default_conf['exchange']['pair_whitelist']) whitelist = copy.deepcopy(default_conf['exchange']['pair_whitelist'])
init(default_conf, create_engine('sqlite://')) init(default_conf, create_engine('sqlite://'))
trade = create_trade(15.0) create_trade(15.0)
Trade.session.add(trade)
Trade.session.flush() trade = Trade.query.first()
assert trade is not None assert trade is not None
assert trade.stake_amount == 15.0 assert trade.stake_amount == 15.0
assert trade.is_open assert trade.is_open
@ -176,13 +176,14 @@ def test_handle_trade(default_conf, limit_buy_order, limit_sell_order, mocker):
buy=MagicMock(return_value='mocked_limit_buy'), buy=MagicMock(return_value='mocked_limit_buy'),
sell=MagicMock(return_value='mocked_limit_sell')) sell=MagicMock(return_value='mocked_limit_sell'))
init(default_conf, create_engine('sqlite://')) init(default_conf, create_engine('sqlite://'))
trade = create_trade(15.0) create_trade(15.0)
trade.update(limit_buy_order)
Trade.session.add(trade) trade = Trade.query.first()
Trade.session.flush()
trade = Trade.query.filter(Trade.is_open.is_(True)).first()
assert trade assert trade
trade.update(limit_buy_order)
assert trade.is_open is True
handle_trade(trade) handle_trade(trade)
assert trade.open_order_id == 'mocked_limit_sell' assert trade.open_order_id == 'mocked_limit_sell'
@ -205,15 +206,14 @@ def test_close_trade(default_conf, ticker, limit_buy_order, limit_sell_order, mo
# Create trade and sell it # Create trade and sell it
init(default_conf, create_engine('sqlite://')) init(default_conf, create_engine('sqlite://'))
trade = create_trade(15.0) create_trade(15.0)
Trade.session.add(trade)
trade.update(limit_buy_order) trade = Trade.query.first()
trade = Trade.query.filter(Trade.is_open.is_(True)).first()
assert trade assert trade
trade.update(limit_buy_order)
trade.update(limit_sell_order) trade.update(limit_sell_order)
trade = Trade.query.filter(Trade.is_open.is_(False)).first() assert trade.is_open is False
assert trade
with pytest.raises(ValueError, match=r'.*closed trade.*'): with pytest.raises(ValueError, match=r'.*closed trade.*'):
handle_trade(trade) handle_trade(trade)

View File

@ -101,11 +101,7 @@ def test_status_handle(default_conf, update, ticker, mocker):
msg_mock.reset_mock() msg_mock.reset_mock()
# Create some test data # Create some test data
trade = create_trade(15.0) create_trade(15.0)
assert trade
Trade.session.add(trade)
Trade.session.flush()
# Trigger status while we have a fulfilled order for the open trade # Trigger status while we have a fulfilled order for the open trade
_status(bot=MagicMock(), update=update) _status(bot=MagicMock(), update=update)
@ -141,10 +137,7 @@ def test_status_table_handle(default_conf, update, ticker, mocker):
msg_mock.reset_mock() msg_mock.reset_mock()
# Create some test data # Create some test data
trade = create_trade(15.0) create_trade(15.0)
assert trade
Trade.session.add(trade)
Trade.session.flush()
_status_table(bot=MagicMock(), update=update) _status_table(bot=MagicMock(), update=update)
@ -177,8 +170,8 @@ def test_profit_handle(default_conf, update, ticker, limit_buy_order, limit_sell
msg_mock.reset_mock() msg_mock.reset_mock()
# Create some test data # Create some test data
trade = create_trade(15.0) create_trade(15.0)
assert trade trade = Trade.query.first()
# Simulate fulfilled LIMIT_BUY order for trade # Simulate fulfilled LIMIT_BUY order for trade
trade.update(limit_buy_order) trade.update(limit_buy_order)
@ -193,8 +186,6 @@ def test_profit_handle(default_conf, update, ticker, limit_buy_order, limit_sell
trade.close_date = datetime.utcnow() trade.close_date = datetime.utcnow()
trade.is_open = False trade.is_open = False
Trade.session.add(trade)
Trade.session.flush()
_profit(bot=MagicMock(), update=update) _profit(bot=MagicMock(), update=update)
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
@ -216,11 +207,10 @@ def test_forcesell_handle(default_conf, update, ticker, mocker):
init(default_conf, create_engine('sqlite://')) init(default_conf, create_engine('sqlite://'))
# Create some test data # Create some test data
trade = create_trade(15.0) create_trade(15.0)
assert trade
Trade.session.add(trade) trade = Trade.query.first()
Trade.session.flush() assert trade
update.message.text = '/forcesell 1' update.message.text = '/forcesell 1'
_forcesell(bot=MagicMock(), update=update) _forcesell(bot=MagicMock(), update=update)
@ -245,8 +235,7 @@ def test_forcesell_all_handle(default_conf, update, ticker, mocker):
# Create some test data # Create some test data
for _ in range(4): for _ in range(4):
Trade.session.add(create_trade(15.0)) create_trade(15.0)
Trade.session.flush()
rpc_mock.reset_mock() rpc_mock.reset_mock()
update.message.text = '/forcesell all' update.message.text = '/forcesell all'
@ -309,7 +298,8 @@ def test_performance_handle(
init(default_conf, create_engine('sqlite://')) init(default_conf, create_engine('sqlite://'))
# Create some test data # Create some test data
trade = create_trade(15.0) create_trade(15.0)
trade = Trade.query.first()
assert trade assert trade
# Simulate fulfilled LIMIT_BUY order for trade # Simulate fulfilled LIMIT_BUY order for trade
@ -320,8 +310,6 @@ def test_performance_handle(
trade.close_date = datetime.utcnow() trade.close_date = datetime.utcnow()
trade.is_open = False trade.is_open = False
Trade.session.add(trade)
Trade.session.flush()
_performance(bot=MagicMock(), update=update) _performance(bot=MagicMock(), update=update)
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
@ -351,9 +339,7 @@ def test_count_handle(default_conf, update, ticker, mocker):
update_state(State.RUNNING) update_state(State.RUNNING)
# Create some test data # Create some test data
Trade.session.add(create_trade(15.0)) create_trade(15.0)
Trade.session.flush()
msg_mock.reset_mock() msg_mock.reset_mock()
_count(bot=MagicMock(), update=update) _count(bot=MagicMock(), update=update)