aiden-shared-calculations-unified 1.0.39 → 1.0.40

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.
@@ -1,5 +1,12 @@
1
1
  /**
2
2
  * @fileoverview Tracks the investment flow of "smart money".
3
+ *
4
+ * --- FIX ---
5
+ * The core logic (identifySmartMoney) has been moved from process() to
6
+ * getResult(). This is critical to prevent a race condition where
7
+ * this calculation tries to *read* the profitability shards
8
+ * before user_profitability_tracker has *written* them.
9
+ * --- END FIX ---
3
10
  */
4
11
 
5
12
  const { Firestore } = require('@google-cloud/firestore');
@@ -8,20 +15,20 @@ const firestore = new Firestore();
8
15
  const { getInstrumentSectorMap } = require('../../../utils/sector_mapping_provider');
9
16
 
10
17
  class SmartMoneyFlow {
11
- // ... (rest of the code is unchanged) ...
12
18
  constructor() {
13
19
  this.smartMoneyUsers = new Set();
14
- this.sectorFlow = {};
15
20
  this.sectorMap = null; // Cache for the sector map
21
+
22
+ // --- NEW ---
23
+ // We now store the portfolio data during process()
24
+ this.todayPortfolios = {};
25
+ this.yesterdayPortfolios = {};
26
+ // --- END NEW ---
16
27
  }
17
28
 
18
29
  async process(todayPortfolio, yesterdayPortfolio, userId) {
19
- // Load smart money users only if the set is empty
20
- if (this.smartMoneyUsers.size === 0) {
21
- await this.identifySmartMoney();
22
- // Log after identification attempt
23
- console.log(`Identified ${this.smartMoneyUsers.size} smart money users.`);
24
- }
30
+ // --- FIX: process() NO LONGER calls identifySmartMoney ---
31
+ // It just caches the portfolios we need for getResult()
25
32
 
26
33
  // Load sector map if not already loaded
27
34
  if (!this.sectorMap) {
@@ -29,8 +36,6 @@ class SmartMoneyFlow {
29
36
  this.sectorMap = await getInstrumentSectorMap();
30
37
  if (!this.sectorMap || Object.keys(this.sectorMap).length === 0) {
31
38
  console.warn('Sector map loaded but is empty.');
32
- } else {
33
- // console.log('Sector map loaded successfully.'); // Optional: remove if too verbose
34
39
  }
35
40
  } catch (error) {
36
41
  console.error('Failed to load sector map:', error);
@@ -38,36 +43,11 @@ class SmartMoneyFlow {
38
43
  }
39
44
  }
40
45
 
41
- // Check if the current user is considered "smart money"
42
- if (this.smartMoneyUsers.has(userId) && todayPortfolio && yesterdayPortfolio) {
43
- // Ensure sectorMap is available before proceeding
44
- if (!this.sectorMap) {
45
- console.warn(`Skipping user ${userId}: Sector map not available.`);
46
- return;
47
- }
48
- const todaySectorInvestment = this.calculateSectorInvestment(todayPortfolio);
49
- const yesterdaySectorInvestment = this.calculateSectorInvestment(yesterdayPortfolio);
50
-
51
- // Calculate change in investment per sector
52
- const allSectors = new Set([...Object.keys(todaySectorInvestment), ...Object.keys(yesterdaySectorInvestment)]);
53
- for (const sector of allSectors) {
54
- const todayAmount = todaySectorInvestment[sector] || 0;
55
- const yesterdayAmount = yesterdaySectorInvestment[sector] || 0;
56
- const change = todayAmount - yesterdayAmount;
57
-
58
- // Only record if there is a change
59
- if (change !== 0) {
60
- if (!this.sectorFlow[sector]) {
61
- this.sectorFlow[sector] = 0;
62
- }
63
- this.sectorFlow[sector] += change;
64
- }
65
- }
66
- } else {
67
- // Optional: Log why processing is skipped for a user
68
- // if (!this.smartMoneyUsers.has(userId)) console.log(`User ${userId} is not smart money.`);
69
- // if (!todayPortfolio) console.log(`User ${userId}: Missing today's portfolio.`);
70
- // if (!yesterdayPortfolio) console.log(`User ${userId}: Missing yesterday's portfolio.`);
46
+ if (todayPortfolio) {
47
+ this.todayPortfolios[userId] = todayPortfolio;
48
+ }
49
+ if (yesterdayPortfolio) {
50
+ this.yesterdayPortfolios[userId] = yesterdayPortfolio;
71
51
  }
72
52
  }
73
53
 
@@ -149,18 +129,57 @@ class SmartMoneyFlow {
149
129
  }
150
130
 
151
131
 
152
- getResult() {
132
+ async getResult() {
133
+ // --- FIX: MOVED FROM process() ---
134
+ // 1. Identify smart money *now*, after Pass 1's getResult() has run
135
+ await this.identifySmartMoney();
136
+
137
+ // 2. Ensure sector map is loaded (it should be from process())
138
+ if (!this.sectorMap) {
139
+ console.error('SmartMoneyFlow: Sector map not loaded, cannot get result.');
140
+ return { smart_money_flow: {} };
141
+ }
142
+ // --- END FIX ---
143
+
144
+ const sectorFlow = {};
145
+
146
+ // 3. Loop through the cached portfolios
147
+ for (const userId of this.smartMoneyUsers) {
148
+ const todayPortfolio = this.todayPortfolios[userId];
149
+ const yesterdayPortfolio = this.yesterdayPortfolios[userId];
150
+
151
+ if (todayPortfolio && yesterdayPortfolio) {
152
+ const todaySectorInvestment = this.calculateSectorInvestment(todayPortfolio);
153
+ const yesterdaySectorInvestment = this.calculateSectorInvestment(yesterdayPortfolio);
154
+
155
+ // Calculate change in investment per sector
156
+ const allSectors = new Set([...Object.keys(todaySectorInvestment), ...Object.keys(yesterdaySectorInvestment)]);
157
+ for (const sector of allSectors) {
158
+ const todayAmount = todaySectorInvestment[sector] || 0;
159
+ const yesterdayAmount = yesterdaySectorInvestment[sector] || 0;
160
+ const change = todayAmount - yesterdayAmount;
161
+
162
+ // Only record if there is a change
163
+ if (change !== 0) {
164
+ if (!sectorFlow[sector]) {
165
+ sectorFlow[sector] = 0;
166
+ }
167
+ sectorFlow[sector] += change;
168
+ }
169
+ }
170
+ }
171
+ }
172
+
153
173
  // Return only sectors with non-zero flow if desired, or the full object
154
174
  const filteredFlow = {};
155
- for (const sector in this.sectorFlow) {
156
- if (this.sectorFlow[sector] !== 0) {
157
- filteredFlow[sector] = this.sectorFlow[sector];
175
+ for (const sector in sectorFlow) {
176
+ if (sectorFlow[sector] !== 0) {
177
+ filteredFlow[sector] = sectorFlow[sector];
158
178
  }
159
179
  }
160
- // console.log("Final Smart Money Flow:", filteredFlow); // Optional: Log final result
180
+ console.log("Final Smart Money Flow:", filteredFlow);
161
181
  return { smart_money_flow: filteredFlow };
162
- // Or return the full object: return { smart_money_flow: this.sectorFlow };
163
182
  }
164
183
  }
165
184
 
166
- module.exports = SmartMoneyFlow;
185
+ module.exports = SmartMoneyFlow;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aiden-shared-calculations-unified",
3
- "version": "1.0.39",
3
+ "version": "1.0.40",
4
4
  "description": "Shared calculation modules for the BullTrackers Computation System.",
5
5
  "main": "index.js",
6
6
  "files": [