aiden-shared-calculations-unified 1.0.8 → 1.0.9

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 (31) hide show
  1. package/calculations/pnl/average_daily_pnl_all_users.js +1 -1
  2. package/calculations/pnl/average_daily_pnl_per_sector.js +1 -1
  3. package/calculations/pnl/average_daily_pnl_per_stock.js +1 -1
  4. package/calculations/pnl/average_daily_position_pnl.js +1 -1
  5. package/calculations/pnl/pnl_distribution_per_stock.js +52 -52
  6. package/calculations/pnl/profitability_ratio_per_stock.js +50 -50
  7. package/calculations/pnl/profitability_skew_per_stock.js +58 -58
  8. package/calculations/sanity/users_processed.js +26 -26
  9. package/calculations/sectors/total_long_per_sector.js +1 -1
  10. package/calculations/sectors/total_short_per_sector.js +1 -1
  11. package/calculations/short_and_long_stats/long_position_per_stock.js +1 -1
  12. package/calculations/short_and_long_stats/sentiment_per_stock.js +49 -49
  13. package/calculations/short_and_long_stats/short_position_per_stock.js +1 -1
  14. package/calculations/short_and_long_stats/total_long_figures.js +1 -1
  15. package/calculations/short_and_long_stats/total_short_figures.js +1 -1
  16. package/calculations/speculators/distance_to_stop_loss_per_leverage.js +78 -78
  17. package/calculations/speculators/distance_to_tp_per_leverage.js +76 -76
  18. package/calculations/speculators/entry_distance_to_sl_per_leverage.js +78 -78
  19. package/calculations/speculators/entry_distance_to_tp_per_leverage.js +77 -77
  20. package/calculations/speculators/holding_duration_per_asset.js +55 -55
  21. package/calculations/speculators/leverage_per_asset.js +46 -46
  22. package/calculations/speculators/leverage_per_sector.js +44 -44
  23. package/calculations/speculators/risk_reward_ratio_per_asset.js +60 -60
  24. package/calculations/speculators/speculator_asset_sentiment.js +81 -81
  25. package/calculations/speculators/speculator_danger_zone.js +57 -57
  26. package/calculations/speculators/stop_loss_distance_by_sector_short_long_breakdown.js +91 -91
  27. package/calculations/speculators/stop_loss_distance_by_ticker_short_long_breakdown.js +73 -73
  28. package/calculations/speculators/stop_loss_per_asset.js +55 -55
  29. package/calculations/speculators/take_profit_per_asset.js +55 -55
  30. package/calculations/speculators/tsl_per_asset.js +51 -51
  31. package/package.json +1 -1
