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

        gross_key = 'gross_gained_or_invested_{}'.format(self.profit_currency)
        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,
            gross_key: gain_in_profit_currency + total_fee_in_profit_currency,
            'net_gained_or_invested_{}'.format(self.profit_currency): gain_in_profit_currency,
            'amount': selling_amount,
            'exchanged_for': receiving_asset,
            'exchanged_asset_euro_exchange_rate': receiving_asset_rate_in_profit_currency,
            'time': tsToDate(timestamp, formatstr='%d/%m/%Y %H:%M:%S'),
            'is_virtual': is_virtual,
        })
        paid_in_profit_currency = (
            selling_amount * rate_in_profit_currency + total_fee_in_profit_currency
        )
        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,
            received_in_profit_currency=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,
            ),
            timestamp=timestamp,
            is_virtual=is_virtual,
            taxable_amount=taxable_amount,
            taxable_bought_cost=taxable_bought_cost,
        )
Exemplo n.º 2
0
    def add_sell(
        self,
        selling_asset,
        rate_in_profit_currency,
        total_fee_in_profit_currency,
        gain_in_profit_currency,
        selling_amount,
        receiving_asset,
        receiving_amount,
        receiving_asset_rate_in_profit_currency,
        taxable_amount,
        taxable_bought_cost,
        timestamp,
        is_virtual,
    ):
        if not self.create_csv:
            return

        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,
            "gross_gained_or_invested_{}".format(self.profit_currency):
            gain_in_profit_currency + total_fee_in_profit_currency,
            "net_gained_or_invested_{}".format(self.profit_currency):
            gain_in_profit_currency,
            "amount":
            selling_amount,
            "exchanged_for":
            receiving_asset,
            "exchanged_asset_euro_exchange_rate":
            receiving_asset_rate_in_profit_currency,
            "time":
            tsToDate(timestamp, formatstr='%d/%m/%Y %H:%M:%S'),
            "is_virtual":
            is_virtual,
        })
        self.add_to_allevents(
            event_type='sell',
            paid_in_profit_currency=selling_amount * rate_in_profit_currency +
            total_fee_in_profit_currency,
            paid_asset=selling_asset,
            paid_in_asset=selling_amount,
            received_asset=receiving_asset,
            received_in_asset=receiving_amount,
            received_in_profit_currency=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,
            ),
            timestamp=timestamp,
            is_virtual=is_virtual,
            taxable_amount=taxable_amount,
            taxable_bought_cost=taxable_bought_cost,
        )
Exemplo n.º 3
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 not in FIAT_CURRENCIES 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,
                )
Exemplo n.º 4
0
    def add_sell(self,
                 selling_asset,
                 selling_amount,
                 receiving_asset,
                 receiving_amount,
                 gain_in_profit_currency,
                 total_fee_in_profit_currency,
                 trade_rate,
                 rate_in_profit_currency,
                 timestamp,
                 loan_settlement=False,
                 is_virtual=False):

        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,
            ))

        debug_enabled = logger.isEnabledFor(logging.DEBUG)
        if debug_enabled:
            if loan_settlement:
                logger.debug(
                    'Loan Settlement Selling {} of "{}" for {} "{}" at {}'.
                    format(selling_amount, selling_asset,
                           gain_in_profit_currency, self.profit_currency,
                           tsToDate(timestamp, formatstr='%d/%m/%Y %H:%M:%S')))
            else:
                logger.debug(
                    'Selling {} of "{}" for {} "{}" ({} "{}" per "{}" or {} "{}" '
                    'per "{}") for a gain of {} "{}" and a fee of {} "{} at {}'
                    .format(selling_amount, selling_asset, receiving_amount,
                            receiving_asset, trade_rate, receiving_asset,
                            selling_asset, rate_in_profit_currency,
                            self.profit_currency, selling_asset,
                            gain_in_profit_currency, self.profit_currency,
                            total_fee_in_profit_currency, self.profit_currency,
                            tsToDate(timestamp,
                                     formatstr='%d/%m/%Y %H:%M:%S')))

        # 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 not in FIAT_CURRENCIES 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
                self.settlement_losses += settlement_loss
                if debug_enabled:
                    logger.debug("Loan Settlement Loss: {} {}".format(
                        settlement_loss, self.profit_currency))
            elif debug_enabled:
                logger.debug("Taxable P/L: {} {} General P/L: {} {}".format(
                    taxable_profit_loss,
                    self.profit_currency,
                    general_profit_loss,
                    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:
                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,
                )
Exemplo n.º 5
0
    def add_sell(
        self,
        selling_asset: typing.Asset,
        rate_in_profit_currency: FVal,
        total_fee_in_profit_currency: typing.Fee,
        gain_in_profit_currency: FVal,
        selling_amount: FVal,
        receiving_asset: typing.Asset,
        receiving_amount: FVal,
        receiving_asset_rate_in_profit_currency: FVal,
        taxable_amount: FVal,
        taxable_bought_cost: FVal,
        timestamp: typing.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':
            tsToDate(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,
        )