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