Skip to content

Commit

Permalink
Add index change calculation to streams
Browse files Browse the repository at this point in the history
This commit introduces functionality to calculate year-over-year index changes for streams.
  • Loading branch information
outerlook committed Oct 29, 2024
1 parent 9677a8a commit b0179ae
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 11 deletions.
29 changes: 18 additions & 11 deletions docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const client = new NodeTSNClient({
endpoint: "https://staging.tsn.truflation.com",
signerInfo: {
address: wallet.address,
signer: wallet, // Must implement signMessage (e.g. ethers Wallet)
signer: wallet, // Must implement signMessage (e.g. ethers Wallet)
},
chainId: "tsn-1",
});
Expand All @@ -32,21 +32,29 @@ const type = await stream.getType(); // Returns StreamType
const records = await stream.getRecord({
dateFrom: "2024-01-01",
dateTo: "2024-01-31",
frozenAt: 12345 // Optional block height
frozenAt: 12345, // Optional block height
});

// Get stream index
const index = await stream.getIndex({
dateFrom: "2024-01-01",
dateFrom: "2024-01-01",
dateTo: "2024-01-31",
baseDate: "2023-12-31"
baseDate: "2023-12-31",
});

// Get first record
const firstRecord = await stream.getFirstRecord({
afterDate: "2024-01-01",
frozenAt: 12345
frozenAt: 12345,
}); // Returns StreamRecord | null

// Calculate year-over-year changes
const changes = await stream.getIndexChange({
dateFrom: "2024-01-01",
dateTo: "2024-12-31",
daysInterval: 365,
baseDate: "2024-01-01",
}); // Returns StreamRecord[]
```

### Primitive Stream Operations
Expand All @@ -56,7 +64,7 @@ const primitiveStream = client.loadPrimitiveStream(streamLocator);

// Insert data
await primitiveStream.insertRecords([
{ dateValue: "2024-01-01", value: "100.5" }
{ dateValue: "2024-01-01", value: "100.5" },
]);
```

Expand All @@ -70,15 +78,15 @@ await composedStream.setTaxonomy({
taxonomyItems: [
{
childStream: childStreamLocator,
weight: "1.5"
}
weight: "1.5",
},
],
startDate: "2024-01-01" // Optional
startDate: "2024-01-01", // Optional
});

// Get taxonomy
const taxonomy = await composedStream.describeTaxonomies({
latestVersion: true
latestVersion: true,
});
```

Expand Down Expand Up @@ -119,5 +127,4 @@ const allStreams = await client.getAllStreams();
const ownerStreams = await client.getAllStreams(ownerAddress);
```


For comprehensive examples of these APIs in use, please check our [integration tests](../tests/integration).
33 changes: 33 additions & 0 deletions src/contracts-api/stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ export interface StreamRecord {
value: string;
}

export interface GetIndexChangeInput extends GetRecordInput {
daysInterval: number;
}

export class Stream {
protected kwilClient: WebKwil | NodeKwil;
protected kwilSigner: KwilSigner;
Expand Down Expand Up @@ -482,4 +486,33 @@ export class Stream {
};
});
}

/**
* Returns the index change of the stream within the given date range
*/
public async getIndexChange(
input: GetIndexChangeInput,
): Promise<StreamRecord[]> {
const result = await this.call<{ date_value: string; value: string }[]>(
"get_index_change",
[
ActionInput.fromObject({
$date_from: input.dateFrom,
$date_to: input.dateTo,
$frozen_at: input.frozenAt,
$base_date: input.baseDate,
$days_interval: input.daysInterval,
}),
],
);

return result
.mapRight((result) =>
result.map((row) => ({
dateValue: row.date_value,
value: row.value,
})),
)
.throw();
}
}
64 changes: 64 additions & 0 deletions tests/integration/primitiveStream.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,69 @@ describe.sequential(
}
},
);

testWithDefaultWallet(
"should calculate index changes correctly",
async ({ defaultClient }) => {
// Generate a unique stream ID
const streamId = await StreamId.generate("test-primitive-stream");

try {
// Deploy and initialize stream
await defaultClient.deployStream(streamId, "primitive", true);
const primitiveStream = defaultClient.loadPrimitiveStream({
streamId,
dataProvider: defaultClient.address(),
});
const initTx = await primitiveStream.initializeStream();
await defaultClient.waitForTx(initTx.data!.tx_hash!);

// Insert historical records (2022)
const historicalRecords = [
{ dateValue: "2022-01-01", value: "100" },
{ dateValue: "2022-06-01", value: "120" },
{ dateValue: "2022-12-01", value: "150" },
];
const historicalTx =
await primitiveStream.insertRecords(historicalRecords);
await defaultClient.waitForTx(historicalTx.data!.tx_hash!);

// Insert current records (2023)
const currentRecords = [
{ dateValue: "2023-01-01", value: "200" },
{ dateValue: "2023-06-01", value: "180" },
{ dateValue: "2023-12-01", value: "240" },
];
const currentTx = await primitiveStream.insertRecords(currentRecords);
await defaultClient.waitForTx(currentTx.data!.tx_hash!);

// Calculate year-over-year changes
const changes = await primitiveStream.getIndexChange({
dateFrom: "2023-01-01",
dateTo: "2023-12-31",
daysInterval: 365,
baseDate: "2022-01-01",
});

// Verify the changes
expect(changes.length).toBe(3);

// 2023-01-01 vs 2022-01-01: ((200 - 100) / 100) * 100 = 100%
expect(changes[0].dateValue).toBe("2023-01-01");
expect(parseFloat(changes[0].value)).toBeCloseTo(100);

// 2023-06-01 vs 2022-06-01: ((180 - 120) / 120) * 100 = 50%
expect(changes[1].dateValue).toBe("2023-06-01");
expect(parseFloat(changes[1].value)).toBeCloseTo(50);

// 2023-12-01 vs 2022-12-01: ((240 - 150) / 150) * 100 = 60%
expect(changes[2].dateValue).toBe("2023-12-01");
expect(parseFloat(changes[2].value)).toBeCloseTo(60);
} finally {
// Cleanup
await defaultClient.destroyStream(streamId, true);
}
},
);
},
);

0 comments on commit b0179ae

Please sign in to comment.