aiden-shared-calculations-unified 1.0.82 → 1.0.84

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 (71) hide show
  1. package/calculations/core/asset-pnl-status.js +122 -104
  2. package/calculations/core/asset-position-size.js +110 -73
  3. package/calculations/core/average-daily-pnl-all-users.js +17 -3
  4. package/calculations/core/average-daily-pnl-per-sector.js +83 -75
  5. package/calculations/core/average-daily-pnl-per-stock.js +84 -73
  6. package/calculations/core/average-daily-position-pnl.js +2 -2
  7. package/calculations/core/holding-duration-per-asset.js +24 -23
  8. package/calculations/core/instrument-price-change-1d.js +72 -82
  9. package/calculations/core/instrument-price-momentum-20d.js +66 -100
  10. package/calculations/core/long-position-per-stock.js +21 -13
  11. package/calculations/core/overall-holding-duration.js +8 -3
  12. package/calculations/core/overall-profitability-ratio.js +2 -2
  13. package/calculations/core/platform-buy-sell-sentiment.js +75 -22
  14. package/calculations/core/platform-daily-bought-vs-sold-count.js +19 -10
  15. package/calculations/core/platform-daily-ownership-delta.js +39 -15
  16. package/calculations/core/platform-ownership-per-sector.js +38 -18
  17. package/calculations/core/platform-total-positions-held.js +36 -14
  18. package/calculations/core/pnl-distribution-per-stock.js +39 -36
  19. package/calculations/core/price-metrics.js +70 -172
  20. package/calculations/core/profitability-ratio-per-sector.js +23 -29
  21. package/calculations/core/profitability-ratio-per-stock.js +20 -13
  22. package/calculations/core/profitability-skew-per-stock.js +20 -13
  23. package/calculations/core/profitable-and-unprofitable-status.js +34 -10
  24. package/calculations/core/sentiment-per-stock.js +20 -9
  25. package/calculations/core/short-position-per-stock.js +23 -37
  26. package/calculations/core/social-activity-aggregation.js +41 -115
  27. package/calculations/core/social-asset-posts-trend.js +77 -94
  28. package/calculations/core/social-event-correlation.js +87 -106
  29. package/calculations/core/social-sentiment-aggregation.js +56 -138
  30. package/calculations/core/social-top-mentioned-words.js +74 -106
  31. package/calculations/core/social-topic-interest-evolution.js +94 -94
  32. package/calculations/core/social-topic-sentiment-matrix.js +90 -74
  33. package/calculations/core/social-word-mentions-trend.js +92 -106
  34. package/calculations/core/speculator-asset-sentiment.js +63 -92
  35. package/calculations/core/speculator-danger-zone.js +77 -90
  36. package/calculations/core/speculator-distance-to-stop-loss-per-leverage.js +75 -90
  37. package/calculations/core/speculator-distance-to-tp-per-leverage.js +75 -88
  38. package/calculations/core/speculator-entry-distance-to-sl-per-leverage.js +75 -90
  39. package/calculations/core/speculator-entry-distance-to-tp-per-leverage.js +74 -89
  40. package/calculations/core/speculator-leverage-per-asset.js +62 -57
  41. package/calculations/core/speculator-leverage-per-sector.js +53 -65
  42. package/calculations/core/speculator-risk-reward-ratio-per-asset.js +71 -76
  43. package/calculations/core/speculator-stop-loss-distance-by-sector-short-long-breakdown.js +60 -81
  44. package/calculations/core/speculator-stop-loss-distance-by-ticker-short-long-breakdown.js +57 -77
  45. package/calculations/core/speculator-stop-loss-per-asset.js +43 -80
  46. package/calculations/core/speculator-take-profit-per-asset.js +45 -69
  47. package/calculations/core/speculator-tsl-per-asset.js +42 -49
  48. package/calculations/core/total-long-figures.js +19 -19
  49. package/calculations/core/total-long-per-sector.js +39 -36
  50. package/calculations/core/total-short-figures.js +19 -19
  51. package/calculations/core/total-short-per-sector.js +39 -36
  52. package/calculations/core/users-processed.js +52 -25
  53. package/calculations/gauss/cohort-capital-flow.js +38 -29
  54. package/calculations/gauss/cohort-definer.js +17 -25
  55. package/calculations/gauss/daily-dna-filter.js +10 -4
  56. package/calculations/gauss/gauss-divergence-signal.js +28 -6
  57. package/calculations/gem/cohort-momentum-state.js +113 -92
  58. package/calculations/gem/cohort-skill-definition.js +23 -53
  59. package/calculations/gem/platform-conviction-divergence.js +62 -116
  60. package/calculations/gem/quant-skill-alpha-signal.js +107 -123
  61. package/calculations/gem/skilled-cohort-flow.js +178 -167
  62. package/calculations/gem/skilled-unskilled-divergence.js +73 -113
  63. package/calculations/gem/unskilled-cohort-flow.js +176 -166
  64. package/calculations/helix/helix-contrarian-signal.js +91 -83
  65. package/calculations/helix/herd-consensus-score.js +135 -97
  66. package/calculations/helix/winner-loser-flow.js +14 -14
  67. package/calculations/pyro/risk-appetite-index.js +121 -123
  68. package/calculations/pyro/squeeze-potential.js +93 -125
  69. package/calculations/pyro/volatility-signal.js +109 -97
  70. package/package.json +9 -9
  71. package/README.MD +0 -78
