aiden-shared-calculations-unified 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @fileoverview Calculates the total number of positions 'bought' vs 'sold' based on daily owner delta.
3
+ * Uses the 'daily_instrument_insights' collection (truth of source).
4
+ * 'Bought' = sum of positive deltas, 'Sold' = sum of absolute negative deltas.
5
+ */
6
+
7
+ class DailyBoughtVsSoldCount {
8
+ constructor() {
9
+ this.totalBought = 0;
10
+ this.totalSold = 0;
11
+ this.processedDay = false; // Flag to run logic only once per day
12
+ }
13
+
14
+ // Needs insights from today and yesterday
15
+ async process(todayPortfolio, yesterdayPortfolio, userId, context, todayInsights, yesterdayInsights) {
16
+ if (this.processedDay) return;
17
+ this.processedDay = true;
18
+
19
+ if (!todayInsights || !todayInsights.insights || !yesterdayInsights || !yesterdayInsights.insights) {
20
+ console.warn('[DailyBoughtVsSoldCount] Missing insights data for today or yesterday.');
21
+ return;
22
+ }
23
+
24
+ const yesterdayTotals = new Map(yesterdayInsights.insights.map(i => [i.instrumentId, i.total]));
25
+
26
+ for (const instrument of todayInsights.insights) {
27
+ const instrumentId = instrument.instrumentId;
28
+ const todayTotal = instrument.total || 0;
29
+ const yesterdayTotal = yesterdayTotals.get(instrumentId) || 0;
30
+
31
+ const delta = todayTotal - yesterdayTotal;
32
+
33
+ if (delta > 0) {
34
+ this.totalBought += delta;
35
+ } else if (delta < 0) {
36
+ this.totalSold += Math.abs(delta); // Sum of absolute decreases
37
+ }
38
+ }
39
+ }
40
+
41
+ getResult() {
42
+ // Return the final aggregated counts
43
+ return {
44
+ total_positions_bought_delta: this.totalBought,
45
+ total_positions_sold_delta: this.totalSold
46
+ };
47
+ }
48
+
49
+ reset() {
50
+ this.totalBought = 0;
51
+ this.totalSold = 0;
52
+ this.processedDay = false;
53
+ }
54
+ }
55
+
56
+ module.exports = DailyBoughtVsSoldCount;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @fileoverview Calculates the total number of 'buy' vs 'sell' (short) positions across all instruments.
3
+ * Uses the 'daily_instrument_insights' collection (truth of source).
4
+ */
5
+
6
+ class DailyBuySellSentimentCount {
7
+ constructor() {
8
+ this.totalBuyPositions = 0;
9
+ this.totalSellPositions = 0;
10
+ this.processedDay = false; // Flag to run logic only once per day
11
+ }
12
+
13
+ // Only needs today's insights
14
+ async process(todayPortfolio, yesterdayPortfolio, userId, context, todayInsights, yesterdayInsights) {
15
+ if (this.processedDay) return;
16
+ this.processedDay = true;
17
+
18
+ if (!todayInsights || !todayInsights.insights) {
19
+ console.warn('[DailyBuySellSentimentCount] Missing insights data for today.');
20
+ return;
21
+ }
22
+
23
+ for (const instrument of todayInsights.insights) {
24
+ const totalOwners = instrument.total || 0;
25
+ if (totalOwners > 0) {
26
+ const buyPercent = (instrument.buy || 0) / 100;
27
+ const sellPercent = (instrument.sell || 0) / 100; // 'sell' means short here
28
+
29
+ this.totalBuyPositions += (buyPercent * totalOwners);
30
+ this.totalSellPositions += (sellPercent * totalOwners);
31
+ }
32
+ }
33
+ }
34
+
35
+ getResult() {
36
+ // Return the final rounded sums
37
+ return {
38
+ total_buy_positions: Math.round(this.totalBuyPositions),
39
+ total_sell_positions: Math.round(this.totalSellPositions) // 'sell' are shorts
40
+ };
41
+ }
42
+
43
+ reset() {
44
+ this.totalBuyPositions = 0;
45
+ this.totalSellPositions = 0;
46
+ this.processedDay = false;
47
+ }
48
+ }
49
+
50
+ module.exports = DailyBuySellSentimentCount;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @fileoverview Calculates the daily change (delta) in total owners for each instrument.
3
+ * Uses the 'daily_instrument_insights' collection (truth of source).
4
+ */
5
+ const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
6
+
7
+ class DailyOwnershipDelta {
8
+ constructor() {
9
+ this.deltaByTicker = {};
10
+ this.mappings = null;
11
+ }
12
+
13
+ // This calculation only needs insights data, not portfolio data.
14
+ // It runs daily but needs 'yesterday's insights to calculate the delta.
15
+ async process(todayPortfolio, yesterdayPortfolio, userId, context, todayInsights, yesterdayInsights) {
16
+ // We only need to run the core logic once per day, not per user.
17
+ // Use a flag to ensure it runs only on the first user processed for the day.
18
+ if (this.processedDay) return;
19
+ this.processedDay = true; // Set flag
20
+
21
+ if (!todayInsights || !todayInsights.insights || !yesterdayInsights || !yesterdayInsights.insights) {
22
+ console.warn('[DailyOwnershipDelta] Missing insights data for today or yesterday.');
23
+ return;
24
+ }
25
+
26
+ if (!this.mappings) {
27
+ this.mappings = await loadInstrumentMappings();
28
+ }
29
+
30
+ const yesterdayTotals = new Map(yesterdayInsights.insights.map(i => [i.instrumentId, i.total]));
31
+
32
+ for (const instrument of todayInsights.insights) {
33
+ const instrumentId = instrument.instrumentId;
34
+ const todayTotal = instrument.total || 0;
35
+ const yesterdayTotal = yesterdayTotals.get(instrumentId) || 0; // Default to 0 if not found yesterday
36
+
37
+ const delta = todayTotal - yesterdayTotal;
38
+ const ticker = this.mappings.instrumentToTicker[instrumentId] || `id_${instrumentId}`;
39
+
40
+ this.deltaByTicker[ticker] = delta;
41
+ }
42
+ }
43
+
44
+ getResult() {
45
+ // Return the final calculated delta for each ticker
46
+ return this.deltaByTicker;
47
+ }
48
+
49
+ reset() {
50
+ this.deltaByTicker = {};
51
+ this.processedDay = false; // Reset the flag for the next day
52
+ this.mappings = null;
53
+ }
54
+ }
55
+
56
+ module.exports = DailyOwnershipDelta;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @fileoverview Calculates the total number of positions held across all instruments for the day.
3
+ * Uses the 'daily_instrument_insights' collection (truth of source).
4
+ */
5
+
6
+ class DailyTotalPositionsHeld {
7
+ constructor() {
8
+ this.totalPositions = 0;
9
+ this.processedDay = false; // Flag to run logic only once per day
10
+ }
11
+
12
+ // Only needs today's insights
13
+ async process(todayPortfolio, yesterdayPortfolio, userId, context, todayInsights, yesterdayInsights) {
14
+ if (this.processedDay) return;
15
+ this.processedDay = true;
16
+
17
+ if (!todayInsights || !todayInsights.insights) {
18
+ console.warn('[DailyTotalPositionsHeld] Missing insights data for today.');
19
+ return;
20
+ }
21
+
22
+ for (const instrument of todayInsights.insights) {
23
+ this.totalPositions += (instrument.total || 0);
24
+ }
25
+ }
26
+
27
+ getResult() {
28
+ // Return the final sum
29
+ return {
30
+ total_positions_held: this.totalPositions
31
+ };
32
+ }
33
+
34
+ reset() {
35
+ this.totalPositions = 0;
36
+ this.processedDay = false;
37
+ }
38
+ }
39
+
40
+ module.exports = DailyTotalPositionsHeld;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aiden-shared-calculations-unified",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Shared calculation modules for the BullTrackers Computation System.",
5
5
  "main": "index.js",
6
6
  "files": [