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.
- 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 -14
- 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 +9 -9
- package/README.MD +0 -78
|
@@ -1,141 +1,124 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
2
|
+
* @fileoverview Calculation (Pass 2 - Meta) for social posts trend.
|
|
3
|
+
* --- FIX ---
|
|
4
|
+
* 1. Changed 'process' signature to 5-arg 'meta' standard.
|
|
5
|
+
* 2. Changed data access to read 'dateStr.social' (Arg 1).
|
|
6
|
+
* 3. Changed 'socialDoc.posts' (Object) to 'socialDoc' (Object).
|
|
7
|
+
* 4. Changed 'post.timestamp' to 'post.createdAt'.
|
|
8
|
+
* 5. Changed 'post.instrumentIds' to 'post.tickers'.
|
|
9
|
+
* 6. Removed 'instrumentToTicker' mapping as 'post.tickers' is already tickers.
|
|
9
10
|
*/
|
|
11
|
+
|
|
10
12
|
class SocialAssetPostsTrend {
|
|
13
|
+
|
|
11
14
|
constructor() {
|
|
12
|
-
|
|
13
|
-
this.assetData = new Map();
|
|
15
|
+
this.result = {};
|
|
14
16
|
}
|
|
15
17
|
|
|
16
|
-
// --- NEW ---
|
|
17
|
-
/**
|
|
18
|
-
* Statically defines all metadata for the manifest builder.
|
|
19
|
-
*/
|
|
20
18
|
static getMetadata() {
|
|
21
19
|
return {
|
|
22
20
|
type: 'meta',
|
|
23
|
-
rootDataDependencies: ['social'],
|
|
24
|
-
isHistorical:
|
|
21
|
+
rootDataDependencies: ['social'],
|
|
22
|
+
isHistorical: true,
|
|
25
23
|
userType: 'n/a',
|
|
26
24
|
category: 'core_social'
|
|
27
25
|
};
|
|
28
26
|
}
|
|
29
27
|
|
|
30
|
-
// --- NEW ---
|
|
31
|
-
/**
|
|
32
|
-
* Statically declare dependencies.
|
|
33
|
-
*/
|
|
34
28
|
static getDependencies() {
|
|
35
29
|
return [];
|
|
36
30
|
}
|
|
37
31
|
|
|
38
|
-
/**
|
|
39
|
-
* Defines the output schema for this calculation.
|
|
40
|
-
* @returns {object} JSON Schema object
|
|
41
|
-
*/
|
|
42
32
|
static getSchema() {
|
|
43
33
|
const tickerSchema = {
|
|
44
34
|
"type": "object",
|
|
45
|
-
"description": "Daily and trended post count for a specific asset.",
|
|
46
35
|
"properties": {
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
},
|
|
51
|
-
"trend_30d_pct": {
|
|
52
|
-
"type": "number",
|
|
53
|
-
"description": "Percentage change from the 30-day average post count."
|
|
54
|
-
},
|
|
55
|
-
"history_30d": {
|
|
56
|
-
"type": "array",
|
|
57
|
-
"description": "30-day history of post counts (today first).",
|
|
58
|
-
"items": { "type": "number" }
|
|
59
|
-
}
|
|
36
|
+
"posts_1d_pct": { "type": "number" },
|
|
37
|
+
"posts_7d_pct": { "type": "number" },
|
|
38
|
+
"trend_ratio": { "type": ["number", "null"] }
|
|
60
39
|
},
|
|
61
|
-
"required": ["
|
|
40
|
+
"required": ["posts_1d_pct", "posts_7d_pct", "trend_ratio"]
|
|
62
41
|
};
|
|
63
42
|
|
|
64
43
|
return {
|
|
65
44
|
"type": "object",
|
|
66
|
-
"description": "
|
|
67
|
-
"patternProperties": {
|
|
68
|
-
"^.*$": tickerSchema // Ticker
|
|
69
|
-
},
|
|
45
|
+
"description": "Calculates the 1-day vs 7-day percentage of total posts for each asset.",
|
|
46
|
+
"patternProperties": { "^.*$": tickerSchema },
|
|
70
47
|
"additionalProperties": tickerSchema
|
|
71
48
|
};
|
|
72
49
|
}
|
|
73
50
|
|
|
74
|
-
// ---
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const yHistoryData = await calculationUtils.loadYesterdayData('social-asset-posts-trend');
|
|
86
|
-
|
|
87
|
-
// 2. Initialize state with history
|
|
88
|
-
if (yHistoryData) {
|
|
89
|
-
for (const [ticker, data] of Object.entries(yHistoryData)) {
|
|
90
|
-
this.assetData.set(ticker, {
|
|
91
|
-
count: 0, // Today's count starts at 0
|
|
92
|
-
history: data.history_30d || []
|
|
93
|
-
});
|
|
94
|
-
}
|
|
51
|
+
// --- THIS IS THE FIX ---
|
|
52
|
+
async process(dateStr, rootData, dependencies, config, fetchedDependencies) {
|
|
53
|
+
|
|
54
|
+
// Get social data from Arg 1 (metaPayload)
|
|
55
|
+
const socialDoc = dateStr.social; // This IS the map of posts
|
|
56
|
+
// Get the date from Arg 1
|
|
57
|
+
const todayDateStr = dateStr.date;
|
|
58
|
+
|
|
59
|
+
if (!socialDoc || typeof socialDoc !== 'object' || !todayDateStr) {
|
|
60
|
+
this.result = {};
|
|
61
|
+
return;
|
|
95
62
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
63
|
+
|
|
64
|
+
const today = new Date(todayDateStr + 'T00:00:00Z');
|
|
65
|
+
const sevenDaysAgo = new Date(today);
|
|
66
|
+
sevenDaysAgo.setUTCDate(today.getUTCDate() - 7);
|
|
67
|
+
|
|
68
|
+
const counts1d = new Map();
|
|
69
|
+
const counts7d = new Map();
|
|
70
|
+
let total1d = 0;
|
|
71
|
+
let total7d = 0;
|
|
72
|
+
|
|
73
|
+
for (const post of Object.values(socialDoc)) {
|
|
74
|
+
const postDate = new Date(post.createdAt); // Use 'createdAt'
|
|
75
|
+
const is1d = postDate.toISOString().slice(0, 10) === todayDateStr;
|
|
76
|
+
const is7d = postDate >= sevenDaysAgo;
|
|
77
|
+
|
|
78
|
+
if (!is7d) continue;
|
|
79
|
+
|
|
80
|
+
// Use 'tickers' array directly from schema
|
|
81
|
+
for (const ticker of (post.tickers || [])) {
|
|
82
|
+
if (!ticker) continue;
|
|
83
|
+
|
|
84
|
+
if (is7d) {
|
|
85
|
+
counts7d.set(ticker, (counts7d.get(ticker) || 0) + 1);
|
|
86
|
+
total7d++;
|
|
87
|
+
}
|
|
88
|
+
if (is1d) {
|
|
89
|
+
counts1d.set(ticker, (counts1d.get(ticker) || 0) + 1);
|
|
90
|
+
total1d++;
|
|
105
91
|
}
|
|
106
|
-
const data = this.assetData.get(ticker);
|
|
107
|
-
data.count++;
|
|
108
92
|
}
|
|
109
93
|
}
|
|
110
|
-
}
|
|
111
94
|
|
|
112
|
-
async getResult() {
|
|
113
95
|
const result = {};
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const avg_30d = history.reduce((a, b) => a + b, 0) / history.length;
|
|
123
|
-
if (avg_30d > 0) {
|
|
124
|
-
trend_30d_pct = ((todayCount - avg_30d) / avg_30d) * 100;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
96
|
+
const allTickers = new Set([...counts1d.keys(), ...counts7d.keys()]);
|
|
97
|
+
|
|
98
|
+
for (const ticker of allTickers) {
|
|
99
|
+
const c1 = counts1d.get(ticker) || 0;
|
|
100
|
+
const c7 = counts7d.get(ticker) || 0;
|
|
101
|
+
|
|
102
|
+
const pct1d = (total1d > 0) ? (c1 / total1d) * 100 : 0;
|
|
103
|
+
const pct7d = (total7d > 0) ? (c7 / total7d) * 100 : 0;
|
|
127
104
|
|
|
128
105
|
result[ticker] = {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
106
|
+
posts_1d_pct: pct1d,
|
|
107
|
+
posts_7d_pct: pct7d,
|
|
108
|
+
trend_ratio: (pct7d > 0) ? (pct1d / pct7d) : null
|
|
132
109
|
};
|
|
133
110
|
}
|
|
134
|
-
|
|
111
|
+
|
|
112
|
+
this.result = result;
|
|
113
|
+
}
|
|
114
|
+
// --- END FIX ---
|
|
115
|
+
|
|
116
|
+
async getResult(fetchedDependencies) {
|
|
117
|
+
return this.result;
|
|
135
118
|
}
|
|
136
119
|
|
|
137
120
|
reset() {
|
|
138
|
-
this.
|
|
121
|
+
this.result = {};
|
|
139
122
|
}
|
|
140
123
|
}
|
|
141
124
|
|
|
@@ -1,143 +1,124 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview
|
|
3
|
-
*
|
|
2
|
+
* @fileoverview Calculation (Pass 2 - Meta) for social event correlation.
|
|
3
|
+
* --- FIX ---
|
|
4
|
+
* 1. Changed 'process' signature to 5-arg 'meta' standard.
|
|
5
|
+
* 2. Changed data access to read 'dateStr.social' (Arg 1).
|
|
6
|
+
* 3. Changed 'socialDoc.posts' to 'socialDoc' (Object).
|
|
7
|
+
* 4. **Rewrote logic** to infer events from 'post.pollData' and
|
|
8
|
+
* 'post.sentiment.topics' as 'post.event' does not exist in schema.
|
|
4
9
|
*/
|
|
5
|
-
|
|
6
10
|
class SocialEventCorrelation {
|
|
11
|
+
|
|
7
12
|
constructor() {
|
|
8
|
-
this.
|
|
9
|
-
this.yesterdayTickerVolume = {};
|
|
10
|
-
this.todayTopicCounts = {}; // { "TICKER": { "topic": count } }
|
|
11
|
-
this.processed = false;
|
|
13
|
+
this.result = {};
|
|
12
14
|
}
|
|
13
15
|
|
|
14
|
-
// --- NEW ---
|
|
15
|
-
/**
|
|
16
|
-
* Statically defines all metadata for the manifest builder.
|
|
17
|
-
*/
|
|
18
16
|
static getMetadata() {
|
|
19
17
|
return {
|
|
20
|
-
type: '
|
|
18
|
+
type: 'meta',
|
|
21
19
|
rootDataDependencies: ['social'],
|
|
22
|
-
isHistorical:
|
|
23
|
-
userType: '
|
|
20
|
+
isHistorical: false,
|
|
21
|
+
userType: 'n/a',
|
|
24
22
|
category: 'core_social'
|
|
25
23
|
};
|
|
26
24
|
}
|
|
27
25
|
|
|
28
|
-
// --- NEW ---
|
|
29
|
-
/**
|
|
30
|
-
* Statically declare dependencies.
|
|
31
|
-
*/
|
|
32
26
|
static getDependencies() {
|
|
33
27
|
return [];
|
|
34
28
|
}
|
|
35
29
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
// 2. Aggregate Topics (if target provided)
|
|
54
|
-
if (topicTarget) {
|
|
55
|
-
if (!topicTarget[ticker]) {
|
|
56
|
-
topicTarget[ticker] = {};
|
|
57
|
-
}
|
|
58
|
-
// New structure: post.sentiment is { overallSentiment: "...", topics: [...] }
|
|
59
|
-
const topics = post.sentiment?.topics;
|
|
60
|
-
if (topics && Array.isArray(topics)) {
|
|
61
|
-
for (const topic of topics) {
|
|
62
|
-
// Normalize topic to lowercase for consistent counting
|
|
63
|
-
const normalizedTopic = topic.toLowerCase();
|
|
64
|
-
topicTarget[ticker][normalizedTopic] = (topicTarget[ticker][normalizedTopic] || 0) + 1;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
30
|
+
static getSchema() {
|
|
31
|
+
const eventSchema = {
|
|
32
|
+
"type": "object",
|
|
33
|
+
"properties": {
|
|
34
|
+
"topic_distribution": { "type": "object" },
|
|
35
|
+
"sentiment_distribution": { "type": "object" },
|
|
36
|
+
"post_count": { "type": "number" }
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
"type": "object",
|
|
42
|
+
"description": "Correlates social events (e.g., 'poll') with topic and sentiment distributions.",
|
|
43
|
+
"properties": {
|
|
44
|
+
"poll": eventSchema,
|
|
45
|
+
"earnings": eventSchema, // Inferred from topics
|
|
46
|
+
"launch": eventSchema // Inferred from topics
|
|
68
47
|
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
_initEvent(result, eventName) {
|
|
52
|
+
if (!result[eventName]) {
|
|
53
|
+
result[eventName] = {
|
|
54
|
+
topic_distribution: {},
|
|
55
|
+
sentiment_distribution: {},
|
|
56
|
+
post_count: 0
|
|
57
|
+
};
|
|
69
58
|
}
|
|
70
59
|
}
|
|
71
60
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
async process(todayPortfolio, yesterdayPortfolio, userId, context, todayInsights, yesterdayInsights, todaySocialPostInsights, yesterdaySocialPostInsights) {
|
|
83
|
-
|
|
84
|
-
if (this.processed) {
|
|
85
|
-
return; // Run only once
|
|
61
|
+
// --- THIS IS THE FIX ---
|
|
62
|
+
async process(dateStr, rootData, dependencies, config, fetchedDependencies) {
|
|
63
|
+
const result = {};
|
|
64
|
+
|
|
65
|
+
// Get social data from Arg 1 (metaPayload)
|
|
66
|
+
const socialDoc = dateStr.social; // This IS the map of posts
|
|
67
|
+
|
|
68
|
+
if (!socialDoc || typeof socialDoc !== 'object') {
|
|
69
|
+
this.result = {};
|
|
70
|
+
return;
|
|
86
71
|
}
|
|
87
|
-
this.processed = true;
|
|
88
72
|
|
|
89
|
-
|
|
90
|
-
this._processPosts(yesterdaySocialPostInsights, this.yesterdayTickerVolume);
|
|
73
|
+
for (const post of Object.values(socialDoc)) {
|
|
91
74
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
75
|
+
// Infer events from schema.md fields
|
|
76
|
+
const topics = post.sentiment?.topics || [];
|
|
77
|
+
const sentiment = post.sentiment?.overallSentiment || 'Neutral';
|
|
78
|
+
|
|
79
|
+
const detectedEvents = new Set();
|
|
95
80
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const results = {};
|
|
100
|
-
const allTickers = new Set([
|
|
101
|
-
...Object.keys(this.todayTickerVolume),
|
|
102
|
-
...Object.keys(this.yesterdayTickerVolume)
|
|
103
|
-
]);
|
|
104
|
-
|
|
105
|
-
for (const ticker of allTickers) {
|
|
106
|
-
const todayVolume = this.todayTickerVolume[ticker] || 0;
|
|
107
|
-
// Use 1 as baseline if yesterday was 0 to avoid -100% change, but 0 for spike calc
|
|
108
|
-
const yesterdayVolumeForCalc = this.yesterdayTickerVolume[ticker] || 0;
|
|
109
|
-
|
|
110
|
-
let volumeSpikePercent = 0;
|
|
111
|
-
if (yesterdayVolumeForCalc > 0) {
|
|
112
|
-
volumeSpikePercent = ((todayVolume - yesterdayVolumeForCalc) / yesterdayVolumeForCalc) * 100;
|
|
113
|
-
} else if (todayVolume > 0) {
|
|
114
|
-
volumeSpikePercent = todayVolume * 100.0; // e.g., 0 to 5 posts is a 500% increase
|
|
81
|
+
// Event 1: Check for Polls
|
|
82
|
+
if (post.pollData) {
|
|
83
|
+
detectedEvents.add('poll');
|
|
115
84
|
}
|
|
116
85
|
|
|
117
|
-
//
|
|
118
|
-
if (
|
|
86
|
+
// Event 2: Check for Topics as Events
|
|
87
|
+
if (topics.includes('Earnings')) {
|
|
88
|
+
detectedEvents.add('earnings');
|
|
89
|
+
}
|
|
90
|
+
// Add any other topic-based events you want to track
|
|
91
|
+
// if (topics.includes('Launch')) {
|
|
92
|
+
// detectedEvents.add('launch');
|
|
93
|
+
// }
|
|
119
94
|
|
|
120
|
-
|
|
121
|
-
const topics = this.todayTopicCounts[ticker] || {};
|
|
122
|
-
const correlatedEvents = Object.entries(topics)
|
|
123
|
-
.map(([topic, postCount]) => ({ topic, postCount }))
|
|
124
|
-
.sort((a, b) => b.postCount - a.postCount); // Sort by count descending
|
|
95
|
+
if (detectedEvents.size === 0) continue;
|
|
125
96
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
97
|
+
for (const eventName of detectedEvents) {
|
|
98
|
+
this._initEvent(result, eventName);
|
|
99
|
+
const eventData = result[eventName];
|
|
100
|
+
eventData.post_count++;
|
|
101
|
+
|
|
102
|
+
// Aggregate topics
|
|
103
|
+
for (const topic of topics) {
|
|
104
|
+
eventData.topic_distribution[topic] = (eventData.topic_distribution[topic] || 0) + 1;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Aggregate sentiment
|
|
108
|
+
eventData.sentiment_distribution[sentiment] = (eventData.sentiment_distribution[sentiment] || 0) + 1;
|
|
109
|
+
}
|
|
131
110
|
}
|
|
132
111
|
|
|
133
|
-
|
|
112
|
+
this.result = result;
|
|
113
|
+
}
|
|
114
|
+
// --- END FIX ---
|
|
115
|
+
|
|
116
|
+
async getResult(fetchedDependencies) {
|
|
117
|
+
return this.result;
|
|
134
118
|
}
|
|
135
119
|
|
|
136
120
|
reset() {
|
|
137
|
-
this.
|
|
138
|
-
this.yesterdayTickerVolume = {};
|
|
139
|
-
this.todayTopicCounts = {};
|
|
140
|
-
this.processed = false;
|
|
121
|
+
this.result = {};
|
|
141
122
|
}
|
|
142
123
|
}
|
|
143
124
|
|