def test_receiving_value_from_tx(accountant, google_service):
    """
    Test that receiving a transaction that provides value works fine
    """
    addr2 = make_ethereum_address()
    tx_hash = '0x5cc0e6e62753551313412492296d5e57bea0a9d1ce507cc96aa4aa076c5bde7a'
    history = [
        HistoryBaseEntry(
            event_identifier=tx_hash,
            sequence_index=0,
            timestamp=1569924574000,
            location=Location.BLOCKCHAIN,
            location_label=make_ethereum_address(),
            asset=A_ETH,
            balance=Balance(amount=FVal('1.5')),
            notes=f'Received 1.5 ETH from {addr2}',
            event_type=HistoryEventType.RECEIVE,
            event_subtype=HistoryEventSubType.NONE,
            counterparty=addr2,
        )
    ]
    accounting_history_process(
        accountant,
        start_ts=0,
        end_ts=1640493376,
        history_list=history,
    )
    no_message_errors(accountant.msg_aggregator)
    expected_pnls = PnlTotals({
        AccountingEventType.TRANSACTION_EVENT:
        PNL(taxable=FVal('242.385'), free=ZERO),
    })
    check_pnls_and_csv(accountant, expected_pnls, google_service)
Beispiel #2
0
def test_buying_selling_eth_before_daofork(accountant, google_service):
    history3 = [
        Trade(
            timestamp=1446979735,  # 11/08/2015
            location=Location.EXTERNAL,
            base_asset=A_ETH,
            quote_asset=A_EUR,
            trade_type=TradeType.BUY,
            amount=FVal(1450),
            rate=FVal('0.2315893'),
            fee=None,
            fee_currency=None,
            link=None,
        ), Trade(  # selling ETH prefork should also reduce our ETC amount
            timestamp=1461021812,  # 18/04/2016 (taxable)
            location=Location.KRAKEN,
            base_asset=A_ETH,  # cryptocompare hourly ETC/EUR price: 7.88
            quote_asset=A_EUR,
            trade_type=TradeType.SELL,
            amount=FVal(50),
            rate=FVal('7.88'),
            fee=FVal('0.5215'),
            fee_currency=A_EUR,
            link=None,
        ), Trade(  # selling ETC after the fork
            timestamp=1481979135,  # 17/12/2016
            location=Location.KRAKEN,
            base_asset=A_ETC,  # cryptocompare hourly ETC/EUR price: 7.88
            quote_asset=A_EUR,
            trade_type=TradeType.SELL,  # not-taxable -- considered bought with ETH so after year
            amount=FVal(550),
            rate=FVal('1.78'),
            fee=FVal('0.9375'),
            fee_currency=A_EUR,
            link=None,
        ), Trade(  # selling ETH after the fork
            timestamp=1482138141,  # 19/12/2016
            location=Location.KRAKEN,
            base_asset=A_ETH,  # cryptocompare hourly ETH/EUR price: 7.45
            quote_asset=A_EUR,
            trade_type=TradeType.SELL,  # not-taxable -- after 1 year
            amount=FVal(10),
            rate=FVal('7.45'),
            fee=FVal('0.12'),
            fee_currency=A_EUR,
            link=None,
        ),
    ]
    accounting_history_process(accountant, 1436979735, 1495751688, history3)
    no_message_errors(accountant.msg_aggregator)
    # make sure that the intermediate ETH sell before the fork reduced our ETC
    assert accountant.pots[0].cost_basis.get_calculated_asset_amount('ETC') == FVal(850)
    assert accountant.pots[0].cost_basis.get_calculated_asset_amount('ETH') == FVal(1390)

    expected_pnls = PnlTotals({
        AccountingEventType.TRADE: PNL(taxable=FVal('382.4205350'), free=FVal('923.8099920')),
        AccountingEventType.FEE: PNL(taxable=FVal('-1.579'), free=ZERO),
    })
    check_pnls_and_csv(accountant, expected_pnls, google_service)
Beispiel #3
0
def test_selling_crypto_bought_with_crypto(accountant, google_service):
    history = [
        Trade(
            timestamp=1446979735,
            location=Location.EXTERNAL,
            base_asset=A_BTC,
            quote_asset=A_EUR,
            trade_type=TradeType.BUY,
            amount=FVal(82),
            rate=FVal('268.678317859'),
            fee=None,
            fee_currency=None,
            link=None,
        ),
        Trade(
            timestamp=1449809536,  # cryptocompare hourly BTC/EUR price: 386.175
            location=Location.POLONIEX,
            base_asset=A_XMR,  # cryptocompare hourly XMR/EUR price: 0.39665
            quote_asset=A_BTC,
            trade_type=TradeType.BUY,
            amount=FVal(375),
            rate=FVal('0.0010275'),
            fee=FVal('0.9375'),
            fee_currency=A_XMR,
            link=None,
        ),
        Trade(
            timestamp=
            1458070370,  # cryptocompare hourly rate XMR/EUR price: 1.0443027675
            location=Location.KRAKEN,
            base_asset=A_XMR,
            quote_asset=A_EUR,
            trade_type=TradeType.SELL,
            amount=FVal(45),
            rate=FVal('1.0443027675'),
            fee=FVal('0.117484061344'),
            fee_currency=A_XMR,
            link=None,
        ),
    ]
    accounting_history_process(accountant, 1436979735, 1495751688, history)
    no_message_errors(accountant.msg_aggregator)
    # Make sure buying XMR with BTC also creates a BTC sell
    sells = accountant.pots[0].cost_basis.get_events(A_BTC).spends
    assert len(sells) == 1
    assert sells[0].timestamp == 1449809536
    assert sells[0].amount.is_close(FVal('0.3853125'))
    assert sells[0].rate.is_close(FVal('386.03406326'))

    expected_pnls = PnlTotals({
        AccountingEventType.TRADE:
        PNL(taxable=FVal('74.3118704999540625'), free=ZERO),
        AccountingEventType.FEE:
        PNL(taxable=FVal('-0.419658351381311222'), free=ZERO),
    })
    check_pnls_and_csv(accountant, expected_pnls, google_service)