@@ -1,63 +1,18 @@
1
1
  /**
2
- * @fileoverview Calculation (Pass 4) for the "Quant-Skill Alpha Signal".
2
+ * @fileoverview GEM Product Line (Pass 4)
3
3
  *
4
- * This metric synthesizes multiple Pass 1, 2, and 3 signals into a
5
- * single, actionable "raw score" for each asset. It is designed to
6
- * be the final, tradable signal from this computation branch.
7
- *
8
- * It weights:
9
- * 1. Skilled/Unskilled Divergence (Pass 3)
10
- * 2. Unskilled "FOMO" (from Cohort Momentum, Pass 3)
11
- * 3. Platform vs. Sample Divergence (Pass 1)
12
- * 4. Social Media Sentiment (Pass 1)
4
+ * This is the final, stateless signal generator for the GEM line.
5
+ * It answers: "Are skilled users buying into *positive* momentum
6
+ * while unskilled users are buying into *negative* momentum?"
13
7
  */
14
8
  class QuantSkillAlphaSignal {
9
+
10
+ // --- STANDARD 2: ADDED ---
15
11
  constructor() {
16
- // Define the weights for the model.
17
- // These would be optimized via backtesting.
18
- this.W_DIVERGENCE = 0.40; // Skilled vs Unskilled
19
- this.W_FOMO = 0.30; // Unskilled Momentum (faded)
20
- this.W_PLATFORM = 0.15; // Sample vs Platform
21
- this.W_SOCIAL = 0.15; // Social Sentiment
12
+ this.result = {};
22
13
  }
23
14
 
24
- /**
25
- * Defines the output schema for this calculation.
26
- * @returns {object} JSON Schema object
27
- */
28
- static getSchema() {
29
- const tickerSchema = {
30
- "type": "object",
31
- "properties": {
32
- "raw_alpha_score": {
33
- "type": "number",
34
- "description": "The final weighted signal score. > 0 is bullish, < 0 is bearish."
35
- },
36
- "signal_status": {
37
- "type": "string",
38
- "description": "A human-readable signal (e.g., 'Strong Buy', 'Neutral')."
39
- },
40
- "component_divergence_score": { "type": "number" },
41
- "component_unskilled_fomo_score": { "type": "number" },
42
- "component_platform_divergence_score": { "type": "number" },
43
- "component_social_sentiment_score": { "type": "number" }
44
- },
45
- "required": ["raw_alpha_score", "signal_status"]
46
- };
47
-
48
- return {
49
- "type": "object",
50
- "description": "A final, weighted alpha signal combining skill divergence, momentum, and sentiment.",
51
- "patternProperties": {
52
- "^.*$": tickerSchema // Ticker
53
- },
54
- "additionalProperties": tickerSchema
55
- };
56
- }
57
-
58
- /**
59
- * Statically defines all metadata for the manifest builder.
60
- */
15
+ /** Statically defines metadata */
61
16
  static getMetadata() {
62
17
  return {
63
18
  type: 'meta',
@@ -68,102 +23,131 @@ class QuantSkillAlphaSignal {
68
23
  };
69
24
  }
70
25
 
71
- /**
72
- * Statically declare dependencies.
73
- */
26
+ /** Statically declare dependencies */
74
27
  static getDependencies() {
75
28
  return [
76
- // Internal 'gem' dependencies (normalized)
77
- 'skilled-unskilled-divergence',
78
- 'cohort-momentum-state',
79
- 'platform-conviction-divergence',
80
-
81
- // Dependencies on 'core' product line (normalized)
82
- 'social-sentiment-aggregation'
29
+ 'skilled-unskilled-divergence', // from gem (Pass 3)
30
+ 'cohort-momentum-state', // from gem (Pass 2)
31
+ 'instrument-price-momentum-20d'// from core (Pass 1)
83
32
  ];
84
33
  }
85
34
 
86
- process() {
87
- // No-op
35
+ /**
36
+ * Defines the output schema for this calculation.
37
+ */
38
+ static getSchema() {
39
+ const tickerSchema = {
40
+ "type": "object",
41
+ "properties": {
42
+ "signal": { "type": "string", "enum": ["Strong Buy", "Buy", "Neutral", "Sell", "Strong Sell"] },
43
+ "gem_score": { "type": "number" },
44
+ "components": {
45
+ "type": "object",
46
+ "properties": {
47
+ "flow_divergence": { "type": "number" },
48
+ "momentum_divergence": { "type": "number" },
49
+ "asset_momentum": { "type": "number" }
50
+ }
51
+ }
52
+ },
53
+ "required": ["signal", "gem_score", "components"]
54
+ };
55
+
56
+ return {
57
+ "type": "object",
58
+ "description": "Generates a final skill-based alpha signal.",
59
+ "patternProperties": { "^.*$": tickerSchema },
60
+ "additionalProperties": tickerSchema
61
+ };
62
+ }
63
+
64
+ _normalize(score) {
65
+ return Math.tanh(score / 5.0) * 10;
88
66
  }
89
67
 
90
68
  /**
91
- * This is a 'meta' calculation.
92
- * @param {object} fetchedDependencies - Results from previous passes.
69
+ * This is a 'meta' calculation. It runs once.
93
70
  */
94
- getResult(fetchedDependencies) {
95
- // FIX: Use normalized dependency names
96
- const divergenceData = fetchedDependencies['skilled-unskilled-divergence']?.assets;
97
- const momentumData = fetchedDependencies['cohort-momentum-state'];
98
- const platformData = fetchedDependencies['platform-conviction-divergence'];
99
- const socialData = fetchedDependencies['social-sentiment-aggregation']?.per_ticker;
71
+ // --- STANDARD 1: UPDATED SIGNATURE (added rootData) ---
72
+ async process(dateStr, rootData, dependencies, config, fetchedDependencies) {
73
+ const { logger, calculationUtils } = dependencies;
74
+
75
+ const flowDivergence = fetchedDependencies['skilled-unskilled-divergence'];
76
+ const momentumExposure = fetchedDependencies['cohort-momentum-state'];
77
+ const assetMomentum = fetchedDependencies['instrument-price-momentum-20d'];
100
78
 
101
- if (!divergenceData || !momentumData || !platformData || !socialData) {
102
- return {}; // Missing one or more key dependencies
79
+ if (!flowDivergence || !momentumExposure || !assetMomentum) {
80
+ logger.log('WARN', `[gem/quant-skill-alpha-signal] Missing dependencies for ${dateStr}.`);
81
+ // --- STANDARD 2: DO NOT RETURN ---
82
+ this.result = {};
83
+ return;
103
84
  }
104
85
 
86
+ const skilledMomentum = momentumExposure.skilled?.average_momentum_exposure_pct || 0;
87
+ const unskilledMomentum = momentumExposure.unskilled?.average_momentum_exposure_pct || 0;
88
+ const momentumDivergence = skilledMomentum - unskilledMomentum;
89
+
105
90
  const result = {};
106
- const allTickers = new Set([
107
- ...Object.keys(divergenceData),
108
- ...Object.keys(momentumData),
109
- ...Object.keys(platformData),
110
- ...Object.keys(socialData)
111
- ]);
91
+ const allTickers = Object.keys(flowDivergence);
112
92
 
113
93
  for (const ticker of allTickers) {
114
- // 1. Get Divergence Signal (Buy = +1, Sell = -1)
115
- const divStatus = divergenceData[ticker]?.status;
116
- const divScore = divStatus === 'Capitulation' ? 1.0 : (divStatus === 'Euphoria' ? -1.0 : 0);
117
-
118
- // 2. Get Unskilled FOMO Signal (We fade this, so we use -1)
119
- // 'unskilled_momentum_score' is high positive when they buy a rally
120
- const fomoScore = momentumData[ticker]?.unskilled_momentum_score || 0;
94
+ const flowData = flowDivergence[ticker];
95
+ const assetMom = assetMomentum[ticker]?.momentum_20d_pct || 0;
121
96
 
122
- // 3. Get Platform Divergence Signal
123
- // 'divergence' is positive when our sample is more bullish than the platform
124
- const platformScore = platformData[ticker]?.divergence || 0;
97
+ // 1. Flow Divergence (Skilled buying, Unskilled selling)
98
+ const flowScore = flowData.flow_divergence_score; // e.g., +1.5
125
99
 
126
- // 4. Get Social Sentiment Signal
127
- // 'net_sentiment_pct' is positive when social is bullish
128
- const socialScore = socialData[ticker]?.net_sentiment_pct || 0;
129
-
130
- // Normalize scores to a similar range (approx -100 to 100)
131
- // (This is a simple normalization; a z-score would be more robust)
132
- const s_div = divScore * 100.0;
133
- const s_fomo = -1 * fomoScore; // Fading the signal
134
- const s_plat = platformScore; // Already 0-100
135
- const s_soc = socialScore; // Already 0-100
136
-
137
- // Calculate final weighted score
138
- const raw_alpha_score =
139
- (s_div * this.W_DIVERGENCE) +
140
- (s_fomo * this.W_FOMO) +
141
- (s_plat * this.W_PLATFORM) +
142
- (s_soc * this.W_SOCIAL);
100
+ // 2. Momentum Divergence (Skilled buying high-mom, Unskilled buying low-mom)
101
+ const momScore = momentumDivergence; // e.g., +20.0
102
+
103
+ // 3. Asset Momentum (Is the asset *actually* in an uptrend?)
104
+ const assetScore = assetMom; // e.g., +15.0
143
105
 
144
- // Determine human-readable status
145
- let status = 'Neutral';
146
- if (raw_alpha_score > 30) status = 'Strong Buy';
147
- else if (raw_alpha_score > 10) status = 'Buy';
148
- else if (raw_alpha_score < -30) status = 'Strong Sell';
149
- else if (raw_alpha_score < -10) status = 'Sell';
106
+ // --- Signal Logic ---
107
+ // We want all three to be positive.
108
+ // 1. Skilled are buying, Unskilled are selling (flowScore > 0)
109
+ // 2. Skilled are buying *more* momentum than Unskilled (momScore > 0)
110
+ // 3. The asset itself has positive momentum (assetScore > 0)
111
+
112
+ // If skilled are buying *and* they are buying into strength, that's a good sign.
113
+ // We combine flow and momentum divergence.
114
+ const divergenceFactor = (flowScore > 0 && momScore > 0) ? (flowScore * momScore) : 0;
115
+
116
+ // The final score is the divergence, *validated* by the asset's own momentum.
117
+ // We scale flowScore (small) and momScore (large) to be comparable
118
+ const scaledFlow = flowScore * 10; // (e.g., 1.5 -> 15)
119
+ const finalScore = (scaledFlow + momScore + assetScore) / 3.0;
120
+
121
+ const gem_score = this._normalize(finalScore);
122
+ let signal = "Neutral";
123
+ if (gem_score > 7.0) signal = "Strong Buy";
124
+ else if (gem_score > 2.5) signal = "Buy";
125
+ else if (gem_score < -7.0) signal = "Strong Sell";
126
+ else if (gem_score < -2.5) signal = "Sell";
150
127
 
151
128
  result[ticker] = {
152
- raw_alpha_score: raw_alpha_score,
153
- signal_status: status,
154
- component_divergence_score: s_div,
155
- component_unskilled_fomo_score: s_fomo,
156
- component_platform_divergence_score: s_plat,
157
- component_social_sentiment_score: s_soc
129
+ signal: signal,
130
+ gem_score: gem_score,
131
+ components: {
132
+ flow_divergence: flowScore,
133
+ momentum_divergence: momScore,
134
+ asset_momentum: assetScore
135
+ }
158
136
  };
159
137
  }
160
138
 
161
- return result;
139
+ // --- STANDARD 2: SET STATE, DO NOT RETURN ---
140
+ this.result = result;
162
141
  }
163
142
 
143
+ // --- STANDARD 2: ADDED ---
144
+ async getResult(fetchedDependencies) {
145
+ return this.result;
146
+ }
147
+
148
+ // --- STANDARD 2: ADDED ---
164
149
  reset() {
165
- // No state
150
+ this.result = {};
166
151
  }
167
152
  }
168
-
169
153
  module.exports = QuantSkillAlphaSignal;