A crypto tax calculation is only as reliable as the transaction data behind it.
That sounds obvious, but it creates an important engineering problem:
What should the system do when the imported data is incomplete or inconsistent?
At The Crypto Support, we are building tools for crypto tax reporting in Romania. Before applying any Romania-specific calculation logic, imported exchange data first needs to pass a series of validation checks.
Otherwise, the software risks producing a very precise answer from bad input.
Parsing successfully does not mean the data is correct
Imagine that an exchange CSV contains this:
2026-03-12,BUY,BTC,0.02
2026-04-01,SELL,BTC,0.03
The parser may successfully understand both rows.
But there is an obvious question:
Where did the extra 0.01 BTC come from?
Maybe:
- another purchase is missing
- the user transferred BTC from another exchange
- an earlier wallet deposit was not imported
- the CSV export covers only part of the year
From a syntax perspective, the data is valid.
From a financial perspective, it may be incomplete.
That distinction matters.
Validation needs multiple layers
A useful import pipeline can validate data at several levels.
1. Structural validation
First, check that the file itself can be interpreted.
Examples:
- required columns exist
- timestamps are valid
- amounts can be parsed
- currencies are recognized
- transaction types are supported
A malformed row should not silently become a zero-value transaction.
It should be reported.
2. Duplicate detection
Users may accidentally import the same CSV twice.
Exchanges may also include overlapping periods across multiple exports.
If duplicate transactions are counted twice, every downstream calculation can be affected.
A transaction fingerprint could use fields such as:
provider
source_transaction_id
timestamp
asset
amount
transaction_type
If the exchange provides a stable transaction ID, that is even better.
The important point is to detect duplicates before calculation.
3. Balance consistency
Suppose the normalized history says:
+0.50 ETH
-0.20 ETH
-0.40 ETH
The calculated balance becomes negative.
That does not necessarily mean the user did something impossible.
It usually means some history is missing.
Maybe ETH was deposited from another wallet.
Maybe an earlier purchase was excluded from the export.
The system should surface that inconsistency rather than hiding it.
4. Swap reconciliation
Crypto swaps can be particularly tricky.
Imagine an exchange represents:
BTC → ETH
as two rows:
SELL BTC
BUY ETH
Another provider might export the same operation as one CONVERT event.
After normalization, the software needs to know that these records belong to the same economic operation.
Otherwise, fees and valuations may become disconnected.
A reconciliation step can try to match records using:
- timestamps
- source transaction IDs
- asset pairs
- corresponding amounts
- provider metadata
5. Missing valuation data
For Romanian reporting, the system may eventually need transaction values expressed consistently in RON.
That means a transaction should not quietly continue through the pipeline if its required valuation information cannot be determined.
A useful state might be:
status: NEEDS_REVIEW
reason: MISSING_FIAT_VALUATION
instead of:
value_ron: 0
Zero is a valid financial value.
"Unknown" is something completely different.
Software should not confuse them.
Fail loudly, not silently
In many applications, developers try to recover automatically from malformed input.
Financial software needs to be more careful.
If a transaction cannot be interpreted confidently, the best behavior may be to stop that transaction from entering the calculation.
The workflow becomes:
Import
↓
Parse
↓
Normalize
↓
Validate
↓
Review problems
↓
Calculate
This adds friction.
But it is useful friction.
A user should know that five transactions need attention before trusting a final tax report.
Make validation explainable
Error messages also matter.
This:
ERROR_CODE_3012
is not very helpful.
Something like this is better:
This BTC disposal could not be matched with sufficient acquisition history. Check whether transactions from another exchange or wallet are missing.
The system should help the user fix the data, not simply reject it.
Reliable calculations start before the calculator
For a crypto tax platform built for Romania, the final Romanian tax logic is only one part of the system.
Before we can calculate anything reliably, we need confidence that the transaction history is complete enough to work with.
That is why validation belongs between normalization and calculation.
The basic architecture becomes:
Exchange data
↓
Normalization
↓
Validation
↓
User review
↓
Romanian tax logic
↓
Report
At The Crypto Support, this is one of the principles behind making crypto tax calculations easier to understand and verify for users in Romania.
Want to dive deeper into why this matters? Check out the guide below:
Top comments (0)