@@ -1,55 +1,55 @@
1
- /**
2
- * @fileoverview Calculates the average holding duration of open speculator positions.
3
- */
4
- const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
5
-
6
- class HoldingDurationPerAsset {
7
- constructor() {
8
- this.durationData = {};
9
- this.mappings = null;
10
- }
11
-
12
- process(portfolioData, userId, context) {
13
- if (portfolioData && portfolioData.PublicPositions) {
14
- const now = new Date();
15
- for (const position of portfolioData.PublicPositions) {
16
- const instrumentId = position.InstrumentID;
17
- const openTime = new Date(position.OpenDateTime);
18
- const durationHours = (now - openTime) / (1000 * 60 * 60);
19
-
20
- if (!this.durationData[instrumentId]) {
21
- this.durationData[instrumentId] = { duration_sum_hours: 0, count: 0 };
22
- }
23
- this.durationData[instrumentId].duration_sum_hours += durationHours;
24
- this.durationData[instrumentId].count++;
25
- }
26
- }
27
- }
28
-
29
- async getResult() {
30
- if (!this.mappings) {
31
- this.mappings = await loadInstrumentMappings();
32
- }
33
- const result = {};
34
- for (const instrumentId in this.durationData) {
35
- const ticker = this.mappings.instrumentToTicker[instrumentId] || instrumentId.toString();
36
- const data = this.durationData[instrumentId];
37
-
38
- // REFACTOR: Perform the final calculation directly.
39
- if (data.count > 0) {
40
- result[ticker] = {
41
- average_duration_hours: data.duration_sum_hours / data.count
42
- };
43
- }
44
- }
45
-
46
- return result;
47
- }
48
-
49
- reset() {
50
- this.durationData = {};
51
- this.mappings = null;
52
- }
53
- }
54
-
55
- module.exports = HoldingDurationPerAsset;
1
+ /**
2
+ * @fileoverview Calculates the average holding duration of open speculator positions.
3
+ */
4
+ const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
5
+
6
+ class HoldingDurationPerAsset {
7
+ constructor() {
8
+ this.durationData = {};
9
+ this.mappings = null;
10
+ }
11
+
12
+ process(portfolioData, yesterdayPortfolio, userId, context) {
13
+ if (portfolioData && portfolioData.PublicPositions) {
14
+ const now = new Date();
15
+ for (const position of portfolioData.PublicPositions) {
16
+ const instrumentId = position.InstrumentID;
17
+ const openTime = new Date(position.OpenDateTime);
18
+ const durationHours = (now - openTime) / (1000 * 60 * 60);
19
+
20
+ if (!this.durationData[instrumentId]) {
21
+ this.durationData[instrumentId] = { duration_sum_hours: 0, count: 0 };
22
+ }
23
+ this.durationData[instrumentId].duration_sum_hours += durationHours;
24
+ this.durationData[instrumentId].count++;
25
+ }
26
+ }
27
+ }
28
+
29
+ async getResult() {
30
+ if (!this.mappings) {
31
+ this.mappings = await loadInstrumentMappings();
32
+ }
33
+ const result = {};
34
+ for (const instrumentId in this.durationData) {
35
+ const ticker = this.mappings.instrumentToTicker[instrumentId] || instrumentId.toString();
36
+ const data = this.durationData[instrumentId];
37
+
38
+ // REFACTOR: Perform the final calculation directly.
39
+ if (data.count > 0) {
40
+ result[ticker] = {
41
+ average_duration_hours: data.duration_sum_hours / data.count
42
+ };
43
+ }
44
+ }
45
+
46
+ return result;
47
+ }
48
+
49
+ reset() {
50
+ this.durationData = {};
51
+ this.mappings = null;
52
+ }
53
+ }
54
+
55
+ module.exports = HoldingDurationPerAsset;
@@ -1,47 +1,47 @@
1
- /**
2
- * @fileoverview Calculates leverage usage per instrument for speculators.
3
- */
4
- const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
5
-
6
- class LeveragePerAsset {
7
- constructor() {
8
- this.leverageData = {};
9
- this.mappings = null;
10
- }
11
-
12
- process(portfolioData, userId) {
13
- if (portfolioData && portfolioData.PublicPositions) {
14
- for (const position of portfolioData.PublicPositions) {
15
- const instrumentId = position.InstrumentID;
16
- const leverage = position.Leverage;
17
-
18
- if (!this.leverageData[instrumentId]) {
19
- this.leverageData[instrumentId] = {};
20
- }
21
- this.leverageData[instrumentId][leverage] = (this.leverageData[instrumentId][leverage] || 0) + 1;
22
- }
23
- }
24
- }
25
-
26
- async getResult() {
27
- if (!this.mappings) {
28
- this.mappings = await loadInstrumentMappings();
29
- }
30
- const result = {};
31
- for (const instrumentId in this.leverageData) {
32
- const ticker = this.mappings.instrumentToTicker[instrumentId] || instrumentId.toString();
33
- result[ticker] = this.leverageData[instrumentId];
34
- }
35
- if (Object.keys(result).length === 0) return {};
36
- return {
37
- leverage_per_asset: result
38
- };
39
- }
40
-
41
- reset() {
42
- this.leverageData = {};
43
- this.mappings = null;
44
- }
45
- }
46
-
1
+ /**
2
+ * @fileoverview Calculates leverage usage per instrument for speculators.
3
+ */
4
+ const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
5
+
6
+ class LeveragePerAsset {
7
+ constructor() {
8
+ this.leverageData = {};
9
+ this.mappings = null;
10
+ }
11
+
12
+ process(portfolioData, yesterdayPortfolio, userId, context) {
13
+ if (portfolioData && portfolioData.PublicPositions) {
14
+ for (const position of portfolioData.PublicPositions) {
15
+ const instrumentId = position.InstrumentID;
16
+ const leverage = position.Leverage;
17
+
18
+ if (!this.leverageData[instrumentId]) {
19
+ this.leverageData[instrumentId] = {};
20
+ }
21
+ this.leverageData[instrumentId][leverage] = (this.leverageData[instrumentId][leverage] || 0) + 1;
22
+ }
23
+ }
24
+ }
25
+
26
+ async getResult() {
27
+ if (!this.mappings) {
28
+ this.mappings = await loadInstrumentMappings();
29
+ }
30
+ const result = {};
31
+ for (const instrumentId in this.leverageData) {
32
+ const ticker = this.mappings.instrumentToTicker[instrumentId] || instrumentId.toString();
33
+ result[ticker] = this.leverageData[instrumentId];
34
+ }
35
+ if (Object.keys(result).length === 0) return {};
36
+ return {
37
+ leverage_per_asset: result
38
+ };
39
+ }
40
+
41
+ reset() {
42
+ this.leverageData = {};
43
+ this.mappings = null;
44
+ }
45
+ }
46
+
47
47
  module.exports = LeveragePerAsset;
