aiden-shared-calculations-unified 1.0.95 → 1.0.96

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 (54) hide show
  1. package/calculations/capitulation/asset-volatility-estimator.js +1 -2
  2. package/calculations/capitulation/retail-capitulation-risk-forecast.js +1 -2
  3. package/calculations/ghost-book/cost-basis-density.js +1 -2
  4. package/calculations/ghost-book/liquidity-vacuum.js +1 -2
  5. package/calculations/ghost-book/retail-gamma-exposure.js +0 -1
  6. package/calculations/predicative-alpha/cognitive-dissonance.js +1 -2
  7. package/calculations/predicative-alpha/diamond-hand-fracture.js +1 -2
  8. package/calculations/predicative-alpha/mimetic-latency.js +1 -2
  9. package/package.json +1 -1
  10. package/calculations/legacy/activity_by_pnl_status.js +0 -119
  11. package/calculations/legacy/asset_crowd_flow.js +0 -163
  12. package/calculations/legacy/capital_deployment_strategy.js +0 -108
  13. package/calculations/legacy/capital_liquidation_performance.js +0 -139
  14. package/calculations/legacy/capital_vintage_performance.js +0 -136
  15. package/calculations/legacy/cash-flow-deployment.js +0 -144
  16. package/calculations/legacy/cash-flow-liquidation.js +0 -146
  17. package/calculations/legacy/crowd-cash-flow-proxy.js +0 -128
  18. package/calculations/legacy/crowd_conviction_score.js +0 -261
  19. package/calculations/legacy/crowd_sharpe_ratio_proxy.js +0 -137
  20. package/calculations/legacy/daily_asset_activity.js +0 -128
  21. package/calculations/legacy/daily_user_activity_tracker.js +0 -182
  22. package/calculations/legacy/deposit_withdrawal_percentage.js +0 -125
  23. package/calculations/legacy/diversification_pnl.js +0 -115
  24. package/calculations/legacy/drawdown_response.js +0 -137
  25. package/calculations/legacy/dumb-cohort-flow.js +0 -238
  26. package/calculations/legacy/gain_response.js +0 -137
  27. package/calculations/legacy/historical_performance_aggregator.js +0 -85
  28. package/calculations/legacy/in_loss_asset_crowd_flow.js +0 -168
  29. package/calculations/legacy/in_profit_asset_crowd_flow.js +0 -168
  30. package/calculations/legacy/negative_expectancy_cohort_flow.js +0 -232
  31. package/calculations/legacy/new_allocation_percentage.js +0 -98
  32. package/calculations/legacy/paper_vs_diamond_hands.js +0 -107
  33. package/calculations/legacy/position_count_pnl.js +0 -120
  34. package/calculations/legacy/positive_expectancy_cohort_flow.js +0 -232
  35. package/calculations/legacy/profit_cohort_divergence.js +0 -115
  36. package/calculations/legacy/profitability_migration.js +0 -104
  37. package/calculations/legacy/reallocation_increase_percentage.js +0 -104
  38. package/calculations/legacy/risk_appetite_change.js +0 -97
  39. package/calculations/legacy/sector_rotation.js +0 -117
  40. package/calculations/legacy/shark_attack_signal.js +0 -112
  41. package/calculations/legacy/smart-cohort-flow.js +0 -238
  42. package/calculations/legacy/smart-dumb-divergence-index.js +0 -143
  43. package/calculations/legacy/smart_dumb_divergence_index_v2.js +0 -138
  44. package/calculations/legacy/smart_money_flow.js +0 -198
  45. package/calculations/legacy/social-predictive-regime-state.js +0 -102
  46. package/calculations/legacy/social-topic-driver-index.js +0 -147
  47. package/calculations/legacy/social-topic-predictive-potential.js +0 -461
  48. package/calculations/legacy/social_flow_correlation.js +0 -112
  49. package/calculations/legacy/speculator_adjustment_activity.js +0 -103
  50. package/calculations/legacy/strategy-performance.js +0 -265
  51. package/calculations/legacy/tsl_effectiveness.js +0 -85
  52. package/calculations/legacy/user-investment-profile.js +0 -313
  53. package/calculations/legacy/user_expectancy_score.js +0 -106
  54. package/calculations/legacy/user_profitability_tracker.js +0 -131
