How we recovered 4.2M trades and identified 1,128 that never existed

Beyond Data Loss: Verifying Every Crypto Trade

Date

Feb 23, 2026

Author

Dmitry Prokofyev, Koinju CTO

Why Your Crypto Prices Might Be Wrong & How to Verify Every Single Trade

In crypto trading, accurate pricing is not a nice-to-have, it is a regulatory requirement. A fund administrator calculating assets value relies on the completeness of the underlying trade data. If the last trade on record isn't actually the last trade that occurred, the pricing is wrong. If a volume-weighted average price is computed from an incomplete set of trades, it is mathematically incorrect.

In our previous post, we showed how our system automatically detects and fills trade sequence gaps using ClickHouse materialized views, recovering over 4.2 million missing trades on Coinbase alone. Today, we go further: what happens when a gap can't be filled / because the trade never existed?

Trades That Don't Exist

This is perhaps the most counter-intuitive and most important aspect of trade data verification.

Exchanges like Coinbase assign sequential integer IDs to every trade, but not every sequence gap represents lost data. If you have trade 32278544 and trade 32278546, trade 32278545 should logically exist between them. Our system detects this gap automatically and attempts to recover the missing trade from Coinbase's REST API:

GET <https://api.exchange.coinbase.com/products/BCH-USD/trades?after=32278546&before=32278544>
GET <https://api.exchange.coinbase.com/products/BCH-USD/trades?after=32278546&before=32278544>
GET <https://api.exchange.coinbase.com/products/BCH-USD/trades?after=32278546&before=32278544>

The response:

[]
[]
[]

Empty. Trade 32278545 was never executed. Coinbase never issued it.

To confirm this isn't an API error, we widen the query range to see the surrounding trades:

GET <https://api.exchange.coinbase.com/products/BCH-USD/trades?after=32278547&before=32278543>
GET <https://api.exchange.coinbase.com/products/BCH-USD/trades?after=32278547&before=32278543>
GET <https://api.exchange.coinbase.com/products/BCH-USD/trades?after=32278547&before=32278543>
[
  {
    "trade_id": 32278546,
    "side": "buy",
    "size": "1.38000000",
    "price": "628.74000000",
    "time": "2021-06-09T17:47:01.823Z"
  },
  {
    "trade_id": 32278544,
    "side": "sell",
    "size": "0.04620000",
    "price": "628.88000000",
    "time": "2021-06-09T17:46:44.259Z"
  }
]
[
  {
    "trade_id": 32278546,
    "side": "buy",
    "size": "1.38000000",
    "price": "628.74000000",
    "time": "2021-06-09T17:47:01.823Z"
  },
  {
    "trade_id": 32278544,
    "side": "sell",
    "size": "0.04620000",
    "price": "628.88000000",
    "time": "2021-06-09T17:46:44.259Z"
  }
]
[
  {
    "trade_id": 32278546,
    "side": "buy",
    "size": "1.38000000",
    "price": "628.74000000",
    "time": "2021-06-09T17:47:01.823Z"
  },
  {
    "trade_id": 32278544,
    "side": "sell",
    "size": "0.04620000",
    "price": "628.88000000",
    "time": "2021-06-09T17:46:44.259Z"
  }
]

The sequence jumps directly from 32278544 to 32278546. Trade 32278545 does not exist on Coinbase. You can call these URLs yourself right now and verify this independently.

Why does this happen? Coinbase assigns trade IDs sequentially at the matching engine level. So if an ID is assigned but no public trade exists, the issue occurs at or after matching. The most likely explanations are administrative or test operations, or the trade being lost in transit between the matching engine and the storage layer during an outage. The exact cause is internal to Coinbase, but the verification is not.

This distinction matters enormously. When a data provider tells you "we have all the trades," you need to know: does that mean they captured everything that exists, or that they never checked what's missing?

At Koinju, every gap is investigated. Every missing trade_id is verified against the exchange. The result is one of two outcomes:

  • Backfilled trade : data was lost during WebSocket collection and recovered via REST API. To date, we have recovered 4,217,760 trades on Coinbase across 2,109 detected gaps : all successfully filled.

  • Confirmed non-existent trade : the exchange API confirms this trade_id was never issued. We have identified 1,128 such phantom trade IDs across 12 Coinbase markets.

We record both outcomes with the exchange API URL used for verification. This is your audit trail.

And this isn't limited to Coinbase. We perform the same sequence-based verification on 7 exchanges that provide sequential trade IDs: Coinbase, Kraken, Binance Futures (COIN-M and USDM), Deribit Futures, Gateio, and OKX. For exchanges without sequential IDs, we use probabilistic candle-based validation, a topic for a future post.


