aiden-shared-calculations-unified 1.0.76 → 1.0.77

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 (114) hide show
  1. package/calculations/{pnl/asset_pnl_status.js → core/asset-pnl-status.js} +20 -0
  2. package/calculations/{asset_metrics/asset_position_size.js → core/asset-position-size.js} +25 -1
  3. package/calculations/{pnl/average_daily_pnl_all_users.js → core/average-daily-pnl-all-users.js} +22 -0
  4. package/calculations/{pnl/average_daily_pnl_per_sector.js → core/average-daily-pnl-per-sector.js} +22 -0
  5. package/calculations/{pnl/average_daily_pnl_per_stock.js → core/average-daily-pnl-per-stock.js} +22 -0
  6. package/calculations/{pnl/average_daily_position_pnl.js → core/average-daily-position-pnl.js} +22 -0
  7. package/calculations/{behavioural/historical/holding_duration_per_asset.js → core/holding-duration-per-asset.js} +44 -4
  8. package/calculations/{meta/gem_instrument-price-momentum.js → core/instrument-price-momentum-20d.js} +17 -4
  9. package/calculations/{short_and_long_stats/long_position_per_stock.js → core/long-position-per-stock.js} +24 -0
  10. package/calculations/{behavioural/overall_holding_duration.js → core/overall-holding-duration.js} +27 -3
  11. package/calculations/{pnl/overall_profitability_ratio.js → core/overall-profitability-ratio.js} +24 -0
  12. package/calculations/{insights/daily_buy_sell_sentiment_count.js → core/platform-buy-sell-sentiment.js} +22 -0
  13. package/calculations/{insights/historical/daily_bought_vs_sold_count.js → core/platform-daily-bought-vs-sold-count.js} +22 -0
  14. package/calculations/{insights/historical/daily_ownership_delta.js → core/platform-daily-ownership-delta.js} +22 -0
  15. package/calculations/{insights/daily_ownership_per_sector.js → core/platform-ownership-per-sector.js} +22 -0
  16. package/calculations/{insights/daily_total_positions_held.js → core/platform-total-positions-held.js} +22 -0
  17. package/calculations/{pnl/pnl_distribution_per_stock.js → core/pnl-distribution-per-stock.js} +24 -0
  18. package/calculations/{pnl/profitability_ratio_per_sector,js → core/profitability-ratio-per-sector.js} +35 -5
  19. package/calculations/{pnl/profitability_ratio_per_stock.js → core/profitability-ratio-per-stock.js} +24 -0
  20. package/calculations/{pnl/profitability_skew_per_stock.js → core/profitability-skew-per-stock.js} +24 -0
  21. package/calculations/{pnl/profitable_and_unprofitable_status.js → core/profitable-and-unprofitable-status.js} +24 -0
  22. package/calculations/{short_and_long_stats/sentiment_per_stock.js → core/sentiment-per-stock.js} +20 -0
  23. package/calculations/{short_and_long_stats/short_position_per_stock.js → core/short-position-per-stock.js} +24 -0
  24. package/calculations/{socialPosts/social_activity_aggregation.js → core/social-activity-aggregation.js} +32 -8
  25. package/calculations/{socialPosts → core}/social-asset-posts-trend.js +30 -8
  26. package/calculations/{socialPosts/social_event_correlation.js → core/social-event-correlation.js} +24 -2
  27. package/calculations/{socialPosts/social_sentiment_aggregation.js → core/social-sentiment-aggregation.js} +23 -0
  28. package/calculations/{socialPosts → core}/social-top-mentioned-words.js +31 -8
  29. package/calculations/{socialPosts → core}/social-topic-interest-evolution.js +35 -11
  30. package/calculations/{socialPosts → core}/social-topic-sentiment-matrix.js +34 -10
  31. package/calculations/{socialPosts → core}/social-word-mentions-trend.js +36 -11
  32. package/calculations/{speculators/speculator_asset_sentiment.js → core/speculator-asset-sentiment.js} +20 -0
  33. package/calculations/{speculators/speculator_danger_zone.js → core/speculator-danger-zone.js} +22 -0
  34. package/calculations/{speculators/distance_to_stop_loss_per_leverage.js → core/speculator-distance-to-stop-loss-per-leverage.js} +24 -0
  35. package/calculations/{speculators/distance_to_tp_per_leverage.js → core/speculator-distance-to-tp-per-leverage.js} +24 -0
  36. package/calculations/{speculators/entry_distance_to_sl_per_leverage.js → core/speculator-entry-distance-to-sl-per-leverage.js} +24 -0
  37. package/calculations/{speculators/entry_distance_to_tp_per_leverage.js → core/speculator-entry-distance-to-tp-per-leverage.js} +24 -0
  38. package/calculations/{speculators/leverage_per_asset.js → core/speculator-leverage-per-asset.js} +20 -0
  39. package/calculations/{speculators/leverage_per_sector.js → core/speculator-leverage-per-sector.js} +22 -0
  40. package/calculations/{speculators/risk_reward_ratio_per_asset.js → core/speculator-risk-reward-ratio-per-asset.js} +20 -0
  41. package/calculations/{speculators/stop_loss_distance_by_sector_short_long_breakdown.js → core/speculator-stop-loss-distance-by-sector-short-long-breakdown.js} +22 -0
  42. package/calculations/{speculators/stop_loss_distance_by_ticker_short_long_breakdown.js → core/speculator-stop-loss-distance-by-ticker-short-long-breakdown.js} +24 -0
  43. package/calculations/{speculators/stop_loss_per_asset.js → core/speculator-stop-loss-per-asset.js} +24 -0
  44. package/calculations/{speculators/take_profit_per_asset.js → core/speculator-take-profit-per-asset.js} +24 -0
  45. package/calculations/{speculators/tsl_per_asset.js → core/speculator-tsl-per-asset.js} +24 -0
  46. package/calculations/{short_and_long_stats/total_long_figures.js → core/total-long-figures.js} +24 -0
  47. package/calculations/{sectors/total_long_per_sector.js → core/total-long-per-sector.js} +22 -0
  48. package/calculations/{short_and_long_stats/total_short_figures.js → core/total-short-figures.js} +24 -0
  49. package/calculations/{sectors/total_short_per_sector.js → core/total-short-per-sector.js} +22 -0
  50. package/calculations/{sanity/users_processed.js → core/users-processed.js} +22 -0
  51. package/calculations/gauss/cohort-capital-flow.js +216 -0
  52. package/calculations/gauss/cohort-definer.js +211 -0
  53. package/calculations/gauss/daily-dna-filter.js +130 -0
  54. package/calculations/gauss/gauss-divergence-signal.js +160 -0
  55. package/calculations/{meta/gem_cohort-momentum-state.js → gem/cohort-momentum-state.js} +22 -7
  56. package/calculations/{behavioural/historical/gem_cohort-skill-definition.js → gem/cohort-skill-definition.js} +18 -1
  57. package/calculations/{sentiment/gem_platform-conviction-divergence.js → gem/platform-conviction-divergence.js} +13 -0
  58. package/calculations/{meta/gem_quant-skill-alpha-signal.js → gem/quant-skill-alpha-signal.js} +25 -8
  59. package/calculations/{behavioural/historical/gem_skilled-cohort-flow.js → gem/skilled-cohort-flow.js} +16 -2
  60. package/calculations/{meta/gem_skilled-unskilled-divergence.js → gem/skilled-unskilled-divergence.js} +18 -4
  61. package/calculations/{behavioural/historical/gem_unskilled-cohort-flow.js → gem/unskilled-cohort-flow.js} +16 -2
  62. package/calculations/helix/helix-contrarian-signal.js +154 -0
  63. package/calculations/helix/herd-consensus-score.js +152 -0
  64. package/calculations/helix/winner-loser-flow.js +206 -0
  65. package/calculations/{behavioural/historical → legacy}/asset_crowd_flow.js +1 -1
  66. package/calculations/{sentiment/historical → legacy}/crowd_conviction_score.js +1 -1
  67. package/calculations/{activity/historical → legacy}/daily_asset_activity.js +1 -1
  68. package/calculations/{behavioural/historical → legacy}/dumb-cohort-flow.js +1 -1
  69. package/calculations/{behavioural/historical → legacy}/in_loss_asset_crowd_flow.js +1 -1
  70. package/calculations/{behavioural/historical → legacy}/in_profit_asset_crowd_flow.js +1 -1
  71. package/calculations/{speculators/historical → legacy}/risk_appetite_change.js +3 -1
  72. package/calculations/{sectors/historical → legacy}/sector_rotation.js +1 -1
  73. package/calculations/{behavioural/historical → legacy}/smart-cohort-flow.js +1 -1
  74. package/calculations/{behavioural/historical → legacy}/smart_money_flow.js +1 -1
  75. package/calculations/{behavioural/historical → legacy}/user-investment-profile.js +2 -2
  76. package/calculations/pyro/risk-appetite-index.js +153 -0
  77. package/calculations/pyro/squeeze-potential.js +158 -0
  78. package/calculations/pyro/volatility-signal.js +133 -0
  79. package/package.json +1 -1
  80. package/calculations/socialPosts/gem_social_sentiment_aggregation.js +0 -146
  81. /package/calculations/{activity/historical → legacy}/activity_by_pnl_status.js +0 -0
  82. /package/calculations/{meta → legacy}/capital_deployment_strategy.js +0 -0
  83. /package/calculations/{meta → legacy}/capital_liquidation_performance.js +0 -0
  84. /package/calculations/{meta → legacy}/capital_vintage_performance.js +0 -0
  85. /package/calculations/{meta → legacy}/cash-flow-deployment.js +0 -0
  86. /package/calculations/{meta → legacy}/cash-flow-liquidation.js +0 -0
  87. /package/calculations/{capital_flow/historical → legacy}/crowd-cash-flow-proxy.js +0 -0
  88. /package/calculations/{meta → legacy}/crowd_sharpe_ratio_proxy.js +0 -0
  89. /package/calculations/{activity/historical → legacy}/daily_user_activity_tracker.js +0 -0
  90. /package/calculations/{capital_flow/historical → legacy}/deposit_withdrawal_percentage.js +0 -0
  91. /package/calculations/{sectors/historical → legacy}/diversification_pnl.js +0 -0
  92. /package/calculations/{behavioural/historical → legacy}/drawdown_response.js +0 -0
  93. /package/calculations/{behavioural/historical → legacy}/gain_response.js +0 -0
  94. /package/calculations/{behavioural/historical → legacy}/historical_performance_aggregator.js +0 -0
  95. /package/calculations/{meta → legacy}/negative_expectancy_cohort_flow.js +0 -0
  96. /package/calculations/{capital_flow/historical → legacy}/new_allocation_percentage.js +0 -0
  97. /package/calculations/{behavioural/historical → legacy}/paper_vs_diamond_hands.js +0 -0
  98. /package/calculations/{behavioural/historical → legacy}/position_count_pnl.js +0 -0
  99. /package/calculations/{meta → legacy}/positive_expectancy_cohort_flow.js +0 -0
  100. /package/calculations/{meta → legacy}/profit_cohort_divergence.js +0 -0
  101. /package/calculations/{pnl/historical → legacy}/profitability_migration.js +0 -0
  102. /package/calculations/{capital_flow/historical → legacy}/reallocation_increase_percentage.js +0 -0
  103. /package/calculations/{meta → legacy}/shark_attack_signal.js +0 -0
  104. /package/calculations/{meta → legacy}/smart-dumb-divergence-index.js +0 -0
  105. /package/calculations/{meta → legacy}/smart_dumb_divergence_index_v2.js +0 -0
  106. /package/calculations/{meta → legacy}/social-predictive-regime-state.js +0 -0
  107. /package/calculations/{meta → legacy}/social-topic-driver-index.js +0 -0
  108. /package/calculations/{meta → legacy}/social-topic-predictive-potential.js +0 -0
  109. /package/calculations/{meta → legacy}/social_flow_correlation.js +0 -0
  110. /package/calculations/{activity/historical → legacy}/speculator_adjustment_activity.js +0 -0
  111. /package/calculations/{backtests → legacy}/strategy-performance.js +0 -0
  112. /package/calculations/{speculators/historical → legacy}/tsl_effectiveness.js +0 -0
  113. /package/calculations/{meta → legacy}/user_expectancy_score.js +0 -0
  114. /package/calculations/{pnl/historical → legacy}/user_profitability_tracker.js +0 -0
