dry_run: keep list of open orders

This commit is contained in:
gcarq 2017-11-05 15:21:16 +01:00
parent 264d71e29e
commit 325f72fd91
3 changed files with 42 additions and 54 deletions

View File

@ -1,5 +1,6 @@
import enum import enum
import logging import logging
from random import randint
from typing import List, Dict from typing import List, Dict
import arrow import arrow
@ -13,6 +14,9 @@ logger = logging.getLogger(__name__)
_API: Exchange = None _API: Exchange = None
_CONF: dict = {} _CONF: dict = {}
# Holds all open sell orders for dry_run
_DRY_RUN_OPEN_ORDERS: Dict[str, Dict] = {}
class Exchanges(enum.Enum): class Exchanges(enum.Enum):
""" """
@ -66,14 +70,36 @@ def validate_pairs(pairs: List[str]) -> None:
def buy(pair: str, rate: float, amount: float) -> str: def buy(pair: str, rate: float, amount: float) -> str:
if _CONF['dry_run']: if _CONF['dry_run']:
return 'dry_run_buy' global _DRY_RUN_OPEN_ORDERS
order_id = 'dry_run_buy_{}'.format(randint(0, 1e6))
_DRY_RUN_OPEN_ORDERS[order_id] = {
'pair': pair,
'rate': rate,
'amount': amount,
'type': 'LIMIT_BUY',
'remaining': 0.0,
'opened': arrow.utcnow().datetime,
'closed': arrow.utcnow().datetime,
}
return order_id
return _API.buy(pair, rate, amount) return _API.buy(pair, rate, amount)
def sell(pair: str, rate: float, amount: float) -> str: def sell(pair: str, rate: float, amount: float) -> str:
if _CONF['dry_run']: if _CONF['dry_run']:
return 'dry_run_sell' global _DRY_RUN_OPEN_ORDERS
order_id = 'dry_run_sell_{}'.format(randint(0, 1e6))
_DRY_RUN_OPEN_ORDERS[order_id] = {
'pair': pair,
'rate': rate,
'amount': amount,
'type': 'LIMIT_SELL',
'remaining': 0.0,
'opened': arrow.utcnow().datetime,
'closed': arrow.utcnow().datetime,
}
return order_id
return _API.sell(pair, rate, amount) return _API.sell(pair, rate, amount)
@ -109,16 +135,11 @@ def cancel_order(order_id: str) -> None:
def get_order(order_id: str) -> Dict: def get_order(order_id: str) -> Dict:
if _CONF['dry_run']: if _CONF['dry_run']:
return { order = _DRY_RUN_OPEN_ORDERS.pop(order_id)
'id': 'dry_run_sell', order.update({
'type': 'LIMIT_SELL', 'id': order_id
'pair': 'mocked', })
'opened': arrow.utcnow().datetime, return order
'rate': 0.07256060,
'amount': 206.43811673387373,
'remaining': 0.0,
'closed': arrow.utcnow().datetime,
}
return _API.get_order(order_id) return _API.get_order(order_id)

View File

@ -201,12 +201,11 @@ def create_trade(stake_amount: float) -> Optional[Trade]:
return Trade(pair=pair, return Trade(pair=pair,
stake_amount=stake_amount, stake_amount=stake_amount,
amount=amount, amount=amount,
fee=fee * 2, fee=fee*2,
open_rate=buy_limit, open_rate=buy_limit,
open_date=datetime.utcnow(), open_date=datetime.utcnow(),
exchange=exchange.get_name().upper(), exchange=exchange.get_name().upper(),
open_order_id=order_id, open_order_id=order_id)
is_open=True)
def init(config: dict, db_url: Optional[str] = None) -> None: def init(config: dict, db_url: Optional[str] = None) -> None:

View File

