def add_sell(
            self,
            selling_asset: Asset,
            rate_in_profit_currency: FVal,
            total_fee_in_profit_currency: Fee,
            gain_in_profit_currency: FVal,
            selling_amount: FVal,
            receiving_asset: Asset,
            receiving_amount: FVal,
            receiving_asset_rate_in_profit_currency: FVal,
            taxable_amount: FVal,
            taxable_bought_cost: FVal,
            timestamp: Timestamp,
            is_virtual: bool,
    ):
        if not self.create_csv:
            return

        exchange_rate_key = f'exchanged_asset_{self.profit_currency}_exchange_rate'
        taxable_profit_received = taxable_gain_for_sell(
            taxable_amount=taxable_amount,
            rate_in_profit_currency=rate_in_profit_currency,
            total_fee_in_profit_currency=total_fee_in_profit_currency,
            selling_amount=selling_amount,
        )
        row = len(self.trades_csv) + 2
        taxable_profit_formula = '=IF(G{}=0,0,K{}-J{})'.format(row, row, row)
        self.trades_csv.append({
            'type': 'sell',
            'asset': selling_asset,
            'price_in_{}'.format(self.profit_currency): rate_in_profit_currency,
            'fee_in_{}'.format(self.profit_currency): total_fee_in_profit_currency,
            'gained_or_invested_{}'.format(self.profit_currency): gain_in_profit_currency,
            'amount': selling_amount,
            'taxable_amount': taxable_amount,
            'exchanged_for': receiving_asset,
            exchange_rate_key: receiving_asset_rate_in_profit_currency,
            'taxable_bought_cost_in_{}'.format(self.profit_currency): taxable_bought_cost,
            'taxable_gain_in_{}'.format(self.profit_currency): taxable_profit_received,
            'taxable_profit_loss_in_{}'.format(self.profit_currency): taxable_profit_formula,
            'time': timestamp_to_date(timestamp, formatstr='%d/%m/%Y %H:%M:%S'),
            'is_virtual': is_virtual,
        })
        paid_in_profit_currency = ZERO
        self.add_to_allevents(
            event_type=EV_SELL,
            paid_in_profit_currency=paid_in_profit_currency,
            paid_asset=selling_asset,
            paid_in_asset=selling_amount,
            received_asset=receiving_asset,
            received_in_asset=receiving_amount,
            taxable_received_in_profit_currency=taxable_profit_received,
            timestamp=timestamp,
            is_virtual=is_virtual,
            taxable_amount=taxable_amount,
            taxable_bought_cost=taxable_bought_cost,
        )