How You Can Verify This Yourself

You don't have to take our word for it. Our completeness API exposes every detected gap and lets you verify each one independently against the exchange.

Query the completeness endpoint:

GET <https://api.koinju.io/v1/completeness/coinbase/BCH-USD>
GET <https://api.koinju.io/v1/completeness/coinbase/BCH-USD>
GET <https://api.koinju.io/v1/completeness/coinbase/BCH-USD>

Response:

{
  "exchange": "coinbase",
  "market": "BCH-USD",
  "total_trades": 74853765,
  "total_nonexistent_trades": 115,
  "gaps": [
    {
      "start_id": 32278544,
      "end_id": 32278546,
      "start_timestamp": "2021-06-09T17:46:44.259Z",
      "end_timestamp": "2021-06-09T17:47:01.823Z",
      "missing_trade_ids": [32278545],
      "resolution": "trade_not_found_on_exchange",
      "verification_url": "<https://api.exchange.coinbase.com/products/BCH-USD/trades?after=32278546&before=32278544>"
    },
    {
      "start_id": 32278549,
      "end_id": 32278551,
      "start_timestamp": "2021-06-09T17:47:08.123Z",
      "end_timestamp": "2021-06-09T17:47:15.456Z",
      "missing_trade_ids": [32278550],
      "resolution": "trade_not_found_on_exchange",
      "verification_url": "<https://api.exchange.coinbase.com/products/BCH-USD/trades?after=32278551&before=32278549>"
    }
  ]
}
{
  "exchange": "coinbase",
  "market": "BCH-USD",
  "total_trades": 74853765,
  "total_nonexistent_trades": 115,
  "gaps": [
    {
      "start_id": 32278544,
      "end_id": 32278546,
      "start_timestamp": "2021-06-09T17:46:44.259Z",
      "end_timestamp": "2021-06-09T17:47:01.823Z",
      "missing_trade_ids": [32278545],
      "resolution": "trade_not_found_on_exchange",
      "verification_url": "<https://api.exchange.coinbase.com/products/BCH-USD/trades?after=32278546&before=32278544>"
    },
    {
      "start_id": 32278549,
      "end_id": 32278551,
      "start_timestamp": "2021-06-09T17:47:08.123Z",
      "end_timestamp": "2021-06-09T17:47:15.456Z",
      "missing_trade_ids": [32278550],
      "resolution": "trade_not_found_on_exchange",
      "verification_url": "<https://api.exchange.coinbase.com/products/BCH-USD/trades?after=32278551&before=32278549>"
    }
  ]
}
{
  "exchange": "coinbase",
  "market": "BCH-USD",
  "total_trades": 74853765,
  "total_nonexistent_trades": 115,
  "gaps": [
    {
      "start_id": 32278544,
      "end_id": 32278546,
      "start_timestamp": "2021-06-09T17:46:44.259Z",
      "end_timestamp": "2021-06-09T17:47:01.823Z",
      "missing_trade_ids": [32278545],
      "resolution": "trade_not_found_on_exchange",
      "verification_url": "<https://api.exchange.coinbase.com/products/BCH-USD/trades?after=32278546&before=32278544>"
    },
    {
      "start_id": 32278549,
      "end_id": 32278551,
      "start_timestamp": "2021-06-09T17:47:08.123Z",
      "end_timestamp": "2021-06-09T17:47:15.456Z",
      "missing_trade_ids": [32278550],
      "resolution": "trade_not_found_on_exchange",
      "verification_url": "<https://api.exchange.coinbase.com/products/BCH-USD/trades?after=32278551&before=32278549>"
    }
  ]
}

The same endpoint also surfaces recovered gaps. Here is BTC-USD, where a brief network interruption on February 1st caused 24 trades to be missed. All 24 were automatically backfilled within 4 minutes:

