From e54e6a7295dfcc322daebbb27bf1d71c538ff387 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 19 Feb 2022 10:58:17 +0100 Subject: [PATCH] Update wallets to also keep Positions --- freqtrade/rpc/rpc.py | 37 +++++++++++++++++++++++++++++++++---- freqtrade/wallets.py | 28 ++++++++++++++++++++++------ 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 5ece392f2..1c0c32846 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -30,6 +30,7 @@ from freqtrade.persistence.models import PairLock from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist from freqtrade.rpc.fiat_convert import CryptoToFiatConverter from freqtrade.strategy.interface import SellCheckTuple +from freqtrade.wallets import PositionWallet, Wallet logger = logging.getLogger(__name__) @@ -566,7 +567,8 @@ class RPC: def _rpc_balance(self, stake_currency: str, fiat_display_currency: str) -> Dict: """ Returns current account balance per crypto """ - output = [] + currencies = [] + positions = [] total = 0.0 try: tickers = self._freqtrade.exchange.get_tickers(cached=True) @@ -577,7 +579,8 @@ class RPC: starting_capital = self._freqtrade.wallets.get_starting_balance() starting_cap_fiat = self._fiat_converter.convert_amount( starting_capital, stake_currency, fiat_display_currency) if self._fiat_converter else 0 - + coin: str + balance: Wallet for coin, balance in self._freqtrade.wallets.get_all_balances().items(): if not balance.total: continue @@ -598,14 +601,39 @@ class RPC: logger.warning(f" Could not get rate for pair {coin}.") continue total = total + (est_stake or 0) - output.append({ + currencies.append({ 'currency': coin, + # TODO: The below can be simplified if we don't assign None to values. 'free': balance.free if balance.free is not None else 0, 'balance': balance.total if balance.total is not None else 0, 'used': balance.used if balance.used is not None else 0, 'est_stake': est_stake or 0, 'stake': stake_currency, }) + symbol: str + position: PositionWallet + for symbol, position in self._freqtrade.wallets.get_all_positions().items(): + + currencies.append({ + 'currency': symbol, + 'free': 0, + 'balance': position.position, + 'used': 0, + 'est_stake': position.collateral, + 'stake': stake_currency, + }) + + positions.append({ + 'currency': symbol, + # 'free': balance.free if balance.free is not None else 0, + # 'balance': balance.total if balance.total is not None else 0, + # 'used': balance.used if balance.used is not None else 0, + 'position': position.position, + 'side': position.side, + 'est_stake': position.collateral, + 'leverage': position.leverage, + 'stake': stake_currency, + }) value = self._fiat_converter.convert_amount( total, stake_currency, fiat_display_currency) if self._fiat_converter else 0 @@ -616,7 +644,8 @@ class RPC: starting_cap_fiat_ratio = (value / starting_cap_fiat) - 1 if starting_cap_fiat else 0.0 return { - 'currencies': output, + 'currencies': currencies, + 'positions': positions, 'total': total, 'symbol': fiat_display_currency, 'value': value, diff --git a/freqtrade/wallets.py b/freqtrade/wallets.py index 2124e004e..f7ee95b0e 100644 --- a/freqtrade/wallets.py +++ b/freqtrade/wallets.py @@ -3,7 +3,7 @@ import logging from copy import deepcopy -from typing import Any, Dict, NamedTuple, Optional +from typing import Dict, NamedTuple, Optional import arrow @@ -26,6 +26,14 @@ class Wallet(NamedTuple): position: float = 0 +class PositionWallet(NamedTuple): + symbol: str + position: float = 0 + leverage: float = 0 + collateral: float = 0 + side: str = 'long' + + class Wallets: def __init__(self, config: dict, exchange: Exchange, log: bool = True) -> None: @@ -33,6 +41,7 @@ class Wallets: self._log = log self._exchange = exchange self._wallets: Dict[str, Wallet] = {} + self._positions: Dict[str, PositionWallet] = {} self.start_cap = config['dry_run_wallet'] self._last_wallet_refresh = 0 self.update() @@ -113,13 +122,17 @@ class Wallets: positions = self._exchange.get_positions() for position in positions: symbol = position['symbol'] - if position['side'] is None: + if position['side'] is None or position['collateral'] == 0.0: # Position is not open ... continue size = self._exchange._contracts_to_amount(symbol, position['contracts']) - - self._wallets[symbol] = Wallet( - symbol, position=size + collateral = position['collateral'] + leverage = position['leverage'] + self._positions[symbol] = PositionWallet( + symbol, position=size, + leverage=leverage, + collateral=collateral, + side=position['side'] ) def update(self, require_update: bool = True) -> None: @@ -139,9 +152,12 @@ class Wallets: logger.info('Wallets synced.') self._last_wallet_refresh = arrow.utcnow().int_timestamp - def get_all_balances(self) -> Dict[str, Any]: + def get_all_balances(self) -> Dict[str, Wallet]: return self._wallets + def get_all_positions(self) -> Dict[str, PositionWallet]: + return self._positions + def get_starting_balance(self) -> float: """ Retrieves starting balance - based on either available capital,