Beispiel #2
0
    def add_sell(
        self,
        selling_asset: Asset,
        selling_amount: FVal,
        receiving_asset: Optional[Asset],
        receiving_amount: Optional[FVal],
        gain_in_profit_currency: FVal,
        total_fee_in_profit_currency: Fee,
        trade_rate: FVal,
        rate_in_profit_currency: FVal,
        timestamp: Timestamp,
        loan_settlement: bool = False,
        is_virtual: bool = False,
    ) -> None:

        if selling_asset not in self.events:
            self.events[selling_asset] = Events(list(), list())

        self.events[selling_asset].sells.append(
            SellEvent(
                amount=selling_amount,
                timestamp=timestamp,
                rate=rate_in_profit_currency,
                fee_rate=total_fee_in_profit_currency / selling_amount,
                gain=gain_in_profit_currency,
            ), )

        self.handle_prefork_asset_sells(selling_asset, selling_amount,
                                        timestamp)

        if loan_settlement:
            log.debug(
                'Loan Settlement Selling Event',
                sensitive_log=True,
                selling_amount=selling_amount,
                selling_asset=selling_asset,
                gain_in_profit_currency=gain_in_profit_currency,
                profit_currency=self.profit_currency,
                timestamp=timestamp,
            )
        else:
            log.debug(
                'Selling Event',
                sensitive_log=True,
                selling_amount=selling_amount,
                selling_asset=selling_asset,
                receiving_amount=receiving_amount,
                receiving_asset=receiving_asset,
                rate=trade_rate,
                rate_in_profit_currency=rate_in_profit_currency,
                profit_currency=self.profit_currency,
                gain_in_profit_currency=gain_in_profit_currency,
                fee_in_profit_currency=total_fee_in_profit_currency,
                timestamp=timestamp,
            )

        # now search the buys for `paid_with_asset` and calculate profit/loss
        (
            taxable_amount,
            taxable_bought_cost,
            taxfree_bought_cost,
        ) = self.search_buys_calculate_profit(
            selling_amount,
            selling_asset,
            timestamp,
        )
        general_profit_loss = 0
        taxable_profit_loss = 0

        # If we don't include crypto2crypto and we sell for crypto, stop here
        if receiving_asset and not receiving_asset.is_fiat(
        ) and not self.include_crypto2crypto:
            return

        # calculate profit/loss
        if not loan_settlement or (loan_settlement
                                   and self.count_profit_for_settlements):
            taxable_gain = taxable_gain_for_sell(
                taxable_amount=taxable_amount,
                rate_in_profit_currency=rate_in_profit_currency,
                total_fee_in_profit_currency=total_fee_in_profit_currency,
                selling_amount=selling_amount,
            )

            general_profit_loss = gain_in_profit_currency - (
                taxfree_bought_cost + taxable_bought_cost +
                total_fee_in_profit_currency)
            taxable_profit_loss = taxable_gain - taxable_bought_cost

        # should never happen, should be stopped at the main loop
        assert timestamp <= self.query_end_ts, (
            "Trade time > query_end_ts found in adding to sell event")

        # count profit/losses if we are inside the query period
        if timestamp >= self.query_start_ts:
            if loan_settlement:
                # If it's a loan settlement we are charged both the fee and the gain
                settlement_loss = gain_in_profit_currency + total_fee_in_profit_currency
                expected = rate_in_profit_currency * selling_amount + total_fee_in_profit_currency
                msg = (
                    f'Expected settlement loss mismatch. rate_in_profit_currency'
                    f' ({rate_in_profit_currency}) * selling_amount'
                    f' ({selling_amount}) + total_fee_in_profit_currency'
                    f' ({total_fee_in_profit_currency}) != settlement_loss '
                    f'({settlement_loss})')
                assert expected == settlement_loss, msg
                self.settlement_losses += settlement_loss
                log.debug(
                    'Loan Settlement Loss',
                    sensitive_log=True,
                    settlement_loss=settlement_loss,
                    profit_currency=self.profit_currency,
                )
            else:
                log.debug(
                    "After Sell Profit/Loss",
                    sensitive_log=True,
                    taxable_profit_loss=taxable_profit_loss,
                    general_profit_loss=general_profit_loss,
                    profit_currency=self.profit_currency,
                )

            self.general_trade_profit_loss += general_profit_loss
            self.taxable_trade_profit_loss += taxable_profit_loss

            if loan_settlement:
                self.csv_exporter.add_loan_settlement(
                    asset=selling_asset,
                    amount=selling_amount,
                    rate_in_profit_currency=rate_in_profit_currency,
                    total_fee_in_profit_currency=total_fee_in_profit_currency,
                    timestamp=timestamp,
                )
            else:
                assert receiving_asset, 'Here receiving asset should have a value'
                self.csv_exporter.add_sell(
                    selling_asset=selling_asset,
                    rate_in_profit_currency=rate_in_profit_currency,
                    total_fee_in_profit_currency=total_fee_in_profit_currency,
                    gain_in_profit_currency=gain_in_profit_currency,
                    selling_amount=selling_amount,
                    receiving_asset=receiving_asset,
                    receiving_amount=receiving_amount,
                    receiving_asset_rate_in_profit_currency=self.
                    get_rate_in_profit_currency(
                        receiving_asset,
                        timestamp,
                    ),
                    taxable_amount=taxable_amount,
                    taxable_bought_cost=taxable_bought_cost,
                    timestamp=timestamp,
                    is_virtual=is_virtual,
                )
