aiden-shared-calculations-unified 1.0.83 → 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.
- package/calculations/core/asset-pnl-status.js +122 -104
- package/calculations/core/asset-position-size.js +110 -73
- package/calculations/core/average-daily-pnl-all-users.js +17 -3
- package/calculations/core/average-daily-pnl-per-sector.js +83 -75
- package/calculations/core/average-daily-pnl-per-stock.js +84 -73
- package/calculations/core/average-daily-position-pnl.js +2 -2
- package/calculations/core/holding-duration-per-asset.js +24 -23
- package/calculations/core/instrument-price-change-1d.js +72 -82
- package/calculations/core/instrument-price-momentum-20d.js +66 -100
- package/calculations/core/long-position-per-stock.js +21 -13
- package/calculations/core/overall-holding-duration.js +8 -3
- package/calculations/core/overall-profitability-ratio.js +2 -2
- package/calculations/core/platform-buy-sell-sentiment.js +75 -22
- package/calculations/core/platform-daily-bought-vs-sold-count.js +19 -10
- package/calculations/core/platform-daily-ownership-delta.js +39 -15
- package/calculations/core/platform-ownership-per-sector.js +38 -18
- package/calculations/core/platform-total-positions-held.js +36 -14
- package/calculations/core/pnl-distribution-per-stock.js +39 -36
- package/calculations/core/price-metrics.js +70 -172
- package/calculations/core/profitability-ratio-per-sector.js +23 -29
- package/calculations/core/profitability-ratio-per-stock.js +20 -13
- package/calculations/core/profitability-skew-per-stock.js +20 -13
- package/calculations/core/profitable-and-unprofitable-status.js +34 -10
- package/calculations/core/sentiment-per-stock.js +20 -9
- package/calculations/core/short-position-per-stock.js +23 -37
- package/calculations/core/social-activity-aggregation.js +41 -115
- package/calculations/core/social-asset-posts-trend.js +77 -94
- package/calculations/core/social-event-correlation.js +87 -106
- package/calculations/core/social-sentiment-aggregation.js +56 -138
- package/calculations/core/social-top-mentioned-words.js +74 -106
- package/calculations/core/social-topic-interest-evolution.js +94 -94
- package/calculations/core/social-topic-sentiment-matrix.js +90 -74
- package/calculations/core/social-word-mentions-trend.js +92 -106
- package/calculations/core/speculator-asset-sentiment.js +63 -92
- package/calculations/core/speculator-danger-zone.js +77 -90
- package/calculations/core/speculator-distance-to-stop-loss-per-leverage.js +75 -90
- package/calculations/core/speculator-distance-to-tp-per-leverage.js +75 -88
- package/calculations/core/speculator-entry-distance-to-sl-per-leverage.js +75 -90
- package/calculations/core/speculator-entry-distance-to-tp-per-leverage.js +74 -89
- package/calculations/core/speculator-leverage-per-asset.js +62 -57
- package/calculations/core/speculator-leverage-per-sector.js +53 -65
- package/calculations/core/speculator-risk-reward-ratio-per-asset.js +71 -76
- package/calculations/core/speculator-stop-loss-distance-by-sector-short-long-breakdown.js +60 -81
- package/calculations/core/speculator-stop-loss-distance-by-ticker-short-long-breakdown.js +57 -77
- package/calculations/core/speculator-stop-loss-per-asset.js +43 -80
- package/calculations/core/speculator-take-profit-per-asset.js +45 -69
- package/calculations/core/speculator-tsl-per-asset.js +42 -49
- package/calculations/core/total-long-figures.js +19 -19
- package/calculations/core/total-long-per-sector.js +39 -36
- package/calculations/core/total-short-figures.js +19 -19
- package/calculations/core/total-short-per-sector.js +39 -36
- package/calculations/core/users-processed.js +52 -25
- package/calculations/gauss/cohort-capital-flow.js +38 -29
- package/calculations/gauss/cohort-definer.js +17 -25
- package/calculations/gauss/daily-dna-filter.js +10 -4
- package/calculations/gauss/gauss-divergence-signal.js +28 -6
- package/calculations/gem/cohort-momentum-state.js +113 -92
- package/calculations/gem/cohort-skill-definition.js +23 -53
- package/calculations/gem/platform-conviction-divergence.js +62 -116
- package/calculations/gem/quant-skill-alpha-signal.js +107 -123
- package/calculations/gem/skilled-cohort-flow.js +178 -167
- package/calculations/gem/skilled-unskilled-divergence.js +73 -113
- package/calculations/gem/unskilled-cohort-flow.js +176 -166
- package/calculations/helix/helix-contrarian-signal.js +91 -83
- package/calculations/helix/herd-consensus-score.js +135 -97
- package/calculations/helix/winner-loser-flow.js +14 -16
- package/calculations/pyro/risk-appetite-index.js +121 -123
- package/calculations/pyro/squeeze-potential.js +93 -125
- package/calculations/pyro/volatility-signal.js +109 -97
- package/package.json +5 -5
- package/README.MD +0 -155
|
@@ -1,63 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview
|
|
2
|
+
* @fileoverview GEM Product Line (Pass 4)
|
|
3
3
|
*
|
|
4
|
-
* This
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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
|
-
|
|
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
|
-
//
|
|
77
|
-
'
|
|
78
|
-
'
|
|
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
|
-
|
|
87
|
-
|
|
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
|
-
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
const
|
|
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 (!
|
|
102
|
-
|
|
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 =
|
|
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
|
-
|
|
115
|
-
const
|
|
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
|
-
//
|
|
123
|
-
|
|
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
|
-
//
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
//
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
-
|
|
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
|
-
|
|
150
|
+
this.result = {};
|
|
166
151
|
}
|
|
167
152
|
}
|
|
168
|
-
|
|
169
153
|
module.exports = QuantSkillAlphaSignal;
|