aiden-shared-calculations-unified 1.0.79 → 1.0.81

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.
@@ -7,68 +7,46 @@
7
7
  * This provides a crowd-wide P&L status for each instrument.
8
8
  *
9
9
  * --- FIX ---
10
- * This version is modified to only store user *IDs* in the arrays,
11
- * not the full user P&L objects, to prevent exceeding the
12
- * 1 MiB Firestore document size limit.
10
+ * This version is modified to *only* store counts. The
11
+ * `users_in_profit` and `users_in_loss` arrays are removed
12
+ * to prevent exceeding the 1 MiB Firestore document size limit.
13
13
  */
14
14
  const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
15
15
 
16
16
  class AssetPnlStatus {
17
17
  constructor() {
18
- // We will store { [instrumentId]: { in_profit: Map(), in_loss: Map() } }
19
- // The maps will store <userId, pnl> but only the keys (userIds) will be saved.
18
+ // We will store { [instrumentId]: { in_profit_count: 0, in_loss_count: 0 } }
19
+ // We no longer store the user maps, just the counts.
20
20
  this.assets = new Map();
21
21
  this.mappings = null;
22
+ this.seenUsers = new Map(); // Map<instrumentId, Set<userId>>
22
23
  }
23
24
 
24
25
  /**
25
26
  * Defines the output schema for this calculation.
26
27
  * --- MODIFIED ---
27
- * The `users_in_profit` and `users_in_loss` schemas are changed
28
- * from `items: userSchema` to `items: { "type": "string" }`.
28
+ * Removed the `users_in_profit` and `users_in_loss` arrays.
29
29
  * @returns {object} JSON Schema object
30
30
  */
31
31
  static getSchema() {
32
- /*
33
- // The userSchema is no longer needed in the output
34
- const userSchema = {
35
- "type": "object",
36
- "properties": {
37
- "userId": { "type": "string" },
38
- "pnl": { "type": "number" }
39
- },
40
- "required": ["userId", "pnl"]
41
- };
42
- */
43
-
44
32
  const tickerSchema = {
45
33
  "type": "object",
46
34
  "description": "P&L status for a specific asset.",
47
35
  "properties": {
48
36
  "in_profit_count": {
49
37
  "type": "number",
50
- "description": "Count of users currently in profit on this asset."
38
+ "description": "Count of unique users currently in profit on this asset."
51
39
  },
52
40
  "in_loss_count": {
53
41
  "type": "number",
54
- "description": "Count of users currently in loss on this asset."
42
+ "description": "Count of unique users currently in loss on this asset."
55
43
  },
56
44
  "profit_ratio": {
57
45
  "type": "number",
58
46
  "description": "Percentage of users in profit (In Profit / Total)."
59
- },
60
- "users_in_profit": {
61
- "type": "array",
62
- "description": "List of user IDs in profit.",
63
- "items": { "type": "string" } // <-- MODIFIED
64
- },
65
- "users_in_loss": {
66
- "type": "array",
67
- "description": "List of user IDs in loss.",
68
- "items": { "type": "string" } // <-- MODIFIED
69
47
  }
70
48
  },
71
- "required": ["in_profit_count", "in_loss_count", "profit_ratio", "users_in_profit", "users_in_loss"]
49
+ "required": ["in_profit_count", "in_loss_count", "profit_ratio"]
72
50
  };
73
51
 
74
52
  return {
@@ -104,8 +82,8 @@ class AssetPnlStatus {
104
82
  _initAsset(instrumentId) {
105
83
  if (!this.assets.has(instrumentId)) {
106
84
  this.assets.set(instrumentId, {
107
- in_profit: new Map(), // Map<userId, pnl>
108
- in_loss: new Map() // Map<userId, pnl>
85
+ in_profit: new Set(),
86
+ in_loss: new Set()
109
87
  });
110
88
  }
111
89
  }
@@ -124,18 +102,20 @@ class AssetPnlStatus {
124
102
  const asset = this.assets.get(instrumentId);
125
103
  const pnl = pos.NetProfit || 0;
126
104
 
105
+ // Only count one user once per asset
127
106
  if (pnl > 0) {
128
- asset.in_profit.set(userId, pnl);
107
+ asset.in_profit.add(userId);
108
+ asset.in_loss.delete(userId); // Ensure user isn't in both
129
109
  } else if (pnl < 0) {
130
- asset.in_loss.set(userId, pnl);
110
+ asset.in_loss.add(userId);
111
+ asset.in_profit.delete(userId); // Ensure user isn't in both
131
112
  }
132
113
  }
133
114
  }
134
115
 
135
116
  /**
136
117
  * --- MODIFIED ---
137
- * This now saves an array of strings (user IDs) instead of
138
- * an array of {userId, pnl} objects to save space.
118
+ * This now saves only counts.
139
119
  */
140
120
  async getResult() {
141
121
  if (!this.mappings) {
@@ -154,10 +134,8 @@ class AssetPnlStatus {
154
134
  result[ticker] = {
155
135
  in_profit_count: profitCount,
156
136
  in_loss_count: lossCount,
157
- profit_ratio: (profitCount / total) * 100,
158
- // Convert Maps to arrays of *keys* (user IDs)
159
- users_in_profit: Array.from(data.in_profit.keys()), // <-- MODIFIED
160
- users_in_loss: Array.from(data.in_loss.keys()) // <-- MODIFIED
137
+ profit_ratio: (profitCount / total) * 100
138
+ // Removed the user arrays
161
139
  };
162
140
  }
163
141
  }
@@ -167,6 +145,7 @@ class AssetPnlStatus {
167
145
  reset() {
168
146
  this.assets.clear();
169
147
  this.mappings = null;
148
+ this.seenUsers.clear();
170
149
  }
171
150
  }
172
151
 
@@ -4,6 +4,10 @@
4
4
  * This metric answers: "What is the aggregated social media
5
5
  * sentiment (bullish, bearish, neutral) globally and
6
6
  * for each ticker?"
7
+ *
8
+ * --- MODIFIED ---
9
+ * Changed `process` method to read from `dependencies.rootData.todaySocialPostInsights`
10
+ * instead of a non-existent `calculationUtils.loadSocialData`.
7
11
  */
8
12
  class SocialSentimentAggregation {
9
13
  constructor() {
@@ -90,19 +94,21 @@ class SocialSentimentAggregation {
90
94
 
91
95
  /**
92
96
  * @param {string} dateStr - Today's date.
93
- * @param {object} dependencies - db, logger.
97
+ * @param {object} dependencies - db, logger, calculationUtils, AND rootData.
94
98
  * @param {object} config - Computation config.
95
99
  * @param {object} fetchedDependencies - (UNUSED) In-memory results.
96
100
  */
97
101
  async process(dateStr, dependencies, config, fetchedDependencies) {
98
- const { calculationUtils } = dependencies;
99
- // This helper should exist on calculationUtils, loaded by the runner
100
- const todaySocialPosts = await calculationUtils.loadSocialData(dateStr);
102
+ // --- MODIFIED ---
103
+ // 'meta' calcs get rootData injected into the dependencies object.
104
+ const todaySocialPosts = dependencies.rootData?.todaySocialPostInsights || {};
105
+ // --- END MODIFIED ---
101
106
 
102
- for (const post of todaySocialPosts) {
107
+ for (const post of Object.values(todaySocialPosts)) {
103
108
  // This logic assumes 'sentiment' is a simple string,
104
109
  // not the object from gemini. This is correct for this calc.
105
- const sentiment = post.sentiment || 'neutral'; // 'bullish', 'bearish', 'neutral'
110
+ // --- MODIFIED: Read from structured sentiment object ---
111
+ const sentiment = post.sentiment?.overallSentiment?.toLowerCase() || 'neutral';
106
112
 
107
113
  // 1. Aggregate global sentiment
108
114
  if (sentiment === 'bullish') {
@@ -14,7 +14,8 @@
14
14
  * from the new dependency.
15
15
  * --------------------------
16
16
  */
17
- const { loadInstrumentMappings } = require('../../../utils/sector_mapping_provider');
17
+ const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
18
+
18
19
 
19
20
  class CohortCapitalFlow {
20
21
  constructor() {
@@ -8,7 +8,8 @@
8
8
  * It then buckets these users into our final, named sub-cohorts
9
9
  * (e.g., "Smart Investors", "FOMO Chasers").
10
10
  */
11
- const { loadInstrumentMappings } = require('../../../utils/sector_mapping_provider');
11
+ const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
12
+
12
13
 
13
14
  class CohortDefiner {
14
15
  constructor() {
@@ -5,11 +5,10 @@
5
5
  * of *unique users* into the 'Winner' (in-profit) and 'Loser'
6
6
  * (in-loss) cohorts?"
7
7
  *
8
- * e.g., "Today, 150 losers capitulated (closed) on AAPL,
9
- * while 25 winners joined (opened)."
10
- *
11
- * This is a 'standard' calc because it must iterate over all
12
- * users to compare their T-1 vs T portfolios.
8
+ * --- MODIFIED ---
9
+ * Removed dependency on 'asset-pnl-status' to fix 1MiB limit.
10
+ * This calculation now determines "winner/loser" status internally
11
+ * by reading the user's portfolio P&L directly.
13
12
  */
14
13
  const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
15
14
 
@@ -18,7 +17,6 @@ class WinnerLoserFlow {
18
17
  constructor() {
19
18
  // We will store { [ticker]: { winners_joined: 0, ... } }
20
19
  this.assetFlows = new Map();
21
- this.cohorts = null; // Caches cohort data
22
20
  this.mappings = null; // Caches mappings
23
21
  }
24
22
 
@@ -76,46 +74,30 @@ class WinnerLoserFlow {
76
74
 
77
75
  /**
78
76
  * Statically declare dependencies.
77
+ * --- MODIFIED ---
78
+ * Removed 'asset-pnl-status' dependency.
79
79
  */
80
80
  static getDependencies() {
81
- return [
82
- 'asset-pnl-status' // from core
83
- ];
84
- }
85
-
86
- /**
87
- * Helper to load cohort data from the dependency (runs once).
88
- */
89
- _loadCohorts(fetchedDependencies) {
90
- if (this.cohorts) return;
91
-
92
- const pnlStatusData = fetchedDependencies['asset-pnl-status'];
93
- if (!pnlStatusData) {
94
- this.cohorts = { winnerMap: new Map(), loserMap: new Map() };
95
- return;
96
- }
97
-
98
- const winnerMap = new Map();
99
- const loserMap = new Map();
100
-
101
- for (const [ticker, data] of Object.entries(pnlStatusData)) {
102
- // 'users_in_profit' and 'users_in_loss' are arrays of user IDs
103
- winnerMap.set(ticker, new Set(data.users_in_profit || []));
104
- loserMap.set(ticker, new Set(data.users_in_loss || []));
105
- }
106
-
107
- this.cohorts = { winnerMap, loserMap };
81
+ return [];
108
82
  }
109
83
 
110
84
  /**
111
- * Helper to get a user's holdings (Instrument IDs)
85
+ * --- MODIFIED ---
86
+ * Helper to get a user's holdings (Instrument IDs) AND their P&L.
87
+ * @returns {Map<InstrumentID, {pnl: number}>}
112
88
  */
113
- _getHoldings(portfolio) {
89
+ _getHoldingsWithPnl(portfolio) {
114
90
  const positions = portfolio?.AggregatedPositions || portfolio?.PublicPositions;
115
91
  if (!positions || !Array.isArray(positions)) {
116
- return new Set();
92
+ return new Map();
93
+ }
94
+ const map = new Map();
95
+ for (const pos of positions) {
96
+ if (pos.InstrumentID) {
97
+ map.set(pos.InstrumentID, { pnl: pos.NetProfit || 0 });
98
+ }
117
99
  }
118
- return new Set(positions.map(p => p.InstrumentID).filter(Boolean));
100
+ return map;
119
101
  }
120
102
 
121
103
  /**
@@ -132,21 +114,19 @@ class WinnerLoserFlow {
132
114
  }
133
115
  }
134
116
 
135
- process(todayPortfolio, yesterdayPortfolio, userId, context, todayInsights, yesterdayInsights, fetchedDependencies) {
117
+ process(todayPortfolio, yesterdayPortfolio, userId, context) {
136
118
  if (!todayPortfolio || !yesterdayPortfolio) {
137
119
  return;
138
120
  }
139
121
 
140
- // Load mappings and cohort data on the first user
141
122
  if (!this.mappings) {
142
123
  this.mappings = context.mappings;
143
124
  }
144
- this._loadCohorts(fetchedDependencies);
145
125
 
146
- const yHoldings = this._getHoldings(yesterdayPortfolio); // Set<InstrumentID>
147
- const tHoldings = this._getHoldings(todayPortfolio); // Set<InstrumentID>
126
+ const yHoldings = this._getHoldingsWithPnl(yesterdayPortfolio); // Map<InstID, {pnl}>
127
+ const tHoldings = this._getHoldingsWithPnl(todayPortfolio); // Map<InstID, {pnl}>
148
128
 
149
- const allInstrumentIds = new Set([...yHoldings, ...tHoldings]);
129
+ const allInstrumentIds = new Set([...yHoldings.keys(), ...tHoldings.keys()]);
150
130
  if (allInstrumentIds.size === 0) {
151
131
  return;
152
132
  }
@@ -155,8 +135,12 @@ class WinnerLoserFlow {
155
135
  const ticker = this.mappings.instrumentToTicker[instrumentId];
156
136
  if (!ticker) continue;
157
137
 
158
- const isWinner = this.cohorts.winnerMap.get(ticker)?.has(userId) || false;
159
- const isLoser = this.cohorts.loserMap.get(ticker)?.has(userId) || false;
138
+ // --- MODIFIED ---
139
+ // Determine cohort status from today's portfolio.
140
+ const tPnl = tHoldings.get(instrumentId)?.pnl;
141
+ const isWinner = tPnl > 0;
142
+ const isLoser = tPnl < 0;
143
+ // --- END MODIFIED ---
160
144
 
161
145
  // We only care about users who are *currently* in a cohort
162
146
  if (!isWinner && !isLoser) {
@@ -199,7 +183,6 @@ class WinnerLoserFlow {
199
183
 
200
184
  reset() {
201
185
  this.assetFlows.clear();
202
- this.cohorts = null;
203
186
  this.mappings = null;
204
187
  }
205
188
  }
@@ -1,13 +1,10 @@
1
1
  /**
2
2
  * @fileoverview Calculation (Pass 3) for "In Loss" cohort asset flow.
3
3
  *
4
- * This metric calculates the "Net Crowd Flow Percentage" for each asset,
5
- * but *only* for the cohort of users who are currently *at a loss*
6
- * on that specific asset.
7
- *
8
- * This helps identify if losers are capitulating or doubling down.
9
- *
10
- * This calculation *depends* on 'asset_pnl_status' to identify the cohort.
4
+ * --- MODIFIED ---
5
+ * Removed dependency on 'asset_pnl_status' to fix 1MiB limit.
6
+ * This calculation now determines "in loss" status internally
7
+ * by reading the *yesterday's* portfolio P&L directly.
11
8
  */
12
9
  const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
13
10
 
@@ -15,7 +12,8 @@ class InLossAssetCrowdFlow {
15
12
  constructor() {
16
13
  this.assetData = new Map();
17
14
  this.mappings = null;
18
- this.inLossCohorts = null; // Map<ticker, Set<userId>>
15
+ // No longer need this:
16
+ // this.inLossCohorts = null;
19
17
  }
20
18
 
21
19
  /**
@@ -57,9 +55,11 @@ class InLossAssetCrowdFlow {
57
55
 
58
56
  /**
59
57
  * Statically declare dependencies.
58
+ * --- MODIFIED ---
59
+ * Removed 'asset_pnl-status'
60
60
  */
61
61
  static getDependencies() {
62
- return ['asset_pnl_status'];
62
+ return [];
63
63
  }
64
64
 
65
65
  _getPortfolioPositions(portfolio) {
@@ -77,31 +77,8 @@ class InLossAssetCrowdFlow {
77
77
  }
78
78
  }
79
79
 
80
- /**
81
- * Helper to get the cohort data from the dependency.
82
- * --- MODIFIED ---
83
- * Reads `data.users_in_loss` as a string array, not an object array.
84
- */
85
- _getInLossCohorts(fetchedDependencies) {
86
- if (this.inLossCohorts) {
87
- return this.inLossCohorts;
88
- }
89
-
90
- const pnlStatusData = fetchedDependencies['asset_pnl_status'];
91
- if (!pnlStatusData) {
92
- return new Map();
93
- }
94
-
95
- // Re-structure the data for efficient lookup
96
- // Map<ticker, Set<userId>>
97
- this.inLossCohorts = new Map();
98
- for (const [ticker, data] of Object.entries(pnlStatusData)) {
99
- // `data.users_in_loss` is now a string[], so no .map() is needed.
100
- const userSet = new Set(data.users_in_loss || []); // <-- MODIFIED
101
- this.inLossCohorts.set(ticker, userSet);
102
- }
103
- return this.inLossCohorts;
104
- }
80
+ // --- MODIFIED ---
81
+ // Removed _getInLossCohorts helper
105
82
 
106
83
  process(todayPortfolio, yesterdayPortfolio, userId, context, todayInsights, yesterdayInsights, fetchedDependencies) {
107
84
  if (!todayPortfolio || !yesterdayPortfolio) {
@@ -109,15 +86,9 @@ class InLossAssetCrowdFlow {
109
86
  }
110
87
 
111
88
  if (!this.mappings) {
112
- // Context contains the mappings loaded in Pass 1
113
89
  this.mappings = context.mappings;
114
90
  }
115
91
 
116
- const cohorts = this._getInLossCohorts(fetchedDependencies);
117
- if (cohorts.size === 0) {
118
- return; // No dependency data
119
- }
120
-
121
92
  const yPos = this._getPortfolioPositions(yesterdayPortfolio);
122
93
  const tPos = this._getPortfolioPositions(todayPortfolio);
123
94
 
@@ -129,22 +100,22 @@ class InLossAssetCrowdFlow {
129
100
  for (const instrumentId of allInstrumentIds) {
130
101
  if (!instrumentId) continue;
131
102
 
132
- const ticker = this.mappings.instrumentToTicker[instrumentId] || `id_${instrumentId}`;
133
- const cohort = cohorts.get(ticker);
103
+ const yP = yPosMap.get(instrumentId);
104
+ const tP = tPosMap.get(instrumentId);
134
105
 
135
- // This user is not in the "in loss" cohort for this asset, skip.
136
- if (!cohort || !cohort.has(userId)) {
137
- continue;
106
+ // --- MODIFIED ---
107
+ // Check P&L from YESTERDAY's position to define cohort
108
+ const yPnl = yP?.NetProfit || 0;
109
+ if (yPnl >= 0) {
110
+ continue; // User was not in loss yesterday, skip.
138
111
  }
112
+ // --- END MODIFIED ---
139
113
 
140
114
  // User *is* in the cohort, process their data
141
115
  this._initAsset(instrumentId);
142
116
  const asset = this.assetData.get(instrumentId);
143
117
  asset.cohort.add(userId); // Track cohort size
144
118
 
145
- const yP = yPosMap.get(instrumentId);
146
- const tP = tPosMap.get(instrumentId);
147
-
148
119
  const yInvested = yP?.InvestedAmount || yP?.Amount || 0;
149
120
  const tInvested = tP?.InvestedAmount || tP?.Amount || 0;
150
121
 
@@ -191,7 +162,6 @@ class InLossAssetCrowdFlow {
191
162
  reset() {
192
163
  this.assetData.clear();
193
164
  this.mappings = null;
194
- this.inLossCohorts = null;
195
165
  }
196
166
  }
197
167
 
@@ -1,13 +1,10 @@
1
1
  /**
2
2
  * @fileoverview Calculation (Pass 3) for "In Profit" cohort asset flow.
3
3
  *
4
- * This metric calculates the "Net Crowd Flow Percentage" for each asset,
5
- * but *only* for the cohort of users who are currently *in profit*
6
- * on that specific asset.
7
- *
8
- * This helps identify if winners are taking profit or adding to positions.
9
- *
10
- * This calculation *depends* on 'asset_pnl_status' to identify the cohort.
4
+ * --- MODIFIED ---
5
+ * Removed dependency on 'asset_pnl_status' to fix 1MiB limit.
6
+ * This calculation now determines "in profit" status internally
7
+ * by reading the *yesterday's* portfolio P&L directly.
11
8
  */
12
9
  const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
13
10
 
@@ -15,7 +12,8 @@ class InProfitAssetCrowdFlow {
15
12
  constructor() {
16
13
  this.assetData = new Map();
17
14
  this.mappings = null;
18
- this.inProfitCohorts = null; // Map<ticker, Set<userId>>
15
+ // No longer need this:
16
+ // this.inProfitCohorts = null;
19
17
  }
20
18
 
21
19
  /**
@@ -57,9 +55,11 @@ class InProfitAssetCrowdFlow {
57
55
 
58
56
  /**
59
57
  * Statically declare dependencies.
58
+ * --- MODIFIED ---
59
+ * Removed 'asset_pnl-status'
60
60
  */
61
61
  static getDependencies() {
62
- return ['asset_pnl_status'];
62
+ return [];
63
63
  }
64
64
 
65
65
  _getPortfolioPositions(portfolio) {
@@ -77,31 +77,8 @@ class InProfitAssetCrowdFlow {
77
77
  }
78
78
  }
79
79
 
80
- /**
81
- * Helper to get the cohort data from the dependency.
82
- * --- MODIFIED ---
83
- * Reads `data.users_in_profit` as a string array, not an object array.
84
- */
85
- _getInProfitCohorts(fetchedDependencies) {
86
- if (this.inProfitCohorts) {
87
- return this.inProfitCohorts;
88
- }
89
-
90
- const pnlStatusData = fetchedDependencies['asset_pnl_status'];
91
- if (!pnlStatusData) {
92
- return new Map();
93
- }
94
-
95
- // Re-structure the data for efficient lookup
96
- // Map<ticker, Set<userId>>
97
- this.inProfitCohorts = new Map();
98
- for (const [ticker, data] of Object.entries(pnlStatusData)) {
99
- // `data.users_in_profit` is now a string[], so no .map() is needed.
100
- const userSet = new Set(data.users_in_profit || []); // <-- MODIFIED
101
- this.inProfitCohorts.set(ticker, userSet);
102
- }
103
- return this.inProfitCohorts;
104
- }
80
+ // --- MODIFIED ---
81
+ // Removed _getInProfitCohorts helper
105
82
 
106
83
  process(todayPortfolio, yesterdayPortfolio, userId, context, todayInsights, yesterdayInsights, fetchedDependencies) {
107
84
  if (!todayPortfolio || !yesterdayPortfolio) {
@@ -109,15 +86,9 @@ class InProfitAssetCrowdFlow {
109
86
  }
110
87
 
111
88
  if (!this.mappings) {
112
- // Context contains the mappings loaded in Pass 1
113
89
  this.mappings = context.mappings;
114
90
  }
115
91
 
116
- const cohorts = this._getInProfitCohorts(fetchedDependencies);
117
- if (cohorts.size === 0) {
118
- return; // No dependency data
119
- }
120
-
121
92
  const yPos = this._getPortfolioPositions(yesterdayPortfolio);
122
93
  const tPos = this._getPortfolioPositions(todayPortfolio);
123
94
 
@@ -129,22 +100,22 @@ class InProfitAssetCrowdFlow {
129
100
  for (const instrumentId of allInstrumentIds) {
130
101
  if (!instrumentId) continue;
131
102
 
132
- const ticker = this.mappings.instrumentToTicker[instrumentId] || `id_${instrumentId}`;
133
- const cohort = cohorts.get(ticker);
103
+ const yP = yPosMap.get(instrumentId);
104
+ const tP = tPosMap.get(instrumentId);
134
105
 
135
- // This user is not in the "in profit" cohort for this asset, skip.
136
- if (!cohort || !cohort.has(userId)) {
137
- continue;
106
+ // --- MODIFIED ---
107
+ // Check P&L from YESTERDAY's position to define cohort
108
+ const yPnl = yP?.NetProfit || 0;
109
+ if (yPnl <= 0) {
110
+ continue; // User was not in profit yesterday, skip.
138
111
  }
139
-
112
+ // --- END MODIFIED ---
113
+
140
114
  // User *is* in the cohort, process their data
141
115
  this._initAsset(instrumentId);
142
116
  const asset = this.assetData.get(instrumentId);
143
117
  asset.cohort.add(userId); // Track cohort size
144
118
 
145
- const yP = yPosMap.get(instrumentId);
146
- const tP = tPosMap.get(instrumentId);
147
-
148
119
  const yInvested = yP?.InvestedAmount || yP?.Amount || 0;
149
120
  const tInvested = tP?.InvestedAmount || tP?.Amount || 0;
150
121
 
@@ -191,7 +162,6 @@ class InProfitAssetCrowdFlow {
191
162
  reset() {
192
163
  this.assetData.clear();
193
164
  this.mappings = null;
194
- this.inProfitCohorts = null;
195
165
  }
196
166
  }
197
167
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aiden-shared-calculations-unified",
3
- "version": "1.0.79",
3
+ "version": "1.0.81",
4
4
  "description": "Shared calculation modules for the BullTrackers Computation System.",
5
5
  "main": "index.js",
6
6
  "files": [