Beispiel #3
0
    def add_sell(
        self,
        location: Location,
        selling_asset: Asset,
        rate_in_profit_currency: FVal,
        total_fee_in_profit_currency: Fee,
        gain_in_profit_currency: FVal,
        selling_amount: FVal,
        receiving_asset: Optional[Asset],
        receiving_amount: Optional[FVal],
        receiving_asset_rate_in_profit_currency: FVal,
        taxable_amount: FVal,
        taxable_bought_cost: FVal,
        timestamp: Timestamp,
        is_virtual: bool,
    ) -> None:
        if not self.create_csv:
            return

        processed_receiving_asset: Union[EmptyStr, Asset] = (
            EmptyStr('') if receiving_asset is None else receiving_asset)
        exported_receiving_asset = '' if receiving_asset is None else receiving_asset.identifier
        processed_receiving_amount = FVal(
            0) if not receiving_amount else receiving_amount
        exchange_rate_key = f'exchanged_asset_{self.profit_currency.identifier}_exchange_rate'
        taxable_profit_received = taxable_gain_for_sell(
            taxable_amount=taxable_amount,
            rate_in_profit_currency=rate_in_profit_currency,
            total_fee_in_profit_currency=total_fee_in_profit_currency,
            selling_amount=selling_amount,
        )
        row = len(self.trades_csv) + 2
        taxable_profit_formula = '=IF(H{}=0,0,L{}-K{})'.format(row, row, row)
        self.trades_csv.append({
            'type':
            'sell',
            'location':
            str(location),
            'asset':
            selling_asset.identifier,
            f'price_in_{self.profit_currency.identifier}':
            rate_in_profit_currency,
            f'fee_in_{self.profit_currency.identifier}':
            total_fee_in_profit_currency,
            f'gained_or_invested_{self.profit_currency.identifier}':
            gain_in_profit_currency,
            'amount':
            selling_amount,
            'taxable_amount':
            taxable_amount,
            'exchanged_for':
            exported_receiving_asset,
            exchange_rate_key:
            receiving_asset_rate_in_profit_currency,
            f'taxable_bought_cost_in_{self.profit_currency.identifier}':
            taxable_bought_cost,
            f'taxable_gain_in_{self.profit_currency.identifier}':
            taxable_profit_received,
            f'taxable_profit_loss_in_{self.profit_currency.identifier}':
            taxable_profit_formula,
            'time':
            timestamp_to_date(timestamp, formatstr='%d/%m/%Y %H:%M:%S'),
            'is_virtual':
            is_virtual,
        })
        paid_in_profit_currency = ZERO
        self.add_to_allevents(
            event_type=EV_SELL,
            location=location,
            paid_in_profit_currency=paid_in_profit_currency,
            paid_asset=selling_asset,
            paid_in_asset=selling_amount,
            received_asset=processed_receiving_asset,
            received_in_asset=processed_receiving_amount,
            taxable_received_in_profit_currency=taxable_profit_received,
            timestamp=timestamp,
            is_virtual=is_virtual,
            taxable_amount=taxable_amount,
            taxable_bought_cost=taxable_bought_cost,
        )
Beispiel #4
0
    def add_sell(
            self,
            location: Location,
            selling_asset: Asset,
            rate_in_profit_currency: FVal,
            total_fee_in_profit_currency: Fee,
            gain_in_profit_currency: FVal,
            selling_amount: FVal,
            receiving_asset: Optional[Asset],
            receiving_amount: Optional[FVal],
            receiving_asset_rate_in_profit_currency: FVal,
            taxable_amount: FVal,
            taxable_bought_cost: FVal,
            timestamp: Timestamp,
            is_virtual: bool,
            cost_basis_info: 'CostBasisInfo',
            total_bought_cost: FVal,
    ) -> None:
        if not self.create_csv:
            return

        processed_receiving_asset: Union[EmptyStr, Asset] = (
            EmptyStr('') if receiving_asset is None else receiving_asset
        )
        exported_receiving_asset = '' if receiving_asset is None else str(receiving_asset)
        processed_receiving_amount = ZERO if not receiving_amount else receiving_amount
        exchange_rate_key = f'exchanged_asset_{self.profit_currency.symbol}_exchange_rate'
        taxable_profit_received = taxable_gain_for_sell(
            taxable_amount=taxable_amount,
            rate_in_profit_currency=rate_in_profit_currency,
            total_fee_in_profit_currency=total_fee_in_profit_currency,
            selling_amount=selling_amount,
        )
        row = len(self.trades_csv) + 2
        taxable_profit_formula = f'=IF(H{row}=0,0,L{row}-K{row})'
        self.trades_csv.append({
            'type': 'sell',
            'location': str(location),
            'asset': str(selling_asset),
            f'price_in_{self.profit_currency.symbol}': rate_in_profit_currency,
            f'fee_in_{self.profit_currency.symbol}': total_fee_in_profit_currency,
            f'gained_or_invested_{self.profit_currency.symbol}': gain_in_profit_currency,
            'amount': selling_amount,
            'taxable_amount': taxable_amount,
            'exchanged_for': exported_receiving_asset,
            exchange_rate_key: receiving_asset_rate_in_profit_currency,
            f'taxable_bought_cost_in_{self.profit_currency.symbol}': taxable_bought_cost,
            f'taxable_gain_in_{self.profit_currency.symbol}': taxable_profit_received,
            f'taxable_profit_loss_in_{self.profit_currency.symbol}': taxable_profit_formula,
            'time': self.timestamp_to_date(timestamp),
            'cost_basis': cost_basis_info.to_string(self.timestamp_to_date),
            'is_virtual': is_virtual,
            f'total_bought_cost_in_{self.profit_currency.symbol}': total_bought_cost,
        })
        paid_in_profit_currency = ZERO
        self.add_to_allevents(
            event_type=EV_SELL,
            location=location,
            paid_in_profit_currency=paid_in_profit_currency,
            paid_asset=selling_asset,
            paid_in_asset=selling_amount,
            received_asset=processed_receiving_asset,
            received_in_asset=processed_receiving_amount,
            taxable_received_in_profit_currency=taxable_profit_received,
            total_received_in_profit_currency=gain_in_profit_currency,
            timestamp=timestamp,
            is_virtual=is_virtual,
            taxable_amount=taxable_amount,
            taxable_bought_cost=taxable_bought_cost,
            total_bought_cost=total_bought_cost,
            cost_basis_info=cost_basis_info,
        )
