aiden-shared-calculations-unified 1.0.14 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/calculations/behavioural/{asset_crowd_flow.js → historical/asset_crowd_flow.js} +2 -2
- package/calculations/behavioural/{smart_money_flow.js → historical/smart_money_flow.js} +1 -1
- package/calculations/meta/cash-flow-liquidation.js +135 -0
- package/calculations/sectors/{diversification_pnl.js → historical/diversification_pnl.js} +1 -1
- package/calculations/sectors/{sector_rotation.js → historical/sector_rotation.js} +1 -1
- package/calculations/sentiment/{crowd_conviction_score.js → historical/crowd_conviction_score.js} +1 -1
- package/package.json +1 -1
- /package/calculations/behavioural/{drawdown_response.js → historical/drawdown_response.js} +0 -0
- /package/calculations/behavioural/{gain_response.js → historical/gain_response.js} +0 -0
- /package/calculations/behavioural/{paper_vs_diamond_hands.js → historical/paper_vs_diamond_hands.js} +0 -0
- /package/calculations/behavioural/{position_count_pnl.js → historical/position_count_pnl.js} +0 -0
- /package/calculations/capital_flow/{deposit_withdrawal_percentage.js → historical/deposit_withdrawal_percentage.js} +0 -0
- /package/calculations/capital_flow/{new_allocation_percentage.js → historical/new_allocation_percentage.js} +0 -0
- /package/calculations/capital_flow/{reallocation_increase_percentage.js → historical/reallocation_increase_percentage.js} +0 -0
- /package/calculations/pnl/{profitability_migration.js → historical/profitability_migration.js} +0 -0
- /package/calculations/pnl/{user_profitability_tracker.js → historical/user_profitability_tracker.js} +0 -0
- /package/calculations/speculators/{risk_appetite_change.js → historical/risk_appetite_change.js} +0 -0
- /package/calculations/speculators/{tsl_effectiveness.js → historical/tsl_effectiveness.js} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const { loadAllPriceData, getDailyPriceChange } = require('
|
|
2
|
-
const { loadInstrumentMappings } = require('
|
|
1
|
+
const { loadAllPriceData, getDailyPriceChange } = require('../../../utils/price_data_provider');
|
|
2
|
+
const { loadInstrumentMappings } = require('../../../utils/sector_mapping_provider');
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @fileoverview Calculates "Net Crowd Flow" for each asset.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
const { Firestore } = require('@google-cloud/firestore');
|
|
6
6
|
const firestore = new Firestore();
|
|
7
7
|
// CORRECTED PATH: ../utils/ instead of ../../utils/
|
|
8
|
-
const { getInstrumentSectorMap } = require('
|
|
8
|
+
const { getInstrumentSectorMap } = require('../../../utils/sector_mapping_provider');
|
|
9
9
|
|
|
10
10
|
class SmartMoneyFlow {
|
|
11
11
|
// ... (rest of the code is unchanged) ...
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Correlates a crowd-wide withdrawal signal with the specific assets
|
|
3
|
+
* that are being sold (liquidated) to fund those withdrawals.
|
|
4
|
+
* This is a meta-calculation that runs in Pass 3.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { FieldValue } = require('@google-cloud/firestore');
|
|
8
|
+
|
|
9
|
+
class CashFlowLiquidation {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.lookbackDays = 7;
|
|
12
|
+
this.correlationWindow = 3;
|
|
13
|
+
// A positive value signals a net crowd withdrawal
|
|
14
|
+
this.withdrawalSignalThreshold = 1.0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
_getDateStr(baseDate, daysAgo) {
|
|
18
|
+
const date = new Date(baseDate + 'T00:00:00Z');
|
|
19
|
+
date.setUTCDate(date.getUTCDate() - daysAgo);
|
|
20
|
+
return date.toISOString().slice(0, 10);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {string} dateStr The date to run the analysis for (e.g., "2025-10-31").
|
|
25
|
+
* @param {object} dependencies The shared dependencies (db, logger).
|
|
26
|
+
* @param {object} config The computation system configuration.
|
|
27
|
+
* @returns {Promise<object|null>} The analysis result or null.
|
|
28
|
+
*/
|
|
29
|
+
async process(dateStr, dependencies, config) {
|
|
30
|
+
const { db, logger } = dependencies;
|
|
31
|
+
const collection = config.resultsCollection;
|
|
32
|
+
|
|
33
|
+
// 1. Build all needed refs in advance for this day
|
|
34
|
+
const dateRefs = [];
|
|
35
|
+
const dates = [];
|
|
36
|
+
|
|
37
|
+
// Refs for the lookback period (for the signal)
|
|
38
|
+
for (let i = 1; i <= this.lookbackDays; i++) {
|
|
39
|
+
const checkDate = this._getDateStr(dateStr, i);
|
|
40
|
+
dates.push({ date: checkDate, category: 'capital_flow', computation: 'crowd-cash-flow-proxy' });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Refs for today's two dependencies
|
|
44
|
+
dates.push({ date: dateStr, category: 'capital_flow', computation: 'crowd-cash-flow-proxy' });
|
|
45
|
+
dates.push({ date: dateStr, category: 'behavioural', computation: 'asset-crowd-flow' });
|
|
46
|
+
|
|
47
|
+
// Build refs array
|
|
48
|
+
const refs = dates.map(d =>
|
|
49
|
+
db.collection(collection).doc(d.date)
|
|
50
|
+
.collection('results').doc(d.category)
|
|
51
|
+
.collection('computations').doc(d.computation)
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
const snapshots = await db.getAll(...refs);
|
|
55
|
+
|
|
56
|
+
// Build map(path -> data)
|
|
57
|
+
const dataMap = new Map();
|
|
58
|
+
snapshots.forEach((snap, idx) => {
|
|
59
|
+
if (snap.exists) dataMap.set(idx, snap.data());
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// 2. Find the withdrawal signal
|
|
63
|
+
let withdrawalSignal = null;
|
|
64
|
+
let withdrawalSignalDay = null;
|
|
65
|
+
|
|
66
|
+
for (let i = 0; i < this.lookbackDays; i++) {
|
|
67
|
+
const flowData = dataMap.get(i);
|
|
68
|
+
const dateUsed = dates[i].date;
|
|
69
|
+
// INVERTED LOGIC: Look for a POSITIVE value
|
|
70
|
+
if (flowData && flowData.cash_flow_effect_proxy > this.withdrawalSignalThreshold) {
|
|
71
|
+
withdrawalSignal = flowData;
|
|
72
|
+
withdrawalSignalDay = dateUsed;
|
|
73
|
+
break; // Found the most recent signal
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (!withdrawalSignal) {
|
|
78
|
+
return {
|
|
79
|
+
status: 'no_withdrawal_signal_found',
|
|
80
|
+
lookback_days: this.lookbackDays,
|
|
81
|
+
signal_threshold: this.withdrawalSignalThreshold
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const daysSinceSignal = (new Date(dateStr) - new Date(withdrawalSignalDay)) / (1000 * 60 * 60 * 24);
|
|
86
|
+
|
|
87
|
+
if (daysSinceSignal <= 0 || daysSinceSignal > this.correlationWindow) {
|
|
88
|
+
return {
|
|
89
|
+
status: 'outside_correlation_window',
|
|
90
|
+
signal_day: withdrawalSignalDay,
|
|
91
|
+
days_since_signal: daysSinceSignal
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 3. Get today's data to find the correlation
|
|
96
|
+
const cashFlowData = dataMap.get(this.lookbackDays);
|
|
97
|
+
const assetFlowData = dataMap.get(this.lookbackDays + 1);
|
|
98
|
+
|
|
99
|
+
if (!cashFlowData || !assetFlowData) {
|
|
100
|
+
logger.log('WARN', `[CashFlowLiquidation] Missing dependency data for ${dateStr}. Skipping.`);
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 'trading_effect' will be negative if the crowd is net-selling
|
|
105
|
+
const netSellPct = cashFlowData.components?.trading_effect || 0;
|
|
106
|
+
const netWithdrawalPct = Math.abs(withdrawalSignal.cash_flow_effect_proxy);
|
|
107
|
+
|
|
108
|
+
// INVERTED LOGIC: Find top *sells*
|
|
109
|
+
const topLiquidations = Object.entries(assetFlowData)
|
|
110
|
+
.filter(([ticker, data]) => data.net_crowd_flow_pct < 0) // Find assets with negative flow
|
|
111
|
+
.sort(([, a], [, b]) => a.net_crowd_flow_pct - b.net_crowd_flow_pct) // Sort ascending (most negative first)
|
|
112
|
+
.slice(0, 10)
|
|
113
|
+
.map(([ticker, data]) => ({
|
|
114
|
+
ticker,
|
|
115
|
+
net_flow_pct: data.net_crowd_flow_pct
|
|
116
|
+
}));
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
status: 'analysis_complete',
|
|
120
|
+
analysis_date: dateStr,
|
|
121
|
+
signal_date: withdrawalSignalDay,
|
|
122
|
+
days_since_signal: daysSinceSignal,
|
|
123
|
+
signal_withdrawal_proxy_pct: netWithdrawalPct,
|
|
124
|
+
day_net_sell_pct: netSellPct, // This value should be negative
|
|
125
|
+
pct_of_withdrawal_funded_today: (Math.abs(netSellPct) / netWithdrawalPct) * 100,
|
|
126
|
+
top_liquidation_assets: topLiquidations
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Must exist for the meta-computation runner
|
|
131
|
+
async getResult() { return null; }
|
|
132
|
+
reset() {}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
module.exports = CashFlowLiquidation;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// CORRECTED PATH: ../utils/ instead of ../../utils/
|
|
2
|
-
const { getInstrumentSectorMap } = require('
|
|
2
|
+
const { getInstrumentSectorMap } = require('../../../utils/sector_mapping_provider');
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Aggregates P/L by the number of unique sectors a user is invested in.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @fileoverview Analyzes sector rotation by comparing investment amounts between two days.
|
|
3
3
|
*/
|
|
4
4
|
// CORRECTED PATH: ../utils/ instead of ../../utils/
|
|
5
|
-
const { getInstrumentSectorMap } = require('
|
|
5
|
+
const { getInstrumentSectorMap } = require('../../../utils/sector_mapping_provider');
|
|
6
6
|
|
|
7
7
|
class SectorRotation {
|
|
8
8
|
// ... (rest of the code is unchanged) ...
|
package/calculations/sentiment/{crowd_conviction_score.js → historical/crowd_conviction_score.js}
RENAMED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @fileoverview Calculates a "Crowd Conviction" score for each instrument.
|
|
3
3
|
*/
|
|
4
4
|
// CORRECTED PATH: ../utils/ instead of ../../utils/
|
|
5
|
-
const { loadInstrumentMappings } = require('
|
|
5
|
+
const { loadInstrumentMappings } = require('../../../utils/sector_mapping_provider');
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class CrowdConvictionScore {
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
/package/calculations/behavioural/{paper_vs_diamond_hands.js → historical/paper_vs_diamond_hands.js}
RENAMED
|
File without changes
|
/package/calculations/behavioural/{position_count_pnl.js → historical/position_count_pnl.js}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/calculations/pnl/{profitability_migration.js → historical/profitability_migration.js}
RENAMED
|
File without changes
|
/package/calculations/pnl/{user_profitability_tracker.js → historical/user_profitability_tracker.js}
RENAMED
|
File without changes
|
/package/calculations/speculators/{risk_appetite_change.js → historical/risk_appetite_change.js}
RENAMED
|
File without changes
|
|
File without changes
|