@catalyst-team/poly-sdk 0.2.0 → 0.3.0
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/LICENSE +1 -1
- package/README.md +548 -813
- package/README.zh-CN.md +805 -0
- package/dist/__tests__/clob-api.test.d.ts +5 -0
- package/dist/__tests__/clob-api.test.d.ts.map +1 -0
- package/dist/__tests__/clob-api.test.js +240 -0
- package/dist/__tests__/clob-api.test.js.map +1 -0
- package/dist/__tests__/integration/arbitrage-service.integration.test.d.ts +12 -0
- package/dist/__tests__/integration/arbitrage-service.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/arbitrage-service.integration.test.js +267 -0
- package/dist/__tests__/integration/arbitrage-service.integration.test.js.map +1 -0
- package/dist/__tests__/integration/bridge-client.integration.test.d.ts +11 -0
- package/dist/__tests__/integration/bridge-client.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/bridge-client.integration.test.js +260 -0
- package/dist/__tests__/integration/bridge-client.integration.test.js.map +1 -0
- package/dist/__tests__/integration/clob-api.integration.test.d.ts +13 -0
- package/dist/__tests__/integration/clob-api.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/clob-api.integration.test.js +170 -0
- package/dist/__tests__/integration/clob-api.integration.test.js.map +1 -0
- package/dist/__tests__/integration/ctf-client.integration.test.d.ts +17 -0
- package/dist/__tests__/integration/ctf-client.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/ctf-client.integration.test.js +234 -0
- package/dist/__tests__/integration/ctf-client.integration.test.js.map +1 -0
- package/dist/__tests__/integration/data-api.integration.test.d.ts +9 -0
- package/dist/__tests__/integration/data-api.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/data-api.integration.test.js +164 -0
- package/dist/__tests__/integration/data-api.integration.test.js.map +1 -0
- package/dist/__tests__/integration/gamma-api.integration.test.d.ts +9 -0
- package/dist/__tests__/integration/gamma-api.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/gamma-api.integration.test.js +170 -0
- package/dist/__tests__/integration/gamma-api.integration.test.js.map +1 -0
- package/dist/__tests__/integration/market-service.integration.test.d.ts +10 -0
- package/dist/__tests__/integration/market-service.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/market-service.integration.test.js +173 -0
- package/dist/__tests__/integration/market-service.integration.test.js.map +1 -0
- package/dist/__tests__/integration/realtime-service-v2.integration.test.d.ts +10 -0
- package/dist/__tests__/integration/realtime-service-v2.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/realtime-service-v2.integration.test.js +307 -0
- package/dist/__tests__/integration/realtime-service-v2.integration.test.js.map +1 -0
- package/dist/__tests__/integration/trading-service.integration.test.d.ts +10 -0
- package/dist/__tests__/integration/trading-service.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/trading-service.integration.test.js +58 -0
- package/dist/__tests__/integration/trading-service.integration.test.js.map +1 -0
- package/dist/__tests__/test-utils.d.ts +92 -0
- package/dist/__tests__/test-utils.d.ts.map +1 -0
- package/dist/__tests__/test-utils.js +143 -0
- package/dist/__tests__/test-utils.js.map +1 -0
- package/dist/clients/bridge-client.d.ts +388 -0
- package/dist/clients/bridge-client.d.ts.map +1 -0
- package/dist/clients/bridge-client.js +587 -0
- package/dist/clients/bridge-client.js.map +1 -0
- package/dist/clients/clob-api.d.ts +391 -0
- package/dist/clients/clob-api.d.ts.map +1 -0
- package/dist/clients/clob-api.js +448 -0
- package/dist/clients/clob-api.js.map +1 -0
- package/dist/clients/ctf-client.d.ts +473 -0
- package/dist/clients/ctf-client.d.ts.map +1 -0
- package/dist/clients/ctf-client.js +915 -0
- package/dist/clients/ctf-client.js.map +1 -0
- package/dist/clients/data-api.d.ts +439 -0
- package/dist/clients/data-api.d.ts.map +1 -0
- package/dist/clients/data-api.js +592 -0
- package/dist/clients/data-api.js.map +1 -0
- package/dist/clients/gamma-api.d.ts +401 -0
- package/dist/clients/gamma-api.d.ts.map +1 -0
- package/dist/clients/gamma-api.js +352 -0
- package/dist/clients/gamma-api.js.map +1 -0
- package/dist/clients/subgraph.d.ts +196 -0
- package/dist/clients/subgraph.d.ts.map +1 -0
- package/dist/clients/subgraph.js +332 -0
- package/dist/clients/subgraph.js.map +1 -0
- package/dist/clients/trading-client.d.ts +252 -0
- package/dist/clients/trading-client.d.ts.map +1 -0
- package/dist/clients/trading-client.js +543 -0
- package/dist/clients/trading-client.js.map +1 -0
- package/dist/clients/websocket-manager.d.ts +103 -0
- package/dist/clients/websocket-manager.d.ts.map +1 -0
- package/dist/clients/websocket-manager.js +200 -0
- package/dist/clients/websocket-manager.js.map +1 -0
- package/dist/core/cache-adapter-bridge.d.ts +36 -0
- package/dist/core/cache-adapter-bridge.d.ts.map +1 -0
- package/dist/core/cache-adapter-bridge.js +81 -0
- package/dist/core/cache-adapter-bridge.js.map +1 -0
- package/dist/core/cache.d.ts +41 -0
- package/dist/core/cache.d.ts.map +1 -0
- package/dist/core/cache.js +72 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/errors.d.ts +39 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +86 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/rate-limiter.d.ts +32 -0
- package/dist/core/rate-limiter.d.ts.map +1 -0
- package/dist/core/rate-limiter.js +75 -0
- package/dist/core/rate-limiter.js.map +1 -0
- package/dist/core/types.d.ts +402 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +19 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/types.test.d.ts +7 -0
- package/dist/core/types.test.d.ts.map +1 -0
- package/dist/core/types.test.js +122 -0
- package/dist/core/types.test.js.map +1 -0
- package/dist/core/unified-cache.d.ts +63 -0
- package/dist/core/unified-cache.d.ts.map +1 -0
- package/dist/core/unified-cache.js +114 -0
- package/dist/core/unified-cache.js.map +1 -0
- package/dist/index.d.ts +151 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +248 -0
- package/dist/index.js.map +1 -0
- package/dist/services/arbitrage-service.d.ts +409 -0
- package/dist/services/arbitrage-service.d.ts.map +1 -0
- package/dist/services/arbitrage-service.js +1440 -0
- package/dist/services/arbitrage-service.js.map +1 -0
- package/dist/services/authorization-service.d.ts +97 -0
- package/dist/services/authorization-service.d.ts.map +1 -0
- package/dist/services/authorization-service.js +279 -0
- package/dist/services/authorization-service.js.map +1 -0
- package/dist/services/market-service.d.ts +208 -0
- package/dist/services/market-service.d.ts.map +1 -0
- package/dist/services/market-service.js +774 -0
- package/dist/services/market-service.js.map +1 -0
- package/dist/services/onchain-service.d.ts +309 -0
- package/dist/services/onchain-service.d.ts.map +1 -0
- package/dist/services/onchain-service.js +417 -0
- package/dist/services/onchain-service.js.map +1 -0
- package/dist/services/realtime-service-v2.d.ts +361 -0
- package/dist/services/realtime-service-v2.d.ts.map +1 -0
- package/dist/services/realtime-service-v2.js +840 -0
- package/dist/services/realtime-service-v2.js.map +1 -0
- package/dist/services/realtime-service.d.ts +82 -0
- package/dist/services/realtime-service.d.ts.map +1 -0
- package/dist/services/realtime-service.js +182 -0
- package/dist/services/realtime-service.js.map +1 -0
- package/dist/services/smart-money-service.d.ts +196 -0
- package/dist/services/smart-money-service.d.ts.map +1 -0
- package/dist/services/smart-money-service.js +358 -0
- package/dist/services/smart-money-service.js.map +1 -0
- package/dist/services/swap-service.d.ts +217 -0
- package/dist/services/swap-service.d.ts.map +1 -0
- package/dist/services/swap-service.js +695 -0
- package/dist/services/swap-service.js.map +1 -0
- package/dist/services/trading-service.d.ts +156 -0
- package/dist/services/trading-service.d.ts.map +1 -0
- package/dist/services/trading-service.js +356 -0
- package/dist/services/trading-service.js.map +1 -0
- package/dist/services/wallet-service.d.ts +275 -0
- package/dist/services/wallet-service.d.ts.map +1 -0
- package/dist/services/wallet-service.js +630 -0
- package/dist/services/wallet-service.js.map +1 -0
- package/dist/utils/price-utils.d.ts +153 -0
- package/dist/utils/price-utils.d.ts.map +1 -0
- package/dist/utils/price-utils.js +236 -0
- package/dist/utils/price-utils.js.map +1 -0
- package/dist/utils/price-utils.test.d.ts +5 -0
- package/dist/utils/price-utils.test.d.ts.map +1 -0
- package/dist/utils/price-utils.test.js +192 -0
- package/dist/utils/price-utils.test.js.map +1 -0
- package/package.json +10 -4
- package/README.en.md +0 -538
- package/docs/00-design.md +0 -760
- package/docs/02-API.md +0 -1148
- package/docs/arb/test-plan.md +0 -387
- package/docs/arb/test-results.md +0 -336
- package/docs/arbitrage.md +0 -754
- package/docs/reports/smart-money-analysis-2025-12-23-cn.md +0 -840
- package/examples/01-basic-usage.ts +0 -68
- package/examples/02-smart-money.ts +0 -95
- package/examples/03-market-analysis.ts +0 -108
- package/examples/04-kline-aggregation.ts +0 -158
- package/examples/05-follow-wallet-strategy.ts +0 -156
- package/examples/06-services-demo.ts +0 -124
- package/examples/07-realtime-websocket.ts +0 -117
- package/examples/08-trading-orders.ts +0 -278
- package/examples/09-rewards-tracking.ts +0 -187
- package/examples/10-ctf-operations.ts +0 -336
- package/examples/11-live-arbitrage-scan.ts +0 -221
- package/examples/12-trending-arb-monitor.ts +0 -406
- package/examples/13-arbitrage-service.ts +0 -211
- package/examples/README.md +0 -179
- package/scripts/README.md +0 -163
- package/scripts/approvals/approve-erc1155.ts +0 -129
- package/scripts/approvals/approve-neg-risk-erc1155.ts +0 -149
- package/scripts/approvals/approve-neg-risk.ts +0 -102
- package/scripts/approvals/check-all-allowances.ts +0 -150
- package/scripts/approvals/check-allowance.ts +0 -129
- package/scripts/approvals/check-ctf-approval.ts +0 -158
- package/scripts/arb/faze-bo3-arb.ts +0 -385
- package/scripts/arb/settle-position.ts +0 -190
- package/scripts/arb/token-rebalancer.ts +0 -420
- package/scripts/arb-tests/01-unit-tests.ts +0 -495
- package/scripts/arb-tests/02-integration-tests.ts +0 -412
- package/scripts/arb-tests/03-e2e-tests.ts +0 -503
- package/scripts/arb-tests/README.md +0 -109
- package/scripts/datas/001-report.md +0 -486
- package/scripts/datas/clone-modal-screenshot.png +0 -0
- package/scripts/deposit/deposit-native-usdc.ts +0 -179
- package/scripts/deposit/deposit-usdc.ts +0 -155
- package/scripts/deposit/swap-usdc-to-usdce.ts +0 -375
- package/scripts/research/research-markets.ts +0 -166
- package/scripts/trading/check-orders.ts +0 -50
- package/scripts/trading/sell-nvidia-positions.ts +0 -206
- package/scripts/trading/test-order.ts +0 -172
- package/scripts/verify/test-approve-trading.ts +0 -98
- package/scripts/verify/test-provider-fix.ts +0 -43
- package/scripts/verify/test-search-mcp.ts +0 -113
- package/scripts/verify/verify-all-apis.ts +0 -160
- package/scripts/wallet/check-wallet-balances.ts +0 -75
- package/scripts/wallet/test-wallet-operations.ts +0 -191
- package/scripts/wallet/verify-wallet-tools.ts +0 -124
- package/src/__tests__/clob-api.test.ts +0 -301
- package/src/__tests__/integration/bridge-client.integration.test.ts +0 -314
- package/src/__tests__/integration/clob-api.integration.test.ts +0 -218
- package/src/__tests__/integration/ctf-client.integration.test.ts +0 -331
- package/src/__tests__/integration/data-api.integration.test.ts +0 -194
- package/src/__tests__/integration/gamma-api.integration.test.ts +0 -206
- package/src/__tests__/test-utils.ts +0 -170
- package/src/clients/bridge-client.ts +0 -841
- package/src/clients/clob-api.ts +0 -629
- package/src/clients/ctf-client.ts +0 -1216
- package/src/clients/data-api.ts +0 -469
- package/src/clients/gamma-api.ts +0 -597
- package/src/clients/trading-client.ts +0 -749
- package/src/clients/websocket-manager.ts +0 -267
- package/src/core/cache-adapter-bridge.ts +0 -94
- package/src/core/cache.ts +0 -85
- package/src/core/errors.ts +0 -117
- package/src/core/rate-limiter.ts +0 -74
- package/src/core/types.ts +0 -360
- package/src/core/unified-cache.ts +0 -153
- package/src/index.ts +0 -461
- package/src/services/arbitrage-service.ts +0 -1807
- package/src/services/authorization-service.ts +0 -357
- package/src/services/market-service.ts +0 -544
- package/src/services/realtime-service.ts +0 -196
- package/src/services/swap-service.ts +0 -896
- package/src/services/wallet-service.ts +0 -259
- package/src/utils/price-utils.ts +0 -307
- package/tsconfig.json +0 -8
- package/vitest.config.ts +0 -19
- package/vitest.integration.config.ts +0 -18
|
@@ -0,0 +1,630 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wallet Service
|
|
3
|
+
*
|
|
4
|
+
* Provides smart money analysis features:
|
|
5
|
+
* - Wallet profile analysis
|
|
6
|
+
* - Position tracking
|
|
7
|
+
* - Activity monitoring
|
|
8
|
+
* - Sell detection for follow wallet strategy
|
|
9
|
+
* - Time-based leaderboard and wallet stats
|
|
10
|
+
*/
|
|
11
|
+
import { CACHE_TTL } from '../core/unified-cache.js';
|
|
12
|
+
/**
|
|
13
|
+
* Collateral Asset ID (USDC)
|
|
14
|
+
* In Polymarket orderbook, "0" represents the collateral token (USDC)
|
|
15
|
+
*/
|
|
16
|
+
const COLLATERAL_ASSET_ID = '0';
|
|
17
|
+
/**
|
|
18
|
+
* Check if an asset ID is collateral (USDC) or outcome token
|
|
19
|
+
*/
|
|
20
|
+
function isCollateralAsset(assetId) {
|
|
21
|
+
return assetId === COLLATERAL_ASSET_ID;
|
|
22
|
+
}
|
|
23
|
+
export class WalletService {
|
|
24
|
+
dataApi;
|
|
25
|
+
subgraph;
|
|
26
|
+
cache;
|
|
27
|
+
constructor(dataApi, subgraph, cache) {
|
|
28
|
+
this.dataApi = dataApi;
|
|
29
|
+
this.subgraph = subgraph;
|
|
30
|
+
this.cache = cache;
|
|
31
|
+
}
|
|
32
|
+
// ===== Time Period Helpers =====
|
|
33
|
+
/**
|
|
34
|
+
* Get start timestamp for a time period
|
|
35
|
+
*/
|
|
36
|
+
getPeriodStartTime(period) {
|
|
37
|
+
const now = Math.floor(Date.now() / 1000);
|
|
38
|
+
switch (period) {
|
|
39
|
+
case 'day':
|
|
40
|
+
return now - 24 * 60 * 60;
|
|
41
|
+
case 'week':
|
|
42
|
+
return now - 7 * 24 * 60 * 60;
|
|
43
|
+
case 'month':
|
|
44
|
+
return now - 30 * 24 * 60 * 60;
|
|
45
|
+
case 'all':
|
|
46
|
+
return 0;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// ===== Wallet Analysis =====
|
|
50
|
+
/**
|
|
51
|
+
* Get comprehensive wallet profile with PnL analysis
|
|
52
|
+
*/
|
|
53
|
+
async getWalletProfile(address) {
|
|
54
|
+
const [positions, activities] = await Promise.all([
|
|
55
|
+
this.dataApi.getPositions(address),
|
|
56
|
+
this.dataApi.getActivity(address, { limit: 100 }),
|
|
57
|
+
]);
|
|
58
|
+
const totalPnL = positions.reduce((sum, p) => sum + (p.cashPnl || 0), 0);
|
|
59
|
+
const realizedPnL = positions.reduce((sum, p) => sum + (p.realizedPnl || 0), 0);
|
|
60
|
+
const unrealizedPnL = totalPnL - realizedPnL;
|
|
61
|
+
const avgPercentPnL = positions.length > 0
|
|
62
|
+
? positions.reduce((sum, p) => sum + (p.percentPnl || 0), 0) / positions.length
|
|
63
|
+
: 0;
|
|
64
|
+
const lastActivity = activities[0];
|
|
65
|
+
return {
|
|
66
|
+
address,
|
|
67
|
+
totalPnL,
|
|
68
|
+
realizedPnL,
|
|
69
|
+
unrealizedPnL,
|
|
70
|
+
avgPercentPnL,
|
|
71
|
+
positionCount: positions.length,
|
|
72
|
+
tradeCount: activities.filter((a) => a.type === 'TRADE').length,
|
|
73
|
+
smartScore: this.calculateSmartScore(positions, activities),
|
|
74
|
+
lastActiveAt: lastActivity ? new Date(lastActivity.timestamp) : new Date(0),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Get positions for a wallet
|
|
79
|
+
*/
|
|
80
|
+
async getWalletPositions(address) {
|
|
81
|
+
return this.dataApi.getPositions(address);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get positions for a specific market
|
|
85
|
+
*/
|
|
86
|
+
async getPositionsForMarket(address, conditionId) {
|
|
87
|
+
const positions = await this.dataApi.getPositions(address);
|
|
88
|
+
return positions.filter((p) => p.conditionId === conditionId);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get wallet activity with summary
|
|
92
|
+
*/
|
|
93
|
+
async getWalletActivity(address, limit = 100) {
|
|
94
|
+
const activities = await this.dataApi.getActivity(address, { limit });
|
|
95
|
+
const buys = activities.filter((a) => a.side === 'BUY');
|
|
96
|
+
const sells = activities.filter((a) => a.side === 'SELL');
|
|
97
|
+
return {
|
|
98
|
+
address,
|
|
99
|
+
activities,
|
|
100
|
+
summary: {
|
|
101
|
+
totalBuys: buys.length,
|
|
102
|
+
totalSells: sells.length,
|
|
103
|
+
buyVolume: buys.reduce((sum, a) => sum + (a.usdcSize || 0), 0),
|
|
104
|
+
sellVolume: sells.reduce((sum, a) => sum + (a.usdcSize || 0), 0),
|
|
105
|
+
activeMarkets: [...new Set(activities.map((a) => a.conditionId))],
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// ===== Wallet Discovery =====
|
|
110
|
+
/**
|
|
111
|
+
* Get leaderboard
|
|
112
|
+
*/
|
|
113
|
+
async getLeaderboard(page = 0, pageSize = 50) {
|
|
114
|
+
return this.dataApi.getLeaderboard({ limit: pageSize, offset: page * pageSize });
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Get top traders from leaderboard
|
|
118
|
+
*/
|
|
119
|
+
async getTopTraders(limit = 10) {
|
|
120
|
+
const leaderboard = await this.dataApi.getLeaderboard({ limit });
|
|
121
|
+
return leaderboard.entries;
|
|
122
|
+
}
|
|
123
|
+
// ===== Time-Based Leaderboard =====
|
|
124
|
+
/**
|
|
125
|
+
* Get leaderboard by time period using official Polymarket API
|
|
126
|
+
*
|
|
127
|
+
* Uses the official Data API which supports time period filtering.
|
|
128
|
+
* This is the recommended method as it uses server-side calculations.
|
|
129
|
+
*
|
|
130
|
+
* @param period - Time period: 'day', 'week', 'month', or 'all'
|
|
131
|
+
* @param limit - Maximum entries to return (default: 50, max: 50)
|
|
132
|
+
* @param sortBy - Sort criteria: 'volume' or 'pnl' (default: 'pnl')
|
|
133
|
+
* @param category - Market category filter (default: 'OVERALL')
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```typescript
|
|
137
|
+
* // Get top traders of the week by PnL
|
|
138
|
+
* const weeklyByPnl = await walletService.getLeaderboardByPeriod('week', 20, 'pnl');
|
|
139
|
+
*
|
|
140
|
+
* // Get top traders by volume
|
|
141
|
+
* const weeklyByVolume = await walletService.getLeaderboardByPeriod('week', 20, 'volume');
|
|
142
|
+
*
|
|
143
|
+
* // Get politics category leaderboard
|
|
144
|
+
* const politics = await walletService.getLeaderboardByPeriod('week', 20, 'pnl', 'POLITICS');
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
async getLeaderboardByPeriod(period, limit = 50, sortBy = 'pnl', category = 'OVERALL') {
|
|
148
|
+
// Map lowercase period to API's uppercase format
|
|
149
|
+
const timePeriodMap = {
|
|
150
|
+
day: 'DAY',
|
|
151
|
+
week: 'WEEK',
|
|
152
|
+
month: 'MONTH',
|
|
153
|
+
all: 'ALL',
|
|
154
|
+
};
|
|
155
|
+
// Map sortBy to API's orderBy format
|
|
156
|
+
const orderByMap = {
|
|
157
|
+
volume: 'VOL',
|
|
158
|
+
pnl: 'PNL',
|
|
159
|
+
};
|
|
160
|
+
const timePeriod = timePeriodMap[period];
|
|
161
|
+
const orderBy = orderByMap[sortBy];
|
|
162
|
+
// Use official API
|
|
163
|
+
const result = await this.dataApi.getLeaderboard({
|
|
164
|
+
timePeriod,
|
|
165
|
+
orderBy,
|
|
166
|
+
category,
|
|
167
|
+
limit,
|
|
168
|
+
});
|
|
169
|
+
// Map to PeriodLeaderboardEntry format
|
|
170
|
+
return result.entries.map((entry, index) => ({
|
|
171
|
+
address: entry.address,
|
|
172
|
+
rank: entry.rank || index + 1,
|
|
173
|
+
volume: entry.volume,
|
|
174
|
+
pnl: entry.pnl,
|
|
175
|
+
// API provides combined PnL, set as total
|
|
176
|
+
totalPnl: entry.pnl,
|
|
177
|
+
realizedPnl: entry.pnl, // API doesn't separate realized/unrealized
|
|
178
|
+
unrealizedPnl: 0,
|
|
179
|
+
// API doesn't provide these breakdowns
|
|
180
|
+
tradeCount: entry.trades || 0,
|
|
181
|
+
buyCount: 0,
|
|
182
|
+
sellCount: 0,
|
|
183
|
+
buyVolume: 0,
|
|
184
|
+
sellVolume: 0,
|
|
185
|
+
makerVolume: 0,
|
|
186
|
+
takerVolume: 0,
|
|
187
|
+
// User profile
|
|
188
|
+
userName: entry.userName,
|
|
189
|
+
profileImage: entry.profileImage,
|
|
190
|
+
}));
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Get a specific user's PnL and ranking for a time period
|
|
194
|
+
*
|
|
195
|
+
* Uses the official Data API's user filter to get a single user's stats.
|
|
196
|
+
*
|
|
197
|
+
* @param address - User's wallet address
|
|
198
|
+
* @param period - Time period: 'day', 'week', 'month', or 'all'
|
|
199
|
+
* @param category - Market category filter (default: 'OVERALL')
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* ```typescript
|
|
203
|
+
* // Get user's weekly PnL
|
|
204
|
+
* const stats = await walletService.getUserPeriodPnl(address, 'week');
|
|
205
|
+
* console.log(`Rank: #${stats.rank}, PnL: $${stats.pnl}`);
|
|
206
|
+
*
|
|
207
|
+
* // Get user's monthly PnL in politics category
|
|
208
|
+
* const politicsStats = await walletService.getUserPeriodPnl(address, 'month', 'POLITICS');
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
async getUserPeriodPnl(address, period, category = 'OVERALL') {
|
|
212
|
+
// Map lowercase period to API's uppercase format
|
|
213
|
+
const timePeriodMap = {
|
|
214
|
+
day: 'DAY',
|
|
215
|
+
week: 'WEEK',
|
|
216
|
+
month: 'MONTH',
|
|
217
|
+
all: 'ALL',
|
|
218
|
+
};
|
|
219
|
+
const timePeriod = timePeriodMap[period];
|
|
220
|
+
// Use official API with user filter
|
|
221
|
+
const result = await this.dataApi.getLeaderboard({
|
|
222
|
+
timePeriod,
|
|
223
|
+
orderBy: 'PNL',
|
|
224
|
+
category,
|
|
225
|
+
user: address,
|
|
226
|
+
limit: 1,
|
|
227
|
+
});
|
|
228
|
+
if (result.entries.length === 0) {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
const entry = result.entries[0];
|
|
232
|
+
return {
|
|
233
|
+
address: entry.address,
|
|
234
|
+
rank: entry.rank || 0,
|
|
235
|
+
volume: entry.volume,
|
|
236
|
+
pnl: entry.pnl,
|
|
237
|
+
totalPnl: entry.pnl,
|
|
238
|
+
realizedPnl: entry.pnl,
|
|
239
|
+
unrealizedPnl: 0,
|
|
240
|
+
tradeCount: entry.trades || 0,
|
|
241
|
+
buyCount: 0,
|
|
242
|
+
sellCount: 0,
|
|
243
|
+
buyVolume: 0,
|
|
244
|
+
sellVolume: 0,
|
|
245
|
+
makerVolume: 0,
|
|
246
|
+
takerVolume: 0,
|
|
247
|
+
userName: entry.userName,
|
|
248
|
+
profileImage: entry.profileImage,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Get wallet stats for a specific time period
|
|
253
|
+
*
|
|
254
|
+
* Combines data from Orderbook Subgraph (trades) and Activity Subgraph (splits/merges/redemptions)
|
|
255
|
+
*
|
|
256
|
+
* @param address - Wallet address
|
|
257
|
+
* @param period - Time period: 'day', 'week', 'month', or 'all'
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```typescript
|
|
261
|
+
* // Get wallet's monthly stats
|
|
262
|
+
* const stats = await walletService.getWalletStatsByPeriod(address, 'month');
|
|
263
|
+
* console.log(`Monthly volume: $${stats.volume}`);
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
266
|
+
async getWalletStatsByPeriod(address, period) {
|
|
267
|
+
const startTime = this.getPeriodStartTime(period);
|
|
268
|
+
const endTime = Math.floor(Date.now() / 1000);
|
|
269
|
+
const cacheKey = `wallet:stats:${address}:${period}`;
|
|
270
|
+
return this.cache.getOrSet(cacheKey, CACHE_TTL.ACTIVITY, async () => {
|
|
271
|
+
// Fetch data in parallel
|
|
272
|
+
const [makerFills, takerFills, splits, merges, redemptions] = await Promise.all([
|
|
273
|
+
this.subgraph.getMakerFills(address, {
|
|
274
|
+
first: 1000,
|
|
275
|
+
where: { timestamp_gte: String(startTime) },
|
|
276
|
+
}),
|
|
277
|
+
this.subgraph.getTakerFills(address, {
|
|
278
|
+
first: 1000,
|
|
279
|
+
where: { timestamp_gte: String(startTime) },
|
|
280
|
+
}),
|
|
281
|
+
this.subgraph.getSplits(address, {
|
|
282
|
+
first: 500,
|
|
283
|
+
where: { timestamp_gte: String(startTime) },
|
|
284
|
+
}),
|
|
285
|
+
this.subgraph.getMerges(address, {
|
|
286
|
+
first: 500,
|
|
287
|
+
where: { timestamp_gte: String(startTime) },
|
|
288
|
+
}),
|
|
289
|
+
this.subgraph.getRedemptions(address, {
|
|
290
|
+
first: 500,
|
|
291
|
+
where: { timestamp_gte: String(startTime) },
|
|
292
|
+
}),
|
|
293
|
+
]);
|
|
294
|
+
// Calculate volumes (amounts are in micro-units, divide by 1e6 for USDC)
|
|
295
|
+
const makerVolume = makerFills.reduce((sum, f) => sum + Number(f.makerAmountFilled) / 1e6, 0);
|
|
296
|
+
const takerVolume = takerFills.reduce((sum, f) => sum + Number(f.takerAmountFilled) / 1e6, 0);
|
|
297
|
+
const redemptionPayout = redemptions.reduce((sum, r) => sum + Number(r.payout) / 1e6, 0);
|
|
298
|
+
return {
|
|
299
|
+
address,
|
|
300
|
+
period,
|
|
301
|
+
startTime,
|
|
302
|
+
endTime,
|
|
303
|
+
volume: makerVolume + takerVolume,
|
|
304
|
+
tradeCount: makerFills.length + takerFills.length,
|
|
305
|
+
makerVolume,
|
|
306
|
+
takerVolume,
|
|
307
|
+
makerCount: makerFills.length,
|
|
308
|
+
takerCount: takerFills.length,
|
|
309
|
+
splitCount: splits.length,
|
|
310
|
+
mergeCount: merges.length,
|
|
311
|
+
redemptionCount: redemptions.length,
|
|
312
|
+
redemptionPayout,
|
|
313
|
+
};
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Fetch all order filled events in a time period with pagination
|
|
318
|
+
*/
|
|
319
|
+
async fetchAllFillsInPeriod(startTime, maxItems = 5000) {
|
|
320
|
+
const allFills = [];
|
|
321
|
+
let skip = 0;
|
|
322
|
+
const first = 1000;
|
|
323
|
+
while (allFills.length < maxItems) {
|
|
324
|
+
const fills = await this.subgraph.getOrderFilledEvents({
|
|
325
|
+
first,
|
|
326
|
+
skip,
|
|
327
|
+
where: startTime > 0 ? { timestamp_gte: String(startTime) } : undefined,
|
|
328
|
+
orderBy: 'timestamp',
|
|
329
|
+
orderDirection: 'desc',
|
|
330
|
+
});
|
|
331
|
+
if (fills.length === 0)
|
|
332
|
+
break;
|
|
333
|
+
allFills.push(...fills);
|
|
334
|
+
skip += first;
|
|
335
|
+
// Break if we got less than requested (no more data)
|
|
336
|
+
if (fills.length < first)
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
return allFills.slice(0, maxItems);
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Parse OrderFilledEvent into user trades
|
|
343
|
+
*
|
|
344
|
+
* OrderFilledEvent 结构:
|
|
345
|
+
* - makerAssetId = "0" (USDC): Maker 卖 USDC = BUY outcome token
|
|
346
|
+
* - makerAssetId = 长数字: Maker 卖 outcome token = SELL
|
|
347
|
+
*/
|
|
348
|
+
parseOrderFilledEvent(fill) {
|
|
349
|
+
const timestamp = Number(fill.timestamp);
|
|
350
|
+
const makerSellsCollateral = isCollateralAsset(fill.makerAssetId);
|
|
351
|
+
if (makerSellsCollateral) {
|
|
352
|
+
// Maker: 卖 USDC, 买 Outcome Token = BUY
|
|
353
|
+
// Taker: 卖 Outcome Token, 买 USDC = SELL
|
|
354
|
+
const usdcAmount = Number(fill.makerAmountFilled) / 1e6;
|
|
355
|
+
const tokenAmount = Number(fill.takerAmountFilled) / 1e6;
|
|
356
|
+
const price = tokenAmount > 0 ? usdcAmount / tokenAmount : 0;
|
|
357
|
+
const tokenId = fill.takerAssetId;
|
|
358
|
+
return [
|
|
359
|
+
{
|
|
360
|
+
timestamp,
|
|
361
|
+
user: fill.maker.toLowerCase(),
|
|
362
|
+
role: 'maker',
|
|
363
|
+
side: 'BUY',
|
|
364
|
+
tokenId,
|
|
365
|
+
tokenAmount,
|
|
366
|
+
usdcAmount,
|
|
367
|
+
price,
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
timestamp,
|
|
371
|
+
user: fill.taker.toLowerCase(),
|
|
372
|
+
role: 'taker',
|
|
373
|
+
side: 'SELL',
|
|
374
|
+
tokenId,
|
|
375
|
+
tokenAmount,
|
|
376
|
+
usdcAmount,
|
|
377
|
+
price,
|
|
378
|
+
},
|
|
379
|
+
];
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
// Maker: 卖 Outcome Token, 买 USDC = SELL
|
|
383
|
+
// Taker: 卖 USDC, 买 Outcome Token = BUY
|
|
384
|
+
const tokenAmount = Number(fill.makerAmountFilled) / 1e6;
|
|
385
|
+
const usdcAmount = Number(fill.takerAmountFilled) / 1e6;
|
|
386
|
+
const price = tokenAmount > 0 ? usdcAmount / tokenAmount : 0;
|
|
387
|
+
const tokenId = fill.makerAssetId;
|
|
388
|
+
return [
|
|
389
|
+
{
|
|
390
|
+
timestamp,
|
|
391
|
+
user: fill.maker.toLowerCase(),
|
|
392
|
+
role: 'maker',
|
|
393
|
+
side: 'SELL',
|
|
394
|
+
tokenId,
|
|
395
|
+
tokenAmount,
|
|
396
|
+
usdcAmount,
|
|
397
|
+
price,
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
timestamp,
|
|
401
|
+
user: fill.taker.toLowerCase(),
|
|
402
|
+
role: 'taker',
|
|
403
|
+
side: 'BUY',
|
|
404
|
+
tokenId,
|
|
405
|
+
tokenAmount,
|
|
406
|
+
usdcAmount,
|
|
407
|
+
price,
|
|
408
|
+
},
|
|
409
|
+
];
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Update position with a trade and calculate realized PnL
|
|
414
|
+
*
|
|
415
|
+
* 买入: 增加持仓,更新平均成本
|
|
416
|
+
* 卖出: 减少持仓,计算已实现盈亏 = 卖出收入 - 成本基础
|
|
417
|
+
*/
|
|
418
|
+
updatePositionWithTrade(position, trade) {
|
|
419
|
+
if (trade.side === 'BUY') {
|
|
420
|
+
// 买入:增加持仓,更新平均成本
|
|
421
|
+
const newAmount = position.amount + trade.tokenAmount;
|
|
422
|
+
const newTotalCost = position.totalCost + trade.usdcAmount;
|
|
423
|
+
const newAvgCost = newAmount > 0 ? newTotalCost / newAmount : 0;
|
|
424
|
+
return {
|
|
425
|
+
...position,
|
|
426
|
+
amount: newAmount,
|
|
427
|
+
totalCost: newTotalCost,
|
|
428
|
+
avgCost: newAvgCost,
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
else {
|
|
432
|
+
// 卖出:减少持仓,计算已实现盈亏
|
|
433
|
+
const sellAmount = Math.min(trade.tokenAmount, position.amount);
|
|
434
|
+
const costBasis = sellAmount * position.avgCost;
|
|
435
|
+
const revenue = (sellAmount / trade.tokenAmount) * trade.usdcAmount;
|
|
436
|
+
const realizedPnl = revenue - costBasis;
|
|
437
|
+
const newAmount = position.amount - sellAmount;
|
|
438
|
+
const newTotalCost = newAmount > 0 ? newAmount * position.avgCost : 0;
|
|
439
|
+
return {
|
|
440
|
+
...position,
|
|
441
|
+
amount: newAmount,
|
|
442
|
+
totalCost: newTotalCost,
|
|
443
|
+
realizedPnl: position.realizedPnl + realizedPnl,
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Calculate unrealized PnL for a position
|
|
449
|
+
*
|
|
450
|
+
* 未实现盈亏 = 当前市值 - 总成本
|
|
451
|
+
* 假设当前价格约等于最后交易价格 (简化处理)
|
|
452
|
+
*/
|
|
453
|
+
calculateUnrealizedPnl(position, lastPrice) {
|
|
454
|
+
if (position.amount <= 0)
|
|
455
|
+
return 0;
|
|
456
|
+
const currentValue = position.amount * lastPrice;
|
|
457
|
+
return currentValue - position.totalCost;
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Aggregate user statistics with PnL calculation from order filled events
|
|
461
|
+
*
|
|
462
|
+
* 核心计算流程:
|
|
463
|
+
* 1. 解析 OrderFilledEvent 为标准化的 ParsedTrade
|
|
464
|
+
* 2. 按时间顺序处理每笔交易
|
|
465
|
+
* 3. 追踪每个用户每个 token 的持仓和平均成本
|
|
466
|
+
* 4. 卖出时计算已实现盈亏
|
|
467
|
+
* 5. 期末计算未实现盈亏
|
|
468
|
+
*/
|
|
469
|
+
aggregateUserStatsWithPnl(fills) {
|
|
470
|
+
const userStats = new Map();
|
|
471
|
+
const lastPrices = new Map(); // 记录每个 token 的最后交易价格
|
|
472
|
+
// 初始化用户统计
|
|
473
|
+
const getOrCreateUserStats = (address) => {
|
|
474
|
+
let stats = userStats.get(address);
|
|
475
|
+
if (!stats) {
|
|
476
|
+
stats = {
|
|
477
|
+
address,
|
|
478
|
+
volume: 0,
|
|
479
|
+
tradeCount: 0,
|
|
480
|
+
buyCount: 0,
|
|
481
|
+
sellCount: 0,
|
|
482
|
+
buyVolume: 0,
|
|
483
|
+
sellVolume: 0,
|
|
484
|
+
realizedPnl: 0,
|
|
485
|
+
unrealizedPnl: 0,
|
|
486
|
+
positions: new Map(),
|
|
487
|
+
};
|
|
488
|
+
userStats.set(address, stats);
|
|
489
|
+
}
|
|
490
|
+
return stats;
|
|
491
|
+
};
|
|
492
|
+
// 解析所有交易
|
|
493
|
+
const allTrades = [];
|
|
494
|
+
for (const fill of fills) {
|
|
495
|
+
const trades = this.parseOrderFilledEvent(fill);
|
|
496
|
+
allTrades.push(...trades);
|
|
497
|
+
}
|
|
498
|
+
// 按时间排序 (升序,确保正确计算成本基础)
|
|
499
|
+
allTrades.sort((a, b) => a.timestamp - b.timestamp);
|
|
500
|
+
// 处理每笔交易
|
|
501
|
+
for (const trade of allTrades) {
|
|
502
|
+
const stats = getOrCreateUserStats(trade.user);
|
|
503
|
+
// 更新交易统计
|
|
504
|
+
stats.volume += trade.usdcAmount;
|
|
505
|
+
stats.tradeCount += 1;
|
|
506
|
+
if (trade.side === 'BUY') {
|
|
507
|
+
stats.buyCount += 1;
|
|
508
|
+
stats.buyVolume += trade.usdcAmount;
|
|
509
|
+
}
|
|
510
|
+
else {
|
|
511
|
+
stats.sellCount += 1;
|
|
512
|
+
stats.sellVolume += trade.usdcAmount;
|
|
513
|
+
}
|
|
514
|
+
// 更新持仓和计算已实现 PnL
|
|
515
|
+
let position = stats.positions.get(trade.tokenId);
|
|
516
|
+
if (!position) {
|
|
517
|
+
position = {
|
|
518
|
+
tokenId: trade.tokenId,
|
|
519
|
+
amount: 0,
|
|
520
|
+
avgCost: 0,
|
|
521
|
+
totalCost: 0,
|
|
522
|
+
realizedPnl: 0,
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
const oldRealizedPnl = position.realizedPnl;
|
|
526
|
+
position = this.updatePositionWithTrade(position, trade);
|
|
527
|
+
stats.positions.set(trade.tokenId, position);
|
|
528
|
+
// 累加已实现 PnL
|
|
529
|
+
stats.realizedPnl += position.realizedPnl - oldRealizedPnl;
|
|
530
|
+
// 记录最后价格
|
|
531
|
+
if (trade.price > 0) {
|
|
532
|
+
lastPrices.set(trade.tokenId, trade.price);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
// 计算每个用户的未实现 PnL
|
|
536
|
+
for (const [, stats] of userStats) {
|
|
537
|
+
let totalUnrealizedPnl = 0;
|
|
538
|
+
for (const [tokenId, position] of stats.positions) {
|
|
539
|
+
if (position.amount > 0) {
|
|
540
|
+
const lastPrice = lastPrices.get(tokenId) || position.avgCost;
|
|
541
|
+
totalUnrealizedPnl += this.calculateUnrealizedPnl(position, lastPrice);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
stats.unrealizedPnl = totalUnrealizedPnl;
|
|
545
|
+
}
|
|
546
|
+
return userStats;
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Discover active wallets from recent trades
|
|
550
|
+
*/
|
|
551
|
+
async discoverActiveWallets(limit = 100) {
|
|
552
|
+
const trades = await this.dataApi.getTrades({ limit: 1000 });
|
|
553
|
+
// Count trades per wallet
|
|
554
|
+
const walletCounts = new Map();
|
|
555
|
+
for (const trade of trades) {
|
|
556
|
+
if (trade.proxyWallet) {
|
|
557
|
+
walletCounts.set(trade.proxyWallet, (walletCounts.get(trade.proxyWallet) || 0) + 1);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
// Sort by trade count
|
|
561
|
+
return [...walletCounts.entries()]
|
|
562
|
+
.sort((a, b) => b[1] - a[1])
|
|
563
|
+
.slice(0, limit)
|
|
564
|
+
.map(([address, tradeCount]) => ({ address, tradeCount }));
|
|
565
|
+
}
|
|
566
|
+
// ===== Sell Detection (Follow Wallet Strategy) =====
|
|
567
|
+
/**
|
|
568
|
+
* Detect sell activity for a wallet in a specific market
|
|
569
|
+
*/
|
|
570
|
+
async detectSellActivity(address, conditionId, sinceTimestamp, peakValue) {
|
|
571
|
+
const activities = await this.dataApi.getActivity(address, { limit: 200, type: 'TRADE' });
|
|
572
|
+
const sellTransactions = activities.filter((a) => a.conditionId === conditionId && a.side === 'SELL' && a.timestamp >= sinceTimestamp);
|
|
573
|
+
const totalSellAmount = sellTransactions.reduce((sum, a) => sum + (a.usdcSize || a.size * a.price), 0);
|
|
574
|
+
// Calculate sell ratio if peak value is provided
|
|
575
|
+
const sellRatio = peakValue && peakValue > 0 ? totalSellAmount / peakValue : 0;
|
|
576
|
+
return {
|
|
577
|
+
totalSellAmount,
|
|
578
|
+
sellTransactions,
|
|
579
|
+
sellRatio,
|
|
580
|
+
shouldExit: sellRatio >= 0.3, // 30% threshold for exit signal
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Track sell ratio for multiple wallets (aggregated)
|
|
585
|
+
*/
|
|
586
|
+
async trackGroupSellRatio(addresses, conditionId, peakTotalValue, sinceTimestamp) {
|
|
587
|
+
const walletSells = [];
|
|
588
|
+
let cumulativeSellAmount = 0;
|
|
589
|
+
for (const address of addresses) {
|
|
590
|
+
const sellData = await this.detectSellActivity(address, conditionId, sinceTimestamp);
|
|
591
|
+
walletSells.push({ address, sellAmount: sellData.totalSellAmount });
|
|
592
|
+
cumulativeSellAmount += sellData.totalSellAmount;
|
|
593
|
+
}
|
|
594
|
+
const sellRatio = peakTotalValue > 0 ? cumulativeSellAmount / peakTotalValue : 0;
|
|
595
|
+
return {
|
|
596
|
+
cumulativeSellAmount,
|
|
597
|
+
sellRatio,
|
|
598
|
+
shouldExit: sellRatio >= 0.3,
|
|
599
|
+
walletSells,
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
// ===== Smart Score Calculation =====
|
|
603
|
+
calculateSmartScore(positions, activities) {
|
|
604
|
+
// Weights: PnL 40%, Win Rate 30%, Consistency 20%, Activity 10%
|
|
605
|
+
// PnL Score (0-40)
|
|
606
|
+
const avgPnL = positions.length > 0
|
|
607
|
+
? positions.reduce((sum, p) => sum + (p.percentPnl || 0), 0) / positions.length
|
|
608
|
+
: 0;
|
|
609
|
+
const pnlScore = Math.min(40, Math.max(0, ((avgPnL + 50) / 100) * 40));
|
|
610
|
+
// Win Rate Score (0-30)
|
|
611
|
+
const winningPositions = positions.filter((p) => (p.cashPnl || 0) > 0).length;
|
|
612
|
+
const winRate = positions.length > 0 ? winningPositions / positions.length : 0;
|
|
613
|
+
const winRateScore = winRate * 30;
|
|
614
|
+
// Consistency Score (0-20)
|
|
615
|
+
const pnlValues = positions.map((p) => p.percentPnl || 0);
|
|
616
|
+
const variance = this.calculateVariance(pnlValues);
|
|
617
|
+
const consistencyScore = Math.max(0, 20 - variance / 10);
|
|
618
|
+
// Activity Score (0-10)
|
|
619
|
+
const recentTrades = activities.filter((a) => a.timestamp > Date.now() - 7 * 24 * 60 * 60 * 1000).length;
|
|
620
|
+
const activityScore = Math.min(10, (recentTrades / 5) * 10);
|
|
621
|
+
return Math.round(pnlScore + winRateScore + consistencyScore + activityScore);
|
|
622
|
+
}
|
|
623
|
+
calculateVariance(values) {
|
|
624
|
+
if (values.length === 0)
|
|
625
|
+
return 0;
|
|
626
|
+
const mean = values.reduce((a, b) => a + b, 0) / values.length;
|
|
627
|
+
return values.reduce((sum, v) => sum + Math.pow(v - mean, 2), 0) / values.length;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
//# sourceMappingURL=wallet-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet-service.js","sourceRoot":"","sources":["../../src/services/wallet-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAcH,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAarD;;;GAGG;AACH,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEhC;;GAEG;AACH,SAAS,iBAAiB,CAAC,OAAe;IACxC,OAAO,OAAO,KAAK,mBAAmB,CAAC;AACzC,CAAC;AAqHD,MAAM,OAAO,aAAa;IAEd;IACA;IACA;IAHV,YACU,OAAsB,EACtB,QAAwB,EACxB,KAAmB;QAFnB,YAAO,GAAP,OAAO,CAAe;QACtB,aAAQ,GAAR,QAAQ,CAAgB;QACxB,UAAK,GAAL,KAAK,CAAc;IAC1B,CAAC;IAEJ,kCAAkC;IAElC;;OAEG;IACK,kBAAkB,CAAC,MAAkB;QAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC1C,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,KAAK;gBACR,OAAO,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;YAC5B,KAAK,MAAM;gBACT,OAAO,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;YAChC,KAAK,OAAO;gBACV,OAAO,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;YACjC,KAAK,KAAK;gBACR,OAAO,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IAED,8BAA8B;IAE9B;;OAEG;IACH,KAAK,CAAC,gBAAgB,CAAC,OAAe;QACpC,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAChD,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC;YAClC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;SAClD,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACzE,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAChF,MAAM,aAAa,GAAG,QAAQ,GAAG,WAAW,CAAC;QAE7C,MAAM,aAAa,GACjB,SAAS,CAAC,MAAM,GAAG,CAAC;YAClB,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM;YAC/E,CAAC,CAAC,CAAC,CAAC;QAER,MAAM,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QAEnC,OAAO;YACL,OAAO;YACP,QAAQ;YACR,WAAW;YACX,aAAa;YACb,aAAa;YACb,aAAa,EAAE,SAAS,CAAC,MAAM;YAC/B,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,MAAM;YAC/D,UAAU,EAAE,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,UAAU,CAAC;YAC3D,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;SAC5E,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,kBAAkB,CAAC,OAAe;QACtC,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,qBAAqB,CAAC,OAAe,EAAE,WAAmB;QAC9D,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAC3D,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,WAAW,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB,CAAC,OAAe,EAAE,KAAK,GAAG,GAAG;QAClD,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAEtE,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;QACxD,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;QAE1D,OAAO;YACL,OAAO;YACP,UAAU;YACV,OAAO,EAAE;gBACP,SAAS,EAAE,IAAI,CAAC,MAAM;gBACtB,UAAU,EAAE,KAAK,CAAC,MAAM;gBACxB,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC9D,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;gBAChE,aAAa,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;aAClE;SACF,CAAC;IACJ,CAAC;IAED,+BAA+B;IAE/B;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,EAAE,QAAQ,GAAG,EAAE;QAC1C,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAG,QAAQ,EAAE,CAAC,CAAC;IACnF,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,KAAK,GAAG,EAAE;QAC5B,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACjE,OAAO,WAAW,CAAC,OAAO,CAAC;IAC7B,CAAC;IAED,qCAAqC;IAErC;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,KAAK,CAAC,sBAAsB,CAC1B,MAAkB,EAClB,KAAK,GAAG,EAAE,EACV,SAA4B,KAAK,EACjC,WAAgC,SAAS;QAEzC,iDAAiD;QACjD,MAAM,aAAa,GAA8C;YAC/D,GAAG,EAAE,KAAK;YACV,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,OAAO;YACd,GAAG,EAAE,KAAK;SACX,CAAC;QAEF,qCAAqC;QACrC,MAAM,UAAU,GAAkD;YAChE,MAAM,EAAE,KAAK;YACb,GAAG,EAAE,KAAK;SACX,CAAC;QAEF,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QAEnC,mBAAmB;QACnB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;YAC/C,UAAU;YACV,OAAO;YACP,QAAQ;YACR,KAAK;SACN,CAAC,CAAC;QAEH,uCAAuC;QACvC,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YAC3C,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,KAAK,GAAG,CAAC;YAC7B,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,0CAA0C;YAC1C,QAAQ,EAAE,KAAK,CAAC,GAAG;YACnB,WAAW,EAAE,KAAK,CAAC,GAAG,EAAE,2CAA2C;YACnE,aAAa,EAAE,CAAC;YAChB,uCAAuC;YACvC,UAAU,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC;YAC7B,QAAQ,EAAE,CAAC;YACX,SAAS,EAAE,CAAC;YACZ,SAAS,EAAE,CAAC;YACZ,UAAU,EAAE,CAAC;YACb,WAAW,EAAE,CAAC;YACd,WAAW,EAAE,CAAC;YACd,eAAe;YACf,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,YAAY,EAAE,KAAK,CAAC,YAAY;SACjC,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,KAAK,CAAC,gBAAgB,CACpB,OAAe,EACf,MAAkB,EAClB,WAAgC,SAAS;QAEzC,iDAAiD;QACjD,MAAM,aAAa,GAA8C;YAC/D,GAAG,EAAE,KAAK;YACV,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,OAAO;YACd,GAAG,EAAE,KAAK;SACX,CAAC;QAEF,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;QAEzC,oCAAoC;QACpC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;YAC/C,UAAU;YACV,OAAO,EAAE,KAAK;YACd,QAAQ;YACR,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,CAAC;SACT,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAChC,OAAO;YACL,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC;YACrB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,QAAQ,EAAE,KAAK,CAAC,GAAG;YACnB,WAAW,EAAE,KAAK,CAAC,GAAG;YACtB,aAAa,EAAE,CAAC;YAChB,UAAU,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC;YAC7B,QAAQ,EAAE,CAAC;YACX,SAAS,EAAE,CAAC;YACZ,SAAS,EAAE,CAAC;YACZ,UAAU,EAAE,CAAC;YACb,WAAW,EAAE,CAAC;YACd,WAAW,EAAE,CAAC;YACd,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,YAAY,EAAE,KAAK,CAAC,YAAY;SACjC,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,sBAAsB,CAC1B,OAAe,EACf,MAAkB;QAElB,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,gBAAgB,OAAO,IAAI,MAAM,EAAE,CAAC;QAErD,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;YAClE,yBAAyB;YACzB,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAC9E,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,EAAE;oBACnC,KAAK,EAAE,IAAI;oBACX,KAAK,EAAE,EAAE,aAAa,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE;iBAC5C,CAAC;gBACF,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,EAAE;oBACnC,KAAK,EAAE,IAAI;oBACX,KAAK,EAAE,EAAE,aAAa,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE;iBAC5C,CAAC;gBACF,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE;oBAC/B,KAAK,EAAE,GAAG;oBACV,KAAK,EAAE,EAAE,aAAa,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE;iBAC5C,CAAC;gBACF,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE;oBAC/B,KAAK,EAAE,GAAG;oBACV,KAAK,EAAE,EAAE,aAAa,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE;iBAC5C,CAAC;gBACF,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,OAAO,EAAE;oBACpC,KAAK,EAAE,GAAG;oBACV,KAAK,EAAE,EAAE,aAAa,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE;iBAC5C,CAAC;aACH,CAAC,CAAC;YAEH,yEAAyE;YACzE,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CACnC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,GAAG,GAAG,EACnD,CAAC,CACF,CAAC;YACF,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CACnC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,GAAG,GAAG,EACnD,CAAC,CACF,CAAC;YACF,MAAM,gBAAgB,GAAG,WAAW,CAAC,MAAM,CACzC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,GAAG,EACxC,CAAC,CACF,CAAC;YAEF,OAAO;gBACL,OAAO;gBACP,MAAM;gBACN,SAAS;gBACT,OAAO;gBACP,MAAM,EAAE,WAAW,GAAG,WAAW;gBACjC,UAAU,EAAE,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM;gBACjD,WAAW;gBACX,WAAW;gBACX,UAAU,EAAE,UAAU,CAAC,MAAM;gBAC7B,UAAU,EAAE,UAAU,CAAC,MAAM;gBAC7B,UAAU,EAAE,MAAM,CAAC,MAAM;gBACzB,UAAU,EAAE,MAAM,CAAC,MAAM;gBACzB,eAAe,EAAE,WAAW,CAAC,MAAM;gBACnC,gBAAgB;aACjB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,qBAAqB,CACjC,SAAiB,EACjB,QAAQ,GAAG,IAAI;QAEf,MAAM,QAAQ,GAAuB,EAAE,CAAC;QACxC,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,MAAM,KAAK,GAAG,IAAI,CAAC;QAEnB,OAAO,QAAQ,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC;gBACrD,KAAK;gBACL,IAAI;gBACJ,KAAK,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;gBACvE,OAAO,EAAE,WAAW;gBACpB,cAAc,EAAE,MAAM;aACvB,CAAC,CAAC;YAEH,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAM;YAE9B,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;YACxB,IAAI,IAAI,KAAK,CAAC;YAEd,qDAAqD;YACrD,IAAI,KAAK,CAAC,MAAM,GAAG,KAAK;gBAAE,MAAM;QAClC,CAAC;QAED,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED;;;;;;OAMG;IACK,qBAAqB,CAAC,IAAsB;QAClD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzC,MAAM,oBAAoB,GAAG,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAElE,IAAI,oBAAoB,EAAE,CAAC;YACzB,uCAAuC;YACvC,wCAAwC;YACxC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,GAAG,CAAC;YACxD,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,GAAG,CAAC;YACzD,MAAM,KAAK,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC;YAElC,OAAO;gBACL;oBACE,SAAS;oBACT,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;oBAC9B,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,KAAK;oBACX,OAAO;oBACP,WAAW;oBACX,UAAU;oBACV,KAAK;iBACN;gBACD;oBACE,SAAS;oBACT,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;oBAC9B,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,MAAM;oBACZ,OAAO;oBACP,WAAW;oBACX,UAAU;oBACV,KAAK;iBACN;aACF,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,wCAAwC;YACxC,uCAAuC;YACvC,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,GAAG,CAAC;YACzD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,GAAG,CAAC;YACxD,MAAM,KAAK,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC;YAElC,OAAO;gBACL;oBACE,SAAS;oBACT,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;oBAC9B,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,MAAM;oBACZ,OAAO;oBACP,WAAW;oBACX,UAAU;oBACV,KAAK;iBACN;gBACD;oBACE,SAAS;oBACT,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;oBAC9B,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,KAAK;oBACX,OAAO;oBACP,WAAW;oBACX,UAAU;oBACV,KAAK;iBACN;aACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACK,uBAAuB,CAC7B,QAAuB,EACvB,KAAkB;QAElB,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACzB,iBAAiB;YACjB,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC;YACtD,MAAM,YAAY,GAAG,QAAQ,CAAC,SAAS,GAAG,KAAK,CAAC,UAAU,CAAC;YAC3D,MAAM,UAAU,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YAEhE,OAAO;gBACL,GAAG,QAAQ;gBACX,MAAM,EAAE,SAAS;gBACjB,SAAS,EAAE,YAAY;gBACvB,OAAO,EAAE,UAAU;aACpB,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,kBAAkB;YAClB,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YAChE,MAAM,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC;YAChD,MAAM,OAAO,GAAG,CAAC,UAAU,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC;YACpE,MAAM,WAAW,GAAG,OAAO,GAAG,SAAS,CAAC;YAExC,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,GAAG,UAAU,CAAC;YAC/C,MAAM,YAAY,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YAEtE,OAAO;gBACL,GAAG,QAAQ;gBACX,MAAM,EAAE,SAAS;gBACjB,SAAS,EAAE,YAAY;gBACvB,WAAW,EAAE,QAAQ,CAAC,WAAW,GAAG,WAAW;aAChD,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACK,sBAAsB,CAAC,QAAuB,EAAE,SAAiB;QACvE,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;QACnC,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC;QACjD,OAAO,YAAY,GAAG,QAAQ,CAAC,SAAS,CAAC;IAC3C,CAAC;IAED;;;;;;;;;OASG;IACK,yBAAyB,CAC/B,KAAyB;QAEzB,MAAM,SAAS,GAAG,IAAI,GAAG,EAA2B,CAAC;QACrD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC,CAAC,qBAAqB;QAEnE,UAAU;QACV,MAAM,oBAAoB,GAAG,CAAC,OAAe,EAAmB,EAAE;YAChE,IAAI,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACnC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,KAAK,GAAG;oBACN,OAAO;oBACP,MAAM,EAAE,CAAC;oBACT,UAAU,EAAE,CAAC;oBACb,QAAQ,EAAE,CAAC;oBACX,SAAS,EAAE,CAAC;oBACZ,SAAS,EAAE,CAAC;oBACZ,UAAU,EAAE,CAAC;oBACb,WAAW,EAAE,CAAC;oBACd,aAAa,EAAE,CAAC;oBAChB,SAAS,EAAE,IAAI,GAAG,EAAE;iBACrB,CAAC;gBACF,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAChC,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QAEF,SAAS;QACT,MAAM,SAAS,GAAkB,EAAE,CAAC;QACpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;YAChD,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QAC5B,CAAC;QAED,wBAAwB;QACxB,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;QAEpD,SAAS;QACT,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAE/C,SAAS;YACT,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC;YACjC,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC;YAEtB,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBACzB,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC;gBACpB,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,UAAU,CAAC;YACtC,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC;gBACrB,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,CAAC;YACvC,CAAC;YAED,iBAAiB;YACjB,IAAI,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAClD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,QAAQ,GAAG;oBACT,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,MAAM,EAAE,CAAC;oBACT,OAAO,EAAE,CAAC;oBACV,SAAS,EAAE,CAAC;oBACZ,WAAW,EAAE,CAAC;iBACf,CAAC;YACJ,CAAC;YAED,MAAM,cAAc,GAAG,QAAQ,CAAC,WAAW,CAAC;YAC5C,QAAQ,GAAG,IAAI,CAAC,uBAAuB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YACzD,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAE7C,YAAY;YACZ,KAAK,CAAC,WAAW,IAAI,QAAQ,CAAC,WAAW,GAAG,cAAc,CAAC;YAE3D,SAAS;YACT,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;gBACpB,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QAED,iBAAiB;QACjB,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI,SAAS,EAAE,CAAC;YAClC,IAAI,kBAAkB,GAAG,CAAC,CAAC;YAC3B,KAAK,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBAClD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxB,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC;oBAC9D,kBAAkB,IAAI,IAAI,CAAC,sBAAsB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;gBACzE,CAAC;YACH,CAAC;YACD,KAAK,CAAC,aAAa,GAAG,kBAAkB,CAAC;QAC3C,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,qBAAqB,CAAC,KAAK,GAAG,GAAG;QACrC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAE7D,0BAA0B;QAC1B,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC/C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;gBACtB,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACtF,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,OAAO,CAAC,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC;aAC/B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;aAC3B,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;aACf,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,sDAAsD;IAEtD;;OAEG;IACH,KAAK,CAAC,kBAAkB,CACtB,OAAe,EACf,WAAmB,EACnB,cAAsB,EACtB,SAAkB;QAElB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAE1F,MAAM,gBAAgB,GAAG,UAAU,CAAC,MAAM,CACxC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,WAAW,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,SAAS,IAAI,cAAc,CAC3F,CAAC;QAEF,MAAM,eAAe,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAEvG,iDAAiD;QACjD,MAAM,SAAS,GAAG,SAAS,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAE/E,OAAO;YACL,eAAe;YACf,gBAAgB;YAChB,SAAS;YACT,UAAU,EAAE,SAAS,IAAI,GAAG,EAAE,gCAAgC;SAC/D,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,mBAAmB,CACvB,SAAmB,EACnB,WAAmB,EACnB,cAAsB,EACtB,cAAsB;QAOtB,MAAM,WAAW,GAAmD,EAAE,CAAC;QACvE,IAAI,oBAAoB,GAAG,CAAC,CAAC;QAE7B,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;YAChC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;YACrF,WAAW,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,eAAe,EAAE,CAAC,CAAC;YACpE,oBAAoB,IAAI,QAAQ,CAAC,eAAe,CAAC;QACnD,CAAC;QAED,MAAM,SAAS,GAAG,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,oBAAoB,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjF,OAAO;YACL,oBAAoB;YACpB,SAAS;YACT,UAAU,EAAE,SAAS,IAAI,GAAG;YAC5B,WAAW;SACZ,CAAC;IACJ,CAAC;IAED,sCAAsC;IAE9B,mBAAmB,CAAC,SAAqB,EAAE,UAAsB;QACvE,gEAAgE;QAEhE,mBAAmB;QACnB,MAAM,MAAM,GACV,SAAS,CAAC,MAAM,GAAG,CAAC;YAClB,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM;YAC/E,CAAC,CAAC,CAAC,CAAC;QACR,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAEvE,wBAAwB;QACxB,MAAM,gBAAgB,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;QAC9E,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,MAAM,YAAY,GAAG,OAAO,GAAG,EAAE,CAAC;QAElC,2BAA2B;QAC3B,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC;QAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QACnD,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,QAAQ,GAAG,EAAE,CAAC,CAAC;QAEzD,wBAAwB;QACxB,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,MAAM,CAAC;QACzG,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,YAAY,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QAE5D,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,YAAY,GAAG,gBAAgB,GAAG,aAAa,CAAC,CAAC;IAChF,CAAC;IAEO,iBAAiB,CAAC,MAAgB;QACxC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAClC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QAC/D,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;IACnF,CAAC;CACF"}
|