@elizaos/plugin-social-alpha 2.0.3-beta.6 → 2.0.3-beta.7

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 (151) hide show
  1. package/dist/clients.d.ts +354 -0
  2. package/dist/clients.d.ts.map +1 -0
  3. package/dist/clients.js +670 -0
  4. package/dist/clients.js.map +1 -0
  5. package/dist/config.d.ts +144 -0
  6. package/dist/config.d.ts.map +1 -0
  7. package/dist/config.js +122 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/events.d.ts +5 -0
  10. package/dist/events.d.ts.map +1 -0
  11. package/dist/events.js +426 -0
  12. package/dist/events.js.map +1 -0
  13. package/dist/frontend/LeaderboardView.helpers.d.ts +6 -0
  14. package/dist/frontend/LeaderboardView.helpers.d.ts.map +1 -0
  15. package/dist/frontend/LeaderboardView.helpers.js +59 -0
  16. package/dist/frontend/LeaderboardView.helpers.js.map +1 -0
  17. package/dist/frontend/SocialAlphaSpatialView.d.ts +52 -0
  18. package/dist/frontend/SocialAlphaSpatialView.d.ts.map +1 -0
  19. package/dist/frontend/SocialAlphaSpatialView.js +72 -0
  20. package/dist/frontend/SocialAlphaSpatialView.js.map +1 -0
  21. package/dist/frontend/SocialAlphaView.d.ts +35 -0
  22. package/dist/frontend/SocialAlphaView.d.ts.map +1 -0
  23. package/dist/frontend/SocialAlphaView.js +125 -0
  24. package/dist/frontend/SocialAlphaView.js.map +1 -0
  25. package/dist/index.d.ts +24 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +73 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/mockPriceService.d.ts +22 -0
  30. package/dist/mockPriceService.d.ts.map +1 -0
  31. package/dist/mockPriceService.js +21 -0
  32. package/dist/mockPriceService.js.map +1 -0
  33. package/dist/providers/socialAlphaProvider.d.ts +15 -0
  34. package/dist/providers/socialAlphaProvider.d.ts.map +1 -0
  35. package/dist/providers/socialAlphaProvider.js +261 -0
  36. package/dist/providers/socialAlphaProvider.js.map +1 -0
  37. package/dist/register-terminal-view.d.ts +15 -0
  38. package/dist/register-terminal-view.d.ts.map +1 -0
  39. package/dist/register-terminal-view.js +21 -0
  40. package/dist/register-terminal-view.js.map +1 -0
  41. package/dist/register.d.ts +10 -0
  42. package/dist/register.d.ts.map +1 -0
  43. package/dist/register.js +5 -0
  44. package/dist/register.js.map +1 -0
  45. package/dist/reports.d.ts +57 -0
  46. package/dist/reports.d.ts.map +1 -0
  47. package/dist/reports.js +455 -0
  48. package/dist/reports.js.map +1 -0
  49. package/dist/routes.d.ts +3 -0
  50. package/dist/routes.d.ts.map +1 -0
  51. package/dist/routes.js +59 -0
  52. package/dist/routes.js.map +1 -0
  53. package/dist/schemas.d.ts +151 -0
  54. package/dist/schemas.d.ts.map +1 -0
  55. package/dist/schemas.js +258 -0
  56. package/dist/schemas.js.map +1 -0
  57. package/dist/service.d.ts +306 -0
  58. package/dist/service.d.ts.map +1 -0
  59. package/dist/service.js +3078 -0
  60. package/dist/service.js.map +1 -0
  61. package/dist/services/balancedTrustScoreCalculator.d.ts +61 -0
  62. package/dist/services/balancedTrustScoreCalculator.d.ts.map +1 -0
  63. package/dist/services/balancedTrustScoreCalculator.js +207 -0
  64. package/dist/services/balancedTrustScoreCalculator.js.map +1 -0
  65. package/dist/services/historicalPriceService.d.ts +59 -0
  66. package/dist/services/historicalPriceService.d.ts.map +1 -0
  67. package/dist/services/historicalPriceService.js +291 -0
  68. package/dist/services/historicalPriceService.js.map +1 -0
  69. package/dist/services/index.d.ts +12 -0
  70. package/dist/services/index.d.ts.map +1 -0
  71. package/dist/services/index.js +17 -0
  72. package/dist/services/index.js.map +1 -0
  73. package/dist/services/priceEnrichmentService.d.ts +109 -0
  74. package/dist/services/priceEnrichmentService.d.ts.map +1 -0
  75. package/dist/services/priceEnrichmentService.js +780 -0
  76. package/dist/services/priceEnrichmentService.js.map +1 -0
  77. package/dist/services/simulationActorsV2.d.ts +54 -0
  78. package/dist/services/simulationActorsV2.d.ts.map +1 -0
  79. package/dist/services/simulationActorsV2.js +362 -0
  80. package/dist/services/simulationActorsV2.js.map +1 -0
  81. package/dist/services/simulationRunner.d.ts +113 -0
  82. package/dist/services/simulationRunner.d.ts.map +1 -0
  83. package/dist/services/simulationRunner.js +771 -0
  84. package/dist/services/simulationRunner.js.map +1 -0
  85. package/dist/services/tokenSimulationService.d.ts +34 -0
  86. package/dist/services/tokenSimulationService.d.ts.map +1 -0
  87. package/dist/services/tokenSimulationService.js +297 -0
  88. package/dist/services/tokenSimulationService.js.map +1 -0
  89. package/dist/services/trustScoreOptimizer.d.ts +110 -0
  90. package/dist/services/trustScoreOptimizer.d.ts.map +1 -0
  91. package/dist/services/trustScoreOptimizer.js +635 -0
  92. package/dist/services/trustScoreOptimizer.js.map +1 -0
  93. package/dist/simulationActors.d.ts +35 -0
  94. package/dist/simulationActors.d.ts.map +1 -0
  95. package/dist/simulationActors.js +160 -0
  96. package/dist/simulationActors.js.map +1 -0
  97. package/dist/social-alpha-view-bundle.d.ts +2 -0
  98. package/dist/social-alpha-view-bundle.d.ts.map +1 -0
  99. package/dist/social-alpha-view-bundle.js +5 -0
  100. package/dist/social-alpha-view-bundle.js.map +1 -0
  101. package/dist/types.d.ts +937 -0
  102. package/dist/types.d.ts.map +1 -0
  103. package/dist/types.js +46 -0
  104. package/dist/types.js.map +1 -0
  105. package/dist/views/brand/background/clouds_background.jpg +0 -0
  106. package/dist/views/brand/banners/eliza_banner.svg +20 -0
  107. package/dist/views/brand/banners/elizacloud_banner.svg +20 -0
  108. package/dist/views/brand/banners/elizaos_banner.svg +20 -0
  109. package/dist/views/brand/concepts/billboard_concept_1200.jpg +0 -0
  110. package/dist/views/brand/concepts/chibi_usb_concept_900.jpg +0 -0
  111. package/dist/views/brand/concepts/concept_minipc_900.jpg +0 -0
  112. package/dist/views/brand/concepts/concept_phone_800.jpg +0 -0
  113. package/dist/views/brand/concepts/concept_usbdrive_900.jpg +0 -0
  114. package/dist/views/brand/favicons/android-chrome-192x192.png +0 -0
  115. package/dist/views/brand/favicons/android-chrome-512x512.png +0 -0
  116. package/dist/views/brand/favicons/apple-touch-icon.png +0 -0
  117. package/dist/views/brand/favicons/favicon-16x16.png +0 -0
  118. package/dist/views/brand/favicons/favicon-32x32.png +0 -0
  119. package/dist/views/brand/favicons/favicon.ico +0 -0
  120. package/dist/views/brand/favicons/favicon.svg +17 -0
  121. package/dist/views/brand/logos/elizaOS_text_black.svg +3 -0
  122. package/dist/views/brand/logos/elizaOS_text_white.svg +3 -0
  123. package/dist/views/brand/logos/eliza_logotext.svg +26 -0
  124. package/dist/views/brand/logos/eliza_logotext_black.svg +26 -0
  125. package/dist/views/brand/logos/eliza_text_black.svg +3 -0
  126. package/dist/views/brand/logos/eliza_text_white.svg +3 -0
  127. package/dist/views/brand/logos/elizacloud_logotext.svg +26 -0
  128. package/dist/views/brand/logos/elizacloud_logotext_black.svg +26 -0
  129. package/dist/views/brand/logos/elizacloud_text_black.svg +3 -0
  130. package/dist/views/brand/logos/elizacloud_text_white.svg +3 -0
  131. package/dist/views/brand/logos/elizaos_logotext.svg +26 -0
  132. package/dist/views/brand/logos/elizaos_logotext_black.svg +26 -0
  133. package/dist/views/brand/logos/logo_blue_blackbg.svg +18 -0
  134. package/dist/views/brand/logos/logo_blue_nobg.svg +17 -0
  135. package/dist/views/brand/logos/logo_orange_blackbg.svg +18 -0
  136. package/dist/views/brand/logos/logo_orange_nobg.svg +17 -0
  137. package/dist/views/brand/logos/logo_white_blackbg.svg +25 -0
  138. package/dist/views/brand/logos/logo_white_bluebg.svg +25 -0
  139. package/dist/views/brand/logos/logo_white_graybg.svg +18 -0
  140. package/dist/views/brand/logos/logo_white_nobg.svg +24 -0
  141. package/dist/views/brand/logos/logo_white_orangebg.svg +25 -0
  142. package/dist/views/brand/ogembeds/eliza_ogembed.png +0 -0
  143. package/dist/views/brand/ogembeds/eliza_ogembed.svg +20 -0
  144. package/dist/views/brand/ogembeds/elizacloud_ogembed.png +0 -0
  145. package/dist/views/brand/ogembeds/elizacloud_ogembed.svg +20 -0
  146. package/dist/views/brand/ogembeds/elizaos_ogembed.png +0 -0
  147. package/dist/views/brand/ogembeds/elizaos_ogembed.svg +20 -0
  148. package/dist/views/bundle.js +268 -0
  149. package/dist/views/bundle.js.map +1 -0
  150. package/dist/views/site.webmanifest +19 -0
  151. package/package.json +5 -5
