aiden-shared-calculations-unified 1.0.64 → 1.0.66

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 (89) hide show
  1. package/README.MD +1 -1
  2. package/calculations/activity/historical/activity_by_pnl_status.js +33 -0
  3. package/calculations/activity/historical/daily_asset_activity.js +42 -0
  4. package/calculations/activity/historical/daily_user_activity_tracker.js +37 -0
  5. package/calculations/activity/historical/speculator_adjustment_activity.js +26 -0
  6. package/calculations/asset_metrics/asset_position_size.js +36 -0
  7. package/calculations/backtests/strategy-performance.js +41 -0
  8. package/calculations/behavioural/historical/asset_crowd_flow.js +124 -127
  9. package/calculations/behavioural/historical/drawdown_response.js +113 -35
  10. package/calculations/behavioural/historical/dumb-cohort-flow.js +191 -171
  11. package/calculations/behavioural/historical/gain_response.js +113 -34
  12. package/calculations/behavioural/historical/historical_performance_aggregator.js +63 -48
  13. package/calculations/behavioural/historical/in_loss_asset_crowd_flow.js +159 -63
  14. package/calculations/behavioural/historical/in_profit_asset_crowd_flow.js +159 -64
  15. package/calculations/behavioural/historical/paper_vs_diamond_hands.js +86 -19
  16. package/calculations/behavioural/historical/position_count_pnl.js +91 -39
  17. package/calculations/behavioural/historical/smart-cohort-flow.js +192 -172
  18. package/calculations/behavioural/historical/smart_money_flow.js +160 -151
  19. package/calculations/capital_flow/historical/crowd-cash-flow-proxy.js +95 -89
  20. package/calculations/capital_flow/historical/deposit_withdrawal_percentage.js +88 -81
  21. package/calculations/capital_flow/historical/new_allocation_percentage.js +75 -26
  22. package/calculations/capital_flow/historical/reallocation_increase_percentage.js +73 -32
  23. package/calculations/insights/daily_buy_sell_sentiment_count.js +47 -32
  24. package/calculations/insights/daily_total_positions_held.js +28 -24
  25. package/calculations/insights/historical/daily_bought_vs_sold_count.js +101 -36
  26. package/calculations/insights/historical/daily_ownership_delta.js +95 -32
  27. package/calculations/meta/capital_deployment_strategy.js +78 -110
  28. package/calculations/meta/capital_liquidation_performance.js +114 -111
  29. package/calculations/meta/cash-flow-deployment.js +114 -107
  30. package/calculations/meta/cash-flow-liquidation.js +114 -107
  31. package/calculations/meta/crowd_sharpe_ratio_proxy.js +94 -54
  32. package/calculations/meta/negative_expectancy_cohort_flow.js +185 -177
  33. package/calculations/meta/positive_expectancy_cohort_flow.js +186 -181
  34. package/calculations/meta/profit_cohort_divergence.js +83 -59
  35. package/calculations/meta/shark_attack_signal.js +91 -39
  36. package/calculations/meta/smart-dumb-divergence-index.js +114 -98
  37. package/calculations/meta/smart_dumb_divergence_index_v2.js +109 -98
  38. package/calculations/meta/social-predictive-regime-state.js +76 -155
  39. package/calculations/meta/social-topic-driver-index.js +74 -127
  40. package/calculations/meta/user_expectancy_score.js +83 -31
  41. package/calculations/pnl/asset_pnl_status.js +120 -31
  42. package/calculations/pnl/average_daily_pnl_all_users.js +42 -27
  43. package/calculations/pnl/average_daily_pnl_per_sector.js +84 -26
  44. package/calculations/pnl/average_daily_pnl_per_stock.js +71 -29
  45. package/calculations/pnl/average_daily_position_pnl.js +49 -21
  46. package/calculations/pnl/historical/profitability_migration.js +81 -35
  47. package/calculations/pnl/historical/user_profitability_tracker.js +107 -104
  48. package/calculations/pnl/pnl_distribution_per_stock.js +65 -45
  49. package/calculations/pnl/profitability_ratio_per_stock.js +78 -21
  50. package/calculations/pnl/profitability_skew_per_stock.js +86 -31
  51. package/calculations/pnl/profitable_and_unprofitable_status.js +45 -45
  52. package/calculations/sanity/users_processed.js +24 -1
  53. package/calculations/sectors/historical/diversification_pnl.js +104 -42
  54. package/calculations/sectors/historical/sector_rotation.js +94 -45
  55. package/calculations/sectors/total_long_per_sector.js +55 -20
  56. package/calculations/sectors/total_short_per_sector.js +55 -20
  57. package/calculations/sentiment/historical/crowd_conviction_score.js +233 -53
  58. package/calculations/short_and_long_stats/long_position_per_stock.js +50 -14
  59. package/calculations/short_and_long_stats/sentiment_per_stock.js +76 -19
  60. package/calculations/short_and_long_stats/short_position_per_stock.js +50 -13
  61. package/calculations/short_and_long_stats/total_long_figures.js +34 -13
  62. package/calculations/short_and_long_stats/total_short_figures.js +34 -14
  63. package/calculations/socialPosts/social-asset-posts-trend.js +96 -29
  64. package/calculations/socialPosts/social-top-mentioned-words.js +95 -74
  65. package/calculations/socialPosts/social-topic-interest-evolution.js +92 -29
  66. package/calculations/socialPosts/social-topic-sentiment-matrix.js +70 -78
  67. package/calculations/socialPosts/social-word-mentions-trend.js +96 -38
  68. package/calculations/socialPosts/social_activity_aggregation.js +106 -77
  69. package/calculations/socialPosts/social_sentiment_aggregation.js +115 -86
  70. package/calculations/speculators/distance_to_stop_loss_per_leverage.js +82 -43
  71. package/calculations/speculators/distance_to_tp_per_leverage.js +81 -42
  72. package/calculations/speculators/entry_distance_to_sl_per_leverage.js +80 -44
  73. package/calculations/speculators/entry_distance_to_tp_per_leverage.js +81 -44
  74. package/calculations/speculators/historical/risk_appetite_change.js +89 -32
  75. package/calculations/speculators/historical/tsl_effectiveness.js +57 -47
  76. package/calculations/speculators/holding_duration_per_asset.js +83 -23
  77. package/calculations/speculators/leverage_per_asset.js +68 -19
  78. package/calculations/speculators/leverage_per_sector.js +86 -25
  79. package/calculations/speculators/risk_reward_ratio_per_asset.js +82 -28
  80. package/calculations/speculators/speculator_asset_sentiment.js +100 -48
  81. package/calculations/speculators/speculator_danger_zone.js +101 -33
  82. package/calculations/speculators/stop_loss_distance_by_sector_short_long_breakdown.js +93 -66
  83. package/calculations/speculators/stop_loss_distance_by_ticker_short_long_breakdown.js +94 -47
  84. package/calculations/speculators/stop_loss_per_asset.js +94 -26
  85. package/calculations/speculators/take_profit_per_asset.js +95 -27
  86. package/calculations/speculators/tsl_per_asset.js +77 -23
  87. package/package.json +1 -1
  88. package/utils/price_data_provider.js +142 -142
  89. package/utils/sector_mapping_provider.js +74 -74