@@ -81,6 +81,26 @@ class AssetPnlStatus {
81
81
  };
82
82
  }
83
83
 
84
+ /**
85
+ * Statically defines all metadata for the manifest builder.
86
+ */
87
+ static getMetadata() {
88
+ return {
89
+ type: 'standard',
90
+ rootDataDependencies: ['portfolio'],
91
+ isHistorical: false,
92
+ userType: 'all',
93
+ category: 'core_pnl'
94
+ };
95
+ }
96
+
97
+ /**
98
+ * Statically declare dependencies.
99
+ */
100
+ static getDependencies() {
101
+ return [];
102
+ }
103
+
84
104
  _initAsset(instrumentId) {
85
105
  if (!this.assets.has(instrumentId)) {
86
106
  this.assets.set(instrumentId, {
@@ -9,6 +9,28 @@ class AssetPositionSize {
9
9
  this.mappings = null;
10
10
  }
11
11
 
12
+ // --- NEW ---
13
+ /**
14
+ * Statically defines all metadata for the manifest builder.
15
+ */
16
+ static getMetadata() {
17
+ return {
18
+ type: 'standard', // It processes each user
19
+ rootDataDependencies: ['portfolio'], // It only needs portfolio data
20
+ isHistorical: false, // It only needs today's portfolio
21
+ userType: 'all', // It runs for all users
22
+ category: 'core_metrics' // Belongs to the core product line
23
+ };
24
+ }
25
+
26
+ // --- NEW ---
27
+ /**
28
+ * Statically declare dependencies.
29
+ */
30
+ static getDependencies() {
31
+ return []; // This is a Pass 1 calculation
32
+ }
33
+
12
34
  /**
13
35
  * Defines the output schema for this calculation.
14
36
  * @returns {object} JSON Schema object
@@ -45,7 +67,9 @@ class AssetPositionSize {
45
67
  };
46
68
  }
47
69
 
48
- process(portfolioData, yesterdayPortfolio, userId, context, todayInsights, yesterdayInsights) {
70
+ // --- REFACTORED ---
71
+ // Simplified signature. This calc doesn't need history, context, or insights.
72
+ process(portfolioData) {
49
73
  const positions = portfolioData.AggregatedPositions || portfolioData.PublicPositions;
50
74
  if (!positions || !Array.isArray(positions)) return;
51
75
 
@@ -12,6 +12,28 @@ class AverageDailyPnlAllUsers {
12
12
  this.userCount = 0;
13
13
  }
14
14
 
15
+ // --- NEW ---
16
+ /**
17
+ * Statically defines all metadata for the manifest builder.
18
+ */
19
+ static getMetadata() {
20
+ return {
21
+ type: 'standard',
22
+ rootDataDependencies: ['portfolio'], // Needs portfolio.Summary
23
+ isHistorical: false,
24
+ userType: 'all',
25
+ category: 'core_pnl'
26
+ };
27
+ }
28
+
29
+ // --- NEW ---
30
+ /**
31
+ * Statically declare dependencies.
32
+ */
33
+ static getDependencies() {
34
+ return [];
35
+ }
36
+
15
37
  /**
16
38
  * Defines the output schema for this calculation.
17
39
  * @returns {object} JSON Schema object
@@ -15,6 +15,28 @@ class AverageDailyPnlPerSector {
15
15
  this.mappings = null;
16
16
  }
17
17
 
18
+ // --- NEW ---
19
+ /**
20
+ * Statically defines all metadata for the manifest builder.
21
+ */
22
+ static getMetadata() {
23
+ return {
24
+ type: 'standard',
25
+ rootDataDependencies: ['portfolio'], // Needs portfolio positions
26
+ isHistorical: false,
27
+ userType: 'all',
28
+ category: 'core_pnl'
29
+ };
30
+ }
31
+
32
+ // --- NEW ---
33
+ /**
34
+ * Statically declare dependencies.
35
+ */
36
+ static getDependencies() {
37
+ return [];
38
+ }
39
+
18
40
  /**
19
41
  * Defines the output schema for this calculation.
20
42
  * @returns {object} JSON Schema object
@@ -13,6 +13,28 @@ class AverageDailyPnlPerStock {
13
13
  this.mappings = null;
14
14
  }
15
15
 
16
+ // --- NEW ---
17
+ /**
18
+ * Statically defines all metadata for the manifest builder.
19
+ */
20
+ static getMetadata() {
21
+ return {
22
+ type: 'standard',
23
+ rootDataDependencies: ['portfolio'], // Needs portfolio positions
24
+ isHistorical: false,
25
+ userType: 'all',
26
+ category: 'core_pnl'
27
+ };
28
+ }
29
+
30
+ // --- NEW ---
31
+ /**
32
+ * Statically declare dependencies.
33
+ */
34
+ static getDependencies() {
35
+ return [];
36
+ }
37
+
16
38
  /**
17
39
  * Defines the output schema for this calculation.
18
40
  * @returns {object} JSON Schema object
@@ -13,6 +13,28 @@ class AverageDailyPositionPnl {
13
13
  this.positionCount = 0;
14
14
  }
15
15
 
16
+ // --- NEW ---
17
+ /**
18
+ * Statically defines all metadata for the manifest builder.
19
+ */
20
+ static getMetadata() {
21
+ return {
22
+ type: 'standard',
23
+ rootDataDependencies: ['portfolio'], // Needs portfolio positions
24
+ isHistorical: false,
25
+ userType: 'all',
26
+ category: 'core_pnl'
27
+ };
28
+ }
29
+
30
+ // --- NEW ---
31
+ /**
32
+ * Statically declare dependencies.
33
+ */
34
+ static getDependencies() {
35
+ return [];
36
+ }
37
+
16
38
  /**
17
39
  * Defines the output schema for this calculation.
18
40
  * @returns {object} JSON Schema object
@@ -17,6 +17,28 @@ class HoldingDurationPerAsset {
17
17
  this.mappings = null;
18
18
  }
19
19
 
20
+ // --- NEW ---
21
+ /**
22
+ * Statically defines all metadata for the manifest builder.
23
+ */
24
+ static getMetadata() {
25
+ return {
26
+ type: 'standard',
27
+ rootDataDependencies: ['history'], // It only needs the history doc
28
+ isHistorical: false, // It only needs today's history doc
29
+ userType: 'all',
30
+ category: 'core_metrics'
31
+ };
32
+ }
33
+
34
+ // --- NEW ---
35
+ /**
36
+ * Statically declare dependencies.
37
+ */
38
+ static getDependencies() {
39
+ return [];
40
+ }
41
+
20
42
  /**
21
43
  * Defines the output schema for this calculation.
22
44
  * @returns {object} JSON Schema object
@@ -53,14 +75,32 @@ class HoldingDurationPerAsset {
53
75
  }
54
76
  }
55
77
 
78
+ // --- REFACTORED ---
56
79
  /**
57
80
  * Process data from the 'history' root data source.
58
- * @param {object} rootData - The root data object from the runner.
81
+ * @param {object} todayPortfolio - (Not used)
82
+ * @param {object} yesterdayPortfolio - (Not used)
59
83
  * @param {string} userId - The user ID.
84
+ * @param {object} context - (Not used)
85
+ * @param {object} todayInsights - (Not used)
86
+ * @param {object} yesterdayInsights - (Not used)
87
+ * @param {object} todaySocialPostInsights - (Not used)
88
+ * @param {object} yesterdaySocialPostInsights - (Not used)
89
+ * @param {object} todayHistory - The user's history doc for today.
60
90
  */
61
- process(rootData, userId) {
62
- // 1. Get the history data
63
- const historyData = rootData.history;
91
+ process(
92
+ todayPortfolio,
93
+ yesterdayPortfolio,
94
+ userId,
95
+ context,
96
+ todayInsights,
97
+ yesterdayInsights,
98
+ todaySocialPostInsights,
99
+ yesterdaySocialPostInsights,
100
+ todayHistory
101
+ ) {
102
+ // 1. Get the history data from the 9th argument
103
+ const historyData = todayHistory;
64
104
  if (!historyData || !Array.isArray(historyData.assets)) {
65
105
  return;
66
106
  }
@@ -7,6 +7,7 @@
7
7
  * It is a 'meta' calculation that runs once, loads all price data,
8
8
  * and provides a reusable momentum signal for downstream passes.
9
9
  */
10
+ // The dependency path is relative to the *calculations* folder
10
11
  const { loadAllPriceData } = require('../../utils/price_data_provider');
11
12
 
12
13
  class InstrumentPriceMomentum {
@@ -37,6 +38,19 @@ class InstrumentPriceMomentum {
37
38
  };
38
39
  }
39
40
 
41
+ /**
42
+ * Statically defines all metadata for the manifest builder.
43
+ */
44
+ static getMetadata() {
45
+ return {
46
+ type: 'meta', // Explicitly a 'meta' calculation
47
+ rootDataDependencies: [], // Relies on price data, not root data
48
+ isHistorical: false,
49
+ userType: 'n/a', // Does not run per-user
50
+ category: 'core_metrics'
51
+ };
52
+ }
53
+
40
54
  /**
41
55
  * This is a Pass 1 calculation and has no dependencies.
42
56
  */
@@ -75,10 +89,9 @@ class InstrumentPriceMomentum {
75
89
  * @returns {Promise<object>} The calculation result.
76
90
  */
77
91
  async process(dateStr, dependencies, config, fetchedDependencies) {
78
- const { logger, calculationUtils, mappings } = dependencies;
92
+ const { logger, calculationUtils } = dependencies;
79
93
 
80
- // Load all price data and mappings
81
- const priceMap = await loadAllPriceData();
94
+ const priceMap = await calculationUtils.loadAllPriceData();
82
95
  const tickerMap = await calculationUtils.loadInstrumentMappings();
83
96
 
84
97
  if (!priceMap || !tickerMap || !tickerMap.instrumentToTicker) {
@@ -93,7 +106,7 @@ class InstrumentPriceMomentum {
93
106
  const instrumentPrices = priceMap[instrumentId];
94
107
  const ticker = tickerMap.instrumentToTicker[instrumentId];
95
108
 
96
- if (!ticker) continue; // Skip if we can't map ID to ticker
109
+ if (!ticker) continue;
97
110
 
98
111
  const priceT = this._findPrice(instrumentPrices, dateStr);
99
112
  const priceT20 = this._findPrice(instrumentPrices, dateStrT20);
@@ -13,6 +13,28 @@ class LongPositionPerStock {
13
13
  this.mappings = null;
14
14
  }
15
15
 
16
+ // --- NEW ---
17
+ /**
18
+ * Statically defines all metadata for the manifest builder.
19
+ */
20
+ static getMetadata() {
21
+ return {
22
+ type: 'standard',
23
+ rootDataDependencies: ['portfolio'],
24
+ isHistorical: false,
25
+ userType: 'all',
26
+ category: 'core_sentiment' // Based on Computation_documentation.md (short_and_long_stats -> sentiment_per_stock)
27
+ };
28
+ }
29
+
30
+ // --- NEW ---
31
+ /**
32
+ * Statically declare dependencies.
33
+ */
34
+ static getDependencies() {
35
+ return [];
36
+ }
37
+
16
38
  /**
17
39
  * Defines the output schema for this calculation.
18
40
  * @returns {object} JSON Schema object
@@ -40,6 +62,8 @@ class LongPositionPerStock {
40
62
  }
41
63
  }
42
64
 
65
+ // --- REFACTORED ---
66
+ // Simplified signature
43
67
  process(portfolioData) {
44
68
  const positions = portfolioData.PublicPositions || portfolioData.AggregatedPositions;
45
69
  if (!positions || !Array.isArray(positions)) {
@@ -12,6 +12,28 @@ class AverageHoldingDurationOverall {
12
12
  this.durationsHours = [];
13
13
  }
14
14
 
15
+ // --- NEW ---
16
+ /**
17
+ * Statically defines all metadata for the manifest builder.
18
+ */
19
+ static getMetadata() {
20
+ return {
21
+ type: 'standard',
22
+ rootDataDependencies: ['history'], // Needs the history doc
23
+ isHistorical: false, // Needs today's history doc
24
+ userType: 'all',
25
+ category: 'core_metrics'
26
+ };
27
+ }
28
+
29
+ // --- NEW ---
30
+ /**
31
+ * Statically declare dependencies.
32
+ */
33
+ static getDependencies() {
34
+ return [];
35
+ }
36
+
15
37
  /**
16
38
  * Defines the output schema for this calculation.
17
39
  * @returns {object} JSON Schema object
@@ -34,14 +56,16 @@ class AverageHoldingDurationOverall {
34
56
  };
35
57
  }
36
58
 
59
+ // --- REFACTORED ---
37
60
  /**
38
61
  * Process data from the 'history' root data source.
39
- * @param {object} rootData - The root data object from the runner.
62
+ * @param {object} todayPortfolio - Contains today's history doc
63
+ * @param {object} yesterdayPortfolio - (Not used)
40
64
  * @param {string} userId - The user ID.
41
65
  */
42
- process(rootData, userId) {
66
+ process(todayPortfolio, yesterdayPortfolio, userId) {
43
67
  // 1. Get the history data
44
- const historyData = rootData.history;
68
+ const historyData = todayPortfolio?.history; // Accessing from the portfolio object
45
69
  if (!historyData || !historyData.all) {
46
70
  return;
47
71
  }
@@ -11,6 +11,28 @@ class ProfitabilityRatioOverall {
11
11
  this.unprofitable = 0;
12
12
  }
13
13
 
14
+ // --- NEW ---
15
+ /**
16
+ * Statically defines all metadata for the manifest builder.
17
+ */
18
+ static getMetadata() {
19
+ return {
20
+ type: 'standard',
21
+ rootDataDependencies: ['portfolio'],
22
+ isHistorical: false,
23
+ userType: 'all',
24
+ category: 'core_pnl'
25
+ };
26
+ }
27
+
28
+ // --- NEW ---
29
+ /**
30
+ * Statically declare dependencies.
31
+ */
32
+ static getDependencies() {
33
+ return [];
34
+ }
35
+
14
36
  /**
15
37
  * Defines the output schema for this calculation.
16
38
  * @returns {object} JSON Schema object
@@ -37,6 +59,8 @@ class ProfitabilityRatioOverall {
37
59
  };
38
60
  }
39
61
 
62
+ // --- REFACTORED ---
63
+ // Simplified signature
40
64
  process(portfolioData) {
41
65
  const positions = portfolioData.PublicPositions || portfolioData.AggregatedPositions;
42
66
  if (!positions || !Array.isArray(positions)) {
@@ -7,6 +7,28 @@
7
7
  */
8
8
  class DailyBuySellSentimentCount {
9
9
 
10
+ // --- NEW ---
11
+ /**
12
+ * Statically defines all metadata for the manifest builder.
13
+ */
14
+ static getMetadata() {
15
+ return {
16
+ type: 'meta',
17
+ rootDataDependencies: ['insights'], // Needs insights doc
18
+ isHistorical: false,
19
+ userType: 'n/a',
20
+ category: 'core_sentiment'
21
+ };
22
+ }
23
+
24
+ // --- NEW ---
25
+ /**
26
+ * Statically declare dependencies.
27
+ */
28
+ static getDependencies() {
29
+ return [];
30
+ }
31
+
10
32
  /**
11
33
  * Defines the output schema for this calculation.
12
34
  * @returns {object} JSON Schema object
@@ -16,6 +16,28 @@ class DailyBoughtVsSoldCount {
16
16
  this.mappings = null;
17
17
  }
18
18
 
19
+ // --- NEW ---
20
+ /**
21
+ * Statically defines all metadata for the manifest builder.
22
+ */
23
+ static getMetadata() {
24
+ return {
25
+ type: 'standard',
26
+ rootDataDependencies: ['portfolio'],
27
+ isHistorical: true, // Needs yesterday's portfolio
28
+ userType: 'all',
29
+ category: 'core_metrics'
30
+ };
31
+ }
32
+
33
+ // --- NEW ---
34
+ /**
35
+ * Statically declare dependencies.
36
+ */
37
+ static getDependencies() {
38
+ return [];
39
+ }
40
+
19
41
  /**
20
42
  * Defines the output schema for this calculation.
21
43
  * @returns {object} JSON Schema object
@@ -12,6 +12,28 @@ const { loadInstrumentMappings } = require('../../../utils/sector_mapping_provid
12
12
 
13
13
  class DailyOwnershipDelta {
14
14
 
15
+ // --- NEW ---
16
+ /**
17
+ * Statically defines all metadata for the manifest builder.
18
+ */
19
+ static getMetadata() {
20
+ return {
21
+ type: 'meta',
22
+ rootDataDependencies: ['insights'], // Needs insights doc
23
+ isHistorical: true, // Needs yesterday's insights doc
24
+ userType: 'n/a',
25
+ category: 'core_metrics'
26
+ };
27
+ }
28
+
29
+ // --- NEW ---
30
+ /**
31
+ * Statically declare dependencies.
32
+ */
33
+ static getDependencies() {
34
+ return [];
35
+ }
36
+
15
37
  /**
16
38
  * Defines the output schema for this calculation.
17
39
  * @returns {object} JSON Schema object
@@ -10,6 +10,28 @@ const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider'
10
10
 
11
11
  class DailyOwnershipPerSector {
12
12
 
13
+ // --- NEW ---
14
+ /**
15
+ * Statically defines all metadata for the manifest builder.
16
+ */
17
+ static getMetadata() {
18
+ return {
19
+ type: 'meta',
20
+ rootDataDependencies: ['insights'], // Needs insights doc
21
+ isHistorical: false,
22
+ userType: 'n/a',
23
+ category: 'core_metrics'
24
+ };
25
+ }
26
+
27
+ // --- NEW ---
28
+ /**
29
+ * Statically declare dependencies.
30
+ */
31
+ static getDependencies() {
32
+ return [];
33
+ }
34
+
13
35
  /**
14
36
  * Defines the output schema for this calculation.
15
37
  * @returns {object} JSON Schema object
@@ -7,6 +7,28 @@
7
7
  */
8
8
  class DailyTotalPositionsHeld {
9
9
 
10
+ // --- NEW ---
11
+ /**
12
+ * Statically defines all metadata for the manifest builder.
13
+ */
14
+ static getMetadata() {
15
+ return {
16
+ type: 'meta',
17
+ rootDataDependencies: ['insights'], // Needs insights doc
18
+ isHistorical: false,
19
+ userType: 'n/a',
20
+ category: 'core_metrics'
21
+ };
22
+ }
23
+
24
+ // --- NEW ---
25
+ /**
26
+ * Statically declare dependencies.
27
+ */
28
+ static getDependencies() {
29
+ return [];
30
+ }
31
+
10
32
  /**
11
33
  * Defines the output schema for this calculation.
12
34
  * @returns {object} JSON Schema object
@@ -35,6 +35,28 @@ class PnlDistributionPerStock {
35
35
  this.mappings = null;
36
36
  }
37
37
 
38
+ // --- NEW ---
39
+ /**
40
+ * Statically defines all metadata for the manifest builder.
41
+ */
42
+ static getMetadata() {
43
+ return {
44
+ type: 'standard',
45
+ rootDataDependencies: ['portfolio'],
46
+ isHistorical: false,
47
+ userType: 'all',
48
+ category: 'core_pnl'
49
+ };
50
+ }
51
+
52
+ // --- NEW ---
53
+ /**
54
+ * Statically declare dependencies.
55
+ */
56
+ static getDependencies() {
57
+ return [];
58
+ }
59
+
38
60
  /**
39
61
  * Defines the output schema for this calculation.
40
62
  * REFACTOR: Schema now describes the server-calculated histogram.
@@ -93,6 +115,8 @@ class PnlDistributionPerStock {
93
115
  }
94
116
  }
95
117
 
118
+ // --- REFACTORED ---
119
+ // Simplified signature
96
120
  process(portfolioData) {
97
121
  const positions = portfolioData.PublicPositions || portfolioData.AggregatedPositions;
98
122
  if (!positions || !Array.isArray(positions)) {
@@ -13,6 +13,28 @@ class ProfitabilityRatioPerSector {
13
13
  this.mappings = null;
14
14
  }
15
15
 
16
+ // --- NEW ---
17
+ /**
18
+ * Statically defines all metadata for the manifest builder.
19
+ */
20
+ static getMetadata() {
21
+ return {
22
+ type: 'standard',
23
+ rootDataDependencies: ['portfolio'],
24
+ isHistorical: false,
25
+ userType: 'all',
26
+ category: 'core_pnl'
27
+ };
28
+ }
29
+
30
+ // --- NEW ---
31
+ /**
32
+ * Statically declare dependencies.
33
+ */
34
+ static getDependencies() {
35
+ return [];
36
+ }
37
+
16
38
  /**
17
39
  * Defines the output schema for this calculation.
18
40
  * @returns {object} JSON Schema object
@@ -47,14 +69,19 @@ class ProfitabilityRatioPerSector {
47
69
  }
48
70
  }
49
71
 
50
- async process(portfolioData) {
72
+ // --- REFACTORED ---
73
+ // This method *is* async because it might load mappings on the first run.
74
+ // The runner should handle this with `await Promise.resolve(calc.process(...))`.
75
+ // The signature is correct because it needs `context` for mappings.
76
+ async process(portfolioData, yesterdayPortfolio, userId, context) {
51
77
  if (!this.mappings) {
52
78
  // Load mappings on first process call
53
- this.mappings = await loadInstrumentMappings();
79
+ // Using context.mappings which are pre-loaded in Pass 1
80
+ this.mappings = context.mappings;
54
81
  }
55
82
 
56
83
  const positions = portfolioData.PublicPositions || portfolioData.AggregatedPositions;
57
- if (!positions || !Array.isArray(positions)) {
84
+ if (!positions || !Array.isArray(positions) || !this.mappings) {
58
85
  return;
59
86
  }
60
87
 
@@ -67,7 +94,10 @@ class ProfitabilityRatioPerSector {
67
94
  }
68
95
 
69
96
  // Find sector name
70
- const sectorName = this.mappings.instrumentToSectorName[instrumentId] || 'N/A';
97
+ // --- FIX: Use the correct mapping ---
98
+ // The mapping from the provider is `instrumentToSector` (ID -> Sector Name)
99
+ // `instrumentToSectorName` is not a property.
100
+ const sectorName = this.mappings.instrumentToSector[instrumentId] || 'N/A';
71
101
  this._initSector(sectorName);
72
102
  const data = this.sectorMap.get(sectorName);
73
103
 
@@ -97,7 +127,7 @@ class ProfitabilityRatioPerSector {
97
127
 
98
128
  reset() {
99
129
  this.sectorMap.clear();
100
- // Do not reset mappings, it's expensive to load
130
+ this.mappings = null; // Reset mappings
101
131
  }
102
132
  }
103
133