GET <https://api.koinju.io/v1/completeness/coinbase/BTC-USD>
GET <https://api.koinju.io/v1/completeness/coinbase/BTC-USD>
GET <https://api.koinju.io/v1/completeness/coinbase/BTC-USD>
{
  "exchange": "coinbase",
  "market": "BTC-USD",
  "total_trades": 878261969,
  "total_nonexistent_trades": 0,
  "gaps": [
    {
      "start_id": 948374373,
      "end_id": 948374398,
      "start_timestamp": "2026-02-01T19:45:12.042Z",
      "end_timestamp": "2026-02-01T19:45:17.084Z",
      "missing_trade_ids_count": 24,
      "resolution": "all_trades_recovered",
      "resolved_at": "2026-02-01T20:03:37Z"
    }
  ]
}
{
  "exchange": "coinbase",
  "market": "BTC-USD",
  "total_trades": 878261969,
  "total_nonexistent_trades": 0,
  "gaps": [
    {
      "start_id": 948374373,
      "end_id": 948374398,
      "start_timestamp": "2026-02-01T19:45:12.042Z",
      "end_timestamp": "2026-02-01T19:45:17.084Z",
      "missing_trade_ids_count": 24,
      "resolution": "all_trades_recovered",
      "resolved_at": "2026-02-01T20:03:37Z"
    }
  ]
}
{
  "exchange": "coinbase",
  "market": "BTC-USD",
  "total_trades": 878261969,
  "total_nonexistent_trades": 0,
  "gaps": [
    {
      "start_id": 948374373,
      "end_id": 948374398,
      "start_timestamp": "2026-02-01T19:45:12.042Z",
      "end_timestamp": "2026-02-01T19:45:17.084Z",
      "missing_trade_ids_count": 24,
      "resolution": "all_trades_recovered",
      "resolved_at": "2026-02-01T20:03:37Z"
    }
  ]
}

878 million trades. Every gap detected was successfully backfilled.

Every gap includes a verification_url pointing directly to the exchange's public API. Click it.


What This Means for Pricing Methodologies

Missing trades don't just create data quality issues. They produce incorrect prices. The impact depends on which pricing methodology your fund uses:

Pricing Method

Description

Impact of Missing Trades

Last-Trade Price

FMV based on the most recent trade

If the missing trade was the last one executed, the reference price is stale or wrong

VWAP

Volume-Weighted Average Price

Missing trades alter both the volume and the weighted price / the result is mathematically incorrect

TWAP

Time-Weighted Average Price

Missing trades create incorrect time intervals between observations, skewing the average

Best Execution

Comparing execution against market

Incomplete data makes it impossible to reconstruct the true market state at execution time

Koinju's completeness API provides this infrastructure: every trade accounted for, every gap explained, every resolution independently verifiable against the exchange's own API.

Want to see completeness analysis for your specific markets or discuss integration options?

Talk to our team!

Check the API documentation

DISCLAIMER:
Koinju is a product of Maarkt, a registered Benchmark administrator ( n° BMR2021000001 ) under the Art. 34 of the "Benchmark" regulation ((EU) 2016/1011), authorized and regulated by the French Financial Markets Authority 🇫🇷. All information and data available on our Website and related Services is provided for information purposes only, and should not be construed as any kind of advice. The Website, its Content and related Services are provided "as is" and "as available", and do not commit the Company to respond to the User's specific need and/or situation. MAARKT cannot be held responsible for any missing or incorrect information. Data provided on the Website is based on unrelated third-parties' data. MAARKT cannot guarantee neither the accuracy, reliability and completeness of these third-parties' data nor related manipulation risks. You accept all risks associated with the use of the Content on the Website provided by our Services and are therefore fully responsible for such use and the consequences that may result.
DISCLAIMER:
Koinju is a product of Maarkt, a registered Benchmark administrator ( n° BMR2021000001 ) under the Art. 34 of the "Benchmark" regulation ((EU) 2016/1011), authorized and regulated by the French Financial Markets Authority 🇫🇷. All information and data available on our Website and related Services is provided for information purposes only, and should not be construed as any kind of advice. The Website, its Content and related Services are provided "as is" and "as available", and do not commit the Company to respond to the User's specific need and/or situation. MAARKT cannot be held responsible for any missing or incorrect information. Data provided on the Website is based on unrelated third-parties' data. MAARKT cannot guarantee neither the accuracy, reliability and completeness of these third-parties' data nor related manipulation risks. You accept all risks associated with the use of the Content on the Website provided by our Services and are therefore fully responsible for such use and the consequences that may result.
DISCLAIMER:
Koinju is a product of Maarkt, a registered Benchmark administrator ( n° BMR2021000001 ) under the Art. 34 of the "Benchmark" regulation ((EU) 2016/1011), authorized and regulated by the French Financial Markets Authority 🇫🇷. All information and data available on our Website and related Services is provided for information purposes only, and should not be construed as any kind of advice. The Website, its Content and related Services are provided "as is" and "as available", and do not commit the Company to respond to the User's specific need and/or situation. MAARKT cannot be held responsible for any missing or incorrect information. Data provided on the Website is based on unrelated third-parties' data. MAARKT cannot guarantee neither the accuracy, reliability and completeness of these third-parties' data nor related manipulation risks. You accept all risks associated with the use of the Content on the Website provided by our Services and are therefore fully responsible for such use and the consequences that may result.