Beispiel #4
0
def test_simple_accounting(accountant, google_service):
    accounting_history_process(accountant, 1436979735, 1495751688, history1)
    no_message_errors(accountant.msg_aggregator)
    expected_pnls = PnlTotals({
        AccountingEventType.TRADE:
        PNL(taxable=FVal('559.6947154'), free=ZERO),
        AccountingEventType.FEE:
        PNL(taxable=FVal('-0.23886813'), free=ZERO),
    })
    check_pnls_and_csv(accountant, expected_pnls, google_service)
def test_nocrypto2crypto(accountant, google_service):
    accounting_history_process(accountant, 1436979735, 1519693374, history5)
    no_message_errors(accountant.msg_aggregator)
    expected_pnls = PnlTotals({
        AccountingEventType.TRADE:
        PNL(taxable=ZERO, free=FVal('264693.433642820')),
        AccountingEventType.FEE:
        PNL(taxable=FVal('-1.1708853227087498964'), free=ZERO),
    })
    check_pnls_and_csv(accountant, expected_pnls, google_service)
def test_no_taxfree_period(accountant, google_service):
    accounting_history_process(accountant, 1436979735, 1519693374, history5)
    no_message_errors(accountant.msg_aggregator)
    expected_pnls = PnlTotals({
        AccountingEventType.TRADE:
        PNL(taxable=FVal('265253.1283582327833875'), free=ZERO),
        AccountingEventType.FEE:
        PNL(taxable=FVal('-0.238868129979988140934107'), free=ZERO),
    })
    check_pnls_and_csv(accountant, expected_pnls, google_service)
Beispiel #7
0
def test_kfee_price_in_accounting(accountant, google_service):
    """
    Test that KFEEs are correctly handled during accounting

    KFEE price is fixed at $0.01
    """
    history = [
        LedgerAction(
            identifier=0,
            timestamp=Timestamp(1539713238),  # 178.615 EUR/ETH
            action_type=LedgerActionType.INCOME,
            location=Location.KRAKEN,
            amount=FVal(1),
            asset=A_ETH,
            rate=None,
            rate_asset=None,
            link=None,
            notes='',
        ), LedgerAction(
            identifier=0,
            timestamp=Timestamp(1539713238),  # 0.8612 USD/EUR. 1 KFEE = $0.01 so 8.612 EUR
            action_type=LedgerActionType.INCOME,
            location=Location.KRAKEN,
            amount=FVal(1000),
            asset=A_KFEE,
            rate=None,
            rate_asset=None,
            link=None,
            notes='',
        ), Trade(
            timestamp=1609537953,
            location=Location.KRAKEN,  # 0.89 USDT/EUR -> PNL: 20 * 0.89 - 0.02*178.615 ->  14.2277
            base_asset=A_ETH,
            quote_asset=A_USDT,
            trade_type=TradeType.SELL,
            amount=FVal('0.02'),
            rate=FVal(1000),
            fee=FVal(30),  # KFEE should not be taken into account
            fee_currency=A_KFEE,
            link=None,
        ),
    ]
    accounting_history_process(
        accountant,
        start_ts=1539713238,
        end_ts=1624395187,
        history_list=history,
    )
    no_message_errors(accountant.msg_aggregator)
    expected_pnls = PnlTotals({
        AccountingEventType.TRADE: PNL(taxable=ZERO, free=FVal('14.2277')),
        AccountingEventType.LEDGER_ACTION: PNL(taxable=FVal('187.227'), free=ZERO),
    })
    check_pnls_and_csv(accountant, expected_pnls, google_service)
Beispiel #8
0
def test_accounting_works_for_empty_history(accountant, google_service):
    history = []
    accounting_history_process(
        accountant=accountant,
        start_ts=1436979735,
        end_ts=1519693374,
        history_list=history,
    )
    no_message_errors(accountant.msg_aggregator)
    expected_pnls = PnlTotals()
    check_pnls_and_csv(accountant, expected_pnls, google_service)
