Don't reset open orders in dry-run on restart
This commit is contained in:
parent
d5486f17d8
commit
0a95ef6ab2
@ -953,6 +953,12 @@ class Exchange:
|
|||||||
order = self.check_dry_limit_order_filled(order)
|
order = self.check_dry_limit_order_filled(order)
|
||||||
return order
|
return order
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
|
from freqtrade.persistence import Order
|
||||||
|
order = Order.order_by_id(order_id)
|
||||||
|
if order:
|
||||||
|
x = order.to_ccxt_object()
|
||||||
|
self._dry_run_open_orders[order_id] = x
|
||||||
|
return x
|
||||||
# Gracefully handle errors with dry-run orders.
|
# Gracefully handle errors with dry-run orders.
|
||||||
raise InvalidOrderException(
|
raise InvalidOrderException(
|
||||||
f'Tried to get an invalid dry-run-order (id: {order_id}). Message: {e}') from e
|
f'Tried to get an invalid dry-run-order (id: {order_id}). Message: {e}') from e
|
||||||
|
@ -64,10 +64,6 @@ def init_db(db_url: str, clean_open_orders: bool = False) -> None:
|
|||||||
_DECL_BASE.metadata.create_all(engine)
|
_DECL_BASE.metadata.create_all(engine)
|
||||||
check_migrate(engine, decl_base=_DECL_BASE, previous_tables=previous_tables)
|
check_migrate(engine, decl_base=_DECL_BASE, previous_tables=previous_tables)
|
||||||
|
|
||||||
# Clean dry_run DB if the db is not in-memory
|
|
||||||
if clean_open_orders and db_url != 'sqlite://':
|
|
||||||
clean_dry_run_db()
|
|
||||||
|
|
||||||
|
|
||||||
def cleanup_db() -> None:
|
def cleanup_db() -> None:
|
||||||
"""
|
"""
|
||||||
@ -76,14 +72,3 @@ def cleanup_db() -> None:
|
|||||||
"""
|
"""
|
||||||
Trade.commit()
|
Trade.commit()
|
||||||
|
|
||||||
|
|
||||||
def clean_dry_run_db() -> None:
|
|
||||||
"""
|
|
||||||
Remove open_order_id from a Dry_run DB
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
for trade in Trade.query.filter(Trade.open_order_id.isnot(None)).all():
|
|
||||||
# Check we are updating only a dry_run order not a prod one
|
|
||||||
if 'dry_run' in trade.open_order_id:
|
|
||||||
trade.open_order_id = None
|
|
||||||
Trade.commit()
|
|
||||||
|
@ -118,6 +118,25 @@ class Order(_DECL_BASE):
|
|||||||
self.order_filled_date = datetime.now(timezone.utc)
|
self.order_filled_date = datetime.now(timezone.utc)
|
||||||
self.order_update_date = datetime.now(timezone.utc)
|
self.order_update_date = datetime.now(timezone.utc)
|
||||||
|
|
||||||
|
def to_ccxt_object(self) -> Dict[str, Any]:
|
||||||
|
return {
|
||||||
|
'id': self.order_id,
|
||||||
|
'symbol': self.ft_pair,
|
||||||
|
'price': self.price,
|
||||||
|
'average': self.average,
|
||||||
|
'amount': self.amount,
|
||||||
|
'cost': self.cost,
|
||||||
|
'type': self.order_type,
|
||||||
|
'side': self.ft_order_side,
|
||||||
|
'filled': self.filled,
|
||||||
|
'remaining': self.remaining,
|
||||||
|
'datetime': self.order_date_utc.strftime('%Y-%m-%dT%H:%M:%S.%3f'),
|
||||||
|
'timestamp': int(self.order_date_utc.timestamp() * 1000),
|
||||||
|
'status': self.status,
|
||||||
|
'fee': None,
|
||||||
|
'info': {},
|
||||||
|
}
|
||||||
|
|
||||||
def to_json(self, entry_side: str) -> Dict[str, Any]:
|
def to_json(self, entry_side: str) -> Dict[str, Any]:
|
||||||
return {
|
return {
|
||||||
'pair': self.ft_pair,
|
'pair': self.ft_pair,
|
||||||
@ -190,6 +209,14 @@ class Order(_DECL_BASE):
|
|||||||
"""
|
"""
|
||||||
return Order.query.filter(Order.ft_is_open.is_(True)).all()
|
return Order.query.filter(Order.ft_is_open.is_(True)).all()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def order_by_id(order_id: str) -> Optional['Order']:
|
||||||
|
"""
|
||||||
|
Retrieve order based on order_id
|
||||||
|
:return: Order or None
|
||||||
|
"""
|
||||||
|
return Order.query.filter(Order.order_id == order_id).first()
|
||||||
|
|
||||||
|
|
||||||
class LocalTrade():
|
class LocalTrade():
|
||||||
"""
|
"""
|
||||||
|
@ -1129,56 +1129,6 @@ def test_calc_profit(
|
|||||||
assert pytest.approx(trade.calc_profit_ratio(rate=close_rate)) == round(profit_ratio, 8)
|
assert pytest.approx(trade.calc_profit_ratio(rate=close_rate)) == round(profit_ratio, 8)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("init_persistence")
|
|
||||||
def test_clean_dry_run_db(default_conf, fee):
|
|
||||||
|
|
||||||
# Simulate dry_run entries
|
|
||||||
trade = Trade(
|
|
||||||
pair='ADA/USDT',
|
|
||||||
stake_amount=0.001,
|
|
||||||
amount=123.0,
|
|
||||||
fee_open=fee.return_value,
|
|
||||||
fee_close=fee.return_value,
|
|
||||||
open_rate=0.123,
|
|
||||||
exchange='binance',
|
|
||||||
open_order_id='dry_run_buy_12345'
|
|
||||||
)
|
|
||||||
Trade.query.session.add(trade)
|
|
||||||
|
|
||||||
trade = Trade(
|
|
||||||
pair='ETC/BTC',
|
|
||||||
stake_amount=0.001,
|
|
||||||
amount=123.0,
|
|
||||||
fee_open=fee.return_value,
|
|
||||||
fee_close=fee.return_value,
|
|
||||||
open_rate=0.123,
|
|
||||||
exchange='binance',
|
|
||||||
open_order_id='dry_run_sell_12345'
|
|
||||||
)
|
|
||||||
Trade.query.session.add(trade)
|
|
||||||
|
|
||||||
# Simulate prod entry
|
|
||||||
trade = Trade(
|
|
||||||
pair='ETC/BTC',
|
|
||||||
stake_amount=0.001,
|
|
||||||
amount=123.0,
|
|
||||||
fee_open=fee.return_value,
|
|
||||||
fee_close=fee.return_value,
|
|
||||||
open_rate=0.123,
|
|
||||||
exchange='binance',
|
|
||||||
open_order_id='prod_buy_12345'
|
|
||||||
)
|
|
||||||
Trade.query.session.add(trade)
|
|
||||||
|
|
||||||
# We have 3 entries: 2 dry_run, 1 prod
|
|
||||||
assert len(Trade.query.filter(Trade.open_order_id.isnot(None)).all()) == 3
|
|
||||||
|
|
||||||
clean_dry_run_db()
|
|
||||||
|
|
||||||
# We have now only the prod
|
|
||||||
assert len(Trade.query.filter(Trade.open_order_id.isnot(None)).all()) == 1
|
|
||||||
|
|
||||||
|
|
||||||
def test_migrate_new(mocker, default_conf, fee, caplog):
|
def test_migrate_new(mocker, default_conf, fee, caplog):
|
||||||
"""
|
"""
|
||||||
Test Database migration (starting with new pairformat)
|
Test Database migration (starting with new pairformat)
|
||||||
|
Loading…
Reference in New Issue
Block a user