Exemplo n.º 1
0
    def _load_all_accounts(self):
        """
        This function allows to load every account that the user has on Coinbase
        These accounts will be used to calculate the taxes, 'in fine'.
        Only the accounts with an real UUID are taken into account
        """

        # Get the list of accounts (not paginated for coinbase pro)
        accounts_list = self.api_client.get_accounts()

        # Save all used accounts
        for account in accounts_list:

            # If the ID is a valid UUID, save the account and print it in DEBUG logs
            match = re.search(r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}", account['id'])
            if match:
                # Get the various values
                id = account['id']
                name = "Account in " + account['currency']
                crypto_balance = account['available']
                crypto_currency = account['currency']

                # Debug print
                fcrypt_log.debug(f"Adding account: {id} ==> {name}: {crypto_balance} {crypto_currency}")

                # Add the account in our list
                self.accounts.append(account)
Exemplo n.º 2
0
    def _load_all_accounts(self):
        """
        This function allows to load every account that the user has on Coinbase
        These accounts will be used to calculate the taxes, 'in fine'.
        Only the accounts with an real UUID are taken into account
        """
        accounts_list = []
        other_pages = True
        last_id = ""
        while other_pages:
            # Get account according to pagination
            if last_id == "":
                api_answer = self.api_client.get_accounts()
            else:
                api_answer = self.api_client.get_accounts(starting_after=last_id)

            accounts_list = accounts_list + api_answer['data']
            if ((api_answer.pagination is not None) and (api_answer.pagination["next_uri"] is not None) and
                    (api_answer.pagination["next_uri"] != "")):
                # Get the pagination object
                pagination_obj = api_answer.pagination
                # Extract 'starting_after' key from next_uri
                parsed = urlparse.urlparse(pagination_obj["next_uri"])
                last_id = parse_qs(parsed.query)['starting_after'][0]
            else:
                other_pages = False

        # Save all used accounts
        for account in accounts_list:

            # If the ID is a valid UUID, save the account and print it in DEBUG logs
            match = re.search(r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}", account['id'])
            if match:
                # Get the various values
                id = account['id']
                name = account['name']
                crypto_balance = account['balance']['amount']
                crypto_currency = account['currency']
                native_balance = account['native_balance']['amount']
                native_currency = account['native_balance']['currency']

                # Debug print
                fcrypt_log.debug(
                    f"Adding account: {id} ==> {name}: {crypto_balance} {crypto_currency}" +
                    f" ({native_balance} {native_currency})")

                # Add the account in our list
                self.accounts.append(account)
Exemplo n.º 3
0
    def get_wallet_value_at(self, crypto_currency: str, fiat_currency: str, time: datetime.datetime) -> Decimal:
        """
        This function allows to get the value of a wallet at a given time.

        :param crypto_currency: Crypto currency of the wallet
        :type crypto_currency: str
        :param fiat_currency: Fiat currency for the result (EUR, USD, etc.)
        :type fiat_currency: str
        :param time: Time where the value is wanted
        :type time: datetime.datetime
        :returns: Decimal -- The wallet value at the given time
        """
        # Firstly, get the wallet balance at the given time
        balance = self.get_wallet_balance_at(crypto_currency, time)

        time_str = str(time)
        normal_balance = str(balance.normalize())

        # Print debug
        fcrypt_log.debug(f"[WALLET] Balance at {time_str}: {normal_balance} {crypto_currency}")

        if balance != 0:

            # Now get the equivalent value in fiat
            rate_currency = crypto_currency + "-" + fiat_currency
            rate_value = self._find_rate_value_from_finders(rate_currency, time)

            if rate_value == Decimal(0):
                # Print error
                fcrypt_log.warning(
                    f"[WALLET] NO RATE FOUND FOR NOT NULL BALANCE !!! Currency: {crypto_currency} \
 - Fiat: {fiat_currency}")
                # Return 0
                wallet_value = Decimal(0)
            else:
                # Calculate the wallet value
                wallet_value = rate_value * balance

                # Print info
                fcrypt_log.debug(
                    f"[WALLET] Value of {crypto_currency} wallet at {time_str}: {wallet_value} {fiat_currency}")

        else:
            wallet_value = Decimal(0)

        return wallet_value