Beispiel #9
0
def test_kraken_staking_events(accountant, google_service):
    """
    Test that staking events from kraken are correctly processed
    """
    history = [
        HistoryBaseEntry(
            event_identifier='XXX',
            sequence_index=0,
            timestamp=1640493374000,
            location=Location.KRAKEN,
            location_label='Kraken 1',
            asset=A_ETH2,
            balance=Balance(
                amount=FVal(0.0000541090),
                usd_value=FVal(0.212353475950),
            ),
            notes=None,
            event_type=HistoryEventType.STAKING,
            event_subtype=HistoryEventSubType.REWARD,
        ),
        HistoryBaseEntry(
            event_identifier='YYY',
            sequence_index=0,
            timestamp=1636638550000,
            location=Location.KRAKEN,
            location_label='Kraken 1',
            asset=A_ETH2,
            balance=Balance(
                amount=FVal(0.0000541090),
                usd_value=FVal(0.212353475950),
            ),
            notes=None,
            event_type=HistoryEventType.STAKING,
            event_subtype=HistoryEventSubType.REWARD,
        )
    ]
    _, events = accounting_history_process(
        accountant,
        start_ts=1636638549,
        end_ts=1640493376,
        history_list=history,
    )
    no_message_errors(accountant.msg_aggregator)
    expected_pnls = PnlTotals({
        AccountingEventType.STAKING:
        PNL(taxable=FVal('0.471505826'), free=ZERO),
    })
    check_pnls_and_csv(accountant, expected_pnls, google_service)
    assert len(events) == 2
    expected_pnls = [FVal('0.25114638241'), FVal('0.22035944359')]
    for idx, event in enumerate(events):
        assert event.pnl.taxable == expected_pnls[idx]
        assert event.type == AccountingEventType.STAKING
Beispiel #10
0
def test_big_taxfree_period(accountant, google_service):
    accounting_history_process(accountant, 1436979735, 1519693374, history5)
    no_message_errors(accountant.msg_aggregator)
    expected_pnls = PnlTotals({
        AccountingEventType.TRADE:
        PNL(taxable=ZERO, free=FVal('265253.1283582327833875')),
        AccountingEventType.FEE:
        PNL(
            taxable=FVal('-1.170885322708749896'),
            free=FVal('0.932017192728761755465893'),
        ),
    })
    check_pnls_and_csv(accountant, expected_pnls, google_service)
Beispiel #11
0
def test_fees_in_received_asset(accountant, google_service):
    """
    Test the sell trade where the fee is nominated in the asset received. We had a bug
    where the PnL report said that there was no documented acquisition.
    """
    history = [
        LedgerAction(
            identifier=0,
            timestamp=Timestamp(1539713238),  # 178.615 EUR/ETH
            action_type=LedgerActionType.INCOME,
            location=Location.BINANCE,
            amount=ONE,
            asset=A_ETH,
            rate=None,
            rate_asset=None,
            link=None,
            notes='',
        ),
        Trade(
            # Sell 0.02 ETH for USDT with rate 1000 USDT/ETH and 0.10 USDT fee
            # So acquired 20 USDT for 0.02 ETH + 0.10 USDT
            # So acquired 20 USDT for 0.02 * 598.26 + 0.10 * 0.89 -> 12.0542 EUR
            # So paid 12.0542/20 -> 0.60271 EUR/USDT
            timestamp=1609537953,  # 0.89 EUR/USDT
            location=Location.BINANCE,
            base_asset=A_ETH,  # 598.26 EUR/ETH
            quote_asset=A_USDT,
            trade_type=TradeType.SELL,
            amount=FVal('0.02'),
            rate=FVal(1000),
            fee=FVal('0.10'),
            fee_currency=A_USDT,
            link=None,
        ),
    ]

    accounting_history_process(
        accountant,
        start_ts=1539713238,
        end_ts=1624395187,
        history_list=history,
    )
    no_message_errors(accountant.msg_aggregator)
    assert accountant.pots[0].cost_basis.get_calculated_asset_amount(A_USDT.identifier).is_close('19.90')  # noqa: E501
    expected_pnls = PnlTotals({
        AccountingEventType.TRADE: PNL(taxable=ZERO, free=FVal('14.2277')),
        AccountingEventType.FEE: PNL(taxable=FVal('-0.060271'), free=ZERO),
        AccountingEventType.LEDGER_ACTION: PNL(taxable=FVal('178.615'), free=ZERO),
    })
    check_pnls_and_csv(accountant, expected_pnls, google_service)
