aiden-shared-calculations-unified 1.0.77 → 1.0.79

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.
@@ -6,7 +6,8 @@
6
6
  *
7
7
  * This calculation now uses the 'history' data source, not 'portfolio'.
8
8
  */
9
- const { loadInstrumentMappings } = require('../../../utils/sector_mapping_provider');
9
+ const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
10
+
10
11
 
11
12
  class HoldingDurationPerAsset {
12
13
  constructor() {
@@ -0,0 +1,111 @@
1
+ /**
2
+ * @fileoverview Calculation (Pass 1 - Meta) for 1-day price change.
3
+ *
4
+ * This metric answers: "What is the 1-day percentage price change for
5
+ * every instrument, handling for market holidays/weekends?"
6
+ *
7
+ * It is a 'meta' calculation that runs once, loads all price data,
8
+ * and provides a reusable 1-day change signal for downstream passes
9
+ * like cohort-capital-flow.
10
+ */
11
+
12
+ class InstrumentPriceChange1D {
13
+
14
+ /**
15
+ * Defines the output schema for this calculation.
16
+ */
17
+ static getSchema() {
18
+ const tickerSchema = {
19
+ "type": "object",
20
+ "properties": {
21
+ "price_change_1d_pct": {
22
+ "type": ["number", "null"],
23
+ "description": "The 1-day (business day adjusted) price change percentage."
24
+ }
25
+ },
26
+ "required": ["price_change_1d_pct"]
27
+ };
28
+
29
+ return {
30
+ "type": "object",
31
+ "description": "Calculates the 1-day price change for all instruments.",
32
+ "patternProperties": {
33
+ "^.*$": tickerSchema // Ticker
34
+ },
35
+ "additionalProperties": tickerSchema
36
+ };
37
+ }
38
+
39
+ /**
40
+ * Statically defines all metadata for the manifest builder.
41
+ */
42
+ static getMetadata() {
43
+ return {
44
+ type: 'meta',
45
+ rootDataDependencies: [], // Relies on price data, not root data
46
+ isHistorical: false, // It needs to look back 1 day, but is not 'historical' in the runner's sense
47
+ userType: 'n/a',
48
+ category: 'core_metrics' // Fits with other price/metric calcs
49
+ };
50
+ }
51
+
52
+ /**
53
+ * This is a Pass 1 calculation and has no dependencies.
54
+ */
55
+ static getDependencies() {
56
+ return [];
57
+ }
58
+
59
+ // Helper to get date string N days ago
60
+ _getDateStr(baseDateStr, daysOffset) {
61
+ const date = new Date(baseDateStr + 'T00:00:00Z');
62
+ date.setUTCDate(date.getUTCDate() + daysOffset);
63
+ return date.toISOString().slice(0, 10);
64
+ }
65
+
66
+ /**
67
+ * This is a 'meta' calculation. It runs once.
68
+ * @param {string} dateStr - The date string 'YYYY-MM-DD'.
69
+ * @param {object} dependencies - The shared dependencies (e.g., logger, calculationUtils).
70
+ * @param {object} config - The computation system configuration.
71
+ * @param {object} fetchedDependencies - (Unused)
72
+ * @returns {Promise<object>} The calculation result.
73
+ */
74
+ async process(dateStr, dependencies, config, fetchedDependencies) {
75
+ const { logger, calculationUtils } = dependencies;
76
+
77
+ // calculationUtils contains all exported functions from the /utils folder
78
+ const priceMap = await calculationUtils.loadAllPriceData();
79
+ const tickerMap = await calculationUtils.loadInstrumentMappings();
80
+
81
+ if (!priceMap || !tickerMap || !tickerMap.instrumentToTicker) {
82
+ logger.log('ERROR', '[instrument-price-change-1d] Failed to load priceMap or mappings.');
83
+ return {};
84
+ }
85
+
86
+ const yesterdayStr = this._getDateStr(dateStr, -1);
87
+ const result = {};
88
+
89
+ for (const instrumentId in priceMap) {
90
+ const ticker = tickerMap.instrumentToTicker[instrumentId];
91
+ if (!ticker) continue;
92
+
93
+ // Use the utility function from price_data_provider.js
94
+ const priceChangeDecimal = calculationUtils.getDailyPriceChange(
95
+ instrumentId,
96
+ yesterdayStr,
97
+ dateStr,
98
+ priceMap
99
+ );
100
+
101
+ result[ticker] = {
102
+ // Convert decimal (0.05) to percentage (5.0) for consistency
103
+ price_change_1d_pct: priceChangeDecimal !== null ? priceChangeDecimal * 100 : null
104
+ };
105
+ }
106
+
107
+ return result;
108
+ }
109
+ }
110
+
111
+ module.exports = InstrumentPriceChange1D;
@@ -7,7 +7,8 @@
7
7
  * This is different from 'daily_asset_activity' because it counts
8
8
  * *positions*, not *unique users*.
9
9
  */
10
- const { loadInstrumentMappings } = require('../../../utils/sector_mapping_provider');
10
+ const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
11
+
11
12
 
12
13
  class DailyBoughtVsSoldCount {
13
14
  constructor() {
@@ -8,7 +8,8 @@
8
8
  * It runs ONCE, loads today's and yesterday's pre-aggregated 'insights' docs,
9
9
  * and calculates the delta based on the 'total' field.
10
10
  */
11
- const { loadInstrumentMappings } = require('../../../utils/sector_mapping_provider');
11
+ const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
12
+
12
13
 
13
14
  class DailyOwnershipDelta {
14
15
 
@@ -6,24 +6,35 @@
6
6
  * the price-adjusted capital flow for each cohort, per asset.
7
7
  *
8
8
  * This is the primary input for the final Pass 4 signal.
9
+ *
10
+ * --- REVISED 11/12/2025 ---
11
+ * - Removed dependency on 'insights' data.
12
+ * - Added dependency on 'instrument-price-change-1d' (Pass 1 meta calc).
13
+ * - Price adjustment logic now uses the reliable 1-day price change
14
+ * from the new dependency.
15
+ * --------------------------
9
16
  */
10
17
  const { loadInstrumentMappings } = require('../../../utils/sector_mapping_provider');
11
18
 
12
19
  class CohortCapitalFlow {
13
20
  constructor() {
14
- // We will store: { [cohortName]: Map<instrumentId, { flow_data... }> }
21
+ // { [cohortName]: Map<instrumentId, { flow_data... }> }
15
22
  this.cohortFlows = new Map();
16
- // This will be a lookup map: { [userId]: "cohortName" }
23
+ // { [userId]: "cohortName" }
17
24
  this.cohortMap = new Map();
18
25
  this.mappings = null;
19
26
  this.dependenciesLoaded = false;
27
+
28
+ // --- NEW ---
29
+ // This will store the { [ticker]: { price_change_1d_pct: 5.5 } } map
30
+ this.priceChangeMap = null;
20
31
  }
21
32
 
22
33
  /**
23
34
  * Defines the output schema for this calculation.
24
- * @returns {object} JSON Schema object
25
35
  */
26
36
  static getSchema() {
37
+ // ... (Schema remains unchanged) ...
27
38
  const flowSchema = {
28
39
  "type": "object",
29
40
  "properties": {
@@ -56,7 +67,9 @@ class CohortCapitalFlow {
56
67
  static getMetadata() {
57
68
  return {
58
69
  type: 'standard',
59
- rootDataDependencies: ['portfolio'],
70
+ // --- REVISED ---
71
+ // Removed 'insights' as it's no longer needed for price.
72
+ rootDataDependencies: ['portfolio', 'history'],
60
73
  isHistorical: true, // Needs T-1 portfolio for flow
61
74
  userType: 'all',
62
75
  category: 'gauss'
@@ -68,12 +81,13 @@ class CohortCapitalFlow {
68
81
  */
69
82
  static getDependencies() {
70
83
  return [
71
- 'cohort-definer' // from gauss (Pass 2)
84
+ 'cohort-definer', // from gauss (Pass 2)
85
+ // --- REVISED ---
86
+ 'instrument-price-change-1d' // from core (Pass 1)
72
87
  ];
73
88
  }
74
89
 
75
90
  _getPortfolioPositions(portfolio) {
76
- // We MUST use AggregatedPositions for this to get 'Invested' (portfolio percentage)
77
91
  return portfolio?.AggregatedPositions;
78
92
  }
79
93
 
@@ -85,7 +99,7 @@ class CohortCapitalFlow {
85
99
  this.cohortFlows.get(cohortName).set(instrumentId, {
86
100
  total_invested_yesterday: 0,
87
101
  total_invested_today: 0,
88
- price_change_yesterday: 0, // This is a weighted sum
102
+ price_change_yesterday: 0, // Weighted sum
89
103
  });
90
104
  }
91
105
  }
@@ -96,14 +110,22 @@ class CohortCapitalFlow {
96
110
  _loadDependencies(fetchedDependencies) {
97
111
  if (this.dependenciesLoaded) return;
98
112
 
113
+ // 1. Load Cohort Definitions
99
114
  const cohortData = fetchedDependencies['cohort-definer'];
100
115
  if (cohortData) {
101
116
  for (const [cohortName, userIds] of Object.entries(cohortData)) {
102
- for (const userId of userIds) {
103
- this.cohortMap.set(userId, cohortName);
117
+ if (Array.isArray(userIds)) {
118
+ for (const userId of userIds) {
119
+ this.cohortMap.set(userId, cohortName);
120
+ }
104
121
  }
105
122
  }
106
123
  }
124
+
125
+ // 2. Load Price Change Data
126
+ // --- REVISED ---
127
+ this.priceChangeMap = fetchedDependencies['instrument-price-change-1d'] || {};
128
+
107
129
  this.dependenciesLoaded = true;
108
130
  }
109
131
 
@@ -116,7 +138,7 @@ class CohortCapitalFlow {
116
138
 
117
139
  const cohortName = this.cohortMap.get(userId);
118
140
  if (!cohortName) {
119
- return; // This user is not in one of our defined cohorts, skip.
141
+ return; // Not in a defined cohort, skip.
120
142
  }
121
143
 
122
144
  if (!todayPortfolio || !yesterdayPortfolio) {
@@ -126,9 +148,14 @@ class CohortCapitalFlow {
126
148
  const yPos = this._getPortfolioPositions(yesterdayPortfolio);
127
149
  const tPos = this._getPortfolioPositions(todayPortfolio);
128
150
 
129
- // We must have AggregatedPositions for both days to do this calculation
130
151
  if (!yPos || !tPos) {
131
- return;
152
+ return; // Must have AggregatedPositions for both days
153
+ }
154
+
155
+ // --- REVISED ---
156
+ // We no longer need insightsMap
157
+ if (!this.priceChangeMap) {
158
+ return; // Cannot calculate price-adjusted flow
132
159
  }
133
160
 
134
161
  const yPosMap = new Map(yPos.map(p => [p.InstrumentID, p]));
@@ -144,15 +171,23 @@ class CohortCapitalFlow {
144
171
  const yP = yPosMap.get(instrumentId);
145
172
  const tP = tPosMap.get(instrumentId);
146
173
 
147
- // 'Invested' is the portfolio percentage (e.g., 5.0 = 5%)
148
174
  const yInvested = yP?.Invested || 0;
149
175
  const tInvested = tP?.Invested || 0;
150
176
 
151
177
  if (yInvested > 0) {
152
178
  asset.total_invested_yesterday += yInvested;
153
- // 'NetProfit' here is actually the 1-day P&L *as a percentage* (e.g., 0.1 for +10%)
154
- const yPriceChange = (yP?.NetProfit || 0);
155
- asset.price_change_yesterday += yPriceChange * yInvested; // Weighted sum
179
+
180
+ // --- REVISED ---
181
+ // Get the 1-day price change from our new dependency
182
+ const ticker = this.mappings.instrumentToTicker[instrumentId];
183
+ const yPriceChange_pct = (ticker && this.priceChangeMap[ticker])
184
+ ? this.priceChangeMap[ticker].price_change_1d_pct
185
+ : 0;
186
+
187
+ // Convert from percentage (5.5) to decimal (0.055)
188
+ const yPriceChange_decimal = (yPriceChange_pct || 0) / 100.0;
189
+
190
+ asset.price_change_yesterday += yPriceChange_decimal * yInvested; // Weighted sum
156
191
  }
157
192
  if (tInvested > 0) {
158
193
  asset.total_invested_today += tInvested;
@@ -168,6 +203,7 @@ class CohortCapitalFlow {
168
203
  const finalResult = {};
169
204
 
170
205
  for (const [cohortName, assetMap] of this.cohortFlows.entries()) {
206
+ // --- REVISED: Initialize cohortAssets as an object ---
171
207
  const cohortAssets = {};
172
208
  for (const [instrumentId, data] of assetMap.entries()) {
173
209
  const ticker = this.mappings.instrumentToTicker[instrumentId];
@@ -176,32 +212,32 @@ class CohortCapitalFlow {
176
212
  const { total_invested_yesterday, total_invested_today, price_change_yesterday } = data;
177
213
 
178
214
  if (total_invested_yesterday > 0) {
179
- // 1. Find the weighted average price change for this cohort/asset
180
- // e.g., (0.1 * 5.0 + 0.05 * 2.0) / (5.0 + 2.0)
181
- const avg_price_change_pct = price_change_yesterday / total_invested_yesterday;
182
-
183
- // 2. Estimate yesterday's value *after* price change
184
- // (This is what the value *would be* if no one bought or sold)
185
- const price_adjusted_yesterday_value = total_invested_yesterday * (1 + avg_price_change_pct);
186
-
187
- // 3. The difference between today's value and the price-adjusted
188
- // value is the *net capital flow*.
215
+ const avg_price_change_decimal = price_change_yesterday / total_invested_yesterday;
216
+ const price_adjusted_yesterday_value = total_invested_yesterday * (1 + avg_price_change_decimal);
189
217
  const flow_contribution = total_invested_today - price_adjusted_yesterday_value;
190
-
191
- // 4. Normalize the flow as a percentage of yesterday's capital
192
218
  const net_flow_percentage = (flow_contribution / total_invested_yesterday) * 100;
193
219
 
194
220
  if (isFinite(net_flow_percentage) && isFinite(flow_contribution)) {
195
221
  cohortAssets[ticker] = {
196
222
  net_flow_percentage: net_flow_percentage,
197
- net_flow_contribution: flow_contribution // This is the %-point flow
223
+ net_flow_contribution: flow_contribution
198
224
  };
199
225
  }
226
+ } else if (total_invested_today > 0) {
227
+ cohortAssets[ticker] = {
228
+ net_flow_percentage: Infinity, // Represents pure inflow
229
+ net_flow_contribution: total_invested_today
230
+ };
200
231
  }
201
232
  }
233
+ // --- REVISED: Match schema { "cohortName": { "assets": { ... } } } ---
234
+ // This was a bug in your original file. The schema expected an object
235
+ // with an 'assets' key, but the code was returning the map directly.
202
236
  finalResult[cohortName] = { assets: cohortAssets };
203
237
  }
204
- // Output is compact and not sharded
238
+
239
+ // --- REVISED: The schema for this calc shows the output is NOT sharded. ---
240
+ // The return should be the final object.
205
241
  return finalResult;
206
242
  }
207
243
 
@@ -210,6 +246,8 @@ class CohortCapitalFlow {
210
246
  this.cohortMap.clear();
211
247
  this.mappings = null;
212
248
  this.dependenciesLoaded = false;
249
+ // --- NEW ---
250
+ this.priceChangeMap = null;
213
251
  }
214
252
  }
215
253
 
@@ -8,7 +8,7 @@
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
  class CohortDefiner {
14
14
  constructor() {
@@ -58,7 +58,10 @@ class CohortDefiner {
58
58
  "smart_scalpers": cohortSchema,
59
59
  "fomo_chasers": cohortSchema,
60
60
  "patient_losers": cohortSchema,
61
- "fomo_bagholders": cohortSchema
61
+ "fomo_bagholders": cohortSchema,
62
+ // --- FIX [PROBLEM 9]: Add uncategorized bucket ---
63
+ "uncategorized_smart": cohortSchema,
64
+ "uncategorized_dumb": cohortSchema
62
65
  },
63
66
  "additionalProperties": cohortSchema
64
67
  };
@@ -73,14 +76,29 @@ class CohortDefiner {
73
76
  const dnaFilterData = fetchedDependencies['daily-dna-filter'];
74
77
  this.momentumData = fetchedDependencies['instrument-price-momentum-20d'];
75
78
 
76
- this.cohortIdSets = {
77
- smart: new Set(dnaFilterData?.smart_cohort_ids || []),
78
- dumb: new Set(dnaFilterData?.dumb_cohort_ids || [])
79
- };
79
+ // --- FIX [PROBLEM 6]: Validate dependency content, not just existence ---
80
+ if (dnaFilterData && dnaFilterData.smart_cohort_ids && dnaFilterData.dumb_cohort_ids) {
81
+ this.cohortIdSets = {
82
+ smart: new Set(dnaFilterData.smart_cohort_ids),
83
+ dumb: new Set(dnaFilterData.dumb_cohort_ids)
84
+ };
85
+ } else {
86
+ // Initialize with empty sets if dependency is missing or malformed
87
+ this.cohortIdSets = {
88
+ smart: new Set(),
89
+ dumb: new Set()
90
+ };
91
+ }
80
92
  }
81
93
 
82
94
  _getFomoScore(todayPortfolio, yesterdayPortfolio) {
83
95
  if (!this.mappings) return 0;
96
+
97
+ // --- FIX [PROBLEM 4 related]: Ensure momentum data is loaded ---
98
+ if (!this.momentumData) {
99
+ return 0; // Cannot calculate FOMO without momentum data
100
+ }
101
+
84
102
  const yIds = new Set((yesterdayPortfolio?.AggregatedPositions || []).map(p => p.InstrumentID));
85
103
  const newPositions = (todayPortfolio?.AggregatedPositions || []).filter(p => p.InstrumentID && !yIds.has(p.InstrumentID));
86
104
  if (newPositions.length === 0) return 0;
@@ -89,6 +107,7 @@ class CohortDefiner {
89
107
  let count = 0;
90
108
  for (const pos of newPositions) {
91
109
  const ticker = this.mappings.instrumentToTicker[pos.InstrumentID];
110
+ // --- FIX [PROBLEM 4 related]: Check momentumData[ticker] exists ---
92
111
  if (ticker && this.momentumData[ticker]) {
93
112
  fomoSum += this.momentumData[ticker].momentum_20d_pct || 0;
94
113
  count++;
@@ -165,19 +184,32 @@ class CohortDefiner {
165
184
  if (vectors.length === 0) return 0;
166
185
  const sorted = vectors.map(v => v[key]).sort((a, b) => a - b);
167
186
  const mid = Math.floor(sorted.length / 2);
187
+ // Handle even-length array by taking average of middle two
188
+ if (sorted.length % 2 === 0 && sorted.length > 0) {
189
+ return (sorted[mid - 1] + sorted[mid]) / 2;
190
+ }
168
191
  return sorted[mid];
169
192
  }
170
193
 
171
194
  getResult() {
172
195
  const cohorts = {};
196
+ const assignedSmart = new Set();
197
+ const assignedDumb = new Set();
173
198
 
174
199
  // 1. Process Smart Cohort
175
200
  const smart_median_time = this._getMedian(this.smartVectors, 'time');
201
+
176
202
  cohorts['smart_investors'] = this.smartVectors
177
203
  .filter(u => u.time >= smart_median_time)
178
- .map(u => u.userId);
204
+ .map(u => { assignedSmart.add(u.userId); return u.userId; });
205
+
179
206
  cohorts['smart_scalpers'] = this.smartVectors
180
207
  .filter(u => u.time < smart_median_time)
208
+ .map(u => { assignedSmart.add(u.userId); return u.userId; });
209
+
210
+ // --- FIX [PROBLEM 9]: Add uncategorized bucket ---
211
+ cohorts['uncategorized_smart'] = this.smartVectors
212
+ .filter(u => !assignedSmart.has(u.userId))
181
213
  .map(u => u.userId);
182
214
 
183
215
  // 2. Process Dumb Cohort
@@ -186,14 +218,19 @@ class CohortDefiner {
186
218
 
187
219
  cohorts['fomo_chasers'] = this.dumbVectors
188
220
  .filter(u => u.fomo >= dumb_median_fomo && u.bagholder < dumb_median_bag)
189
- .map(u => u.userId);
221
+ .map(u => { assignedDumb.add(u.userId); return u.userId; });
190
222
 
191
223
  cohorts['patient_losers'] = this.dumbVectors
192
224
  .filter(u => u.fomo < dumb_median_fomo && u.bagholder >= dumb_median_bag)
193
- .map(u => u.userId);
225
+ .map(u => { assignedDumb.add(u.userId); return u.userId; });
194
226
 
195
227
  cohorts['fomo_bagholders'] = this.dumbVectors
196
228
  .filter(u => u.fomo >= dumb_median_fomo && u.bagholder >= dumb_median_bag)
229
+ .map(u => { assignedDumb.add(u.userId); return u.userId; });
230
+
231
+ // --- FIX [PROBLEM 9]: Add uncategorized bucket ---
232
+ cohorts['uncategorized_dumb'] = this.dumbVectors
233
+ .filter(u => !assignedDumb.has(u.userId))
197
234
  .map(u => u.userId);
198
235
 
199
236
  // Output is a compact map of cohort_name -> [userIds]
@@ -94,20 +94,20 @@ class GaussDivergenceSignal {
94
94
  return {};
95
95
  }
96
96
 
97
- // Define which cohorts are "Smart" and which are "Dumb"
98
- // These names must match the keys from Pass 2
99
97
  const SMART_COHORTS = ['smart_investors', 'smart_scalpers'];
100
98
  const DUMB_COHORTS = ['fomo_chasers', 'patient_losers', 'fomo_bagholders'];
101
99
 
102
100
  const blendedFlows = new Map(); // Map<ticker, { smart: 0, dumb: 0 }>
103
101
 
104
- // 1. Blend all cohort flows into two buckets
102
+ // 1. Blend all cohort flows
105
103
  for (const cohortName in cohortFlows) {
106
104
  const isSmart = SMART_COHORTS.includes(cohortName);
107
105
  const isDumb = DUMB_COHORTS.includes(cohortName);
108
106
  if (!isSmart && !isDumb) continue;
109
107
 
110
- const assets = cohortFlows[cohortName]?.assets;
108
+ // --- REVISED ---
109
+ // Read from the 'assets' property, which contains the map of tickers
110
+ const assets = cohortFlows[cohortName]?.assets;
111
111
  if (!assets) continue;
112
112
 
113
113
  for (const [ticker, data] of Object.entries(assets)) {
@@ -115,7 +115,6 @@ class GaussDivergenceSignal {
115
115
  blendedFlows.set(ticker, { smart: 0, dumb: 0 });
116
116
  }
117
117
 
118
- // Use net_flow_contribution, which is the %-point flow
119
118
  const flow = data.net_flow_contribution || 0;
120
119
 
121
120
  if (isSmart) {
@@ -126,20 +125,14 @@ class GaussDivergenceSignal {
126
125
  }
127
126
  }
128
127
 
129
- // 2. Calculate final signal
128
+ // 2. Calculate final signal (logic unchanged)
130
129
  const result = {};
131
130
  for (const [ticker, data] of blendedFlows.entries()) {
132
-
133
- // The core signal is the divergence: (Smart Flow - Dumb Flow)
134
- // If Smart buys (+1) and Dumb sells (-1), score is +2.
135
- // If Smart sells (-1) and Dumb buys (+1), score is -2.
136
131
  const divergence = data.smart - data.dumb;
137
-
138
- // Normalize the score to a -10 to +10 range
139
132
  const gauss_score = this._normalize(divergence);
140
133
 
141
134
  let signal = "Neutral";
142
- if (gauss_score > 7.0) signal = "Strong Buy"; // e.g., > 1.5% net divergence
135
+ if (gauss_score > 7.0) signal = "Strong Buy";
143
136
  else if (gauss_score > 2.0) signal = "Buy";
144
137
  else if (gauss_score < -7.0) signal = "Strong Sell";
145
138
  else if (gauss_score < -2.0) signal = "Sell";
@@ -152,7 +145,6 @@ class GaussDivergenceSignal {
152
145
  };
153
146
  }
154
147
 
155
- // Final output is compact and non-sharded.
156
148
  return result;
157
149
  }
158
150
  }
@@ -7,7 +7,8 @@
7
7
  * This calculation *depends* on 'cohort-skill-definition'
8
8
  * to identify the cohort.
9
9
  */
10
- const { loadInstrumentMappings } = require('../../../utils/sector_mapping_provider');
10
+ const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
11
+
11
12
 
12
13
  class SkilledCohortFlow {
13
14
  constructor() {
@@ -7,7 +7,8 @@
7
7
  * This calculation *depends* on 'cohort-skill-definition'
8
8
  * to identify the cohort.
9
9
  */
10
- const { loadInstrumentMappings } = require('../../../utils/sector_mapping_provider');
10
+ const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
11
+
11
12
 
12
13
  class UnskilledCohortFlow {
13
14
  constructor() {
@@ -11,7 +11,8 @@
11
11
  * This is a 'standard' calc because it must iterate over all
12
12
  * users to compare their T-1 vs T portfolios.
13
13
  */
14
- const { loadInstrumentMappings } = require('../../../utils/sector_mapping_provider');
14
+ const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
15
+
15
16
 
16
17
  class WinnerLoserFlow {
17
18
  constructor() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aiden-shared-calculations-unified",
3
- "version": "1.0.77",
3
+ "version": "1.0.79",
4
4
  "description": "Shared calculation modules for the BullTrackers Computation System.",
5
5
  "main": "index.js",
6
6
  "files": [