aiden-shared-calculations-unified 1.0.86 → 1.0.88

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.
Files changed (80) hide show
  1. package/calculations/capitulation/asset-volatility-estimator.js +96 -0
  2. package/calculations/capitulation/retail-capitulation-risk-forecast.js +173 -0
  3. package/calculations/core/asset-cost-basis-profile.js +127 -0
  4. package/calculations/core/asset-pnl-status.js +36 -106
  5. package/calculations/core/asset-position-size.js +40 -91
  6. package/calculations/core/average-daily-pnl-all-users.js +18 -57
  7. package/calculations/core/average-daily-pnl-per-sector.js +41 -88
  8. package/calculations/core/average-daily-pnl-per-stock.js +38 -91
  9. package/calculations/core/average-daily-position-pnl.js +19 -49
  10. package/calculations/core/holding-duration-per-asset.js +25 -127
  11. package/calculations/core/instrument-price-change-1d.js +30 -49
  12. package/calculations/core/instrument-price-momentum-20d.js +50 -60
  13. package/calculations/core/long-position-per-stock.js +39 -68
  14. package/calculations/core/overall-holding-duration.js +16 -87
  15. package/calculations/core/overall-profitability-ratio.js +11 -40
  16. package/calculations/core/platform-buy-sell-sentiment.js +41 -124
  17. package/calculations/core/platform-daily-bought-vs-sold-count.js +41 -99
  18. package/calculations/core/platform-daily-ownership-delta.js +68 -126
  19. package/calculations/core/platform-ownership-per-sector.js +45 -96
  20. package/calculations/core/platform-total-positions-held.js +20 -80
  21. package/calculations/core/pnl-distribution-per-stock.js +29 -135
  22. package/calculations/core/price-metrics.js +95 -206
  23. package/calculations/core/profitability-ratio-per-sector.js +34 -79
  24. package/calculations/core/profitability-ratio-per-stock.js +32 -88
  25. package/calculations/core/profitability-skew-per-stock.js +41 -94
  26. package/calculations/core/profitable-and-unprofitable-status.js +44 -76
  27. package/calculations/core/sentiment-per-stock.js +24 -77
  28. package/calculations/core/short-position-per-stock.js +35 -43
  29. package/calculations/core/social-activity-aggregation.js +26 -49
  30. package/calculations/core/social-asset-posts-trend.js +38 -94
  31. package/calculations/core/social-event-correlation.js +26 -93
  32. package/calculations/core/social-sentiment-aggregation.js +20 -44
  33. package/calculations/core/social-top-mentioned-words.js +35 -87
  34. package/calculations/core/social-topic-interest-evolution.js +22 -111
  35. package/calculations/core/social-topic-sentiment-matrix.js +38 -104
  36. package/calculations/core/social-word-mentions-trend.js +27 -104
  37. package/calculations/core/speculator-asset-sentiment.js +31 -72
  38. package/calculations/core/speculator-danger-zone.js +48 -84
  39. package/calculations/core/speculator-distance-to-stop-loss-per-leverage.js +20 -52
  40. package/calculations/core/speculator-distance-to-tp-per-leverage.js +23 -53
  41. package/calculations/core/speculator-entry-distance-to-sl-per-leverage.js +20 -50
  42. package/calculations/core/speculator-entry-distance-to-tp-per-leverage.js +23 -50
  43. package/calculations/core/speculator-leverage-per-asset.js +25 -64
  44. package/calculations/core/speculator-leverage-per-sector.js +27 -63
  45. package/calculations/core/speculator-risk-reward-ratio-per-asset.js +24 -53
  46. package/calculations/core/speculator-stop-loss-distance-by-sector-short-long-breakdown.js +55 -68
  47. package/calculations/core/speculator-stop-loss-distance-by-ticker-short-long-breakdown.js +54 -71
  48. package/calculations/core/speculator-stop-loss-per-asset.js +19 -44
  49. package/calculations/core/speculator-take-profit-per-asset.js +20 -57
  50. package/calculations/core/speculator-tsl-per-asset.js +17 -56
  51. package/calculations/core/test..js +0 -0
  52. package/calculations/core/total-long-figures.js +16 -31
  53. package/calculations/core/total-long-per-sector.js +39 -61
  54. package/calculations/core/total-short-figures.js +13 -32
  55. package/calculations/core/total-short-per-sector.js +39 -61
  56. package/calculations/core/users-processed.js +11 -46
  57. package/calculations/gauss/cohort-capital-flow.js +54 -173
  58. package/calculations/gauss/cohort-definer.js +77 -163
  59. package/calculations/gauss/daily-dna-filter.js +29 -83
  60. package/calculations/gauss/gauss-divergence-signal.js +22 -109
  61. package/calculations/gem/cohort-momentum-state.js +27 -72
  62. package/calculations/gem/cohort-skill-definition.js +36 -52
  63. package/calculations/gem/platform-conviction-divergence.js +18 -60
  64. package/calculations/gem/quant-skill-alpha-signal.js +25 -98
  65. package/calculations/gem/skilled-cohort-flow.js +67 -175
  66. package/calculations/gem/skilled-unskilled-divergence.js +18 -73
  67. package/calculations/gem/unskilled-cohort-flow.js +64 -172
  68. package/calculations/ghost-book/cost-basis-density.js +79 -0
  69. package/calculations/ghost-book/liquidity-vacuum.js +52 -0
  70. package/calculations/ghost-book/retail-gamma-exposure.js +86 -0
  71. package/calculations/helix/helix-contrarian-signal.js +20 -114
  72. package/calculations/helix/herd-consensus-score.js +42 -124
  73. package/calculations/helix/winner-loser-flow.js +36 -118
  74. package/calculations/predicative-alpha/cognitive-dissonance.js +113 -0
  75. package/calculations/predicative-alpha/diamond-hand-fracture.js +90 -0
  76. package/calculations/predicative-alpha/mimetic-latency.js +124 -0
  77. package/calculations/pyro/risk-appetite-index.js +33 -74
  78. package/calculations/pyro/squeeze-potential.js +30 -87
  79. package/calculations/pyro/volatility-signal.js +33 -78
  80. package/package.json +1 -1