Beispiel #12
0
def test_eth2_staking(accountant, google_service):
    """Test that ethereum 2 staking is accounted for properly"""
    history = [
        ValidatorDailyStats(
            validator_index=1,
            timestamp=1607727600,  # ETH price: 449.68 ETH/EUR
            start_amount=FVal('32'),
            end_amount=FVal('32.05'),
            pnl=FVal('0.05'),  # 0.05 * 449.68 = 22.484
        ),
        ValidatorDailyStats(
            validator_index=1,
            timestamp=1607814000,  # ETH price: 469.82 ETH/EUR
            start_amount=FVal('32.05'),
            end_amount=FVal('32.045'),
            pnl=FVal(
                '-0.005'
            ),  # -0.005 * 469.82 + 0.005 * 469.82 - 0.005*449.68 = -2.2484
        ),
        ValidatorDailyStats(
            validator_index=1,
            timestamp=1607900400,  # ETH price: 486.57 ETH/EUR
            start_amount=FVal('32.045'),
            end_amount=FVal('32.085'),
            pnl=FVal('0.04'),  # 0.04 * 486.57 = 19.4628
        ),
        ValidatorDailyStats(
            validator_index=2,
            timestamp=1607900400,
            start_amount=FVal('32'),
            end_amount=FVal('32.045'),
            pnl=FVal('0.045'),  # 0.045 * 486.57 = 21.89565
        ),
    ]

    accounting_history_process(
        accountant,
        start_ts=1606727600,
        end_ts=1640493376,
        history_list=history,
    )
    no_message_errors(accountant.msg_aggregator)
    expected_pnls = PnlTotals({  # 22.484 - 2.2484 + 19.4628 + 21.89565
        AccountingEventType.STAKING: PNL(taxable=FVal('61.59405'), free=ZERO),
    })
    check_pnls_and_csv(accountant, expected_pnls, google_service)
def test_gas_fees_after_year(accountant, google_service):
    """
    Test that for an expense like gas fees after year the "selling" part is tax free
    PnL, and the expense part is taxable pnl.
    """
    tx_hash = '0x5cc0e6e62753551313412492296d5e57bea0a9d1ce507cc96aa4aa076c5bde7a'
    history = [
        LedgerAction(
            identifier=0,
            timestamp=Timestamp(1539713238),  # 178.615 EUR/ETH
            action_type=LedgerActionType.
            GIFT,  # gift so not counting as income
            location=Location.KRAKEN,
            amount=FVal(1),
            asset=A_ETH,
            rate=None,
            rate_asset=None,
            link=None,
            notes='',
        ),
        HistoryBaseEntry(
            event_identifier=tx_hash,
            sequence_index=0,
            timestamp=1640493374000,  # 4072.51 EUR/ETH
            location=Location.BLOCKCHAIN,
            location_label=make_ethereum_address(),
            asset=A_ETH,
            balance=Balance(amount=FVal('0.01')),
            notes='Burned 0.01 ETH in gas',
            event_type=HistoryEventType.SPEND,
            event_subtype=HistoryEventSubType.FEE,
            counterparty=CPT_GAS,
        )
    ]
    accounting_history_process(
        accountant,
        start_ts=0,
        end_ts=1640493376,
        history_list=history,
    )
    no_message_errors(accountant.msg_aggregator)
    expected_pnls = PnlTotals({
        AccountingEventType.TRANSACTION_EVENT:
        PNL(taxable=FVal('-40.7251'), free=FVal('38.93895')),
    })
    check_pnls_and_csv(accountant, expected_pnls, google_service)
Beispiel #14
0
def test_include_gas_costs(accountant, google_service):
    addr1 = '0x2B888954421b424C5D3D9Ce9bB67c9bD47537d12'
    tx_hash = '0x5cc0e6e62753551313412492296d5e57bea0a9d1ce507cc96aa4aa076c5bde7a'
    history = [
        Trade(
            timestamp=1539388574,
            location=Location.EXTERNAL,
            base_asset=A_ETH,
            quote_asset=A_EUR,
            trade_type=TradeType.BUY,
            amount=FVal(10),
            rate=FVal('168.7'),
            fee=None,
            fee_currency=None,
            link=None,
        ),
        HistoryBaseEntry(
            event_identifier=tx_hash,
            sequence_index=0,
            timestamp=1569924574000,
            location=Location.BLOCKCHAIN,
            location_label=addr1,
            asset=A_ETH,
            balance=Balance(amount=FVal('0.000030921')),
            notes=f'Burned 0.000030921 ETH in gas from {addr1}',
            event_type=HistoryEventType.SPEND,
            event_subtype=HistoryEventSubType.FEE,
            counterparty=CPT_GAS,
        )
    ]
    accounting_history_process(accountant,
                               start_ts=1436979735,
                               end_ts=1619693374,
                               history_list=history)  # noqa: E501
    no_message_errors(accountant.msg_aggregator)
    expected = ZERO
    expected_pnls = PnlTotals()
    if accountant.pots[0].settings.include_gas_costs:
        expected = FVal('-0.0052163727')
        expected_pnls[AccountingEventType.TRANSACTION_EVENT] = PNL(
            taxable=expected, free=ZERO)
    check_pnls_and_csv(accountant, expected_pnls, google_service)
