From 39beb5c8375c8abe0fbce95c13f2346e7fe16bee Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 22 Aug 2020 08:39:10 +0200 Subject: [PATCH] Add method to update fees on closed trades --- freqtrade/freqtradebot.py | 22 +++++++++++++++++++++- freqtrade/persistence/models.py | 24 +++++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index c4147e7e4..3783908a2 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -138,6 +138,8 @@ class FreqtradeBot: # This will update the database after the initial migration self.update_open_orders() + self.update_closed_trades_without_assigned_fees() + def process(self) -> None: """ Queries the persistence layer for open trades and handles them, @@ -148,6 +150,8 @@ class FreqtradeBot: # Check whether markets have to be reloaded and reload them when it's needed self.exchange.reload_markets() + self.update_closed_trades_without_assigned_fees() + # Query trades from persistence layer trades = Trade.get_open_trades() @@ -233,7 +237,8 @@ class FreqtradeBot: def update_open_orders(self): """ - Updates open orders based on order list kept in the database + Updates open orders based on order list kept in the database. + Mainly updates the state of orders - but may also close trades """ orders = Order.get_open_orders() logger.info(f"Updating {len(orders)} open orders.") @@ -249,6 +254,21 @@ class FreqtradeBot: except ExchangeError: logger.warning(f"Error updating {order.order_id}") + def update_closed_trades_without_assigned_fees(self): + """ + Update closed trades without close fees assigned. + Only works when Orders are in the database, otherwise the last orderid is unknown. + """ + trades: List[Trade] = Trade.get_sold_trades_without_assigned_fees() + for trade in trades: + + if not trade.is_open and not trade.fee_updated('sell'): + # Get sell fee + order = trade.select_order('sell', 'closed') + if order: + logger.info(f"Updating sell-fee on trade {trade} for order {order.order_id}.") + self.update_trade_state(trade, order.order_id) + def refind_lost_order(self, trade): """ Try refinding a lost trade. diff --git a/freqtrade/persistence/models.py b/freqtrade/persistence/models.py index 31f40f713..01d2286f9 100644 --- a/freqtrade/persistence/models.py +++ b/freqtrade/persistence/models.py @@ -8,7 +8,7 @@ from typing import Any, Dict, List, Optional import arrow from sqlalchemy import (Boolean, Column, DateTime, Float, ForeignKey, Integer, - String, create_engine, desc, func, inspect) + String, create_engine, desc, func, inspect, or_) from sqlalchemy.exc import NoSuchModuleError from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import Query, relationship @@ -508,6 +508,17 @@ class Trade(_DECL_BASE): profit_ratio = (close_trade_price / self.open_trade_price) - 1 return float(f"{profit_ratio:.8f}") + def select_order(self, order_side: str, status: str): + """ + Returns latest order for this orderside and status + Returns None if nothing is found + """ + orders = [o for o in self.orders if o.side == order_side and o.status == status] + if len(orders) > 0: + return orders[-1] + else: + return None + @staticmethod def get_trades(trade_filter=None) -> Query: """ @@ -539,6 +550,17 @@ class Trade(_DECL_BASE): """ return Trade.get_trades(Trade.open_order_id.isnot(None)).all() + @staticmethod + def get_sold_trades_without_assigned_fees(): + """ + Returns all closed trades which don't have fees set correctly + """ + return Trade.get_trades([Trade.fee_close_currency.is_(None), + Trade.id == 100, + Trade.orders.any(), + Trade.is_open.is_(False), + ]).all() + @staticmethod def total_open_trades_stakes() -> float: """