Beispiel #5
0
    def add_sell(
        self,
        location: Location,
        selling_asset: Asset,
        selling_amount: FVal,
        receiving_asset: Optional[Asset],
        receiving_amount: Optional[FVal],
        gain_in_profit_currency: FVal,
        total_fee_in_profit_currency: Fee,
        rate_in_profit_currency: FVal,
        timestamp: Timestamp,
        loan_settlement: bool = False,
        is_virtual: bool = False,
    ) -> None:
        """Account for the given sell action

        May raise:
        - PriceQueryUnsupportedAsset if from/to asset is missing from price oracles
        - NoPriceForGivenTimestamp if we can't find a price for the asset in the given
        timestamp from cryptocompare
        - RemoteError if there is a problem reaching the price oracle server
        or with reading the response returned by the server
        """
        skip_trade = (not self.include_crypto2crypto
                      and not selling_asset.is_fiat() and receiving_asset
                      and not receiving_asset.is_fiat())
        if skip_trade:
            return

        if selling_amount == ZERO:
            logger.error(
                f'Skipping sell trade of {selling_asset.identifier} for '
                f'{receiving_asset.identifier if receiving_asset else "nothing"} at {timestamp}'
                f' since the selling amount is 0', )
            return

        if selling_asset.is_fiat():
            # Should be handled by a virtual buy
            logger.debug(
                f'Skipping sell trade of {selling_asset.identifier} for '
                f'{receiving_asset.identifier if receiving_asset else "nothing"} at {timestamp} '
                f'since selling of FIAT of something will just be treated as a buy.',
            )
            return

        logger.debug(
            f'Processing sell trade of {selling_asset.identifier} for '
            f'{receiving_asset.identifier if receiving_asset else "nothing"} at {timestamp}',
        )

        self.cost_basis.spend_asset(
            location=location,
            timestamp=timestamp,
            asset=selling_asset,
            amount=selling_amount,
            rate=rate_in_profit_currency,
            fee_in_profit_currency=total_fee_in_profit_currency,
            gain_in_profit_currency=gain_in_profit_currency,
        )
        self.handle_prefork_asset_sells(selling_asset, selling_amount,
                                        timestamp)

        # now search the acquisitions for `paid_with_asset` and calculate profit/loss
        cost_basis_info = self.cost_basis.calculate_spend_cost_basis(
            spending_amount=selling_amount,
            spending_asset=selling_asset,
            timestamp=timestamp,
        )
        general_profit_loss = ZERO
        taxable_profit_loss = ZERO

        # If we don't include crypto2crypto and we sell for crypto, stop here
        if receiving_asset and not receiving_asset.is_fiat(
        ) and not self.include_crypto2crypto:
            return

        # calculate profit/loss
        if not loan_settlement or (loan_settlement
                                   and self.count_profit_for_settlements):
            taxable_gain = taxable_gain_for_sell(
                taxable_amount=cost_basis_info.taxable_amount,
                rate_in_profit_currency=rate_in_profit_currency,
                total_fee_in_profit_currency=total_fee_in_profit_currency,
                selling_amount=selling_amount,
            )

            total_bought_cost_in_profit_currency = (
                cost_basis_info.taxfree_bought_cost +
                cost_basis_info.taxable_bought_cost +
                total_fee_in_profit_currency)
            general_profit_loss = gain_in_profit_currency - total_bought_cost_in_profit_currency
            taxable_profit_loss = taxable_gain - cost_basis_info.taxable_bought_cost

        # should never happen, should be stopped at the main loop
        assert timestamp <= self.query_end_ts, (
            'Trade time > query_end_ts found in adding to sell event')

        # count profit/losses if we are inside the query period
        if timestamp >= self.query_start_ts:
            if loan_settlement:
                # If it's a loan settlement we are charged both the fee and the gain
                settlement_loss = gain_in_profit_currency + total_fee_in_profit_currency
                expected = rate_in_profit_currency * selling_amount + total_fee_in_profit_currency
                msg = (
                    f'Expected settlement loss mismatch. rate_in_profit_currency'
                    f' ({rate_in_profit_currency}) * selling_amount'
                    f' ({selling_amount}) + total_fee_in_profit_currency'
                    f' ({total_fee_in_profit_currency}) != settlement_loss '
                    f'({settlement_loss})')
                assert expected == settlement_loss, msg
                self.settlement_losses += settlement_loss
                log.debug(
                    'Loan Settlement Loss',
                    settlement_loss=settlement_loss,
                    profit_currency=self.profit_currency,
                )
            else:
                log.debug(
                    "After Sell Profit/Loss",
                    taxable_profit_loss=taxable_profit_loss,
                    general_profit_loss=general_profit_loss,
                    profit_currency=self.profit_currency,
                )

            self.general_trade_profit_loss += general_profit_loss
            self.taxable_trade_profit_loss += taxable_profit_loss

            if loan_settlement:
                self.csv_exporter.add_loan_settlement(
                    location=location,
                    asset=selling_asset,
                    amount=selling_amount,
                    rate_in_profit_currency=rate_in_profit_currency,
                    total_fee_in_profit_currency=total_fee_in_profit_currency,
                    timestamp=timestamp,
                    cost_basis_info=cost_basis_info,
                )
            else:
                assert receiving_asset, 'Here receiving asset should have a value'
                self.csv_exporter.add_sell(
                    location=location,
                    selling_asset=selling_asset,
                    rate_in_profit_currency=rate_in_profit_currency,
                    total_fee_in_profit_currency=total_fee_in_profit_currency,
                    gain_in_profit_currency=gain_in_profit_currency,
                    selling_amount=selling_amount,
                    receiving_asset=receiving_asset,
                    receiving_amount=receiving_amount,
                    receiving_asset_rate_in_profit_currency=self.
                    get_rate_in_profit_currency(
                        receiving_asset,
                        timestamp,
                    ),
                    taxable_amount=cost_basis_info.taxable_amount,
                    taxable_bought_cost=cost_basis_info.taxable_bought_cost,
                    timestamp=timestamp,
                    cost_basis_info=cost_basis_info,
                    is_virtual=is_virtual,
                    total_bought_cost=total_bought_cost_in_profit_currency,
                )