Beispiel #15
0
def test_buy_event_creation(accountant):
    history = [
        Trade(
            timestamp=1476979735,
            location=Location.KRAKEN,
            base_asset=A_BTC,
            quote_asset=A_EUR,
            trade_type=TradeType.BUY,
            amount=FVal(5),
            rate=FVal('578.505'),
            fee=FVal('0.0012'),
            fee_currency=A_BTC,
            link=None,
        ),
        Trade(
            timestamp=1476979735,
            location=Location.KRAKEN,
            base_asset=A_BTC,
            quote_asset=A_EUR,
            trade_type=TradeType.BUY,
            amount=FVal(5),
            rate=FVal('578.505'),
            fee=FVal('0.0012'),
            fee_currency=A_EUR,
            link=None,
        ),
    ]
    accounting_history_process(accountant, 1436979735, 1519693374, history)
    no_message_errors(accountant.msg_aggregator)
    buys = accountant.pots[0].cost_basis.get_events(A_BTC).acquisitions
    assert len(buys) == 2
    assert buys[0].amount == FVal(5)
    assert buys[0].timestamp == 1476979735
    assert buys[0].rate.is_close(
        '578.6438412')  # (578.505 * 5 + 0.0012 * 578.505)/5

    assert buys[1].amount == FVal(5)
    assert buys[1].timestamp == 1476979735
    assert buys[1].rate == FVal('578.50524')  # (578.505 * 5 + 0.0012)/5
Beispiel #16
0
def test_ignored_assets(accountant, google_service):
    history = history1 + [
        Trade(
            timestamp=1476979735,
            location=Location.KRAKEN,
            base_asset=A_DASH,
            quote_asset=A_EUR,
            trade_type=TradeType.BUY,
            amount=FVal(10),
            rate=FVal('9.76775956284'),
            fee=FVal('0.0011'),
            fee_currency=A_DASH,
            link=None,
        ),
        Trade(
            timestamp=1496979735,
            location=Location.KRAKEN,
            base_asset=A_DASH,
            quote_asset=A_EUR,
            trade_type=TradeType.SELL,
            amount=FVal(5),
            rate=FVal('128.09'),
            fee=FVal('0.015'),
            fee_currency=A_EUR,
            link=None,
        ),
    ]
    accounting_history_process(accountant, 1436979735, 1519693374, history)
    no_message_errors(accountant.msg_aggregator)
    expected_pnls = PnlTotals({
        AccountingEventType.TRADE:
        PNL(taxable=FVal('559.6947154127833875'), free=ZERO),
        AccountingEventType.FEE:
        PNL(taxable=FVal('-0.238868129979988140934107'), free=ZERO),
    })
    check_pnls_and_csv(accountant, expected_pnls, google_service)
Beispiel #17
0
def test_buying_selling_btc_before_bchfork(accountant, google_service):
    history = [
        Trade(
            timestamp=1491593374,  # 04/07/2017
            location=Location.EXTERNAL,
            base_asset=A_BTC,
            quote_asset=A_EUR,
            trade_type=TradeType.BUY,
            amount=FVal('6.5'),
            rate=FVal('1128.905'),
            fee=FVal('0.55'),
            fee_currency=A_EUR,
            link=None,
        ), Trade(  # selling BTC prefork should also reduce the BCH equivalent -- taxable
            timestamp=1500595200,  # 21/07/2017
            location=Location.EXTERNAL,
            base_asset=A_BTC,
            quote_asset=A_EUR,
            trade_type=TradeType.SELL,
            amount=FVal('0.5'),
            rate=FVal('2380.835'),
            fee=FVal('0.15'),
            fee_currency=A_EUR,
            link=None,
        ), Trade(   # selling BCH after the fork -- taxable
            timestamp=1512693374,  # 08/12/2017
            location=Location.KRAKEN,
            base_asset=A_BCH,  # cryptocompare hourly BCH/EUR price: 995.935
            quote_asset=A_EUR,
            trade_type=TradeType.SELL,
            amount=FVal('2.1'),
            rate=FVal('995.935'),
            fee=FVal('0.26'),
            fee_currency=A_EUR,
            link=None,
        ), Trade(
            timestamp=1514937600,  # 03/01/2018
            location=Location.KRAKEN,
            base_asset=A_BTC,  # cryptocompare hourly BCH/EUR price: 995.935
            quote_asset=A_EUR,
            trade_type=TradeType.SELL,
            amount=FVal('1.2'),
            rate=FVal('12404.88'),
            fee=FVal('0.52'),
            fee_currency=A_EUR,
            link=None,
        ),
    ]

    accounting_history_process(accountant, 1436979735, 1519693374, history)
    no_message_errors(accountant.msg_aggregator)
    amount_bch = FVal(3.9)
    amount_btc = FVal(4.8)
    buys = accountant.pots[0].cost_basis.get_events(A_BCH).acquisitions
    assert len(buys) == 1
    assert buys[0].remaining_amount == amount_bch
    assert buys[0].timestamp == 1491593374
    assert buys[0].rate.is_close('1128.98961538')
    assert accountant.pots[0].cost_basis.get_calculated_asset_amount(A_BCH) == amount_bch
    assert accountant.pots[0].cost_basis.get_calculated_asset_amount(A_BTC) == amount_btc

    expected_pnls = PnlTotals({
        AccountingEventType.TRADE: PNL(taxable=FVal('13877.57646153846153846153846'), free=ZERO),
        AccountingEventType.FEE: PNL(taxable=FVal('-1.48'), free=ZERO),
    })
    check_pnls_and_csv(accountant, expected_pnls, google_service)
