aiden-shared-calculations-unified 1.0.105 → 1.0.106
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/core/crowd-cost-basis.js +19 -25
- package/calculations/core/leverage-divergence.js +22 -25
- package/calculations/core/liquidation-cascade.js +18 -19
- package/calculations/core/user-history-reconstructor.js +100 -55
- package/package.json +1 -1
- package/calculations/audit_results.txt +0 -97
- package/calculations/audit_schemas.js +0 -47
|
@@ -1,71 +1,65 @@
|
|
|
1
1
|
class CrowdCostBasis {
|
|
2
|
-
constructor() {
|
|
3
|
-
this.results = {};
|
|
4
|
-
}
|
|
2
|
+
constructor() { this.results = {}; }
|
|
5
3
|
|
|
6
4
|
static getMetadata() {
|
|
7
5
|
return {
|
|
8
6
|
name: 'crowd-cost-basis',
|
|
9
7
|
type: 'meta',
|
|
10
8
|
category: 'History Reconstruction',
|
|
11
|
-
userType: 'n/a',
|
|
9
|
+
userType: 'n/a',
|
|
12
10
|
isHistorical: false,
|
|
13
11
|
rootDataDependencies: ['price']
|
|
14
12
|
};
|
|
15
13
|
}
|
|
16
14
|
|
|
17
|
-
static getDependencies() {
|
|
18
|
-
return ['user-history-reconstructor'];
|
|
19
|
-
}
|
|
15
|
+
static getDependencies() { return ['user-history-reconstructor']; }
|
|
20
16
|
|
|
21
17
|
static getSchema() {
|
|
22
18
|
const schema = {
|
|
23
19
|
"type": "object",
|
|
24
20
|
"properties": {
|
|
25
|
-
"avgEntry": { "type": "number" },
|
|
26
|
-
"holderCount": { "type": "number" },
|
|
27
|
-
"profitabilityPct": { "type": "number" },
|
|
28
|
-
"state": { "type": "string" }
|
|
21
|
+
"avgEntry": { "type": "number", "description": "Global average entry price for all holders." },
|
|
22
|
+
"holderCount": { "type": "number", "description": "Total number of users holding the asset." },
|
|
23
|
+
"profitabilityPct": { "type": "number", "description": "Percentage distance between current price and avg entry." },
|
|
24
|
+
"state": { "type": "string", "description": "Profitability state: PROFIT_SUPPORT or LOSS_RESISTANCE." }
|
|
29
25
|
},
|
|
30
26
|
"required": ["avgEntry", "holderCount", "profitabilityPct", "state"]
|
|
31
27
|
};
|
|
28
|
+
// The result is a Map of Ticker -> Schema
|
|
32
29
|
return { "type": "object", "patternProperties": { "^.*$": schema } };
|
|
33
30
|
}
|
|
34
31
|
|
|
35
32
|
async process(context) {
|
|
36
33
|
const { computed, prices, math } = context;
|
|
37
|
-
|
|
38
|
-
// 1. Access the output of the Standard calculation
|
|
39
34
|
const userReconstructions = computed['user-history-reconstructor'];
|
|
40
35
|
if (!userReconstructions) return;
|
|
41
36
|
|
|
42
|
-
const aggregator = {};
|
|
37
|
+
const aggregator = {};
|
|
43
38
|
|
|
44
|
-
//
|
|
39
|
+
// 1. Iterate Users
|
|
45
40
|
for (const userId in userReconstructions) {
|
|
46
41
|
const userPortfolio = userReconstructions[userId];
|
|
47
42
|
|
|
48
43
|
for (const ticker in userPortfolio) {
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
if (!aggregator[ticker]) aggregator[ticker] = { sumEntry: 0, count: 0 };
|
|
44
|
+
const stats = userPortfolio[ticker];
|
|
52
45
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
46
|
+
if (stats.isHolder === 1) {
|
|
47
|
+
if (!aggregator[ticker]) aggregator[ticker] = { sumEntry: 0, count: 0 };
|
|
48
|
+
aggregator[ticker].sumEntry += stats.avgEntry;
|
|
49
|
+
aggregator[ticker].count++;
|
|
50
|
+
}
|
|
56
51
|
}
|
|
57
52
|
}
|
|
58
53
|
|
|
59
|
-
//
|
|
54
|
+
// 2. Compute Global Cost Basis
|
|
60
55
|
for (const ticker in aggregator) {
|
|
61
56
|
const data = aggregator[ticker];
|
|
62
|
-
if (data.count <
|
|
57
|
+
if (data.count < 5) continue;
|
|
63
58
|
|
|
64
59
|
const globalAvgEntry = data.sumEntry / data.count;
|
|
65
60
|
|
|
66
|
-
// Get
|
|
61
|
+
// Get Price for Context Date
|
|
67
62
|
const priceHistory = math.priceExtractor.getHistory(prices, ticker);
|
|
68
|
-
// The last item in price history for this context is "Today"
|
|
69
63
|
const lastPriceObj = priceHistory[priceHistory.length - 1];
|
|
70
64
|
const currentPrice = lastPriceObj ? lastPriceObj.price : globalAvgEntry;
|
|
71
65
|
|
|
@@ -7,24 +7,22 @@ class LeverageDivergence {
|
|
|
7
7
|
type: 'meta',
|
|
8
8
|
category: 'History Reconstruction',
|
|
9
9
|
userType: 'n/a',
|
|
10
|
-
isHistorical: true,
|
|
10
|
+
isHistorical: true,
|
|
11
11
|
rootDataDependencies: []
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
static getDependencies() {
|
|
16
|
-
return ['user-history-reconstructor'];
|
|
17
|
-
}
|
|
15
|
+
static getDependencies() { return ['user-history-reconstructor']; }
|
|
18
16
|
|
|
19
17
|
static getSchema() {
|
|
20
18
|
const schema = {
|
|
21
19
|
"type": "object",
|
|
22
20
|
"properties": {
|
|
23
|
-
"levHolders": { "type": "number" },
|
|
24
|
-
"spotHolders": { "type": "number" },
|
|
25
|
-
"levDelta": { "type": "number" },
|
|
26
|
-
"spotDelta": { "type": "number" },
|
|
27
|
-
"signal": { "type": "string" }
|
|
21
|
+
"levHolders": { "type": "number", "description": "Count of holders with leverage > 1.1x." },
|
|
22
|
+
"spotHolders": { "type": "number", "description": "Count of holders with leverage <= 1.1x." },
|
|
23
|
+
"levDelta": { "type": "number", "description": "Change in leveraged holders vs yesterday." },
|
|
24
|
+
"spotDelta": { "type": "number", "description": "Change in spot holders vs yesterday." },
|
|
25
|
+
"signal": { "type": "string", "description": "Divergence signal: NEUTRAL, SMART_ACCUMULATION, SPECULATIVE_PUMP, SMART_EXIT." }
|
|
28
26
|
},
|
|
29
27
|
"required": ["levHolders", "spotHolders", "levDelta", "spotDelta", "signal"]
|
|
30
28
|
};
|
|
@@ -35,29 +33,30 @@ class LeverageDivergence {
|
|
|
35
33
|
const { computed, previousComputed } = context;
|
|
36
34
|
|
|
37
35
|
const currentReconstruction = computed['user-history-reconstructor'];
|
|
38
|
-
// Access SELF from yesterday
|
|
39
36
|
const previousResult = previousComputed['leverage-divergence'];
|
|
40
37
|
|
|
41
|
-
const currentAgg = {};
|
|
38
|
+
const currentAgg = {};
|
|
42
39
|
|
|
43
40
|
// 1. Build Today's Aggregates
|
|
44
41
|
for (const userId in currentReconstruction) {
|
|
45
42
|
const userPortfolio = currentReconstruction[userId];
|
|
43
|
+
|
|
46
44
|
for (const ticker in userPortfolio) {
|
|
47
|
-
const
|
|
45
|
+
const stats = userPortfolio[ticker];
|
|
48
46
|
|
|
49
|
-
if (
|
|
47
|
+
if (stats.isHolder === 1) {
|
|
48
|
+
if (!currentAgg[ticker]) currentAgg[ticker] = { levHolders: 0, spotHolders: 0 };
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
if (stats.avgLeverage > 1.1) {
|
|
51
|
+
currentAgg[ticker].levHolders++;
|
|
52
|
+
} else {
|
|
53
|
+
currentAgg[ticker].spotHolders++;
|
|
54
|
+
}
|
|
56
55
|
}
|
|
57
56
|
}
|
|
58
57
|
}
|
|
59
58
|
|
|
60
|
-
// 2. Compare with
|
|
59
|
+
// 2. Compare with Previous Day
|
|
61
60
|
for (const ticker in currentAgg) {
|
|
62
61
|
const curr = currentAgg[ticker];
|
|
63
62
|
const prev = previousResult ? previousResult[ticker] : null;
|
|
@@ -71,12 +70,10 @@ class LeverageDivergence {
|
|
|
71
70
|
const spotDelta = curr.spotHolders - prev.spotHolders;
|
|
72
71
|
|
|
73
72
|
let signal = 'NEUTRAL';
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (spotDelta > 0 && levDelta
|
|
77
|
-
|
|
78
|
-
// Retail (Spot) Selling + Speculators (Lev) Buying = High Conviction Pump
|
|
79
|
-
if (spotDelta < 0 && levDelta > 0) signal = 'SPECULATIVE_PUMP';
|
|
73
|
+
if (spotDelta > 0 && levDelta < 0) signal = 'SMART_ACCUMULATION';
|
|
74
|
+
else if (spotDelta < 0 && levDelta > 0) signal = 'SPECULATIVE_PUMP';
|
|
75
|
+
else if (spotDelta > 0 && levDelta > 0) signal = 'BROAD_ACCUMULATION';
|
|
76
|
+
else if (spotDelta < 0 && levDelta < 0) signal = 'BROAD_EXIT';
|
|
80
77
|
|
|
81
78
|
this.results[ticker] = {
|
|
82
79
|
...curr,
|
|
@@ -12,18 +12,16 @@ class LiquidationCascade {
|
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
static getDependencies() {
|
|
16
|
-
return ['user-history-reconstructor'];
|
|
17
|
-
}
|
|
15
|
+
static getDependencies() { return ['user-history-reconstructor']; }
|
|
18
16
|
|
|
19
17
|
static getSchema() {
|
|
20
18
|
const schema = {
|
|
21
19
|
"type": "object",
|
|
22
20
|
"properties": {
|
|
23
|
-
"totalClosures": { "type": "number" },
|
|
24
|
-
"forcedClosures": { "type": "number" },
|
|
25
|
-
"painIndex": { "type": "number" },
|
|
26
|
-
"isFlushEvent": { "type": "boolean" }
|
|
21
|
+
"totalClosures": { "type": "number", "description": "Total number of positions closed today." },
|
|
22
|
+
"forcedClosures": { "type": "number", "description": "Number of positions closed via Stop Loss (Reason 1)." },
|
|
23
|
+
"painIndex": { "type": "number", "description": "Ratio of forced closures to total closures (0.0 - 1.0)." },
|
|
24
|
+
"isFlushEvent": { "type": "boolean", "description": "True if painIndex > 0.3." }
|
|
27
25
|
},
|
|
28
26
|
"required": ["totalClosures", "forcedClosures", "painIndex", "isFlushEvent"]
|
|
29
27
|
};
|
|
@@ -37,34 +35,35 @@ class LiquidationCascade {
|
|
|
37
35
|
|
|
38
36
|
const aggregator = {};
|
|
39
37
|
|
|
40
|
-
// 1. Aggregate Forced Exits
|
|
41
38
|
for (const userId in userReconstructions) {
|
|
42
39
|
const userPortfolio = userReconstructions[userId];
|
|
43
40
|
|
|
44
41
|
for (const ticker in userPortfolio) {
|
|
45
|
-
const
|
|
42
|
+
const stats = userPortfolio[ticker];
|
|
46
43
|
|
|
47
|
-
if (
|
|
48
|
-
if (!aggregator[ticker]) aggregator[ticker] = {
|
|
44
|
+
if (stats.didSell > 0) {
|
|
45
|
+
if (!aggregator[ticker]) aggregator[ticker] = { totalClosed: 0, forced: 0 };
|
|
49
46
|
|
|
50
|
-
aggregator[ticker].
|
|
51
|
-
|
|
47
|
+
aggregator[ticker].totalClosed += stats.didSell;
|
|
48
|
+
|
|
49
|
+
if (stats.closeReasons && stats.closeReasons["1"]) {
|
|
50
|
+
aggregator[ticker].forced += stats.closeReasons["1"];
|
|
51
|
+
}
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
// 2. Calculate Pain Index
|
|
57
56
|
for (const ticker in aggregator) {
|
|
58
57
|
const data = aggregator[ticker];
|
|
59
|
-
if (data.
|
|
58
|
+
if (data.totalClosed < 5) continue;
|
|
60
59
|
|
|
61
|
-
const forcedRatio = data.forced / data.
|
|
60
|
+
const forcedRatio = data.forced / data.totalClosed;
|
|
62
61
|
|
|
63
62
|
this.results[ticker] = {
|
|
64
|
-
totalClosures: data.
|
|
63
|
+
totalClosures: data.totalClosed,
|
|
65
64
|
forcedClosures: data.forced,
|
|
66
|
-
painIndex: forcedRatio,
|
|
67
|
-
isFlushEvent: forcedRatio > 0.3
|
|
65
|
+
painIndex: forcedRatio,
|
|
66
|
+
isFlushEvent: forcedRatio > 0.3
|
|
68
67
|
};
|
|
69
68
|
}
|
|
70
69
|
}
|
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Reconstructs a user's portfolio state for a specific date from their trade history.
|
|
3
|
-
* Acts as the "Map" phase for downstream Meta aggregations.
|
|
4
|
-
*/
|
|
5
1
|
class UserHistoryReconstructor {
|
|
6
2
|
constructor() {
|
|
7
|
-
this.results = {};
|
|
3
|
+
this.results = {};
|
|
8
4
|
}
|
|
9
5
|
|
|
10
6
|
static getMetadata() {
|
|
11
7
|
return {
|
|
12
8
|
name: 'user-history-reconstructor',
|
|
13
9
|
type: 'standard',
|
|
14
|
-
category: 'History Reconstruction',
|
|
15
|
-
userType: 'all',
|
|
10
|
+
category: 'History Reconstruction',
|
|
11
|
+
userType: 'all',
|
|
16
12
|
isHistorical: false,
|
|
17
13
|
rootDataDependencies: ['history']
|
|
18
14
|
};
|
|
@@ -21,15 +17,29 @@ class UserHistoryReconstructor {
|
|
|
21
17
|
static getDependencies() { return []; }
|
|
22
18
|
|
|
23
19
|
static getSchema() {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
20
|
+
// Schema for a single Ticker's stats
|
|
21
|
+
const tickerSchema = {
|
|
22
|
+
"type": "object",
|
|
23
|
+
"properties": {
|
|
24
|
+
"isHolder": { "type": "number", "description": "1 if the user holds the asset at EOD, 0 otherwise." },
|
|
25
|
+
"didBuy": { "type": "number", "description": "Count of buy trades executed today." },
|
|
26
|
+
"didSell": { "type": "number", "description": "Count of sell trades executed today." },
|
|
27
|
+
"avgEntry": { "type": "number", "description": "Average entry price of held positions." },
|
|
28
|
+
"avgLeverage": { "type": "number", "description": "Average leverage of held positions." },
|
|
29
|
+
"buyLeverage": { "type": "number", "description": "Average leverage of new buys executed today." },
|
|
30
|
+
"closeReasons": {
|
|
31
|
+
"type": "object",
|
|
32
|
+
"description": "Map of close reason codes to counts (0=Manual, 1=Stop/Liq, 5=TP)."
|
|
32
33
|
}
|
|
34
|
+
},
|
|
35
|
+
"required": ["isHolder", "didBuy", "didSell", "avgEntry", "avgLeverage"]
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// The result for a user is a Map of Ticker -> TickerSchema
|
|
39
|
+
return {
|
|
40
|
+
"type": "object",
|
|
41
|
+
"patternProperties": {
|
|
42
|
+
"^.*$": tickerSchema
|
|
33
43
|
}
|
|
34
44
|
};
|
|
35
45
|
}
|
|
@@ -37,72 +47,107 @@ class UserHistoryReconstructor {
|
|
|
37
47
|
async process(context) {
|
|
38
48
|
const { user, math, mappings, date } = context;
|
|
39
49
|
|
|
40
|
-
// 1. Get History
|
|
50
|
+
// 1. Get History (V2 Format Only)
|
|
41
51
|
const history = math.history.getDailyHistory(user);
|
|
42
52
|
const allTrades = history?.PublicHistoryPositions || [];
|
|
43
53
|
|
|
44
54
|
if (allTrades.length === 0) return;
|
|
45
55
|
|
|
46
|
-
// 2.
|
|
47
|
-
const
|
|
48
|
-
|
|
56
|
+
// 2. Define Time Boundaries for "Yesterday" (Target Date)
|
|
57
|
+
const dayStart = new Date(date.today + "T00:00:00.000Z").getTime();
|
|
58
|
+
const dayEnd = new Date(date.today + "T23:59:59.999Z").getTime();
|
|
49
59
|
|
|
50
|
-
// 3. Initialize User State
|
|
51
60
|
this.results[user.id] = {};
|
|
52
61
|
const userState = this.results[user.id];
|
|
53
62
|
|
|
54
|
-
const
|
|
55
|
-
const dayEnd = new Date(date.today + "T23:59:59.999Z").getTime();
|
|
56
|
-
|
|
57
|
-
for (const trade of activeTrades) {
|
|
63
|
+
for (const trade of allTrades) {
|
|
58
64
|
const instId = trade.InstrumentID;
|
|
59
65
|
const ticker = mappings.instrumentToTicker[instId];
|
|
60
66
|
if (!ticker) continue;
|
|
61
67
|
|
|
68
|
+
// Parse Dates
|
|
69
|
+
const openTime = new Date(trade.OpenDateTime).getTime();
|
|
70
|
+
const closeTime = trade.CloseDateTime ? new Date(trade.CloseDateTime).getTime() : null;
|
|
71
|
+
|
|
72
|
+
// 3. Determine States
|
|
73
|
+
const isOpenBeforeEOD = openTime <= dayEnd;
|
|
74
|
+
// Active if it wasn't closed before the day started
|
|
75
|
+
const isClosedAfterSOD = closeTime === null || closeTime >= dayStart;
|
|
76
|
+
|
|
77
|
+
const wasActiveToday = isOpenBeforeEOD && isClosedAfterSOD;
|
|
78
|
+
|
|
79
|
+
// "Held" means active at End of Day
|
|
80
|
+
const isHeldAtEOD = isOpenBeforeEOD && (closeTime === null || closeTime > dayEnd);
|
|
81
|
+
|
|
82
|
+
// "Opened" means OpenTime is inside today
|
|
83
|
+
const isOpenedToday = openTime >= dayStart && openTime <= dayEnd;
|
|
84
|
+
|
|
85
|
+
// "Closed" means CloseTime is inside today
|
|
86
|
+
const isClosedToday = closeTime !== null && closeTime >= dayStart && closeTime <= dayEnd;
|
|
87
|
+
|
|
88
|
+
if (!wasActiveToday) continue;
|
|
89
|
+
|
|
62
90
|
if (!userState[ticker]) {
|
|
63
|
-
userState[ticker] = {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
91
|
+
userState[ticker] = {
|
|
92
|
+
isHolder: 0,
|
|
93
|
+
didBuy: 0,
|
|
94
|
+
didSell: 0,
|
|
95
|
+
sumEntry: 0,
|
|
96
|
+
sumLev: 0,
|
|
97
|
+
holdCount: 0,
|
|
98
|
+
sumBuyLev: 0,
|
|
99
|
+
closeReasons: { "0": 0, "1": 0, "5": 0 }
|
|
69
100
|
};
|
|
70
101
|
}
|
|
71
|
-
|
|
72
102
|
const stats = userState[ticker];
|
|
73
|
-
|
|
74
|
-
//
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
103
|
+
|
|
104
|
+
// 4. Populate Metrics
|
|
105
|
+
if (isHeldAtEOD) {
|
|
106
|
+
stats.isHolder = 1;
|
|
107
|
+
stats.holdCount++;
|
|
108
|
+
stats.sumEntry += (trade.OpenRate || 0);
|
|
109
|
+
stats.sumLev += (trade.Leverage || 1);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (isOpenedToday) {
|
|
113
|
+
stats.didBuy++;
|
|
114
|
+
stats.sumBuyLev += (trade.Leverage || 1);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (isClosedToday) {
|
|
118
|
+
stats.didSell++;
|
|
119
|
+
const reason = String(trade.CloseReason || 0);
|
|
120
|
+
if (stats.closeReasons[reason] === undefined) stats.closeReasons[reason] = 0;
|
|
121
|
+
stats.closeReasons[reason]++;
|
|
87
122
|
}
|
|
88
123
|
}
|
|
89
124
|
|
|
90
|
-
//
|
|
125
|
+
// 5. Cleanup / Average
|
|
91
126
|
for (const ticker in userState) {
|
|
92
127
|
const stats = userState[ticker];
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
stats.
|
|
128
|
+
|
|
129
|
+
if (stats.holdCount > 0) {
|
|
130
|
+
stats.avgEntry = stats.sumEntry / stats.holdCount;
|
|
131
|
+
stats.avgLeverage = stats.sumLev / stats.holdCount;
|
|
132
|
+
} else {
|
|
133
|
+
stats.avgEntry = 0;
|
|
134
|
+
stats.avgLeverage = 0;
|
|
96
135
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
136
|
+
|
|
137
|
+
if (stats.didBuy > 0) {
|
|
138
|
+
stats.buyLeverage = stats.sumBuyLev / stats.didBuy;
|
|
139
|
+
} else {
|
|
140
|
+
stats.buyLeverage = 0;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
delete stats.sumEntry;
|
|
144
|
+
delete stats.sumLev;
|
|
145
|
+
delete stats.sumBuyLev;
|
|
146
|
+
delete stats.holdCount;
|
|
100
147
|
}
|
|
101
148
|
}
|
|
102
149
|
|
|
103
|
-
async getResult() {
|
|
104
|
-
return this.results;
|
|
105
|
-
}
|
|
150
|
+
async getResult() { return this.results; }
|
|
106
151
|
}
|
|
107
152
|
|
|
108
153
|
module.exports = UserHistoryReconstructor;
|
package/package.json
CHANGED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
Scanning 92 files...
|
|
2
|
-
|
|
3
|
-
--- Files MISSING getSchema() ---
|
|
4
|
-
|
|
5
|
-
--- Files WITH getSchema() ---
|
|
6
|
-
capitulation\asset-volatility-estimator.js
|
|
7
|
-
capitulation\retail-capitulation-risk-forecast.js
|
|
8
|
-
core\asset-cost-basis-profile.js
|
|
9
|
-
core\asset-pnl-status.js
|
|
10
|
-
core\asset-position-size.js
|
|
11
|
-
core\average-daily-pnl-all-users.js
|
|
12
|
-
core\average-daily-pnl-per-sector.js
|
|
13
|
-
core\average-daily-pnl-per-stock.js
|
|
14
|
-
core\average-daily-position-pnl.js
|
|
15
|
-
core\crowd-cost-basis.js
|
|
16
|
-
core\holding-duration-per-asset.js
|
|
17
|
-
core\insights-daily-bought-vs-sold-count.js
|
|
18
|
-
core\insights-daily-ownership-delta.js
|
|
19
|
-
core\insights-sentimet-per-stock.js
|
|
20
|
-
core\insights-total-long-per-sector.js
|
|
21
|
-
core\Insights-total-long-per-stock.js
|
|
22
|
-
core\insights-total-positions-held.js
|
|
23
|
-
core\instrument-price-change-1d.js
|
|
24
|
-
core\instrument-price-momentum-20d.js
|
|
25
|
-
core\leverage-divergence.js
|
|
26
|
-
core\liquidation-cascade.js
|
|
27
|
-
core\long-position-per-stock.js
|
|
28
|
-
core\overall-holding-duration.js
|
|
29
|
-
core\overall-profitability-ratio.js
|
|
30
|
-
core\ownership-vs-performance-ytd.js
|
|
31
|
-
core\ownership-vs-volatility.js
|
|
32
|
-
core\platform-buy-sell-sentiment.js
|
|
33
|
-
core\platform-daily-bought-vs-sold-count.js
|
|
34
|
-
core\platform-daily-ownership-delta.js
|
|
35
|
-
core\platform-ownership-per-sector.js
|
|
36
|
-
core\platform-total-positions-held.js
|
|
37
|
-
core\pnl-distribution-per-stock.js
|
|
38
|
-
core\price-metrics.js
|
|
39
|
-
core\profitability-ratio-per-sector.js
|
|
40
|
-
core\profitability-ratio-per-stock.js
|
|
41
|
-
core\profitability-skew-per-stock.js
|
|
42
|
-
core\profitable-and-unprofitable-status.js
|
|
43
|
-
core\sentiment-per-stock.js
|
|
44
|
-
core\short-interest-growth.js
|
|
45
|
-
core\short-position-per-stock.js
|
|
46
|
-
core\social-activity-aggregation.js
|
|
47
|
-
core\social-asset-posts-trend.js
|
|
48
|
-
core\social-event-correlation.js
|
|
49
|
-
core\social-sentiment-aggregation.js
|
|
50
|
-
core\social-top-mentioned-words.js
|
|
51
|
-
core\social-topic-interest-evolution.js
|
|
52
|
-
core\social-topic-sentiment-matrix.js
|
|
53
|
-
core\social-word-mentions-trend.js
|
|
54
|
-
core\speculator-asset-sentiment.js
|
|
55
|
-
core\speculator-danger-zone.js
|
|
56
|
-
core\speculator-distance-to-stop-loss-per-leverage.js
|
|
57
|
-
core\speculator-distance-to-tp-per-leverage.js
|
|
58
|
-
core\speculator-entry-distance-to-sl-per-leverage.js
|
|
59
|
-
core\speculator-entry-distance-to-tp-per-leverage.js
|
|
60
|
-
core\speculator-leverage-per-asset.js
|
|
61
|
-
core\speculator-leverage-per-sector.js
|
|
62
|
-
core\speculator-risk-reward-ratio-per-asset.js
|
|
63
|
-
core\speculator-stop-loss-distance-by-sector-short-long-breakdown.js
|
|
64
|
-
core\speculator-stop-loss-distance-by-ticker-short-long-breakdown.js
|
|
65
|
-
core\speculator-stop-loss-per-asset.js
|
|
66
|
-
core\speculator-take-profit-per-asset.js
|
|
67
|
-
core\speculator-tsl-per-asset.js
|
|
68
|
-
core\total-long-figures.js
|
|
69
|
-
core\total-long-per-sector.js
|
|
70
|
-
core\total-short-figures.js
|
|
71
|
-
core\total-short-per-sector.js
|
|
72
|
-
core\trending-ownership-momentum.js
|
|
73
|
-
core\user-history-reconstructor.js
|
|
74
|
-
core\users-processed.js
|
|
75
|
-
gauss\cohort-capital-flow.js
|
|
76
|
-
gauss\cohort-definer.js
|
|
77
|
-
gauss\daily-dna-filter.js
|
|
78
|
-
gauss\gauss-divergence-signal.js
|
|
79
|
-
gem\cohort-momentum-state.js
|
|
80
|
-
gem\cohort-skill-definition.js
|
|
81
|
-
gem\platform-conviction-divergence.js
|
|
82
|
-
gem\quant-skill-alpha-signal.js
|
|
83
|
-
gem\skilled-cohort-flow.js
|
|
84
|
-
gem\skilled-unskilled-divergence.js
|
|
85
|
-
gem\unskilled-cohort-flow.js
|
|
86
|
-
ghost-book\cost-basis-density.js
|
|
87
|
-
ghost-book\liquidity-vacuum.js
|
|
88
|
-
ghost-book\retail-gamma-exposure.js
|
|
89
|
-
helix\helix-contrarian-signal.js
|
|
90
|
-
helix\herd-consensus-score.js
|
|
91
|
-
helix\winner-loser-flow.js
|
|
92
|
-
predicative-alpha\cognitive-dissonance.js
|
|
93
|
-
predicative-alpha\diamond-hand-fracture.js
|
|
94
|
-
predicative-alpha\mimetic-latency.js
|
|
95
|
-
pyro\risk-appetite-index.js
|
|
96
|
-
pyro\squeeze-potential.js
|
|
97
|
-
pyro\volatility-signal.js
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
const rootDir = __dirname;
|
|
5
|
-
|
|
6
|
-
function getAllFiles(dirPath, arrayOfFiles) {
|
|
7
|
-
const files = fs.readdirSync(dirPath);
|
|
8
|
-
|
|
9
|
-
arrayOfFiles = arrayOfFiles || [];
|
|
10
|
-
|
|
11
|
-
files.forEach(function (file) {
|
|
12
|
-
if (fs.statSync(dirPath + "/" + file).isDirectory()) {
|
|
13
|
-
arrayOfFiles = getAllFiles(dirPath + "/" + file, arrayOfFiles);
|
|
14
|
-
} else {
|
|
15
|
-
if (file.endsWith('.js') && file !== 'audit_schemas.js') {
|
|
16
|
-
arrayOfFiles.push(path.join(dirPath, "/", file));
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
return arrayOfFiles;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const files = getAllFiles(rootDir);
|
|
25
|
-
let missingSchema = [];
|
|
26
|
-
let hasSchema = [];
|
|
27
|
-
|
|
28
|
-
const output = [];
|
|
29
|
-
output.push(`Scanning ${files.length} files...`);
|
|
30
|
-
|
|
31
|
-
files.forEach(file => {
|
|
32
|
-
const content = fs.readFileSync(file, 'utf8');
|
|
33
|
-
if (content.includes('static getSchema()')) {
|
|
34
|
-
hasSchema.push(file);
|
|
35
|
-
} else {
|
|
36
|
-
missingSchema.push(file);
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
output.push('\n--- Files MISSING getSchema() ---');
|
|
41
|
-
missingSchema.forEach(f => output.push(path.relative(rootDir, f)));
|
|
42
|
-
|
|
43
|
-
output.push('\n--- Files WITH getSchema() ---');
|
|
44
|
-
hasSchema.forEach(f => output.push(path.relative(rootDir, f)));
|
|
45
|
-
|
|
46
|
-
fs.writeFileSync(path.join(rootDir, 'audit_results.txt'), output.join('\n'));
|
|
47
|
-
console.log('Audit complete. Results written to audit_results.txt');
|