@@ -1,105 +1,45 @@
1
1
  /**
2
- * @fileoverview Calculation (Pass 1) for total positions held.
3
- *
4
- * REFACTOR: This is now a 'type: "meta"' calculation. It runs ONCE.
5
- * It reads the pre-aggregated 'insights' data source and sums the
6
- * 'total' field from all instruments to get the platform-wide total.
2
+ * @fileoverview Calculation (Pass 1) for total positions count.
3
+ * REFACTORED: Uses context.math.extract.
7
4
  */
8
- class DailyTotalPositionsHeld {
9
-
10
- // --- STANDARD 2: ADDED ---
5
+ class PlatformTotalPositionsHeld {
11
6
  constructor() {
12
- this.result = {};
7
+ this.totalPositions = 0;
13
8
  }
14
9
 
15
- /**
16
- * Statically defines all metadata for the manifest builder.
17
- */
18
10
  static getMetadata() {
19
11
  return {
20
- type: 'meta',
21
- rootDataDependencies: ['insights'], // Needs insights doc
12
+ type: 'standard',
13
+ rootDataDependencies: ['portfolio'],
22
14
  isHistorical: false,
23
- userType: 'n/a',
15
+ userType: 'all',
24
16
  category: 'core_metrics'
25
17
  };
26
18
  }
27
19
 
28
- /**
29
- * Statically declare dependencies.
30
- */
31
- static getDependencies() {
32
- return [];
33
- }
20
+ static getDependencies() { return []; }
34
21
 
35
- /**
36
- * Defines the output schema for this calculation.
37
- */
38
22
  static getSchema() {
39
23
  return {
40
24
  "type": "object",
41
- "description": "Calculates the total number of positions held across all users and instruments.",
42
25
  "properties": {
43
- "totalPositions": {
44
- "type": "number",
45
- "description": "The total aggregated count of all positions."
46
- }
26
+ "total_positions_count": { "type": "number" }
47
27
  },
48
- "required": ["totalPositions"]
28
+ "required": ["total_positions_count"]
49
29
  };
50
30
  }
51
31
 
52
- /**
53
- * This is a 'meta' calculation. It runs once.
54
- */
55
- // --- STANDARD 1: UPDATED SIGNATURE ---
56
- async process(dateStr, rootData, dependencies, config, fetchedDependencies) {
57
- let totalPositions = 0;
58
-
59
- // ---
60
- // FIX: The test harness ('worker.js') is our "ground truth".
61
- //
62
- // 1. Get Logger:
63
- // 'worker.js' passes the context object as ARGUMENT 4 (named 'config').
64
- // ---
65
- const { logger } = config; // 'config' is Param 4
66
-
67
- // ---
68
- // 2. Get Data:
69
- // 'worker.js' passes the root data object as ARGUMENT 1 (named 'dateStr').
70
- // ---
71
- const rootDataToday = dateStr; // 'dateStr' is Param 1
72
- const insightsDoc = rootDataToday.insights;
73
-
74
- if (!insightsDoc || !Array.isArray(insightsDoc.insights)) {
75
- logger.log('WARN', `[daily-total-positions-held] No 'insights' data found.`);
76
- // --- STANDARD 2: SET STATE, DO NOT RETURN ---
77
- this.result = { totalPositions: 0 };
78
- return;
79
- }
80
-
81
- for (const instrument of insightsDoc.insights) {
82
- // The 'total' field from the doc is the total # of positions for that instrument
83
- if (typeof instrument.total === 'number') {
84
- totalPositions += instrument.total;
85
- }
86
- }
87
-
88
- // --- STANDARD 2: SET STATE, DO NOT RETURN ---
89
- this.result = {
90
- totalPositions: totalPositions
91
- };
92
- }
93
-
94
- // --- STANDARD 2: ADDED ---
95
- async getResult(fetchedDependencies) {
96
- return this.result;
32
+ process(context) {
33
+ const { extract } = context.math;
34
+ const { user } = context;
35
+ const positions = extract.getPositions(user.portfolio.today, user.type);
36
+ this.totalPositions += positions.length;
97
37
  }
98
38
 
99
- // --- STANDARD 2: ADDED ---
100
- reset() {
101
- this.result = {};
39
+ getResult() {
40
+ return { total_positions_count: this.totalPositions };
102
41
  }
103
- }
104
42
 
105
- module.exports = DailyTotalPositionsHeld;
43
+ reset() { this.totalPositions = 0; }
44
+ }
45
+ module.exports = PlatformTotalPositionsHeld;
@@ -1,44 +1,23 @@
1
1
  /**
2
2
  * @fileoverview Calculation (Pass 1) for P&L distribution per stock.
3
- *
4
- * This metric tracks the distribution of P&L percentages for all open
5
- * positions, grouped by instrument.
6
- *
7
- * REFACTOR: This calculation now aggregates the distribution into
8
- * predefined buckets on the server-side, returning a chart-ready
9
- * histogram object instead of raw arrays.
10
- *
11
- * --- FIX: 2025-11-12 ---
12
- * This calculation is a dependency for crowd_sharpe_ratio_proxy,
13
- * which requires sum, sumSq, and count for variance calculations.
14
- * This file has been updated to provide *both* the histogram
15
- * and a 'stats' object containing these required values.
16
- * ---------------------
3
+ * REFACTORED: Aggregates distribution of P&L Percentages.
17
4
  */
18
- // --- STANDARD 0: REMOVED require('../../utils/sector_mapping_provider') ---
19
-
20
- // Define the P&L percentage buckets for the histogram
21
5
  const BUCKETS = [
22
- { label: 'loss_heavy', min: -Infinity, max: -50 }, // > 50% loss
23
- { label: 'loss_medium', min: -50, max: -25 }, // 25% to 50% loss
24
- { label: 'loss_light', min: -25, max: 0 }, // 0% to 25% loss
25
- { label: 'gain_light', min: 0, max: 25 }, // 0% to 25% gain
26
- { label: 'gain_medium', min: 25, max: 50 }, // 25% to 50% gain
27
- { label: 'gain_heavy', min: 50, max: 100 }, // 50% to 100% gain
28
- { label: 'gain_extreme', min: 100, max: Infinity } // > 100% gain
6
+ { label: 'loss_heavy', min: -Infinity, max: -50 },
7
+ { label: 'loss_medium', min: -50, max: -25 },
8
+ { label: 'loss_light', min: -25, max: 0 },
9
+ { label: 'gain_light', min: 0, max: 25 },
10
+ { label: 'gain_medium', min: 25, max: 50 },
11
+ { label: 'gain_heavy', min: 50, max: 100 },
12
+ { label: 'gain_extreme', min: 100, max: Infinity }
29
13
  ];
30
14
 
31
15
  class PnlDistributionPerStock {
32
16
  constructor() {
33
- // We will store { [instrumentId]: [pnlPercent1, pnlPercent2, ...] }
34
17
  this.pnlMap = new Map();
35
- // --- STANDARD 0: RENAMED ---
36
18
  this.tickerMap = null;
37
19
  }
38
20
 
39
- /**
40
- * Statically defines all metadata for the manifest builder.
41
- */
42
21
  static getMetadata() {
43
22
  return {
44
23
  type: 'standard',
@@ -49,58 +28,18 @@ class PnlDistributionPerStock {
49
28
  };
50
29
  }
51
30
 
52
- /**
53
- * Statically declare dependencies.
54
- */
55
- static getDependencies() {
56
- return [];
57
- }
31
+ static getDependencies() { return []; }
58
32
 
59
- /**
60
- * Defines the output schema for this calculation.
61
- */
62
33
  static getSchema() {
63
34
  const bucketSchema = {
64
35
  "type": "object",
65
- "description": "Histogram and stats of P&L distribution for a single asset.",
66
36
  "properties": {
67
- "histogram": {
68
- "type": "object",
69
- "description": "Histogram of P&L distribution.",
70
- "properties": {
71
- "loss_heavy": { "type": "number", "description": "Count of positions with > 50% loss" },
72
- "loss_medium": { "type": "number", "description": "Count of positions with 25-50% loss" },
73
- "loss_light": { "type": "number", "description": "Count of positions with 0-25% loss" },
74
- "gain_light": { "type": "number", "description": "Count of positions with 0-25% gain" },
75
- "gain_medium": { "type": "number", "description": "Count of positions with 25-50% gain" },
76
- "gain_heavy": { "type": "number", "description": "Count of positions with 50-100% gain" },
77
- "gain_extreme": { "type": "number", "description": "Count of positions with > 100% gain" },
78
- "total_positions": { "type": "number", "description": "Total positions counted" }
79
- },
80
- "required": ["total_positions"]
81
- },
82
- "stats": {
83
- "type": "object",
84
- "description": "Raw statistics needed for variance/Sharpe calculations.",
85
- "properties": {
86
- "sum": { "type": "number", "description": "Sum of all P&L percentages" },
87
- "sumSq": { "type": "number", "description": "Sum of all squared P&L percentages" },
88
- "count": { "type": "number", "description": "Total count of positions" }
89
- },
90
- "required": ["sum", "sumSq", "count"]
91
- }
37
+ "histogram": { "type": "object" },
38
+ "stats": { "type": "object", "required": ["sum", "sumSq", "count"] }
92
39
  },
93
40
  "required": ["histogram", "stats"]
94
41
  };
95
-
96
- return {
97
- "type": "object",
98
- "description": "Calculates a histogram and raw stats of P&L percentage distribution for all open positions, per asset.",
99
- "patternProperties": {
100
- "^.*$": bucketSchema // Ticker
101
- },
102
- "additionalProperties": bucketSchema
103
- };
42
+ return { "type": "object", "patternProperties": { "^.*$": bucketSchema } };
104
43
  }
105
44
 
106
45
  _initAsset(instrumentId) {
@@ -109,74 +48,37 @@ class PnlDistributionPerStock {
109
48
  }
110
49
  }
111
50
 
112
- // --- STANDARD 0: UPDATED SIGNATURE ---
113
- process(todayPortfolio, yesterdayPortfolio, userId, context) {
114
- // --- STANDARD 0: ADDED ---
115
- if (!this.tickerMap) {
116
- this.tickerMap = context.instrumentToTicker;
117
- }
51
+ process(context) {
52
+ const { extract } = context.math;
53
+ const { mappings, user } = context;
54
+ if (!this.tickerMap) this.tickerMap = mappings.instrumentToTicker;
118
55
 
119
- const positions = todayPortfolio.PublicPositions || todayPortfolio.AggregatedPositions;
120
- if (!positions || !Array.isArray(positions)) {
121
- return;
122
- }
56
+ const positions = extract.getPositions(user.portfolio.today, user.type);
123
57
 
124
58
  for (const pos of positions) {
125
- const instrumentId = pos.InstrumentID;
126
-
127
- // ---
128
- // FIX 1: The schema file (schema.md) shows the P&L field
129
- // is 'NetProfit', not 'ProfitRate'.
130
- // ---
131
- const pnlPercent = pos.NetProfit;
132
-
133
- if (!instrumentId || typeof pnlPercent !== 'number') {
134
- continue;
135
- }
59
+ const instId = extract.getInstrumentId(pos);
60
+ if (!instId) continue;
136
61
 
137
- this._initAsset(instrumentId);
62
+ const pnlPercent = extract.getNetProfit(pos);
138
63
 
139
- // ---
140
- // FIX 2: The 'NetProfit' field is already a full percentage
141
- // (e.g., 34.09), not a decimal (e.g., 0.34).
142
- // Do not multiply by 100.
143
- // ---
144
- this.pnlMap.get(instrumentId).push(pnlPercent);
64
+ this._initAsset(instId);
65
+ this.pnlMap.get(instId).push(pnlPercent);
145
66
  }
146
67
  }
147
68
 
148
- /**
149
- * REFACTOR: This method now calculates the distribution on the server.
150
- * --- FIX: 2025-11-12 ---
151
- * Also calculates and returns sum, sumSq, and count.
152
- */
153
69
  async getResult() {
154
- // --- STANDARD 0: REMOVED forbidden data load ---
155
-
156
- // Failsafe check
157
- if (!this.tickerMap) {
158
- return {}; // process() must run first
159
- }
70
+ if (!this.tickerMap) return {};
160
71
 
161
72
  const result = {};
162
-
163
- for (const [instrumentId, pnlValues] of this.pnlMap.entries()) {
164
- // --- STANDARD 0: SIMPLIFIED ---
165
- const ticker = this.tickerMap[instrumentId] || `id_${instrumentId}`;
73
+ for (const [instId, pnlValues] of this.pnlMap.entries()) {
74
+ const ticker = this.tickerMap[instId] || `id_${instId}`;
166
75
  const count = pnlValues.length;
167
76
 
168
- if (count === 0) {
169
- continue;
170
- }
77
+ if (count === 0) continue;
171
78
 
172
79
  const histogram = {
173
- loss_heavy: 0,
174
- loss_medium: 0,
175
- loss_light: 0,
176
- gain_light: 0,
177
- gain_medium: 0,
178
- gain_heavy: 0,
179
- gain_extreme: 0,
80
+ loss_heavy: 0, loss_medium: 0, loss_light: 0,
81
+ gain_light: 0, gain_medium: 0, gain_heavy: 0, gain_extreme: 0,
180
82
  total_positions: count
181
83
  };
182
84
 
@@ -195,15 +97,9 @@ class PnlDistributionPerStock {
195
97
  }
196
98
  }
197
99
 
198
- const stats = {
199
- sum: sum,
200
- sumSq: sumSq,
201
- count: count
202
- };
203
-
204
100
  result[ticker] = {
205
101
  histogram: histogram,
206
- stats: stats
102
+ stats: { sum, sumSq, count }
207
103
  };
208
104
  }
209
105
  return result;
@@ -211,9 +107,7 @@ class PnlDistributionPerStock {
211
107
 
212
108
  reset() {
213
109
  this.pnlMap.clear();
214
- // --- STANDARD 0: RENAMED ---
215
110
  this.tickerMap = null;
216
111
  }
217
112
  }
218
-
219
113
  module.exports = PnlDistributionPerStock;