Beispiel #6
0
    def add_sell(
        self,
        location: Location,
        selling_asset: Asset,
        selling_amount: FVal,
        receiving_asset: Optional[Asset],
        receiving_amount: Optional[FVal],
        gain_in_profit_currency: FVal,
        total_fee_in_profit_currency: Fee,
        trade_rate: FVal,
        rate_in_profit_currency: FVal,
        timestamp: Timestamp,
        loan_settlement: bool = False,
        is_virtual: bool = False,
    ) -> None:
        """Account for the given sell action

        May raise:
        - PriceQueryUnsupportedAsset if from/to asset is missing from price oracles
        - NoPriceForGivenTimestamp if we can't find a price for the asset in the given
        timestamp from cryptocompare
        - RemoteError if there is a problem reaching the price oracle server
        or with reading the response returned by the server
        """
        skip_trade = (not self.include_crypto2crypto
                      and not selling_asset.is_fiat() and receiving_asset
                      and not receiving_asset.is_fiat())
        if skip_trade:
            return

        if selling_asset not in self.events:
            self.events[selling_asset] = Events([], [])

        self.events[selling_asset].sells.append(
            SellEvent(
                amount=selling_amount,
                timestamp=timestamp,
                rate=rate_in_profit_currency,
                fee_rate=total_fee_in_profit_currency / selling_amount,
                gain=gain_in_profit_currency,
            ), )

        self.handle_prefork_asset_sells(selling_asset, selling_amount,
                                        timestamp)

        if loan_settlement:
            log.debug(
                'Loan Settlement Selling Event',
                sensitive_log=True,
                selling_amount=selling_amount,
                selling_asset=selling_asset,
                gain_in_profit_currency=gain_in_profit_currency,
                profit_currency=self.profit_currency,
                timestamp=timestamp,
            )
        else:
            log.debug(
                'Selling Event',
                sensitive_log=True,
                selling_amount=selling_amount,
                selling_asset=selling_asset,
                receiving_amount=receiving_amount,
                receiving_asset=receiving_asset,
                rate=trade_rate,
                rate_in_profit_currency=rate_in_profit_currency,
                profit_currency=self.profit_currency,
                gain_in_profit_currency=gain_in_profit_currency,
                fee_in_profit_currency=total_fee_in_profit_currency,
                timestamp=timestamp,
            )

        # now search the buys for `paid_with_asset` and calculate profit/loss
        (
            taxable_amount,
            taxable_bought_cost,
            taxfree_bought_cost,
        ) = self.search_buys_calculate_profit(
            selling_amount,
            selling_asset,
            timestamp,
        )
        general_profit_loss = ZERO
        taxable_profit_loss = ZERO

        # If we don't include crypto2crypto and we sell for crypto, stop here
        if receiving_asset and not receiving_asset.is_fiat(
        ) and not self.include_crypto2crypto:
            return

        # calculate profit/loss
        if not loan_settlement or (loan_settlement
                                   and self.count_profit_for_settlements):
            taxable_gain = taxable_gain_for_sell(
                taxable_amount=taxable_amount,
                rate_in_profit_currency=rate_in_profit_currency,
                total_fee_in_profit_currency=total_fee_in_profit_currency,
                selling_amount=selling_amount,
            )

            general_profit_loss = gain_in_profit_currency - (
                taxfree_bought_cost + taxable_bought_cost +
                total_fee_in_profit_currency)
            taxable_profit_loss = taxable_gain - taxable_bought_cost

        # should never happen, should be stopped at the main loop
        assert timestamp <= self.query_end_ts, (
            "Trade time > query_end_ts found in adding to sell event")

        # count profit/losses if we are inside the query period
        if timestamp >= self.query_start_ts:
            if loan_settlement:
                # If it's a loan settlement we are charged both the fee and the gain
                settlement_loss = gain_in_profit_currency + total_fee_in_profit_currency
                expected = rate_in_profit_currency * selling_amount + total_fee_in_profit_currency
                msg = (
                    f'Expected settlement loss mismatch. rate_in_profit_currency'
                    f' ({rate_in_profit_currency}) * selling_amount'
                    f' ({selling_amount}) + total_fee_in_profit_currency'
                    f' ({total_fee_in_profit_currency}) != settlement_loss '
                    f'({settlement_loss})')
                assert expected == settlement_loss, msg
                self.settlement_losses += settlement_loss
                log.debug(
                    'Loan Settlement Loss',
                    sensitive_log=True,
                    settlement_loss=settlement_loss,
                    profit_currency=self.profit_currency,
                )
            else:
                log.debug(
                    "After Sell Profit/Loss",
                    sensitive_log=True,
                    taxable_profit_loss=taxable_profit_loss,
                    general_profit_loss=general_profit_loss,
                    profit_currency=self.profit_currency,
                )

            self.general_trade_profit_loss += general_profit_loss
            self.taxable_trade_profit_loss += taxable_profit_loss

            if loan_settlement:
                self.csv_exporter.add_loan_settlement(
                    location=location,
                    asset=selling_asset,
                    amount=selling_amount,
                    rate_in_profit_currency=rate_in_profit_currency,
                    total_fee_in_profit_currency=total_fee_in_profit_currency,
                    timestamp=timestamp,
                )
            else:
                assert receiving_asset, 'Here receiving asset should have a value'
                self.csv_exporter.add_sell(
                    location=location,
                    selling_asset=selling_asset,
                    rate_in_profit_currency=rate_in_profit_currency,
                    total_fee_in_profit_currency=total_fee_in_profit_currency,
                    gain_in_profit_currency=gain_in_profit_currency,
                    selling_amount=selling_amount,
                    receiving_asset=receiving_asset,
                    receiving_amount=receiving_amount,
                    receiving_asset_rate_in_profit_currency=self.
                    get_rate_in_profit_currency(
                        receiving_asset,
                        timestamp,
                    ),
                    taxable_amount=taxable_amount,
                    taxable_bought_cost=taxable_bought_cost,
                    timestamp=timestamp,
                    is_virtual=is_virtual,
                )