@@ -1,143 +0,0 @@
1
- /**
2
- * @fileoverview Calculation (Pass 4) for smart-dumb divergence index.
3
- *
4
- * This metric answers: "What divergence signals (e.g., capitulation,
5
- * euphoria) can be found by comparing the net asset and sector flow
6
- * of the 'smart cohort' vs. the 'dumb cohort'?"
7
- *
8
- * It *depends* on 'smart-cohort-flow' and 'dumb-cohort-flow'.
9
- */
10
- class SmartDumbDivergenceIndex {
11
- constructor() {
12
- // No per-user processing
13
- }
14
-
15
- /**
16
- * Defines the output schema for this calculation.
17
- * @returns {object} JSON Schema object
18
- */
19
- static getSchema() {
20
- const signalSchema = {
21
- "type": "object",
22
- "properties": {
23
- "status": {
24
- "type": "string",
25
- "enum": ["Capitulation", "Euphoria", "Confirmation (Buy)", "Confirmation (Sell)", "Divergence (Smart Buy)", "Divergence (Smart Sell)", "Neutral"]
26
- },
27
- "smart_flow_pct": { "type": "number" },
28
- "dumb_flow_pct": { "type": "number" }
29
- },
30
- "required": ["status", "smart_flow_pct", "dumb_flow_pct"]
31
- };
32
-
33
- return {
34
- "type": "object",
35
- "description": "Generates divergence signals by comparing net flow of 'Smart' vs. 'Dumb' cohorts, by asset and sector.",
36
- "properties": {
37
- "assets": {
38
- "type": "object",
39
- "description": "Divergence signals per asset.",
40
- "patternProperties": { "^.*$": signalSchema }, // Ticker
41
- "additionalProperties": signalSchema
42
- },
43
- "sectors": {
44
- "type": "object",
45
- "description": "Divergence signals per sector.",
46
- "patternProperties": { "^.*$": signalSchema }, // Sector
47
- "additionalProperties": signalSchema
48
- }
49
- },
50
- "required": ["assets", "sectors"]
51
- };
52
- }
53
-
54
- /**
55
- * Statically declare dependencies.
56
- */
57
- static getDependencies() {
58
- return [
59
- 'smart-cohort-flow', // Pass 3
60
- 'dumb-cohort-flow' // Pass 3
61
- ];
62
- }
63
-
64
- process() {
65
- // No-op
66
- }
67
-
68
- _calculateDivergence(smartFlow, dumbFlow) {
69
- const result = {};
70
- if (!smartFlow || !dumbFlow) {
71
- return result;
72
- }
73
-
74
- const allKeys = new Set([...Object.keys(smartFlow), ...Object.keys(dumbFlow)]);
75
- const THRESHOLD = 1; // Min flow %
76
-
77
- for (const key of allKeys) {
78
- const sFlow = smartFlow[key]?.net_flow_percentage || 0;
79
- const dFlow = dumbFlow[key]?.net_flow_percentage || 0;
80
-
81
- let status = 'Neutral';
82
-
83
- // Both buying
84
- if (sFlow > THRESHOLD && dFlow > THRESHOLD) {
85
- status = 'Confirmation (Buy)';
86
- }
87
- // Both selling
88
- else if (sFlow < -THRESHOLD && dFlow < -THRESHOLD) {
89
- status = 'Confirmation (Sell)';
90
- }
91
- // Smart buying, Dumb selling
92
- else if (sFlow > THRESHOLD && dFlow < -THRESHOLD) {
93
- status = 'Capitulation'; // Smart buying the dip from dumb money
94
- }
95
- // Smart selling, Dumb buying
96
- else if (sFlow < -THRESHOLD && dFlow > THRESHOLD) {
97
- status = 'Euphoria'; // Smart selling into dumb money fomo
98
- }
99
- // Smart buying, Dumb neutral
100
- else if (sFlow > THRESHOLD && Math.abs(dFlow) < THRESHOLD) {
101
- status = 'Divergence (Smart Buy)';
102
- }
103
- // Smart selling, Dumb neutral
104
- else if (sFlow < -THRESHOLD && Math.abs(dFlow) < THRESHOLD) {
105
- status = 'Divergence (Smart Sell)';
106
- }
107
- // Dumb buying, Smart neutral
108
- else if (dFlow > THRESHOLD && Math.abs(sFlow) < THRESHOLD) {
109
- status = 'Divergence (Smart Sell)'; // Implied smart sell
110
- }
111
- // Dumb selling, Smart neutral
112
- else if (dFlow < -THRESHOLD && Math.abs(sFlow) < THRESHOLD) {
113
- status = 'Divergence (Smart Buy)'; // Implied smart buy
114
- }
115
-
116
- result[key] = {
117
- status: status,
118
- smart_flow_pct: sFlow,
119
- dumb_flow_pct: dFlow
120
- };
121
- }
122
- return result;
123
- }
124
-
125
- getResult(fetchedDependencies) {
126
- const smartFlowData = fetchedDependencies['smart-cohort-flow'];
127
- const dumbFlowData = fetchedDependencies['dumb-cohort-flow'];
128
-
129
- const assetResult = this._calculateDivergence(smartFlowData?.assets, dumbFlowData?.assets);
130
- const sectorResult = this._calculateDivergence(smartFlowData?.sectors, dumbFlowData?.sectors);
131
-
132
- return {
133
- assets: assetResult,
134
- sectors: sectorResult
135
- };
136
- }
137
-
138
- reset() {
139
- // No state
140
- }
141
- }
142
-
143
- module.exports = SmartDumbDivergenceIndex;
@@ -1,138 +0,0 @@
1
- /**
2
- * @fileoverview Calculation (Pass 5) for smart-dumb divergence v2.
3
- *
4
- * This is a more advanced version that likely uses a different
5
- * cohort definition (e.g., 'expectancy' based) and combines more
6
- * signals.
7
- *
8
- * It *depends* on 'positive_expectancy_cohort_flow' and
9
- * 'negative_expectancy_cohort_flow'.
10
- */
11
- class SmartDumbDivergenceIndexV2 {
12
- constructor() {
13
- // No per-user processing
14
- }
15
-
16
- /**
17
- * Defines the output schema for this calculation.
18
- * @returns {object} JSON Schema object
19
- */
20
- static getSchema() {
21
- const signalSchema = {
22
- "type": "object",
23
- "properties": {
24
- "status": {
25
- "type": "string",
26
- "enum": ["Capitulation", "Euphoria", "Confirmation (Buy)", "Confirmation (Sell)", "Divergence (Smart Buy)", "Divergence (Smart Sell)", "Neutral"]
27
- },
28
- "smart_flow_pct": { "type": "number" },
29
- "dumb_flow_pct": { "type": "number" }
30
- },
31
- "required": ["status", "smart_flow_pct", "dumb_flow_pct"]
32
- };
33
-
34
- return {
35
- "type": "object",
36
- "description": "Generates divergence signals (V2) by comparing net flow of 'Positive Expectancy' vs. 'Negative Expectancy' cohorts.",
37
- "properties": {
38
- "assets": {
39
- "type": "object",
40
- "description": "Divergence signals per asset.",
41
- "patternProperties": { "^.*$": signalSchema }, // Ticker
42
- "additionalProperties": signalSchema
43
- },
44
- "sectors": {
45
- "type": "object",
46
- "description": "Divergence signals per sector.",
47
- "patternProperties": { "^.*$": signalSchema }, // Sector
48
- "additionalProperties": signalSchema
49
- }
50
- },
51
- "required": ["assets", "sectors"]
52
- };
53
- }
54
-
55
- /**
56
- * Statically declare dependencies.
57
- */
58
- static getDependencies() {
59
- return [
60
- 'positive_expectancy_cohort_flow', // Pass 4
61
- 'negative_expectancy_cohort_flow' // Pass 4
62
- ];
63
- }
64
-
65
- process() {
66
- // No-op
67
- }
68
-
69
- _calculateDivergence(smartFlow, dumbFlow) {
70
- const result = {};
71
- if (!smartFlow || !dumbFlow) {
72
- return result;
73
- }
74
-
75
- const allKeys = new Set([...Object.keys(smartFlow), ...Object.keys(dumbFlow)]);
76
- const THRESHOLD = 1; // Min flow %
77
-
78
- for (const key of allKeys) {
79
- // "Smart" = Positive Expectancy
80
- const sFlow = smartFlow[key]?.net_flow_percentage || 0;
81
- // "Dumb" = Negative Expectancy
82
- const dFlow = dumbFlow[key]?.net_flow_percentage || 0;
83
-
84
- let status = 'Neutral';
85
-
86
- if (sFlow > THRESHOLD && dFlow > THRESHOLD) {
87
- status = 'Confirmation (Buy)';
88
- }
89
- else if (sFlow < -THRESHOLD && dFlow < -THRESHOLD) {
90
- status = 'Confirmation (Sell)';
91
- }
92
- else if (sFlow > THRESHOLD && dFlow < -THRESHOLD) {
93
- status = 'Capitulation';
94
- }
95
- else if (sFlow < -THRESHOLD && dFlow > THRESHOLD) {
96
- status = 'Euphoria';
97
- }
98
- else if (sFlow > THRESHOLD && Math.abs(dFlow) < THRESHOLD) {
99
- status = 'Divergence (Smart Buy)';
100
- }
101
- else if (sFlow < -THRESHOLD && Math.abs(dFlow) < THRESHOLD) {
102
- status = 'Divergence (Smart Sell)';
103
- }
104
- else if (dFlow > THRESHOLD && Math.abs(sFlow) < THRESHOLD) {
105
- status = 'Divergence (Smart Sell)'; // Implied
106
- }
107
- else if (dFlow < -THRESHOLD && Math.abs(sFlow) < THRESHOLD) {
108
- status = 'Divergence (Smart Buy)'; // Implied
109
- }
110
-
111
- result[key] = {
112
- status: status,
113
- smart_flow_pct: sFlow,
114
- dumb_flow_pct: dFlow
115
- };
116
- }
117
- return result;
118
- }
119
-
120
- getResult(fetchedDependencies) {
121
- const smartFlowData = fetchedDependencies['positive_expectancy_cohort_flow'];
122
- const dumbFlowData = fetchedDependencies['negative_expectancy_cohort_flow'];
123
-
124
- const assetResult = this._calculateDivergence(smartFlowData?.assets, dumbFlowData?.assets);
125
- const sectorResult = this._calculateDivergence(smartFlowData?.sectors, dumbFlowData?.sectors);
126
-
127
- return {
128
- assets: assetResult,
129
- sectors: sectorResult
130
- };
131
- }
132
-
133
- reset() {
134
- // No state
135
- }
136
- }
137
-
138
- module.exports = SmartDumbDivergenceIndexV2;
@@ -1,198 +0,0 @@
1
- /**
2
- * @fileoverview Calculation (Pass 3) for smart money flow.
3
- *
4
- * This metric calculates the "Net Crowd Flow Percentage" for
5
- * "Smart Money" users, defined as users who were profitable
6
- * in 5 of the last 7 days.
7
- *
8
- * This calculation *depends* on 'user_profitability_tracker'
9
- * to identify the cohort.
10
- */
11
- const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
12
-
13
- class SmartMoneyFlow {
14
- constructor() {
15
- // This calculation only aggregates by sector
16
- this.sectorData = new Map();
17
- this.mappings = null;
18
- this.smartMoneyUserIds = null;
19
- }
20
-
21
- /**
22
- * Defines the output schema for this calculation.
23
- * @returns {object} JSON Schema object
24
- */
25
- static getSchema() {
26
- return {
27
- "type": "object",
28
- "description": "Calculates net capital flow % (price-adjusted) for the 'Smart Money' cohort (profitable 5 of last 7 days), aggregated by sector.",
29
- "properties": {
30
- "cohort_size": {
31
- "type": "number",
32
- "description": "The number of users identified as being in the Smart Money Cohort."
33
- },
34
- "sectors": {
35
- "type": "object",
36
- "description": "Price-adjusted net flow per sector.",
37
- "patternProperties": {
38
- // Sector
39
- "^.*$": {
40
- "type": "object",
41
- "properties": {
42
- "net_flow_percentage": { "type": "number" },
43
- "total_invested_today": { "type": "number" },
44
- "total_invested_yesterday": { "type": "number" }
45
- },
46
- "required": ["net_flow_percentage", "total_invested_today", "total_invested_yesterday"]
47
- }
48
- },
49
- "additionalProperties": {
50
- "type": "object",
51
- "properties": {
52
- "net_flow_percentage": { "type": "number" },
53
- "total_invested_today": { "type": "number" },
54
- "total_invested_yesterday": { "type": "number" }
55
- }
56
- }
57
- }
58
- },
59
- "required": ["cohort_size", "sectors"]
60
- };
61
- }
62
-
63
- /**
64
- * Statically declare dependencies.
65
- */
66
- static getDependencies() {
67
- return ['user_profitability_tracker'];
68
- }
69
-
70
- _getPortfolioPositions(portfolio) {
71
- return portfolio?.PublicPositions || portfolio?.AggregatedPositions;
72
- }
73
-
74
- _initSector(sector) {
75
- if (!this.sectorData.has(sector)) {
76
- this.sectorData.set(sector, {
77
- total_invested_yesterday: 0,
78
- total_invested_today: 0,
79
- price_change_yesterday: 0,
80
- });
81
- }
82
- }
83
-
84
- /**
85
- * Helper to get the cohort IDs from the dependency.
86
- */
87
- _getSmartMoneyCohort(fetchedDependencies) {
88
- if (this.smartMoneyUserIds) {
89
- return this.smartMoneyUserIds;
90
- }
91
-
92
- const profitabilityData = fetchedDependencies['user_profitability_tracker'];
93
- if (!profitabilityData || !profitabilityData.user_details) {
94
- return new Set();
95
- }
96
-
97
- this.smartMoneyUserIds = new Set();
98
- for (const [userId, data] of Object.entries(profitabilityData.user_details)) {
99
- // Definition: Profitable in 5 of the last 7 days.
100
- if (data.profitable_days_7d >= 5) {
101
- this.smartMoneyUserIds.add(userId);
102
- }
103
- }
104
- return this.smartMoneyUserIds;
105
- }
106
-
107
- process(todayPortfolio, yesterdayPortfolio, userId, context, todayInsights, yesterdayInsights, fetchedDependencies) {
108
- const smartMoneyCohort = this._getSmartMoneyCohort(fetchedDependencies);
109
-
110
- // This user is not in the "smart money cohort", skip.
111
- if (!smartMoneyCohort.has(userId)) {
112
- return;
113
- }
114
-
115
- if (!todayPortfolio || !yesterdayPortfolio) {
116
- return;
117
- }
118
-
119
- const yPos = this._getPortfolioPositions(yesterdayPortfolio);
120
- const tPos = this._getPortfolioPositions(todayPortfolio);
121
-
122
- const yPosMap = new Map(yPos?.map(p => [p.InstrumentID, p]) || []);
123
- const tPosMap = new Map(tPos?.map(p => [p.InstrumentID, p]) || []);
124
-
125
- const allInstrumentIds = new Set([...yPosMap.keys(), ...tPosMap.keys()]);
126
-
127
- if (!this.mappings) {
128
- // Context contains the mappings loaded in Pass 1
129
- this.mappings = context.mappings;
130
- }
131
-
132
- for (const instrumentId of allInstrumentIds) {
133
- if (!instrumentId) continue;
134
-
135
- const yP = yPosMap.get(instrumentId);
136
- const tP = tPosMap.get(instrumentId);
137
-
138
- const yInvested = yP?.InvestedAmount || yP?.Amount || 0;
139
- const tInvested = tP?.InvestedAmount || tP?.Amount || 0;
140
-
141
- // Get sector and initialize it
142
- const sector = this.mappings.instrumentToSector[instrumentId] || 'Other';
143
- this._initSector(sector);
144
- const sectorAsset = this.sectorData.get(sector);
145
-
146
- if (yInvested > 0) {
147
- const yPriceChange = (yP?.PipsRate || 0) / (yP?.OpenRate || 1);
148
- sectorAsset.total_invested_yesterday += yInvested;
149
- sectorAsset.price_change_yesterday += yPriceChange * yInvested;
150
- }
151
- if (tInvested > 0) {
152
- sectorAsset.total_invested_today += tInvested;
153
- }
154
- }
155
- }
156
-
157
- async getResult(fetchedDependencies) {
158
- // Ensure mappings are loaded (can be from context or loaded now)
159
- if (!this.mappings) {
160
- this.mappings = await loadInstrumentMappings();
161
- }
162
-
163
- // Ensure cohort is calculated at least once
164
- const smartMoneyCohort = this._getSmartMoneyCohort(fetchedDependencies);
165
-
166
- // Calculate Sector Flow
167
- const sectorResult = {};
168
- for (const [sector, data] of this.sectorData.entries()) {
169
- const { total_invested_yesterday, total_invested_today, price_change_yesterday } = data;
170
-
171
- if (total_invested_yesterday > 0) {
172
- const avg_price_change_pct = price_change_yesterday / total_invested_yesterday;
173
- const price_contribution = total_invested_yesterday * avg_price_change_pct;
174
- const flow_contribution = total_invested_today - (total_invested_yesterday + price_contribution);
175
- const net_flow_percentage = (flow_contribution / total_invested_yesterday) * 100;
176
-
177
- sectorResult[sector] = {
178
- net_flow_percentage: net_flow_percentage,
179
- total_invested_today: total_invested_today,
180
- total_invested_yesterday: total_invested_yesterday
181
- };
182
- }
183
- }
184
-
185
- return {
186
- cohort_size: smartMoneyCohort.size,
187
- sectors: sectorResult
188
- };
189
- }
190
-
191
- reset() {
192
- this.sectorData.clear();
193
- this.mappings = null;
194
- this.smartMoneyUserIds = null;
195
- }
196
- }
197
-
198
- module.exports = SmartMoneyFlow;
@@ -1,102 +0,0 @@
1
- /**
2
- * @fileoverview Calculation (Pass 5) for social predictive regime.
3
- *
4
- * This metric answers: "Are we in a 'social-driven' or 'flow-driven'
5
- * market regime?"
6
- *
7
- * It *depends* on 'social_flow_correlation' (Pass 4) to make
8
- * a determination.
9
- */
10
- class SocialPredictiveRegimeState {
11
- constructor() {
12
- // No per-user processing
13
- }
14
-
15
- /**
16
- * Defines the output schema for this calculation.
17
- * @returns {object} JSON Schema object
18
- */
19
- static getSchema() {
20
- return {
21
- "type": "object",
22
- "description": "Determines if the market is in a 'social-driven' or 'flow-driven' regime based on correlation.",
23
- "properties": {
24
- "regime": {
25
- "type": "string",
26
- "enum": ["Social-Driven", "Flow-Driven", "Decoupled", "Unknown"],
27
- "description": "The current market regime."
28
- },
29
- "average_correlation": {
30
- "type": "number",
31
- "description": "The average correlation value across all assets from 'social_flow_correlation'."
32
- },
33
- "correlated_assets_count": {
34
- "type": "number",
35
- "description": "Number of assets with a strong positive correlation."
36
- },
37
- "decoupled_assets_count": {
38
- "type": "number",
39
- "description": "Number of assets with a weak or negative correlation."
40
- }
41
- },
42
- "required": ["regime", "average_correlation", "correlated_assets_count", "decoupled_assets_count"]
43
- };
44
- }
45
-
46
- /**
47
- * Statically declare dependencies.
48
- */
49
- static getDependencies() {
50
- return [
51
- 'social_flow_correlation' // Pass 4
52
- ];
53
- }
54
-
55
- process() {
56
- // No-op
57
- }
58
-
59
- getResult(fetchedDependencies) {
60
- const correlationData = fetchedDependencies['social_flow_correlation'];
61
-
62
- const defaults = {
63
- regime: "Unknown",
64
- average_correlation: 0,
65
- correlated_assets_count: 0,
66
- decoupled_assets_count: 0
67
- };
68
-
69
- if (!correlationData) {
70
- return defaults;
71
- }
72
-
73
- const correlations = Object.values(correlationData).map(d => d.correlation_30d).filter(c => c !== null);
74
- if (correlations.length === 0) {
75
- return defaults;
76
- }
77
-
78
- const avgCorrelation = correlations.reduce((a, b) => a + b, 0) / correlations.length;
79
- const correlatedCount = correlations.filter(c => c > 0.5).length;
80
- const decoupledCount = correlations.filter(c => c <= 0.5).length;
81
-
82
- let regime = "Decoupled";
83
- if (avgCorrelation > 0.5 && correlatedCount > decoupledCount) {
84
- regime = "Social-Driven";
85
- } else if (avgCorrelation < 0.2) {
86
- regime = "Flow-Driven"; // Social is not predictive, flow is
87
- }
88
-
89
- return {
90
- regime: regime,
91
- average_correlation: avgCorrelation,
92
- correlated_assets_count: correlatedCount,
93
- decoupled_assets_count: decoupledCount
94
- };
95
- }
96
-
97
- reset() {
98
- // No state
99
- }
100
- }
101
-
102
- module.exports = SocialPredictiveRegimeState;