@@ -1,45 +1,45 @@
1
- const { getInstrumentSectorMap } = require('../../utils/sector_mapping_provider');
2
-
3
- /**
4
- * @fileoverview Calculates leverage usage per sector for speculators.
5
- */
6
-
7
- class LeveragePerSector {
8
- constructor() {
9
- this.positions = [];
10
- }
11
-
12
- process(portfolioData, userId) {
13
- if (portfolioData && portfolioData.PublicPositions) {
14
- this.positions.push(...portfolioData.PublicPositions);
15
- }
16
- }
17
-
18
- async getResult() {
19
- if (this.positions.length === 0) return {};
20
-
21
- const sectorMap = await getInstrumentSectorMap();
22
- const leverageData = {};
23
-
24
- for (const position of this.positions) {
25
- const instrumentId = position.InstrumentID;
26
- const sector = sectorMap[instrumentId] || 'N/A';
27
- const leverage = position.Leverage;
28
-
29
- if (!leverageData[sector]) {
30
- leverageData[sector] = {};
31
- }
32
- leverageData[sector][leverage] = (leverageData[sector][leverage] || 0) + 1;
33
- }
34
-
35
- return {
36
- leverage_per_sector: leverageData
37
- };
38
- }
39
-
40
- reset() {
41
- this.positions = [];
42
- }
43
- }
44
-
1
+ const { getInstrumentSectorMap } = require('../../utils/sector_mapping_provider');
2
+
3
+ /**
4
+ * @fileoverview Calculates leverage usage per sector for speculators.
5
+ */
6
+
7
+ class LeveragePerSector {
8
+ constructor() {
9
+ this.positions = [];
10
+ }
11
+
12
+ process(portfolioData, yesterdayPortfolio, userId, context) {
13
+ if (portfolioData && portfolioData.PublicPositions) {
14
+ this.positions.push(...portfolioData.PublicPositions);
15
+ }
16
+ }
17
+
18
+ async getResult() {
19
+ if (this.positions.length === 0) return {};
20
+
21
+ const sectorMap = await getInstrumentSectorMap();
22
+ const leverageData = {};
23
+
24
+ for (const position of this.positions) {
25
+ const instrumentId = position.InstrumentID;
26
+ const sector = sectorMap[instrumentId] || 'N/A';
27
+ const leverage = position.Leverage;
28
+
29
+ if (!leverageData[sector]) {
30
+ leverageData[sector] = {};
31
+ }
32
+ leverageData[sector][leverage] = (leverageData[sector][leverage] || 0) + 1;
33
+ }
34
+
35
+ return {
36
+ leverage_per_sector: leverageData
37
+ };
38
+ }
39
+
40
+ reset() {
41
+ this.positions = [];
42
+ }
43
+ }
44
+
45
45
  module.exports = LeveragePerSector;