Beispiel #7
0
    def add_sell(
        self,
        location: Location,
        selling_asset: Asset,
        rate_in_profit_currency: FVal,
        total_fee_in_profit_currency: Fee,
        gain_in_profit_currency: FVal,
        selling_amount: FVal,
        receiving_asset: Optional[Asset],
        receiving_amount: Optional[FVal],
        receiving_asset_rate_in_profit_currency: FVal,
        taxable_amount: FVal,
        taxable_bought_cost: FVal,
        timestamp: Timestamp,
        is_virtual: bool,
        cost_basis_info: 'CostBasisInfo',
        total_bought_cost: FVal,
        link: Optional[str],
        notes: Optional[str],
    ) -> None:
        if not self.create_csv:
            return

        exported_receiving_asset = '' if receiving_asset is None else str(
            receiving_asset)
        processed_receiving_amount = ZERO if not receiving_amount else receiving_amount
        exchange_rate_key = f'exchanged_asset_{self.profit_currency.symbol}_exchange_rate'
        taxable_profit_received = taxable_gain_for_sell(
            taxable_amount=taxable_amount,
            rate_in_profit_currency=rate_in_profit_currency,
            total_fee_in_profit_currency=total_fee_in_profit_currency,
            selling_amount=selling_amount,
        )
        row = len(self.trades_csv) + 2
        taxable_profit_csv = self._add_if_formula(
            condition=f'H{row}=0',
            if_true='0',
            if_false=f'L{row}-K{row}',
            actual_value=taxable_profit_received,
        )
        self.trades_csv.append({
            'type':
            'sell',
            'location':
            str(location),
            'asset':
            str(selling_asset),
            f'price_in_{self.profit_currency.symbol}':
            rate_in_profit_currency,
            f'fee_in_{self.profit_currency.symbol}':
            total_fee_in_profit_currency,
            f'gained_or_invested_{self.profit_currency.symbol}':
            gain_in_profit_currency,
            'amount':
            selling_amount,
            'taxable_amount':
            taxable_amount,
            'exchanged_for':
            exported_receiving_asset,
            exchange_rate_key:
            receiving_asset_rate_in_profit_currency,
            f'taxable_bought_cost_in_{self.profit_currency.symbol}':
            taxable_bought_cost,
            f'taxable_gain_in_{self.profit_currency.symbol}':
            taxable_profit_received,
            f'taxable_profit_loss_in_{self.profit_currency.symbol}':
            taxable_profit_csv,
            'time':
            self.timestamp_to_date(timestamp),
            'cost_basis':
            cost_basis_info.to_string(self.timestamp_to_date),
            'is_virtual':
            is_virtual,
            f'total_bought_cost_in_{self.profit_currency.symbol}':
            total_bought_cost,
            'link':
            link,
            'notes':
            notes,
        })
        paid_in_profit_currency = ZERO
        self.add_to_allevents(
            event_type=EV_SELL,
            location=location,
            paid_in_profit_currency=paid_in_profit_currency,
            paid_asset=selling_asset,
            paid_in_asset=selling_amount,
            received_asset=receiving_asset,
            received_in_asset=processed_receiving_amount,
            taxable_received_in_profit_currency=taxable_profit_received,
            total_received_in_profit_currency=gain_in_profit_currency,
            timestamp=timestamp,
            is_virtual=is_virtual,
            taxable_amount=taxable_amount,
            taxable_bought_cost=taxable_bought_cost,
            total_bought_cost=total_bought_cost,
            cost_basis_info=cost_basis_info,
            link=link,
            notes=notes,
        )