@@ -1,139 +1,146 @@
1
1
  /**
2
- * @fileoverview Correlates a crowd-wide withdrawal signal with the specific assets
3
- * that are being sold (liquidated) to fund those withdrawals.
2
+ * @fileoverview Calculation (Pass 3) for cash flow liquidation.
4
3
  *
5
- * --- META REFACTOR (v2) ---
6
- * This calc fetches *today's* dependencies from the runner, but still
7
- * performs its own historical lookback for the *signal*.
4
+ * This metric answers: "Following a net withdrawal event, what percentage
5
+ * of that withdrawal was funded by selling *today*, and which assets
6
+ * are being liquidated the most?"
7
+ *
8
+ * It *depends* on 'crowd-cash-flow-proxy' (to know if it's a
9
+ * withdrawal day) and 'asset_crowd_flow' (to see where flow went).
8
10
  */
9
-
10
- const { FieldValue } = require('@google-cloud/firestore');
11
-
12
11
  class CashFlowLiquidation {
12
+ constructor() {
13
+ // No per-user processing
14
+ }
13
15
 
14
16
  /**
15
- * (NEW) Statically declare dependencies.
17
+ * Defines the output schema for this calculation.
18
+ * @returns {object} JSON Schema object
16
19
  */
17
- static getDependencies() {
18
- return ['crowd-cash-flow-proxy', 'asset-crowd-flow'];
19
- }
20
-
21
- constructor() {
22
- this.lookbackDays = 7;
23
- this.correlationWindow = 3;
24
- // A positive value signals a net crowd withdrawal
25
- this.withdrawalSignalThreshold = 0.005;
26
- }
20
+ static getSchema() {
21
+ const assetFlowSchema = {
22
+ "type": "object",
23
+ "properties": {
24
+ "ticker": { "type": "string" },
25
+ "net_flow_contribution": { "type": "number" },
26
+ "percent_of_total_outflow": { "type": "number" }
27
+ },
28
+ "required": ["ticker", "net_flow_contribution", "percent_of_total_outflow"]
29
+ };
27
30
 
28
- _getDateStr(baseDate, daysAgo) {
29
- const date = new Date(baseDate + 'T00:00:00Z');
30
- date.setUTCDate(date.getUTCDate() - daysAgo);
31
- return date.toISOString().slice(0, 10);
31
+ return {
32
+ "type": "object",
33
+ "description": "On net withdrawal days, tracks % of withdrawal funded by selling and which assets were sold.",
34
+ "properties": {
35
+ "is_net_withdrawal_day": {
36
+ "type": "boolean",
37
+ "description": "True if today was a net withdrawal day."
38
+ },
39
+ "net_cash_flow_proxy": {
40
+ "type": "number",
41
+ "description": "The total estimated net cash flow (negative)."
42
+ },
43
+ "total_net_capital_flow": {
44
+ "type": "number",
45
+ "description": "The sum of all *negative* net capital flows from assets (total liquidation)."
46
+ },
47
+ "funding_percentage": {
48
+ "type": ["number", "null"],
49
+ "description": "Percentage of net cash flow funded by selling (Total Net Flow / Net Cash Flow). Null if no cash flow."
50
+ },
51
+ "top_outflow_assets": {
52
+ "type": "array",
53
+ "description": "Top 5 assets being liquidated.",
54
+ "items": assetFlowSchema
55
+ },
56
+ "asset_flow_details": {
57
+ "type": "array",
58
+ "description": "Full list of all assets and their outflows.",
59
+ "items": assetFlowSchema
60
+ }
61
+ },
62
+ "required": ["is_net_withdrawal_day", "net_cash_flow_proxy", "total_net_capital_flow", "funding_percentage", "top_outflow_assets", "asset_flow_details"]
63
+ };
32
64
  }
33
65
 
34
66
  /**
35
- * REFACTORED PROCESS METHOD
36
- * @param {string} dateStr The date to run the analysis for (e.g., "2025-10-31").
37
- * @param {object} dependencies The shared dependencies (db, logger).
38
- * @param {object} config The computation system configuration.
39
- * @param {object} fetchedDependencies In-memory results from previous passes.
40
- * @returns {Promise<object|null>} The analysis result or null.
67
+ * Statically declare dependencies.
41
68
  */
42
- async process(dateStr, dependencies, config, fetchedDependencies) {
43
- const { db, logger } = dependencies;
44
- const collection = config.resultsCollection;
45
- const resultsSub = config.resultsSubcollection || 'results';
46
- const compsSub = config.computationsSubcollection || 'computations';
69
+ static getDependencies() {
70
+ return [
71
+ 'crowd-cash-flow-proxy', // Pass 2
72
+ 'asset_crowd_flow' // Pass 2
73
+ ];
74
+ }
47
75
 
48
- // 1. Get same-day dependencies from `fetchedDependencies`
49
- const cashFlowData = fetchedDependencies['crowd-cash-flow-proxy'];
50
- const assetFlowData = fetchedDependencies['asset-crowd-flow'];
76
+ process() {
77
+ // No-op
78
+ }
51
79
 
52
- if (!cashFlowData || !assetFlowData) {
53
- logger.log('WARN', `[CashFlowLiquidation] Missing critical in-memory dependency data for ${dateStr}. Skipping.`);
54
- return null;
55
- }
80
+ getResult(fetchedDependencies) {
81
+ const cashFlowData = fetchedDependencies['crowd-cash-flow-proxy'];
82
+ const assetFlowData = fetchedDependencies['asset_crowd_flow'];
83
+
84
+ const defaults = {
85
+ is_net_withdrawal_day: false,
86
+ net_cash_flow_proxy: 0,
87
+ total_net_capital_flow: 0,
88
+ funding_percentage: null,
89
+ top_outflow_assets: [],
90
+ asset_flow_details: []
91
+ };
56
92
 
57
- // 2. Historical lookback for signal (still uses Firestore)
58
- const dates = [];
59
- for (let i = 1; i <= this.lookbackDays; i++) {
60
- const checkDate = this._getDateStr(dateStr, i);
61
- dates.push({ date: checkDate, category: 'capital_flow', computation: 'crowd-cash-flow-proxy' });
93
+ if (!cashFlowData || !assetFlowData || cashFlowData.net_cash_flow_proxy >= 0) {
94
+ // Not a net withdrawal day
95
+ return defaults;
62
96
  }
63
- const refs = dates.map(d =>
64
- db.collection(collection).doc(d.date)
65
- .collection(resultsSub).doc(d.category)
66
- .collection(compsSub).doc(d.computation)
67
- );
68
- const snapshots = await db.getAll(...refs);
69
- const dataMap = new Map();
70
- snapshots.forEach((snap, idx) => {
71
- if (snap.exists) dataMap.set(idx, snap.data());
72
- });
73
-
74
- // 2. Find the withdrawal signal
75
- let withdrawalSignal = null;
76
- let withdrawalSignalDay = null;
77
97
 
78
- for (let i = 0; i < this.lookbackDays; i++) {
79
- const flowData = dataMap.get(i);
80
- const dateUsed = dates[i].date;
81
- // INVERTED LOGIC: Look for a POSITIVE value
82
- if (flowData && flowData.cash_flow_effect_proxy > this.withdrawalSignalThreshold) {
83
- withdrawalSignal = flowData;
84
- withdrawalSignalDay = dateUsed;
85
- break; // Found the most recent signal
98
+ const netCashFlow = cashFlowData.net_cash_flow_proxy; // This is a negative number
99
+ let totalNetOutflow = 0;
100
+ const allFlows = [];
101
+
102
+ for (const [ticker, data] of Object.entries(assetFlowData)) {
103
+ // We only care about *negative* flow (liquidation)
104
+ if (data.net_flow_contribution < 0) {
105
+ totalNetOutflow += data.net_flow_contribution; // Summing negative numbers
106
+ allFlows.push({
107
+ ticker: ticker,
108
+ net_flow_contribution: data.net_flow_contribution
109
+ });
86
110
  }
87
111
  }
88
112
 
89
- if (!withdrawalSignal) {
113
+ if (totalNetOutflow === 0) {
114
+ // Net withdrawal day, but no negative flow detected
90
115
  return {
91
- status: 'no_withdrawal_signal_found',
92
- lookback_days: this.lookbackDays,
93
- signal_threshold: this.withdrawalSignalThreshold
116
+ ...defaults,
117
+ is_net_withdrawal_day: true,
118
+ net_cash_flow_proxy: netCashFlow,
119
+ funding_percentage: 0
94
120
  };
95
121
  }
96
122
 
97
- // 3. Check correlation window
98
- const daysSinceSignal = (new Date(dateStr) - new Date(withdrawalSignalDay)) / (1000 * 60 * 60 * 24);
99
-
100
- if (daysSinceSignal <= 0 || daysSinceSignal > this.correlationWindow) {
101
- return {
102
- status: 'outside_correlation_window',
103
- signal_day: withdrawalSignalDay,
104
- days_since_signal: daysSinceSignal
105
- };
106
- }
107
-
108
- // 4. Use in-memory data for today's analysis
109
- // 'trading_effect' will be negative if the crowd is net-selling
110
- const netSellPct = cashFlowData.components?.trading_effect || 0;
111
- const netWithdrawalPct = Math.abs(withdrawalSignal.cash_flow_effect_proxy);
112
-
113
- // INVERTED LOGIC: Find top *sells*
114
- const topLiquidations = Object.entries(assetFlowData)
115
- .filter(([ticker, data]) => data.net_crowd_flow_pct < 0) // Find assets with negative flow
116
- .sort(([, a], [, b]) => a.net_crowd_flow_pct - b.net_crowd_flow_pct) // Sort ascending (most negative first)
117
- .slice(0, 10)
118
- .map(([ticker, data]) => ({
119
- ticker,
120
- net_flow_pct: data.net_crowd_flow_pct
121
- }));
123
+ // Calculate percent_of_total_outflow for each
124
+ const asset_flow_details = allFlows.map(flow => ({
125
+ ...flow,
126
+ // (Negative / Negative) * 100 = Positive %
127
+ percent_of_total_outflow: (flow.net_flow_contribution / totalNetOutflow) * 100
128
+ })).sort((a, b) => a.net_flow_contribution - b.net_flow_contribution); // Sort ascending (most negative first)
122
129
 
123
130
  return {
124
- status: 'analysis_complete',
125
- analysis_date: dateStr,
126
- signal_date: withdrawalSignalDay,
127
- days_since_signal: daysSinceSignal,
128
- signal_withdrawal_proxy_pct: netWithdrawalPct,
129
- day_net_sell_pct: netSellPct, // This value should be negative
130
- pct_of_withdrawal_funded_today: (Math.abs(netSellPct) / netWithdrawalPct) * 100,
131
- top_liquidation_assets: topLiquidations
131
+ is_net_withdrawal_day: true,
132
+ net_cash_flow_proxy: netCashFlow,
133
+ total_net_capital_flow: totalNetOutflow,
134
+ // (Negative / Negative) * 100 = Positive %
135
+ funding_percentage: (netCashFlow < 0) ? (totalNetOutflow / netCashFlow) * 100 : null,
136
+ top_outflow_assets: asset_flow_details.slice(0, 5),
137
+ asset_flow_details: asset_flow_details
132
138
  };
133
139
  }
134
140
 
135
- async getResult() { return null; }
136
- reset() {}
141
+ reset() {
142
+ // No state
143
+ }
137
144
  }
138
145
 
139
146
  module.exports = CashFlowLiquidation;
@@ -1,84 +1,124 @@
1
1
  /**
2
- * @fileoverview Meta-calculation (Pass 3) to calculate a proxy for the
3
- * crowd's "Sharpe Ratio" (risk-adjusted return) on a per-asset basis.
4
- * It uses the components from 'pnl_distribution_per_stock' to calculate
5
- * the standard deviation of P/L, which serves as the "risk".
2
+ * @fileoverview Calculation (Pass 2) for crowd sharpe ratio proxy.
3
+ *
4
+ * This metric answers: "What is the crowd's risk-adjusted return
5
+ * (Sharpe Ratio proxy) for each asset?"
6
+ *
7
+ * It uses the distribution of P&L from 'pnl_distribution_per_stock'
8
+ * to calculate variance (risk).
6
9
  */
10
+ const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
7
11
 
8
12
  class CrowdSharpeRatioProxy {
9
- constructor() {}
13
+ constructor() {
14
+ this.mappings = null;
15
+ }
10
16
 
11
17
  /**
12
- * @param {string} dateStr The date to run the analysis for (e.g., "2025-10-31").
13
- * @param {object} dependencies The shared dependencies (db, logger).
14
- * @param {object} config The computation system configuration.
15
- * @param {object} computedDependencies In-memory results from previous passes.
16
- * @returns {Promise<object|null>} The analysis result or null.
18
+ * Defines the output schema for this calculation.
19
+ * @returns {object} JSON Schema object
17
20
  */
18
- async process(dateStr, dependencies, config, computedDependencies) {
19
- const { logger } = dependencies;
21
+ static getSchema() {
22
+ const tickerSchema = {
23
+ "type": "object",
24
+ "description": "Sharpe Ratio proxy metrics for a specific asset.",
25
+ "properties": {
26
+ "sharpe_ratio_proxy": {
27
+ "type": "number",
28
+ "description": "Risk-adjusted return proxy (Mean P&L / StdDev P&L). Assumes risk-free rate is 0."
29
+ },
30
+ "average_pnl": { "type": "number" },
31
+ "std_dev_pnl": { "type": "number" },
32
+ "variance_pnl": { "type": "number" },
33
+ "position_count": { "type": "number" }
34
+ },
35
+ "required": ["sharpe_ratio_proxy", "average_pnl", "std_dev_pnl", "position_count"]
36
+ };
20
37
 
21
- // 1. Get dependency from in-memory cache
22
- const data = computedDependencies['pnl-distribution-per-stock'];
38
+ return {
39
+ "type": "object",
40
+ "description": "Calculates a risk-adjusted return (Sharpe Ratio proxy) for each asset based on P&L distribution.",
41
+ "patternProperties": {
42
+ "^.*$": tickerSchema // Matches any string key (ticker)
43
+ },
44
+ "additionalProperties": tickerSchema
45
+ };
46
+ }
23
47
 
24
- // 2. Handle missing dependency
25
- if (!data) {
26
- logger.log('WARN', `[CrowdSharpeRatioProxy] Missing dependency 'pnl-distribution-per-stock' for ${dateStr}. Skipping.`);
27
- return null;
28
- }
48
+ /**
49
+ * Statically declare dependencies.
50
+ */
51
+ static getDependencies() {
52
+ return [
53
+ 'pnl_distribution_per_stock' // Pass 1
54
+ ];
55
+ }
29
56
 
30
- const pnlDistribution = data.pnl_distribution_by_asset;
57
+ process() {
58
+ // No-op
59
+ }
31
60
 
32
- if (!pnlDistribution) {
33
- logger.log('WARN', `[CrowdSharpeRatioProxy] Dependency data for ${dateStr} is empty. Skipping.`);
34
- return null;
61
+ async getResult(fetchedDependencies) {
62
+ const pnlDistData = fetchedDependencies['pnl_distribution_per_stock'];
63
+
64
+ if (!pnlDistData) {
65
+ return {};
66
+ }
67
+
68
+ if (!this.mappings) {
69
+ this.mappings = await loadInstrumentMappings();
35
70
  }
36
71
 
37
- const results = {};
72
+ const result = {};
38
73
 
39
- // 3. Calculate Sharpe Proxy for each asset
40
- for (const ticker in pnlDistribution) {
41
- const stats = pnlDistribution[ticker];
42
- const N = stats.position_count;
74
+ for (const [instrumentId, data] of Object.entries(pnlDistData)) {
75
+ const { sum, sumSq, count } = data;
43
76
 
44
- // Need at least 2 data points to calculate variance
45
- if (N < 2) continue;
77
+ if (count < 2) {
78
+ continue; // Need at least 2 data points for variance
79
+ }
46
80
 
47
- const mean = stats.pnl_sum / N; // E(x)
48
- const mean_sq = stats.pnl_sum_sq / N; // E(x^2)
81
+ // Calculate Mean (Average P&L)
82
+ const mean = sum / count;
49
83
 
50
- const variance = mean_sq - (mean * mean);
51
-
52
- // If variance is negative (floating point error) or zero, we can't get std_dev
53
- if (variance <= 0) {
54
- results[ticker] = {
55
- average_pnl: mean,
56
- std_dev_pnl: 0,
57
- sharpe_ratio_proxy: 0,
58
- position_count: N
59
- };
84
+ // Calculate Variance
85
+ // Var(X) = E[X^2] - (E[X])^2
86
+ const meanSq = sumSq / count;
87
+ const variance = meanSq - (mean * mean);
88
+
89
+ // Handle potential float precision errors
90
+ if (variance < 0) {
60
91
  continue;
61
92
  }
62
93
 
63
- const std_dev = Math.sqrt(variance); // "Risk"
94
+ // Calculate Standard Deviation (Risk)
95
+ const stdDev = Math.sqrt(variance);
96
+
97
+ if (stdDev === 0) {
98
+ continue; // No risk, Sharpe ratio is infinite/undefined
99
+ }
100
+
101
+ // Calculate Sharpe Ratio Proxy (assuming risk-free rate = 0)
102
+ // Sharpe = Mean(Return) / StdDev(Return)
103
+ const sharpeProxy = mean / stdDev;
64
104
 
65
- // Calculate Sharpe Ratio (Return / Risk)
66
- // (Assuming 0 risk-free rate)
67
- const sharpe_proxy = mean / std_dev;
105
+ const ticker = this.mappings.instrumentToTicker[instrumentId] || `id_${instrumentId}`;
68
106
 
69
- results[ticker] = {
107
+ result[ticker] = {
108
+ sharpe_ratio_proxy: sharpeProxy,
70
109
  average_pnl: mean,
71
- std_dev_pnl: std_dev,
72
- sharpe_ratio_proxy: sharpe_proxy,
73
- position_count: N
110
+ std_dev_pnl: stdDev,
111
+ variance_pnl: variance,
112
+ position_count: count
74
113
  };
75
114
  }
76
-
77
- return results;
115
+
116
+ return result;
78
117
  }
79
118
 
80
- async getResult() { return null; }
81
- reset() {}
119
+ reset() {
120
+ this.mappings = null;
121
+ }
82
122
  }
83
123
 
84
124
  module.exports = CrowdSharpeRatioProxy;