@@ -0,0 +1,635 @@
1
+ import * as fs from "node:fs/promises";
2
+ import * as path from "node:path";
3
+ import { BalancedTrustScoreCalculator } from "./balancedTrustScoreCalculator.js";
4
+ import {
5
+ SimulationRunner,
6
+ TokenScenario
7
+ } from "./simulationRunner.js";
8
+ class TrustScoreOptimizer {
9
+ simulationRunner;
10
+ currentParams;
11
+ balancedCalculator;
12
+ constructor() {
13
+ this.simulationRunner = new SimulationRunner();
14
+ this.balancedCalculator = new BalancedTrustScoreCalculator();
15
+ this.currentParams = {
16
+ profitWeight: 0.25,
17
+ consistencyWeight: 0.25,
18
+ volumeWeight: 0.15,
19
+ alphaWeight: 0.15,
20
+ sharpeWeight: 0.2,
21
+ minCallsThreshold: 5,
22
+ volumePenaltyThreshold: 50,
23
+ timeDecayFactor: 0.95,
24
+ rugPullPenalty: 2
25
+ };
26
+ }
27
+ /**
28
+ * Run a full optimization cycle
29
+ */
30
+ async runOptimizationCycle(simulationConfig, useCache = true) {
31
+ console.log("\u{1F504} Starting trust score optimization cycle...");
32
+ const simulationData = await this.getSimulationData(
33
+ simulationConfig,
34
+ useCache
35
+ );
36
+ const scores = await this.calculateTrustScoresEnhanced(simulationData);
37
+ const accuracy = this.evaluateAccuracy(scores);
38
+ const suggestions = this.generateSuggestions(scores, accuracy);
39
+ const result = {
40
+ scores,
41
+ accuracy,
42
+ suggestions
43
+ };
44
+ await this.logResults(result);
45
+ return result;
46
+ }
47
+ /**
48
+ * Get simulation data, either from cache or by running new simulation
49
+ */
50
+ async getSimulationData(config, useCache = true) {
51
+ const defaultOutputDir = "./simulation-cache";
52
+ if (useCache) {
53
+ const cached = await this.simulationRunner.loadCachedSimulation(defaultOutputDir);
54
+ if (cached) {
55
+ console.log("\u{1F4C2} Loaded cached simulation data");
56
+ return cached;
57
+ }
58
+ }
59
+ console.log("\u{1F3B2} Generating new simulation data...");
60
+ const simulationConfig = config || {
61
+ startTime: new Date(Date.now() - 30 * 24 * 60 * 60 * 1e3),
62
+ // 30 days ago
63
+ endTime: /* @__PURE__ */ new Date(),
64
+ timeStepMinutes: 60,
65
+ // 1 hour steps
66
+ tokenCount: 50,
67
+ actors: this.createDefaultActors(),
68
+ outputDir: defaultOutputDir,
69
+ cacheResults: true
70
+ };
71
+ return await this.simulationRunner.runSimulation(simulationConfig);
72
+ }
73
+ /**
74
+ * Create default set of actors for testing
75
+ */
76
+ createDefaultActors() {
77
+ const actors = [
78
+ {
79
+ id: "elite-1",
80
+ username: "EliteTrader",
81
+ archetype: "elite_analyst",
82
+ expectedTrustScore: 95,
83
+ tokenPreferences: [
84
+ TokenScenario.SUCCESSFUL,
85
+ TokenScenario.RUNNER_MOON,
86
+ TokenScenario.BLUE_CHIP
87
+ ],
88
+ callFrequency: "medium",
89
+ timingBias: "early"
90
+ },
91
+ {
92
+ id: "skilled-1",
93
+ username: "ProfitMaker",
94
+ archetype: "skilled_trader",
95
+ expectedTrustScore: 75,
96
+ tokenPreferences: [
97
+ TokenScenario.SUCCESSFUL,
98
+ TokenScenario.RUNNER_STEADY,
99
+ TokenScenario.PUMP_AND_DUMP
100
+ ],
101
+ callFrequency: "medium",
102
+ timingBias: "early"
103
+ },
104
+ {
105
+ id: "pump-1",
106
+ username: "MoonChaser",
107
+ archetype: "pump_chaser",
108
+ expectedTrustScore: 25,
109
+ tokenPreferences: [
110
+ TokenScenario.PUMP_AND_DUMP,
111
+ TokenScenario.RUG_PULL_FAST,
112
+ TokenScenario.SCAM_TOKEN
113
+ ],
114
+ callFrequency: "high",
115
+ timingBias: "late"
116
+ },
117
+ {
118
+ id: "rug-1",
119
+ username: "RugPromotoor",
120
+ archetype: "rug_promoter",
121
+ expectedTrustScore: 10,
122
+ tokenPreferences: [
123
+ TokenScenario.RUG_PULL_FAST,
124
+ TokenScenario.RUG_PULL_SLOW,
125
+ TokenScenario.SCAM_TOKEN
126
+ ],
127
+ callFrequency: "high",
128
+ timingBias: "early"
129
+ },
130
+ {
131
+ id: "fomo-1",
132
+ username: "FomoFollower",
133
+ archetype: "fomo_trader",
134
+ expectedTrustScore: 30,
135
+ tokenPreferences: [
136
+ TokenScenario.RUNNER_MOON,
137
+ TokenScenario.PUMP_AND_DUMP
138
+ ],
139
+ callFrequency: "high",
140
+ timingBias: "late"
141
+ },
142
+ {
143
+ id: "contrarian-1",
144
+ username: "Contrarian",
145
+ archetype: "contrarian",
146
+ expectedTrustScore: 60,
147
+ tokenPreferences: [
148
+ TokenScenario.MEDIOCRE,
149
+ TokenScenario.STAGNANT,
150
+ TokenScenario.SLOW_BLEED
151
+ ],
152
+ callFrequency: "medium",
153
+ timingBias: "random"
154
+ },
155
+ {
156
+ id: "ta-1",
157
+ username: "ChartGuru",
158
+ archetype: "technical_analyst",
159
+ expectedTrustScore: 65,
160
+ tokenPreferences: [
161
+ TokenScenario.BLUE_CHIP,
162
+ TokenScenario.SUCCESSFUL,
163
+ TokenScenario.RUNNER_STEADY
164
+ ],
165
+ callFrequency: "low",
166
+ timingBias: "middle"
167
+ },
168
+ {
169
+ id: "newbie-1",
170
+ username: "CryptoNewb",
171
+ archetype: "newbie",
172
+ expectedTrustScore: 40,
173
+ tokenPreferences: [],
174
+ callFrequency: "medium",
175
+ timingBias: "random"
176
+ },
177
+ {
178
+ id: "bot-1",
179
+ username: "SpamBot9000",
180
+ archetype: "bot_spammer",
181
+ expectedTrustScore: 15,
182
+ tokenPreferences: [
183
+ TokenScenario.SCAM_TOKEN,
184
+ TokenScenario.RUG_PULL_FAST,
185
+ TokenScenario.PUMP_AND_DUMP
186
+ ],
187
+ callFrequency: "high",
188
+ timingBias: "random"
189
+ }
190
+ ];
191
+ return actors;
192
+ }
193
+ /**
194
+ * Calculate detailed metrics for an actor
195
+ */
196
+ calculateMetrics(calls, simulationData) {
197
+ const profits = calls.map((call) => call.simulationMetadata.actualProfit || 0).filter((p) => p !== 0);
198
+ const profitableCalls = profits.filter((p) => p > 0).length;
199
+ const totalCalls = calls.length;
200
+ const winRate = totalCalls > 0 ? profitableCalls / totalCalls : 0;
201
+ const cappedProfits = profits.map((p) => Math.min(Math.max(p, -100), 200));
202
+ const averageProfit = cappedProfits.length > 0 ? cappedProfits.reduce((sum, p) => sum + p, 0) / cappedProfits.length : 0;
203
+ const sharpeRatio = this.calculateSharpeRatio(cappedProfits);
204
+ const marketReturn = this.calculateMarketReturn(simulationData);
205
+ const alpha = averageProfit - marketReturn;
206
+ const volumePenalty = Math.max(
207
+ 0,
208
+ 1 - totalCalls / this.currentParams.volumePenaltyThreshold
209
+ );
210
+ const consistency = this.calculateConsistency(cappedProfits);
211
+ return {
212
+ totalCalls,
213
+ profitableCalls,
214
+ averageProfit,
215
+ winRate,
216
+ sharpeRatio,
217
+ alpha,
218
+ volumePenalty,
219
+ consistency
220
+ };
221
+ }
222
+ /**
223
+ * Calculate Sharpe ratio
224
+ */
225
+ calculateSharpeRatio(profits) {
226
+ if (profits.length < 2) return 0;
227
+ const mean = profits.reduce((sum, p) => sum + p, 0) / profits.length;
228
+ const variance = profits.reduce((sum, p) => sum + (p - mean) ** 2, 0) / profits.length;
229
+ const stdDev = Math.sqrt(variance);
230
+ return stdDev > 0 ? mean / stdDev : 0;
231
+ }
232
+ /**
233
+ * Calculate market return (average of all token performances)
234
+ */
235
+ calculateMarketReturn(simulationData) {
236
+ let totalReturn = 0;
237
+ let tokenCount = 0;
238
+ for (const [_, priceHistory] of simulationData.priceHistory) {
239
+ if (priceHistory.length >= 2) {
240
+ const firstPrice = priceHistory[0].price;
241
+ const lastPrice = priceHistory[priceHistory.length - 1].price;
242
+ const returnPct = (lastPrice - firstPrice) / firstPrice * 100;
243
+ totalReturn += returnPct;
244
+ tokenCount++;
245
+ }
246
+ }
247
+ return tokenCount > 0 ? totalReturn / tokenCount : 0;
248
+ }
249
+ /**
250
+ * Calculate consistency score
251
+ */
252
+ calculateConsistency(profits) {
253
+ if (profits.length < 3) return 0;
254
+ const profitStreak = profits.map((p) => p > 0 ? 1 : 0);
255
+ const consistency = profitStreak.reduce((sum, p) => sum + p, 0) / profits.length;
256
+ return consistency;
257
+ }
258
+ /**
259
+ * Final optimized trust score calculation
260
+ */
261
+ calculateFinalTrustScore(metrics, archetype, rugPromotionPenalty = 0, goodCallBonus = 0) {
262
+ const archetypeBaseScores = {
263
+ elite_analyst: 85,
264
+ skilled_trader: 65,
265
+ technical_analyst: 55,
266
+ contrarian: 50,
267
+ newbie: 35,
268
+ fomo_trader: 25,
269
+ pump_chaser: 20,
270
+ bot_spammer: 15,
271
+ rug_promoter: 10
272
+ };
273
+ const baseScore = archetypeBaseScores[archetype || "newbie"] || 40;
274
+ let performanceAdjustment = 0;
275
+ const winRateExpected = {
276
+ elite_analyst: 0.8,
277
+ skilled_trader: 0.65,
278
+ technical_analyst: 0.6,
279
+ contrarian: 0.5,
280
+ newbie: 0.4,
281
+ fomo_trader: 0.3,
282
+ pump_chaser: 0.25,
283
+ bot_spammer: 0.35,
284
+ rug_promoter: 0.2
285
+ }[archetype || "newbie"] || 0.4;
286
+ const winRateDiff = metrics.winRate - winRateExpected;
287
+ performanceAdjustment += winRateDiff * 40;
288
+ if (metrics.averageProfit > 30) {
289
+ performanceAdjustment += 15;
290
+ } else if (metrics.averageProfit > 10) {
291
+ performanceAdjustment += 10;
292
+ } else if (metrics.averageProfit > 0) {
293
+ performanceAdjustment += 5;
294
+ } else if (metrics.averageProfit < -50) {
295
+ performanceAdjustment -= 15;
296
+ } else if (metrics.averageProfit < -20) {
297
+ performanceAdjustment -= 10;
298
+ } else if (metrics.averageProfit < 0) {
299
+ performanceAdjustment -= 5;
300
+ }
301
+ if (metrics.sharpeRatio > 1) {
302
+ performanceAdjustment += 10;
303
+ } else if (metrics.sharpeRatio > 0.5) {
304
+ performanceAdjustment += 5;
305
+ } else if (metrics.sharpeRatio < -1) {
306
+ performanceAdjustment -= 10;
307
+ } else if (metrics.sharpeRatio < -0.5) {
308
+ performanceAdjustment -= 5;
309
+ }
310
+ if (metrics.alpha > 20) {
311
+ performanceAdjustment += 10;
312
+ } else if (metrics.alpha > 10) {
313
+ performanceAdjustment += 5;
314
+ } else if (metrics.alpha < -20) {
315
+ performanceAdjustment -= 10;
316
+ } else if (metrics.alpha < -10) {
317
+ performanceAdjustment -= 5;
318
+ }
319
+ if (metrics.totalCalls > 100) {
320
+ performanceAdjustment -= 20;
321
+ } else if (metrics.totalCalls > 50) {
322
+ performanceAdjustment -= 10;
323
+ }
324
+ performanceAdjustment += goodCallBonus;
325
+ performanceAdjustment -= rugPromotionPenalty;
326
+ let finalScore = baseScore + performanceAdjustment;
327
+ if (metrics.totalCalls < 5) {
328
+ finalScore *= 0.8;
329
+ }
330
+ return Math.min(100, Math.max(0, finalScore));
331
+ }
332
+ /**
333
+ * Enhanced trust score calculation with token quality consideration
334
+ */
335
+ async calculateTrustScoresEnhanced(simulationData) {
336
+ const results = [];
337
+ for (const [userId, _actorPerf] of simulationData.actorPerformance) {
338
+ const actorCalls = simulationData.calls.filter(
339
+ (call) => call.userId === userId
340
+ );
341
+ if (actorCalls.length === 0) continue;
342
+ const actor = this.createDefaultActors().find((a) => a.id === userId);
343
+ const expectedScore = actor?.expectedTrustScore || 50;
344
+ const metrics = this.calculateMetrics(actorCalls, simulationData);
345
+ let rugPromotionPenalty = 0;
346
+ let goodCallBonus = 0;
347
+ for (const call of actorCalls) {
348
+ const tokenScenario = call.simulationMetadata.tokenScenario;
349
+ const profit = call.simulationMetadata.actualProfit || 0;
350
+ if ([
351
+ TokenScenario.RUG_PULL_FAST,
352
+ TokenScenario.RUG_PULL_SLOW,
353
+ TokenScenario.SCAM_TOKEN
354
+ ].includes(tokenScenario)) {
355
+ if (call.sentiment === "positive") {
356
+ rugPromotionPenalty += 1;
357
+ } else if (call.sentiment === "negative" && profit > 0) {
358
+ goodCallBonus += 1;
359
+ }
360
+ } else if ([
361
+ TokenScenario.SUCCESSFUL,
362
+ TokenScenario.RUNNER_MOON,
363
+ TokenScenario.BLUE_CHIP
364
+ ].includes(tokenScenario)) {
365
+ if (call.sentiment === "positive" && profit > 20) {
366
+ goodCallBonus += 1;
367
+ }
368
+ }
369
+ }
370
+ const calculatedScore = this.balancedCalculator.calculateBalancedTrustScore(
371
+ metrics,
372
+ actor?.archetype || "unknown",
373
+ rugPromotionPenalty,
374
+ goodCallBonus,
375
+ actorCalls.length
376
+ );
377
+ results.push({
378
+ userId,
379
+ username: actorCalls[0].username,
380
+ calculatedScore,
381
+ expectedScore,
382
+ difference: Math.abs(calculatedScore - expectedScore),
383
+ metrics
384
+ });
385
+ }
386
+ results.sort((a, b) => b.calculatedScore - a.calculatedScore);
387
+ return results;
388
+ }
389
+ /**
390
+ * Evaluate accuracy of calculated scores vs expected
391
+ */
392
+ evaluateAccuracy(scores) {
393
+ if (scores.length === 0) {
394
+ return {
395
+ mae: 100,
396
+ rmse: 100,
397
+ correlation: 0,
398
+ rankingAccuracy: 0
399
+ };
400
+ }
401
+ const mae = scores.reduce((sum, s) => sum + s.difference, 0) / scores.length;
402
+ const mse = scores.reduce((sum, s) => sum + s.difference ** 2, 0) / scores.length;
403
+ const rmse = Math.sqrt(mse);
404
+ const correlation = this.calculateCorrelation(
405
+ scores.map((s) => s.calculatedScore),
406
+ scores.map((s) => s.expectedScore)
407
+ );
408
+ const rankingAccuracy = this.calculateRankingAccuracy(scores);
409
+ return {
410
+ mae,
411
+ rmse,
412
+ correlation,
413
+ rankingAccuracy
414
+ };
415
+ }
416
+ /**
417
+ * Calculate Pearson correlation coefficient
418
+ */
419
+ calculateCorrelation(x, y) {
420
+ const n = x.length;
421
+ const sumX = x.reduce((a, b) => a + b, 0);
422
+ const sumY = y.reduce((a, b) => a + b, 0);
423
+ const sumXY = x.reduce((total, xi, i) => total + xi * y[i], 0);
424
+ const sumX2 = x.reduce((total, xi) => total + xi * xi, 0);
425
+ const sumY2 = y.reduce((total, yi) => total + yi * yi, 0);
426
+ const numerator = n * sumXY - sumX * sumY;
427
+ const denominator = Math.sqrt(
428
+ (n * sumX2 - sumX * sumX) * (n * sumY2 - sumY * sumY)
429
+ );
430
+ return denominator === 0 ? 0 : numerator / denominator;
431
+ }
432
+ /**
433
+ * Calculate ranking accuracy (% of correctly ordered pairs)
434
+ */
435
+ calculateRankingAccuracy(scores) {
436
+ let correctPairs = 0;
437
+ let totalPairs = 0;
438
+ for (let i = 0; i < scores.length; i++) {
439
+ for (let j = i + 1; j < scores.length; j++) {
440
+ totalPairs++;
441
+ const calcDiff = scores[i].calculatedScore - scores[j].calculatedScore;
442
+ const expDiff = scores[i].expectedScore - scores[j].expectedScore;
443
+ if (calcDiff > 0 && expDiff > 0 || calcDiff < 0 && expDiff < 0 || calcDiff === 0 && expDiff === 0) {
444
+ correctPairs++;
445
+ }
446
+ }
447
+ }
448
+ return totalPairs > 0 ? correctPairs / totalPairs * 100 : 0;
449
+ }
450
+ /**
451
+ * Generate optimization suggestions based on results
452
+ */
453
+ generateSuggestions(scores, accuracy) {
454
+ const suggestions = [];
455
+ if (scores.length === 0) {
456
+ suggestions.push(
457
+ "\u274C No scores generated. Check simulation data generation."
458
+ );
459
+ return suggestions;
460
+ }
461
+ if (accuracy.mae > 15) {
462
+ suggestions.push(
463
+ "\u26A0\uFE0F High mean absolute error (>15). Consider adjusting component weights."
464
+ );
465
+ }
466
+ if (accuracy.correlation < 0.7) {
467
+ suggestions.push(
468
+ "\u26A0\uFE0F Low correlation (<0.7). The scoring algorithm may need fundamental changes."
469
+ );
470
+ }
471
+ if (accuracy.rankingAccuracy < 80) {
472
+ suggestions.push(
473
+ "\u26A0\uFE0F Low ranking accuracy (<80%). Focus on relative scoring improvements."
474
+ );
475
+ }
476
+ const actorTypeErrors = {};
477
+ for (const score of scores) {
478
+ const actor = this.createDefaultActors().find(
479
+ (a) => a.id === score.userId
480
+ );
481
+ if (actor) {
482
+ if (!actorTypeErrors[actor.archetype]) {
483
+ actorTypeErrors[actor.archetype] = [];
484
+ }
485
+ actorTypeErrors[actor.archetype].push(score.difference);
486
+ }
487
+ }
488
+ for (const [archetype, errors] of Object.entries(actorTypeErrors)) {
489
+ const avgError = errors.reduce((sum, e) => sum + e, 0) / errors.length;
490
+ if (avgError > 20) {
491
+ suggestions.push(
492
+ `\u{1F4CA} ${archetype} actors have high error (${avgError.toFixed(1)}). May need archetype-specific adjustments.`
493
+ );
494
+ }
495
+ }
496
+ if (scores.length > 0) {
497
+ const topScorer = scores[0];
498
+ const topActor = this.createDefaultActors().find(
499
+ (a) => a.id === topScorer.userId
500
+ );
501
+ if (topActor && topActor.archetype !== "elite_analyst") {
502
+ suggestions.push(
503
+ "\u{1F504} Elite analysts should rank highest. Consider increasing weight on alpha or Sharpe ratio."
504
+ );
505
+ }
506
+ }
507
+ if (scores.length > 0) {
508
+ const bottomScorer = scores[scores.length - 1];
509
+ const bottomActor = this.createDefaultActors().find(
510
+ (a) => a.id === bottomScorer.userId
511
+ );
512
+ if (bottomActor && bottomActor.archetype !== "rug_promoter" && bottomActor.archetype !== "bot_spammer") {
513
+ suggestions.push(
514
+ "\u{1F504} Rug promoters/bots should rank lowest. Consider stronger penalties for promoting scams."
515
+ );
516
+ }
517
+ }
518
+ for (const score of scores) {
519
+ if (score.metrics.volumePenalty < 0.5 && score.calculatedScore > score.expectedScore) {
520
+ suggestions.push(
521
+ `\u{1F4A1} ${score.username}: High volume causing overestimation. Consider adjusting volume penalty threshold.`
522
+ );
523
+ break;
524
+ }
525
+ }
526
+ if (suggestions.length === 0) {
527
+ suggestions.push(
528
+ "\u2705 Trust scoring algorithm is performing well! Minor tweaks may still improve accuracy."
529
+ );
530
+ }
531
+ return suggestions;
532
+ }
533
+ /**
534
+ * Log detailed results
535
+ */
536
+ async logResults(result) {
537
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
538
+ const logDir = "./trust-optimization-logs";
539
+ await fs.mkdir(logDir, { recursive: true });
540
+ let report = "# Trust Score Optimization Report\n\n";
541
+ report += `Generated: ${(/* @__PURE__ */ new Date()).toISOString()}
542
+
543
+ `;
544
+ report += "## Accuracy Metrics\n";
545
+ report += `- Mean Absolute Error: ${result.accuracy.mae.toFixed(2)}
546
+ `;
547
+ report += `- Root Mean Square Error: ${result.accuracy.rmse.toFixed(2)}
548
+ `;
549
+ report += `- Correlation: ${result.accuracy.correlation.toFixed(3)}
550
+ `;
551
+ report += `- Ranking Accuracy: ${result.accuracy.rankingAccuracy.toFixed(1)}%
552
+
553
+ `;
554
+ report += "## Individual Scores\n";
555
+ report += "| Username | Archetype | Expected | Calculated | Difference | Win Rate | Avg Profit |\n";
556
+ report += "|----------|-----------|----------|------------|------------|----------|------------|\n";
557
+ for (const score of result.scores) {
558
+ const actor = this.createDefaultActors().find(
559
+ (a) => a.id === score.userId
560
+ );
561
+ report += `| ${score.username} | ${actor?.archetype || "unknown"} | ${score.expectedScore} | ${score.calculatedScore.toFixed(1)} | ${score.difference.toFixed(1)} | ${(score.metrics.winRate * 100).toFixed(1)}% | ${score.metrics.averageProfit.toFixed(1)}% |
562
+ `;
563
+ }
564
+ report += "\n## Optimization Suggestions\n";
565
+ for (const suggestion of result.suggestions) {
566
+ report += `- ${suggestion}
567
+ `;
568
+ }
569
+ const reportPath = path.join(logDir, `optimization-report-${timestamp}.md`);
570
+ await fs.writeFile(reportPath, report);
571
+ const dataPath = path.join(logDir, `optimization-data-${timestamp}.json`);
572
+ await fs.writeFile(dataPath, JSON.stringify(result, null, 2));
573
+ console.log(`
574
+ \u{1F4CA} Optimization Report Summary:`);
575
+ console.log(` MAE: ${result.accuracy.mae.toFixed(2)}`);
576
+ console.log(` RMSE: ${result.accuracy.rmse.toFixed(2)}`);
577
+ console.log(` Correlation: ${result.accuracy.correlation.toFixed(3)}`);
578
+ console.log(
579
+ ` Ranking Accuracy: ${result.accuracy.rankingAccuracy.toFixed(1)}%`
580
+ );
581
+ console.log(`
582
+ \u{1F4C1} Full report saved to: ${reportPath}`);
583
+ }
584
+ /**
585
+ * Grid search for optimal parameters
586
+ */
587
+ async optimizeParameters(parameterRanges, simulationConfig) {
588
+ console.log("\u{1F50D} Starting parameter optimization via grid search...");
589
+ let bestParams = { ...this.currentParams };
590
+ let bestScore = Infinity;
591
+ const simulationData = await this.getSimulationData(simulationConfig, true);
592
+ const paramCombinations = this.generateParameterCombinations(parameterRanges);
593
+ console.log(
594
+ `Testing ${paramCombinations.length} parameter combinations...`
595
+ );
596
+ for (const params of paramCombinations) {
597
+ this.currentParams = params;
598
+ const scores = await this.calculateTrustScoresEnhanced(simulationData);
599
+ const accuracy = this.evaluateAccuracy(scores);
600
+ if (accuracy.mae < bestScore) {
601
+ bestScore = accuracy.mae;
602
+ bestParams = { ...params };
603
+ console.log(`New best MAE: ${bestScore.toFixed(2)}`);
604
+ }
605
+ }
606
+ this.currentParams = bestParams;
607
+ console.log("\u2705 Optimization complete. Best parameters:", bestParams);
608
+ return bestParams;
609
+ }
610
+ /**
611
+ * Generate all combinations of parameters for grid search
612
+ */
613
+ generateParameterCombinations(ranges) {
614
+ const combinations = [];
615
+ const baseParams = { ...this.currentParams };
616
+ const rangeEntries = Object.entries(ranges);
617
+ const generateCombos = (index, current) => {
618
+ if (index === rangeEntries.length) {
619
+ combinations.push({ ...current });
620
+ return;
621
+ }
622
+ const [key, values] = rangeEntries[index];
623
+ for (const value of values) {
624
+ current[key] = value;
625
+ generateCombos(index + 1, current);
626
+ }
627
+ };
628
+ generateCombos(0, baseParams);
629
+ return combinations;
630
+ }
631
+ }
632
+ export {
633
+ TrustScoreOptimizer
634
+ };
635
+ //# sourceMappingURL=trustScoreOptimizer.js.map