Beispiel #18
0
def test_buying_selling_bch_before_bsvfork(accountant, google_service):
    history = [
        Trade(  # 6.5 BTC 6.5 BCH 6.5 BSV
            timestamp=1491593374,  # 04/07/2017
            location=Location.EXTERNAL,
            base_asset=A_BTC,
            quote_asset=A_EUR,
            trade_type=TradeType.BUY,
            amount=FVal('6.5'),
            rate=FVal('1128.905'),
            fee=FVal('0.55'),
            fee_currency=A_EUR,
            link=None,
        ), Trade(  # selling BTC prefork should also reduce the BCH and BSV equivalent -- taxable
            # 6 BTC 6 BCH 6 BSV
            timestamp=1500595200,  # 21/07/2017
            location=Location.EXTERNAL,
            base_asset=A_BTC,
            quote_asset=A_EUR,
            trade_type=TradeType.SELL,
            amount=FVal('0.5'),
            rate=FVal('2380.835'),
            fee=FVal('0.15'),
            fee_currency=A_EUR,
            link=None,
        ), Trade(  # selling BCH after the fork should also reduce BSV equivalent -- taxable
            # 6 BTC 3.9 BCH 3.9 BSV
            timestamp=1512693374,  # 08/12/2017
            location=Location.KRAKEN,
            base_asset=A_BCH,  # cryptocompare hourly BCH/EUR price: 995.935
            quote_asset=A_EUR,
            trade_type=TradeType.SELL,
            amount=FVal('2.1'),
            rate=FVal('995.935'),
            fee=FVal('0.26'),
            fee_currency=A_EUR,
            link=None,
        ), Trade(  # 4.8 BTC 3.9 BCH 3.9 BSV
            timestamp=1514937600,  # 03/01/2018
            location=Location.KRAKEN,
            base_asset=A_BTC,  # cryptocompare hourly BCH/EUR price: 995.935
            quote_asset=A_EUR,
            trade_type=TradeType.SELL,
            amount=FVal('1.2'),
            rate=FVal('12404.88'),
            fee=FVal('0.52'),
            fee_currency=A_EUR,
            link=None,
        ), Trade(  # buying BCH before the BSV fork should increase BSV equivalent
            # 4.8 BTC 4.9 BCH 4.9 BSV
            timestamp=1524937600,
            location=Location.KRAKEN,
            base_asset=A_BCH,  # cryptocompare hourly BCH/EUR price: 1146.98
            quote_asset=A_EUR,
            trade_type=TradeType.BUY,
            amount=ONE,
            rate=FVal('1146.98'),
            fee=FVal('0.52'),
            fee_currency=A_EUR,
            link=None,
        ), Trade(   # selling BCH before the BSV fork should decrease the BSV equivalent
            # 4.8 BTC 4.6 BCH 4.6 BSV
            timestamp=1525937600,
            location=Location.KRAKEN,
            base_asset=A_BCH,  # cryptocompare hourly BCH/EUR price: 1146.98
            quote_asset=A_EUR,
            trade_type=TradeType.SELL,
            amount=FVal('0.3'),
            rate=FVal('1272.05'),
            fee=FVal('0.52'),
            fee_currency=A_EUR,
            link=None,
        ), Trade(   # selling BCH after the BSV fork should not affect the BSV equivalent
            # 4.8 BTC 4.1 BCH 4.6 BSV
            timestamp=1552304352,
            location=Location.KRAKEN,
            base_asset=A_BCH,  # cryptocompare hourly BCH/EUR price: 114.27
            quote_asset=A_EUR,
            trade_type=TradeType.SELL,
            amount=FVal('0.5'),
            rate=FVal('114.27'),
            fee=FVal('0.52'),
            fee_currency=A_EUR,
            link=None,
        ),
    ]

    accounting_history_process(accountant, 1436979735, 1569693374, history)
    no_message_errors(accountant.msg_aggregator)
    amount_btc = FVal(4.8)
    amount_bch = FVal(4.1)
    amount_bsv = FVal(4.6)
    bch_buys = accountant.pots[0].cost_basis.get_events(A_BCH).acquisitions
    assert len(bch_buys) == 2
    assert sum(x.remaining_amount for x in bch_buys) == amount_bch
    assert bch_buys[0].timestamp == 1491593374
    assert bch_buys[1].timestamp == 1524937600
    bsv_buys = accountant.pots[0].cost_basis.get_events(A_BSV).acquisitions
    assert len(bsv_buys) == 2
    assert sum(x.remaining_amount for x in bsv_buys) == amount_bsv
    assert bsv_buys[0].timestamp == 1491593374
    assert bsv_buys[1].timestamp == 1524937600
    assert accountant.pots[0].cost_basis.get_calculated_asset_amount(A_BCH) == amount_bch
    assert accountant.pots[0].cost_basis.get_calculated_asset_amount(A_BTC) == amount_btc
    assert accountant.pots[0].cost_basis.get_calculated_asset_amount(A_BSV) == amount_bsv
    expected_pnls = PnlTotals({
        AccountingEventType.TRADE: PNL(
            taxable=FVal('13877.57646153846153846153846'),
            free=FVal('-464.4416923076923076923076920'),
        ),
        AccountingEventType.FEE: PNL(taxable=FVal('-3.04'), free=ZERO),
    })
    check_pnls_and_csv(accountant, expected_pnls, google_service)
