Separating report expiry from futures expiry in Chainlink Data Streams

The futures report schema includes two expiry fields and a price observation interval. Choosing the wrong one can attach a price to a historical instant that it never covered.

Use the price interval for a historical observation

In a verified v14 report, compare the requested instant with validFromTimestamp and observationsTimestamp. The fixture covers seconds 1000 through 1004: 1002 is inside and 1010 is outside. The later expiresAt value does not extend that observation interval. expiryTime refers to the underlying futures contract.

const r = {validFromTimestamp: 1000, observationsTimestamp: 1004,
           expiresAt: 1030, expiryTime: 90000};
for (const t of [1002, 1010])
  console.log(r.validFromTimestamp <= t && t <= r.observationsTimestamp);

Store the identity of the contract being charted

Retain the feed ID, contract month and contract expiry with each price record. When a chart changes to a different contract, the new expiry helps explain a discontinuity even if the ticker looks similar. For a decision about whether the market is open, interpret the feed’s documented marketStatus mapping; a recent timestamp alone does not answer that question.

docs.chain.link Futures report schema v14