@@ -1,60 +1,60 @@
1
- /**
2
- * @fileoverview Calculates the average risk-reward ratio per asset from speculator positions.
3
- */
4
- const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
5
-
6
- class RiskRewardRatioPerAsset {
7
- constructor() {
8
- this.rrData = {};
9
- this.mappings = null;
10
- }
11
-
12
- process(portfolioData, userId, context) {
13
- if (portfolioData && portfolioData.PublicPositions) {
14
- for (const position of portfolioData.PublicPositions) {
15
- if (position.TakeProfitRate > 0 && position.StopLossRate > 0) {
16
- const instrumentId = position.InstrumentID;
17
- const openRate = position.OpenRate;
18
- const potentialReward = Math.abs(position.TakeProfitRate - openRate);
19
- const potentialRisk = Math.abs(openRate - position.StopLossRate);
20
-
21
- if (potentialRisk > 0) {
22
- const ratio = potentialReward / potentialRisk;
23
- if (!this.rrData[instrumentId]) {
24
- this.rrData[instrumentId] = { ratio_sum: 0, count: 0 };
25
- }
26
- this.rrData[instrumentId].ratio_sum += ratio;
27
- this.rrData[instrumentId].count++;
28
- }
29
- }
30
- }
31
- }
32
- }
33
-
34
- async getResult() {
35
- if (!this.mappings) {
36
- this.mappings = await loadInstrumentMappings();
37
- }
38
- const result = {};
39
- for (const instrumentId in this.rrData) {
40
- const ticker = this.mappings.instrumentToTicker[instrumentId] || instrumentId.toString();
41
- const data = this.rrData[instrumentId];
42
-
43
- // REFACTOR: Perform the final calculation directly.
44
- if (data.count > 0) {
45
- result[ticker] = {
46
- average_ratio: data.ratio_sum / data.count
47
- };
48
- }
49
- }
50
-
51
- return result;
52
- }
53
-
54
- reset() {
55
- this.rrData = {};
56
- this.mappings = null;
57
- }
58
- }
59
-
60
- module.exports = RiskRewardRatioPerAsset;
1
+ /**
2
+ * @fileoverview Calculates the average risk-reward ratio per asset from speculator positions.
3
+ */
4
+ const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
5
+
6
+ class RiskRewardRatioPerAsset {
7
+ constructor() {
8
+ this.rrData = {};
9
+ this.mappings = null;
10
+ }
11
+
12
+ process(portfolioData, yesterdayPortfolio, userId, context) {
13
+ if (portfolioData && portfolioData.PublicPositions) {
14
+ for (const position of portfolioData.PublicPositions) {
15
+ if (position.TakeProfitRate > 0 && position.StopLossRate > 0) {
16
+ const instrumentId = position.InstrumentID;
17
+ const openRate = position.OpenRate;
18
+ const potentialReward = Math.abs(position.TakeProfitRate - openRate);
19
+ const potentialRisk = Math.abs(openRate - position.StopLossRate);
20
+
21
+ if (potentialRisk > 0) {
22
+ const ratio = potentialReward / potentialRisk;
23
+ if (!this.rrData[instrumentId]) {
24
+ this.rrData[instrumentId] = { ratio_sum: 0, count: 0 };
25
+ }
26
+ this.rrData[instrumentId].ratio_sum += ratio;
27
+ this.rrData[instrumentId].count++;
28
+ }
29
+ }
30
+ }
31
+ }
32
+ }
33
+
34
+ async getResult() {
35
+ if (!this.mappings) {
36
+ this.mappings = await loadInstrumentMappings();
37
+ }
38
+ const result = {};
39
+ for (const instrumentId in this.rrData) {
40
+ const ticker = this.mappings.instrumentToTicker[instrumentId] || instrumentId.toString();
41
+ const data = this.rrData[instrumentId];
42
+
43
+ // REFACTOR: Perform the final calculation directly.
44
+ if (data.count > 0) {
45
+ result[ticker] = {
46
+ average_ratio: data.ratio_sum / data.count
47
+ };
48
+ }
49
+ }
50
+
51
+ return result;
52
+ }
53
+
54
+ reset() {
55
+ this.rrData = {};
56
+ this.mappings = null;
57
+ }
58
+ }
59
+
60
+ module.exports = RiskRewardRatioPerAsset;
@@ -1,81 +1,81 @@
1
- /**
2
- * Aggregates and calculates average P/L, leverage, SL, and TP data for longs vs. shorts
3
- * on a per-asset basis for speculators.
4
- */
5
- const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
6
-
7
- class SpeculatorAssetSentiment {
8
- constructor() {
9
- this.assets = {};
10
- this.mappings = null;
11
- }
12
-
13
- _initAsset(instrumentId) {
14
- if (!this.assets[instrumentId]) {
15
- this.assets[instrumentId] = {
16
- long: { count: 0, pnl_sum: 0, leverage_sum: 0, sl_rate_sum: 0, tp_rate_sum: 0 },
17
- short: { count: 0, pnl_sum: 0, leverage_sum: 0, sl_rate_sum: 0, tp_rate_sum: 0 }
18
- };
19
- }
20
- }
21
-
22
- process(portfolioData, userId, context) {
23
- const positions = portfolioData.PublicPositions;
24
- if (!positions || !Array.isArray(positions)) return;
25
-
26
- for (const position of positions) {
27
- const instrumentId = position.InstrumentID;
28
- if (!instrumentId) continue;
29
-
30
- this._initAsset(instrumentId);
31
-
32
- const direction = position.IsBuy ? 'long' : 'short';
33
- const stats = this.assets[instrumentId][direction];
34
-
35
- stats.count++;
36
- stats.pnl_sum += position.NetProfit;
37
- stats.leverage_sum += position.Leverage;
38
-
39
- if (position.StopLossRate && position.StopLossRate > 0) {
40
- stats.sl_rate_sum += position.StopLossRate;
41
- }
42
- if (position.TakeProfitRate && position.TakeProfitRate > 0) {
43
- stats.tp_rate_sum += position.TakeProfitRate;
44
- }
45
- }
46
- }
47
-
48
- async getResult() {
49
- if (!this.mappings) {
50
- this.mappings = await loadInstrumentMappings();
51
- }
52
-
53
- const finalResult = {};
54
-
55
- for (const instrumentId in this.assets) {
56
- const ticker = this.mappings.instrumentToTicker[instrumentId] || instrumentId.toString();
57
- finalResult[ticker] = {};
58
-
59
- for (const direction in this.assets[instrumentId]) {
60
- const stats = this.assets[instrumentId][direction];
61
- // REFACTOR: Perform final calculations.
62
- finalResult[ticker][direction] = {
63
- count: stats.count,
64
- average_pnl: stats.count > 0 ? stats.pnl_sum / stats.count : 0,
65
- average_leverage: stats.count > 0 ? stats.leverage_sum / stats.count : 0,
66
- average_sl_rate: stats.count > 0 ? stats.sl_rate_sum / stats.count : 0,
67
- average_tp_rate: stats.count > 0 ? stats.tp_rate_sum / stats.count : 0,
68
- };
69
- }
70
- }
71
-
72
- return finalResult;
73
- }
74
-
75
- reset() {
76
- this.assets = {};
77
- this.mappings = null;
78
- }
79
- }
80
-
81
- module.exports = SpeculatorAssetSentiment;
1
+ /**
2
+ * Aggregates and calculates average P/L, leverage, SL, and TP data for longs vs. shorts
3
+ * on a per-asset basis for speculators.
4
+ */
5
+ const { loadInstrumentMappings } = require('../../utils/sector_mapping_provider');
6
+
7
+ class SpeculatorAssetSentiment {
8
+ constructor() {
9
+ this.assets = {};
10
+ this.mappings = null;
11
+ }
12
+
13
+ _initAsset(instrumentId) {
14
+ if (!this.assets[instrumentId]) {
15
+ this.assets[instrumentId] = {
16
+ long: { count: 0, pnl_sum: 0, leverage_sum: 0, sl_rate_sum: 0, tp_rate_sum: 0 },
17
+ short: { count: 0, pnl_sum: 0, leverage_sum: 0, sl_rate_sum: 0, tp_rate_sum: 0 }
18
+ };
19
+ }
20
+ }
21
+
22
+ process(portfolioData, yesterdayPortfolio, userId, context) {
23
+ const positions = portfolioData.PublicPositions;
24
+ if (!positions || !Array.isArray(positions)) return;
25
+
26
+ for (const position of positions) {
27
+ const instrumentId = position.InstrumentID;
28
+ if (!instrumentId) continue;
29
+
30
+ this._initAsset(instrumentId);
31
+
32
+ const direction = position.IsBuy ? 'long' : 'short';
33
+ const stats = this.assets[instrumentId][direction];
34
+
35
+ stats.count++;
36
+ stats.pnl_sum += position.NetProfit;
37
+ stats.leverage_sum += position.Leverage;
38
+
39
+ if (position.StopLossRate && position.StopLossRate > 0) {
40
+ stats.sl_rate_sum += position.StopLossRate;
41
+ }
42
+ if (position.TakeProfitRate && position.TakeProfitRate > 0) {
43
+ stats.tp_rate_sum += position.TakeProfitRate;
44
+ }
45
+ }
46
+ }
47
+
48
+ async getResult() {
49
+ if (!this.mappings) {
50
+ this.mappings = await loadInstrumentMappings();
51
+ }
52
+
53
+ const finalResult = {};
54
+
55
+ for (const instrumentId in this.assets) {
56
+ const ticker = this.mappings.instrumentToTicker[instrumentId] || instrumentId.toString();
57
+ finalResult[ticker] = {};
58
+
59
+ for (const direction in this.assets[instrumentId]) {
60
+ const stats = this.assets[instrumentId][direction];
61
+ // REFACTOR: Perform final calculations.
62
+ finalResult[ticker][direction] = {
63
+ count: stats.count,
64
+ average_pnl: stats.count > 0 ? stats.pnl_sum / stats.count : 0,
65
+ average_leverage: stats.count > 0 ? stats.leverage_sum / stats.count : 0,
66
+ average_sl_rate: stats.count > 0 ? stats.sl_rate_sum / stats.count : 0,
67
+ average_tp_rate: stats.count > 0 ? stats.tp_rate_sum / stats.count : 0,
68
+ };
69
+ }
70
+ }
71
+
72
+ return finalResult;
73
+ }
74
+
75
+ reset() {
76
+ this.assets = {};
77
+ this.mappings = null;
78
+ }
79
+ }
80
+
81
+ module.exports = SpeculatorAssetSentiment;