Beispiel #19
0
def test_sell_fiat_for_crypto(accountant, google_service):
    """
    Test for https://github.com/rotki/rotki/issues/2993
    Make sure that selling fiat for crypto does not give warnings due to
    inability to trace the source of the sold fiat.
    """
    history = [
        Trade(
            timestamp=1446979735,
            location=Location.KRAKEN,
            base_asset=A_EUR,
            quote_asset=A_BTC,
            trade_type=TradeType.SELL,
            amount=FVal(2000),
            rate=FVal('0.002'),
            fee=FVal('0.0012'),
            fee_currency=A_EUR,
            link=None,
        ),
        Trade(
            # Selling 500 CHF for ETH with 0.004 CHF/ETH. + 0.02 EUR
            # That means 2 ETH for 500 CHF + 0.02 EUR -> with 1.001 CHF/EUR ->
            # (500*1.001 + 0.02)/2 -> 250.26 EUR per ETH
            timestamp=1496979735,
            location=Location.KRAKEN,
            base_asset=A_CHF,
            quote_asset=A_ETH,
            trade_type=TradeType.SELL,
            amount=FVal(500),
            rate=FVal('0.004'),
            fee=FVal('0.02'),
            fee_currency=A_EUR,
            link=None,
        ),
        Trade(
            timestamp=1506979735,
            location=Location.KRAKEN,
            base_asset=A_ETH,
            quote_asset=A_EUR,
            trade_type=TradeType.SELL,
            amount=ONE,
            rate=FVal(25000),
            fee=FVal('0.02'),
            fee_currency=A_EUR,
            link=None,
        ),
    ]
    accounting_history_process(
        accountant=accountant,
        start_ts=1436979735,
        end_ts=1519693374,
        history_list=history,
    )
    no_message_errors(accountant.msg_aggregator)
    expected_pnls = PnlTotals({
        AccountingEventType.TRADE:
        PNL(taxable=FVal('24749.74'), free=ZERO),
        AccountingEventType.FEE:
        PNL(taxable=FVal('-0.0412'), free=ZERO),
    })
    check_pnls_and_csv(accountant, expected_pnls, google_service)
Beispiel #20
0
def test_ignored_transactions(accountant, google_service):
    addr1 = '0x2B888954421b424C5D3D9Ce9bB67c9bD47537d12'
    tx_hash = '0x5cc0e6e62753551313412492296d5e57bea0a9d1ce507cc96aa4aa076c5bde7a'
    ignored_tx_hash = '0x1000e6e62753551313412492296d5e57bea0a9d1ce507cc96aa4aa076c5bde11'
    accountant.db.add_to_ignored_action_ids(
        action_type=ActionType.ETHEREUM_TRANSACTION,
        identifiers=[ignored_tx_hash],
    )
    history = [
        Trade(
            timestamp=1539388574,
            location=Location.EXTERNAL,
            base_asset=A_ETH,
            quote_asset=A_EUR,
            trade_type=TradeType.BUY,
            amount=FVal(10),
            rate=FVal('168.7'),
            fee=None,
            fee_currency=None,
            link=None,
        ),
        HistoryBaseEntry(
            identifier=
            'uniqueid1',  # should normally be given by DB at write time
            event_identifier=tx_hash,
            sequence_index=0,
            timestamp=1569924574000,
            location=Location.BLOCKCHAIN,
            location_label=addr1,
            asset=A_ETH,
            balance=Balance(amount=FVal('0.000030921')),
            notes=f'Burned 0.000030921 ETH in gas from {addr1}',
            event_type=HistoryEventType.SPEND,
            event_subtype=HistoryEventSubType.FEE,
            counterparty=CPT_GAS,
        ),
        HistoryBaseEntry(
            identifier=
            'uniqueid2',  # should normally be given by DB at write time
            event_identifier=ignored_tx_hash,
            sequence_index=0,
            timestamp=1569934574000,
            location=Location.BLOCKCHAIN,
            location_label=addr1,
            asset=A_ETH,
            balance=Balance(amount=FVal('0.000040921')),
            notes=f'Burned 0.000040921 ETH in gas from {addr1}',
            event_type=HistoryEventType.SPEND,
            event_subtype=HistoryEventSubType.FEE,
            counterparty=CPT_GAS,
        )
    ]
    _, events = accounting_history_process(accountant,
                                           start_ts=1436979735,
                                           end_ts=1619693374,
                                           history_list=history)  # noqa: E501
    assert len(events) == 3
    no_message_errors(accountant.msg_aggregator)
    expected_pnls = PnlTotals({
        AccountingEventType.TRANSACTION_EVENT:
        PNL(taxable=FVal('-0.0052163727'), free=ZERO),
    })
    check_pnls_and_csv(accountant, expected_pnls, google_service)