Exemplo n.º 4
0
    def _load_all_transactions(self):
        """
        This function allows to load every transaction that the user has done on Coinbase
        These transactions, in fine, will allow us to go back in time in the account, to know
        what was on each account, at a given time
        """
        # Get all transactions
        for account in self.accounts:
            transactions_list = []
            other_pages = True
            last_id = ""

            while other_pages:
                # Get account according to pagination
                if last_id == "":
                    # Get the transactions for this account
                    tmp_transactions = self.api_client.get_transactions(account['id'])
                else:
                    # Get the transactions for this account
                    tmp_transactions = self.api_client.get_transactions(account['id'], starting_after=last_id)

                transactions_list = transactions_list + tmp_transactions['data']
                if ((tmp_transactions.pagination is not None) and
                    (tmp_transactions.pagination["next_uri"] is not None) and
                        (tmp_transactions.pagination["next_uri"] != "")):
                    # Get the pagination object
                    pagination_obj = tmp_transactions.pagination
                    # Extract 'starting_after' key from next_uri
                    parsed = urlparse.urlparse(pagination_obj["next_uri"])
                    last_id = parse_qs(parsed.query)['starting_after'][0]
                else:
                    other_pages = False

            # Print the transactions
            for transaction in transactions_list:
                # print(transaction)
                transaction_type = transaction['type']
                amount = transaction['amount']['amount']
                currency = transaction['amount']['currency']
                date = transaction['updated_at']
                if not str.startswith(amount, "-"):
                    amount = "+" + amount
                account = self._extract_account_id(transaction['resource_path'])
                fcrypt_log.debug(f"[TRANSACTION][{transaction_type}] {date}: {amount} {currency} ==> {account}")

            self.transactions.extend(transactions_list)
Exemplo n.º 5
0
    def get_wallet_balance_at(self, currency: str, time: datetime.datetime) -> Decimal:
        """
        This function allows to get the balance of a wallet at a given time.

        :param currency: Currency we want the value for
        :type currency: str
        :param time: Time where the value is wanted
        :type time: datetime.datetime
        :returns: Decimal -- The wallet balance at the given time
        """
        # Firstly, get the corresponding account ID
        account_id = ""
        for account in self.accounts:
            if ('currency' in account) and (account['currency'] == currency):
                account_id = account['id']
                current_balance = Decimal(account['balance'])

        if account_id == "":
            raise ValueError("No account found for this currency")

        # Then apply every transaction in reverse if the datetime of this transaction
        # is posterior to the wanted datetime
        for transaction in self.transactions:
            # Extract account ID
            tmp_account_id = transaction["account_id"]
            # Check if the account ids correspond
            if (tmp_account_id == account_id):
                # Extract the datetime
                operation_datetime = isoparse(transaction['created_at'])
                # If datetime posterior or equal to the time given by user, reverse it
                if operation_datetime >= time:
                    trans_amount = Decimal(transaction['amount'])
                    tmp_balance = current_balance - trans_amount
                    fcrypt_log.debug(f"[REVERSED TRANSACTION] {trans_amount} {currency} ==> {account_id}")
                    fcrypt_log.debug(
                        f"[REVERSED TRANSACTION] Operation {current_balance}-{trans_amount} = {tmp_balance}")
                    current_balance = tmp_balance

        return current_balance
Exemplo n.º 6
0
    def _load_all_transactions(self):
        """
        This function allows to load every transaction that the user has done on Coinbase
        These transactions, in fine, will allow us to go back in time in the account, to know
        what was on each account, at a given time
        """
        # Get all transactions
        for account in self.accounts:

            # Get all account history for the current account
            history_gen = self.api_client.get_account_history(account['id'])
            movements_list = list(history_gen)

            # Print and take into account the transactions
            for movement in movements_list:
                movement_type = movement.get("type", "[NOT KNOWN]")
                amount = movement.get("amount", "[NOT KNOWN]")
                balance = movement.get("balance", "[NOT KNOWN]")
                details = movement.get("details", "[NOT KNOWN]")
                date = movement.get("created_at", "[NOT KNOWN]")

                if not str.startswith(amount, "-"):
                    amount = "+" + amount

                # Copy the dictionary and add the account ID in it
                tmp_movement = movement.copy()
                tmp_movement["account_id"] = account['id']

                fcrypt_log.debug(
                    f"[TRANSACTION] {movement_type} | {date}: {amount} {account['currency']} ==> {account['id']}")
                fcrypt_log.debug(f"              Balance: {balance} {account['currency']}")
                fcrypt_log.debug(f"              Details: {details}")

                # Add the account movement according to its type
                if movement_type == "fee":
                    self.fee.append(tmp_movement)
                else:
                    self.transactions.append(tmp_movement)