@ -6,6 +6,7 @@ import pytest
from jsonschema import validate from jsonschema import validate
from telegram import Bot, Update, Message, Chat from telegram import Bot, Update, Message, Chat
from freqtrade import exchange
from freqtrade.main import init, create_trade from freqtrade.main import init, create_trade
from freqtrade.misc import update_state, State, get_state, CONF_SCHEMA from freqtrade.misc import update_state, State, get_state, CONF_SCHEMA
from freqtrade.persistence import Trade from freqtrade.persistence import Trade
@ -74,8 +75,7 @@ def test_status_handle(conf, update, mocker):
'bid': 0.07256061, 'bid': 0.07256061,
'ask': 0.072661, 'ask': 0.072661,
'last': 0.07256061 'last': 0.07256061
}), }))
buy=MagicMock(return_value='mocked_order_id'))
init(conf, 'sqlite://') init(conf, 'sqlite://')
# Create some test data # Create some test data
@ -84,26 +84,10 @@ def test_status_handle(conf, update, mocker):
Trade.session.add(trade) Trade.session.add(trade)
Trade.session.flush() Trade.session.flush()
# Trigger status while we don't know the open_rate yet
_status(bot=MagicBot(), update=update)
# Simulate fulfilled LIMIT_BUY order for trade
trade.update({
'id': 'mocked_limit_buy',
'type': 'LIMIT_BUY',
'pair': 'mocked',
'opened': datetime.utcnow(),
'rate': 0.07256060,
'amount': 206.43811673387373,
'remaining': 0.0,
'closed': datetime.utcnow(),
})
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=MagicBot(), update=update) _status(bot=MagicBot(), update=update)
assert msg_mock.call_count == 3 assert msg_mock.call_count == 2
assert '[BTC_ETH]' in msg_mock.call_args_list[-1][0][0] assert '[BTC_ETH]' in msg_mock.call_args_list[-1][0][0]
@ -121,8 +105,7 @@ def test_profit_handle(conf, update, mocker):
'bid': 0.07256061, 'bid': 0.07256061,
'ask': 0.072661, 'ask': 0.072661,
'last': 0.07256061 'last': 0.07256061
}), }))
buy=MagicMock(return_value='mocked_limit_buy'))
init(conf, 'sqlite://') init(conf, 'sqlite://')
# Create some test data # Create some test data
@ -153,7 +136,6 @@ def test_profit_handle(conf, update, mocker):
}) })
trade.close_date = datetime.utcnow() trade.close_date = datetime.utcnow()
trade.open_order_id = None
trade.is_open = False trade.is_open = False
Trade.session.add(trade) Trade.session.add(trade)
Trade.session.flush() Trade.session.flush()
@ -178,26 +160,13 @@ def test_forcesell_handle(conf, update, mocker):
'bid': 0.07256061, 'bid': 0.07256061,
'ask': 0.072661, 'ask': 0.072661,
'last': 0.07256061 'last': 0.07256061
}), }))
buy=MagicMock(return_value='mocked_order_id'))
init(conf, 'sqlite://') init(conf, 'sqlite://')
# Create some test data # Create some test data
trade = create_trade(15.0) trade = create_trade(15.0)
assert trade assert trade
# Simulate fulfilled LIMIT_BUY order for trade
trade.update({
'id': 'mocked_limit_buy',
'type': 'LIMIT_BUY',
'pair': 'mocked',
'opened': datetime.utcnow(),
'rate': 0.07256060,
'amount': 206.43811673387373,
'remaining': 0.0,
'closed': datetime.utcnow(),
})
Trade.session.add(trade) Trade.session.add(trade)
Trade.session.flush() Trade.session.flush()
@ -206,7 +175,7 @@ def test_forcesell_handle(conf, update, mocker):
assert msg_mock.call_count == 2 assert msg_mock.call_count == 2
assert 'Selling [BTC/ETH]' in msg_mock.call_args_list[-1][0][0] assert 'Selling [BTC/ETH]' in msg_mock.call_args_list[-1][0][0]
assert '0.072561 (profit: ~-0.5%)' in msg_mock.call_args_list[-1][0][0] assert '0.072561 (profit: ~-0.64%)' in msg_mock.call_args_list[-1][0][0]
def test_performance_handle(conf, update, mocker): def test_performance_handle(conf, update, mocker):
@ -223,8 +192,7 @@ def test_performance_handle(conf, update, mocker):
'bid': 0.07256061, 'bid': 0.07256061,
'ask': 0.072661, 'ask': 0.072661,
'last': 0.07256061 'last': 0.07256061
}), }))
buy=MagicMock(return_value='mocked_order_id'))
init(conf, 'sqlite://') init(conf, 'sqlite://')
# Create some test data # Create some test data