Beispiel #21
0
def test_assets_movements_not_accounted_for(accountant, expected,
                                            google_service):
    # asset_movements_list partially copied from
    # rotkehlchen/tests/integration/test_end_to_end_tax_report.py
    history = [
        Trade(
            timestamp=1446979735,
            location=Location.EXTERNAL,
            base_asset=A_BTC,
            quote_asset=A_EUR,
            trade_type=TradeType.BUY,
            amount=FVal(82),
            rate=FVal('268.678317859'),
            fee=None,
            fee_currency=None,
            link=None,
        ),
        Trade(
            timestamp=1446979735,
            location=Location.EXTERNAL,
            base_asset=A_ETH,
            quote_asset=A_EUR,
            trade_type=TradeType.BUY,
            amount=FVal(1450),
            rate=FVal('0.2315893'),
            fee=None,
            fee_currency=None,
            link=None,
        ),
        AssetMovement(
            # before query period -- 8.915 * 0.001 = 8.915e-3
            location=Location.KRAKEN,
            category=AssetMovementCategory.WITHDRAWAL,
            address=None,
            transaction_id=None,
            timestamp=Timestamp(1479510304),  # 18/11/2016,
            asset=A_ETH,  # cryptocompare hourly ETH/EUR: 8.915
            amount=FVal('95'),
            fee_asset=A_ETH,
            fee=Fee(FVal('0.001')),
            link='krakenid1',
        ),
        AssetMovement(  # 0.00029*1964.685 = 0.56975865
            location=Location.POLONIEX,
            address='foo',
            transaction_id='0xfoo',
            category=AssetMovementCategory.WITHDRAWAL,
            timestamp=Timestamp(1495969504),  # 28/05/2017,
            asset=A_BTC,  # cryptocompare hourly BTC/EUR: 1964.685
            amount=FVal('8.5'),
            fee_asset=A_BTC,
            fee=Fee(FVal('0.00029')),
            link='poloniexid1',
        ),
    ]

    accounting_history_process(
        accountant=accountant,
        start_ts=1436979735,
        end_ts=1519693374,
        history_list=history,
    )
    no_message_errors(accountant.msg_aggregator)
    expected_pnls = PnlTotals()
    if expected != ZERO:
        expected_pnls[AccountingEventType.ASSET_MOVEMENT] = PNL(
            taxable=expected, free=ZERO)  # noqa: E501
    check_pnls_and_csv(accountant, expected_pnls, google_service)
Beispiel #22
0
def test_margin_events_affect_gained_lost_amount(accountant, google_service):
    history = [
        Trade(
            timestamp=1476979735,
            location=Location.KRAKEN,
            base_asset=A_BTC,
            quote_asset=A_EUR,
            trade_type=TradeType.BUY,
            amount=FVal(5),
            rate=FVal('578.505'),
            fee=FVal('0.0012'),
            fee_currency=A_BTC,
            link=None,
        ),
        Trade(  # 2519.62 - 0.02 - ((0.0012*578.505)/5 + 578.505)
            timestamp=1476979735,
            location=Location.KRAKEN,
            base_asset=A_BTC,
            quote_asset=A_EUR,
            trade_type=TradeType.SELL,
            amount=FVal(1),
            rate=FVal('2519.62'),
            fee=FVal('0.02'),
            fee_currency=A_EUR,
            link=None,
        ),
    ]
    history += [
        MarginPosition(
            location=Location.POLONIEX,  # BTC/EUR: 810.49
            open_time=1484438400,  # 15/01/2017
            close_time=1484629704,  # 17/01/2017
            profit_loss=FVal('-0.5'),
            pl_currency=A_BTC,
            fee=FVal('0.001'),
            fee_currency=A_BTC,
            link='1',
            notes='margin1',
        ),
        MarginPosition(
            location=Location.POLONIEX,  # BTC/EUR: 979.39
            open_time=1487116800,  # 15/02/2017
            close_time=1487289600,  # 17/02/2017
            profit_loss=FVal('0.25'),
            pl_currency=A_BTC,
            fee=FVal('0.001'),
            fee_currency=A_BTC,
            link='2',
            notes='margin2',
        )
    ]

    accounting_history_process(
        accountant=accountant,
        start_ts=1436979735,
        end_ts=1519693374,
        history_list=history,
    )
    no_message_errors(accountant.msg_aggregator)
    assert accountant.pots[0].cost_basis.get_calculated_asset_amount(
        'BTC').is_close('3.7468')
    expected_pnls = PnlTotals({
        AccountingEventType.TRADE:
        PNL(taxable=FVal('1940.9761588'), free=ZERO),
        AccountingEventType.FEE:
        PNL(taxable=FVal('-1.87166029184'), free=ZERO),
        AccountingEventType.MARGIN_POSITION:
        PNL(taxable=FVal('-44.47442060'), free=ZERO),
    })
    check_pnls_and_csv(accountant, expected_pnls, google_service)