@one_deploy/sdk 1.0.7 → 1.2.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/README.md +339 -0
- package/dist/ForexPoolDataGenerator--__twRwl.d.mts +76 -0
- package/dist/ForexPoolDataGenerator-eUgwsU_B.d.ts +76 -0
- package/dist/OneForexTradeHistory-TlKxjbFF.d.ts +250 -0
- package/dist/OneForexTradeHistory-iDySMcw0.d.mts +250 -0
- package/dist/components/index.d.mts +539 -0
- package/dist/components/index.d.ts +539 -0
- package/dist/components/index.js +7295 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/index.mjs +7243 -0
- package/dist/components/index.mjs.map +1 -0
- package/dist/config/index.d.mts +1 -0
- package/dist/config/index.d.ts +1 -0
- package/dist/console-BfTMA7ah.d.mts +504 -0
- package/dist/console-BfTMA7ah.d.ts +504 -0
- package/dist/hooks/index.d.mts +323 -1
- package/dist/hooks/index.d.ts +323 -1
- package/dist/hooks/index.js +3223 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +3204 -1
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.d.mts +18 -352
- package/dist/index.d.ts +18 -352
- package/dist/index.js +8646 -574
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +8449 -432
- package/dist/index.mjs.map +1 -1
- package/dist/providers/index.d.mts +31 -31
- package/dist/providers/index.d.ts +31 -31
- package/dist/providers/index.js +140 -153
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/index.mjs +100 -109
- package/dist/providers/index.mjs.map +1 -1
- package/dist/react-native.d.mts +8 -144
- package/dist/react-native.d.ts +8 -144
- package/dist/react-native.js +2640 -689
- package/dist/react-native.js.map +1 -1
- package/dist/react-native.mjs +2610 -691
- package/dist/react-native.mjs.map +1 -1
- package/dist/services/index.d.mts +85 -4
- package/dist/services/index.d.ts +85 -4
- package/dist/services/index.js +1621 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/index.mjs +1619 -1
- package/dist/services/index.mjs.map +1 -1
- package/dist/types/index.d.mts +203 -1
- package/dist/types/index.d.ts +203 -1
- package/dist/types/index.js +275 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/index.mjs +251 -0
- package/dist/types/index.mjs.map +1 -1
- package/dist/useForexTrading-BleeSor8.d.mts +80 -0
- package/dist/useForexTrading-ZgW_G40Q.d.ts +80 -0
- package/package.json +9 -2
- package/src/components/OneConnectButton.tsx +24 -1
- package/src/components/OneNFTGallery.tsx +13 -7
- package/src/components/OneOfframpWidget.tsx +4 -3
- package/src/components/OnePayWidget.tsx +10 -1
- package/src/components/OneSendWidget.tsx +3 -3
- package/src/components/OneSwapWidget.tsx +4 -4
- package/src/components/OneTransactionButton.tsx +28 -3
- package/src/components/OneWalletBalance.tsx +1 -1
- package/src/components/ai/OneChainSelector.tsx +63 -336
- package/src/components/ai/OneForexCapitalSplit.tsx +112 -0
- package/src/components/ai/OneForexConsoleView.tsx +90 -0
- package/src/components/ai/OneForexPairSelector.tsx +101 -0
- package/src/components/ai/OneForexPoolCard.tsx +105 -0
- package/src/components/ai/OneForexTradeHistory.tsx +107 -0
- package/src/components/ai/OnePairSelector.tsx +77 -434
- package/src/components/ai/console/OneAIQuantConsole.tsx +423 -0
- package/src/components/ai/console/OneAgentCard.tsx +383 -0
- package/src/components/ai/console/OneAgentConsole.tsx +469 -0
- package/src/components/ai/console/OneDecisionTimeline.tsx +433 -0
- package/src/components/ai/console/OneMetricsDashboard.tsx +493 -0
- package/src/components/ai/console/OnePositionCard.tsx +406 -0
- package/src/components/ai/console/OnePositionDetail.tsx +600 -0
- package/src/components/ai/console/OneRiskIndicator.tsx +464 -0
- package/src/components/ai/console/OneTradingConsole.tsx +660 -0
- package/src/components/ai/console/index.ts +17 -0
- package/src/components/ai/index.ts +10 -0
- package/src/hooks/index.ts +46 -0
- package/src/hooks/useAIDecisions.ts +280 -0
- package/src/hooks/useAIPositions.ts +349 -0
- package/src/hooks/useAIQuantConsole.ts +283 -0
- package/src/hooks/useAIRiskStatus.ts +276 -0
- package/src/hooks/useAITrading.ts +190 -0
- package/src/hooks/useBotSimulation.ts +201 -0
- package/src/hooks/useForexTrading.ts +430 -0
- package/src/hooks/useTradingConsole.ts +243 -0
- package/src/index.ts +123 -5
- package/src/providers/OneProvider.tsx +181 -5
- package/src/providers/index.ts +22 -8
- package/src/react-native.ts +41 -0
- package/src/services/forex/BotSimulationEngine.ts +968 -0
- package/src/services/forex/ForexPoolDataGenerator.ts +542 -0
- package/src/services/forex/ForexSimulationEngine.ts +482 -0
- package/src/services/forex/index.ts +21 -0
- package/src/services/index.ts +16 -0
- package/src/types/aiTrading.ts +151 -0
- package/src/types/console.ts +380 -0
- package/src/types/forex.ts +282 -0
- package/src/types/index.ts +106 -0
- package/dist/price-CgqXPnT3.d.ts +0 -13
- package/dist/price-ClbLHHjv.d.mts +0 -13
- package/dist/supabase-BT0c7q9e.d.mts +0 -82
- package/dist/supabase-BT0c7q9e.d.ts +0 -82
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
2
|
+
// ONE SDK - Trading Console Types & Constants
|
|
3
|
+
// Shared types for real-time trading console components
|
|
4
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
5
|
+
|
|
6
|
+
import type { BotLogEntry, BotState, StrategyPersonality } from '../services/forex/BotSimulationEngine';
|
|
7
|
+
import type { ForexLogEntry, ForexPoolTransaction, ForexLogType } from './forex';
|
|
8
|
+
|
|
9
|
+
// ── Re-exports for convenience ────────────────────────────────────────────────
|
|
10
|
+
|
|
11
|
+
export type { BotLogEntry, BotLogType, BotState, IndicatorSnapshot, StrategyPersonality } from '../services/forex/BotSimulationEngine';
|
|
12
|
+
|
|
13
|
+
// ── Console Log Types ─────────────────────────────────────────────────────────
|
|
14
|
+
|
|
15
|
+
export type AILogType =
|
|
16
|
+
| 'SCAN' | 'THINKING' | 'INDICATOR' | 'ANALYSIS' | 'SIGNAL'
|
|
17
|
+
| 'STRATEGY' | 'DECISION' | 'ORDER' | 'FILLED' | 'PNL'
|
|
18
|
+
| 'RISK' | 'NEWS' | 'SYSTEM';
|
|
19
|
+
|
|
20
|
+
export const AI_LOG_COLORS: Record<AILogType, string> = {
|
|
21
|
+
SCAN: '#06B6D4', // Cyan
|
|
22
|
+
THINKING: '#A855F7', // Purple
|
|
23
|
+
INDICATOR: '#3B82F6', // Blue
|
|
24
|
+
ANALYSIS: '#6366F1', // Indigo
|
|
25
|
+
SIGNAL: '#F59E0B', // Amber
|
|
26
|
+
STRATEGY: '#D946EF', // Fuchsia
|
|
27
|
+
DECISION: '#F97316', // Orange
|
|
28
|
+
ORDER: '#EC4899', // Pink
|
|
29
|
+
FILLED: '#10B981', // Green
|
|
30
|
+
PNL: '#22C55E', // Emerald
|
|
31
|
+
RISK: '#EF4444', // Red
|
|
32
|
+
NEWS: '#14B8A6', // Teal
|
|
33
|
+
SYSTEM: '#9CA3AF', // Gray
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// Forex log type colors (for ForexSimulationEngine logs)
|
|
37
|
+
export const FOREX_LOG_COLORS: Record<ForexLogType, string> = {
|
|
38
|
+
RFQ: '#06B6D4', // Cyan
|
|
39
|
+
QUOTE: '#8B5CF6', // Purple
|
|
40
|
+
MATCH: '#10B981', // Green
|
|
41
|
+
SETTLE: '#F59E0B', // Amber
|
|
42
|
+
PVP: '#3B82F6', // Blue
|
|
43
|
+
HEDGE: '#EC4899', // Pink
|
|
44
|
+
CLEAR: '#14B8A6', // Teal
|
|
45
|
+
POSITION: '#6366F1', // Indigo
|
|
46
|
+
PNL: '#22C55E', // Emerald
|
|
47
|
+
SYSTEM: '#9CA3AF', // Gray
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// ── AI Position Types ─────────────────────────────────────────────────────────
|
|
51
|
+
|
|
52
|
+
export type PositionSide = 'LONG' | 'SHORT';
|
|
53
|
+
export type PositionStatus = 'open' | 'closed' | 'liquidated' | 'pending';
|
|
54
|
+
|
|
55
|
+
export interface AIPosition {
|
|
56
|
+
id: string;
|
|
57
|
+
strategyId: string;
|
|
58
|
+
strategyName: string;
|
|
59
|
+
pair: string;
|
|
60
|
+
side: PositionSide;
|
|
61
|
+
entryPrice: number;
|
|
62
|
+
currentPrice: number;
|
|
63
|
+
size: number;
|
|
64
|
+
leverage: number;
|
|
65
|
+
margin: number;
|
|
66
|
+
pnl: number;
|
|
67
|
+
pnlPercent: number;
|
|
68
|
+
status: PositionStatus;
|
|
69
|
+
stopLoss?: number;
|
|
70
|
+
takeProfit?: number;
|
|
71
|
+
liquidationPrice?: number;
|
|
72
|
+
openTime: number;
|
|
73
|
+
closeTime?: number;
|
|
74
|
+
chain?: string;
|
|
75
|
+
orderId?: string;
|
|
76
|
+
aiConfidence?: number;
|
|
77
|
+
aiReasoning?: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ── AI Decision Types ─────────────────────────────────────────────────────────
|
|
81
|
+
|
|
82
|
+
export type DecisionAction = 'OPEN_LONG' | 'OPEN_SHORT' | 'CLOSE_LONG' | 'CLOSE_SHORT' | 'HOLD' | 'SKIP';
|
|
83
|
+
|
|
84
|
+
export interface AIDecision {
|
|
85
|
+
id: string;
|
|
86
|
+
timestamp: number;
|
|
87
|
+
strategyId: string;
|
|
88
|
+
strategyName: string;
|
|
89
|
+
pair: string;
|
|
90
|
+
action: DecisionAction;
|
|
91
|
+
confidence: number;
|
|
92
|
+
reasoning: string;
|
|
93
|
+
indicators: {
|
|
94
|
+
rsi?: number;
|
|
95
|
+
macd?: number;
|
|
96
|
+
ema?: string;
|
|
97
|
+
volume?: number;
|
|
98
|
+
bollinger?: string;
|
|
99
|
+
};
|
|
100
|
+
signals: string[];
|
|
101
|
+
executed: boolean;
|
|
102
|
+
positionId?: string;
|
|
103
|
+
price?: number;
|
|
104
|
+
size?: number;
|
|
105
|
+
leverage?: number;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ── Risk Status Types ─────────────────────────────────────────────────────────
|
|
109
|
+
|
|
110
|
+
export type RiskLevel = 'low' | 'medium' | 'high' | 'critical';
|
|
111
|
+
export type TradingStatus = 'active' | 'paused' | 'stopped' | 'cooldown';
|
|
112
|
+
|
|
113
|
+
export interface RiskStatus {
|
|
114
|
+
timestamp: number;
|
|
115
|
+
// Portfolio exposure
|
|
116
|
+
totalExposure: number;
|
|
117
|
+
maxExposure: number;
|
|
118
|
+
exposurePercent: number;
|
|
119
|
+
// Daily limits
|
|
120
|
+
dailyPnl: number;
|
|
121
|
+
dailyPnlLimit: number;
|
|
122
|
+
dailyPnlPercent: number;
|
|
123
|
+
dailyTradeCount: number;
|
|
124
|
+
dailyTradeLimit: number;
|
|
125
|
+
// Drawdown
|
|
126
|
+
currentDrawdown: number;
|
|
127
|
+
maxDrawdown: number;
|
|
128
|
+
drawdownPercent: number;
|
|
129
|
+
// Position limits
|
|
130
|
+
openPositions: number;
|
|
131
|
+
maxPositions: number;
|
|
132
|
+
// Risk assessment
|
|
133
|
+
riskLevel: RiskLevel;
|
|
134
|
+
tradingStatus: TradingStatus;
|
|
135
|
+
warnings: string[];
|
|
136
|
+
// Per-strategy risk
|
|
137
|
+
strategyRisks?: Record<string, {
|
|
138
|
+
exposure: number;
|
|
139
|
+
drawdown: number;
|
|
140
|
+
riskLevel: RiskLevel;
|
|
141
|
+
}>;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export const RISK_LEVEL_COLORS: Record<RiskLevel, { color: string; bgColor: string }> = {
|
|
145
|
+
low: { color: '#10B981', bgColor: '#D1FAE5' },
|
|
146
|
+
medium: { color: '#F59E0B', bgColor: '#FEF3C7' },
|
|
147
|
+
high: { color: '#F97316', bgColor: '#FFEDD5' },
|
|
148
|
+
critical: { color: '#EF4444', bgColor: '#FEE2E2' },
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export const TRADING_STATUS_COLORS: Record<TradingStatus, { color: string; bgColor: string }> = {
|
|
152
|
+
active: { color: '#10B981', bgColor: '#D1FAE5' },
|
|
153
|
+
paused: { color: '#F59E0B', bgColor: '#FEF3C7' },
|
|
154
|
+
stopped: { color: '#EF4444', bgColor: '#FEE2E2' },
|
|
155
|
+
cooldown: { color: '#6366F1', bgColor: '#E0E7FF' },
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// ── Console Metrics Types ─────────────────────────────────────────────────────
|
|
159
|
+
|
|
160
|
+
export interface ConsoleMetrics {
|
|
161
|
+
// NAV & Performance
|
|
162
|
+
nav: number;
|
|
163
|
+
navChange24h: number;
|
|
164
|
+
navChangePercent24h: number;
|
|
165
|
+
// P&L
|
|
166
|
+
totalPnl: number;
|
|
167
|
+
realizedPnl: number;
|
|
168
|
+
unrealizedPnl: number;
|
|
169
|
+
pnlToday: number;
|
|
170
|
+
pnl7d: number;
|
|
171
|
+
pnl30d: number;
|
|
172
|
+
// Trading stats
|
|
173
|
+
totalTrades: number;
|
|
174
|
+
tradesToday: number;
|
|
175
|
+
winRate: number;
|
|
176
|
+
winCount: number;
|
|
177
|
+
lossCount: number;
|
|
178
|
+
avgWin: number;
|
|
179
|
+
avgLoss: number;
|
|
180
|
+
profitFactor: number;
|
|
181
|
+
// Position stats
|
|
182
|
+
openPositions: number;
|
|
183
|
+
totalExposure: number;
|
|
184
|
+
avgLeverage: number;
|
|
185
|
+
// By strategy
|
|
186
|
+
strategyMetrics?: Record<string, {
|
|
187
|
+
pnl: number;
|
|
188
|
+
trades: number;
|
|
189
|
+
winRate: number;
|
|
190
|
+
exposure: number;
|
|
191
|
+
}>;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// ── Agent Types ───────────────────────────────────────────────────────────────
|
|
195
|
+
|
|
196
|
+
export type AgentStatus = 'active' | 'paused' | 'idle' | 'error' | 'initializing';
|
|
197
|
+
|
|
198
|
+
export interface AIAgent {
|
|
199
|
+
id: string;
|
|
200
|
+
strategyId: string;
|
|
201
|
+
name: string;
|
|
202
|
+
shortName: string;
|
|
203
|
+
color: string;
|
|
204
|
+
status: AgentStatus;
|
|
205
|
+
// Performance
|
|
206
|
+
totalPnl: number;
|
|
207
|
+
pnlToday: number;
|
|
208
|
+
winRate: number;
|
|
209
|
+
totalTrades: number;
|
|
210
|
+
tradesToday: number;
|
|
211
|
+
// Current state
|
|
212
|
+
currentPair?: string;
|
|
213
|
+
currentPrice?: number;
|
|
214
|
+
lastSignal?: string;
|
|
215
|
+
lastSignalConfidence?: number;
|
|
216
|
+
lastActivity?: number;
|
|
217
|
+
// Positions
|
|
218
|
+
openPositions: number;
|
|
219
|
+
totalExposure: number;
|
|
220
|
+
// Risk
|
|
221
|
+
riskLevel: RiskLevel;
|
|
222
|
+
drawdown: number;
|
|
223
|
+
// Config
|
|
224
|
+
riskTolerance: 'low' | 'medium' | 'high';
|
|
225
|
+
primaryIndicators: string[];
|
|
226
|
+
preferredPairs: string[];
|
|
227
|
+
leverageRange: [number, number];
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export const AGENT_STATUS_COLORS: Record<AgentStatus, { color: string; bgColor: string; label: string }> = {
|
|
231
|
+
active: { color: '#10B981', bgColor: '#D1FAE5', label: 'Active' },
|
|
232
|
+
paused: { color: '#F59E0B', bgColor: '#FEF3C7', label: 'Paused' },
|
|
233
|
+
idle: { color: '#6B7280', bgColor: '#F3F4F6', label: 'Idle' },
|
|
234
|
+
error: { color: '#EF4444', bgColor: '#FEE2E2', label: 'Error' },
|
|
235
|
+
initializing: { color: '#3B82F6', bgColor: '#DBEAFE', label: 'Starting' },
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
// ── Combined Console State ────────────────────────────────────────────────────
|
|
239
|
+
|
|
240
|
+
export interface CombinedLogEntry {
|
|
241
|
+
id: string;
|
|
242
|
+
timestamp: number;
|
|
243
|
+
source: 'ai' | 'forex';
|
|
244
|
+
strategyId?: string;
|
|
245
|
+
strategyName?: string;
|
|
246
|
+
type: string;
|
|
247
|
+
message: string;
|
|
248
|
+
data?: Record<string, any>;
|
|
249
|
+
importance: 'low' | 'medium' | 'high';
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export interface TradingConsoleState {
|
|
253
|
+
ai: {
|
|
254
|
+
strategies: StrategyPersonality[];
|
|
255
|
+
agents: AIAgent[];
|
|
256
|
+
positions: AIPosition[];
|
|
257
|
+
decisions: AIDecision[];
|
|
258
|
+
riskStatus: RiskStatus | null;
|
|
259
|
+
simulationLogs: BotLogEntry[];
|
|
260
|
+
botStates: Map<string, BotState>;
|
|
261
|
+
};
|
|
262
|
+
forex: {
|
|
263
|
+
logs: ForexLogEntry[];
|
|
264
|
+
poolTransactions: ForexPoolTransaction[];
|
|
265
|
+
stats: {
|
|
266
|
+
totalPnl: number;
|
|
267
|
+
totalTrades: number;
|
|
268
|
+
totalPips: number;
|
|
269
|
+
totalLots: number;
|
|
270
|
+
};
|
|
271
|
+
};
|
|
272
|
+
metrics: ConsoleMetrics;
|
|
273
|
+
combinedLogs: CombinedLogEntry[];
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// ── Hook Options ──────────────────────────────────────────────────────────────
|
|
277
|
+
|
|
278
|
+
export interface TradingConsoleOptions {
|
|
279
|
+
simulation?: boolean;
|
|
280
|
+
pollInterval?: number;
|
|
281
|
+
maxLogs?: number;
|
|
282
|
+
strategyIds?: string[];
|
|
283
|
+
autoStart?: boolean;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export interface AIQuantConsoleOptions {
|
|
287
|
+
strategyIds?: string[];
|
|
288
|
+
pollInterval?: number;
|
|
289
|
+
simulation?: boolean;
|
|
290
|
+
maxLogs?: number;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export interface AgentConsoleOptions {
|
|
294
|
+
strategyId: string;
|
|
295
|
+
pollInterval?: number;
|
|
296
|
+
simulation?: boolean;
|
|
297
|
+
maxLogs?: number;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// ── Default Values ────────────────────────────────────────────────────────────
|
|
301
|
+
|
|
302
|
+
export const DEFAULT_CONSOLE_OPTIONS: TradingConsoleOptions = {
|
|
303
|
+
simulation: true,
|
|
304
|
+
pollInterval: 5000,
|
|
305
|
+
maxLogs: 500,
|
|
306
|
+
autoStart: false,
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
export const DEFAULT_RISK_STATUS: RiskStatus = {
|
|
310
|
+
timestamp: Date.now(),
|
|
311
|
+
totalExposure: 0,
|
|
312
|
+
maxExposure: 100000,
|
|
313
|
+
exposurePercent: 0,
|
|
314
|
+
dailyPnl: 0,
|
|
315
|
+
dailyPnlLimit: 5000,
|
|
316
|
+
dailyPnlPercent: 0,
|
|
317
|
+
dailyTradeCount: 0,
|
|
318
|
+
dailyTradeLimit: 50,
|
|
319
|
+
currentDrawdown: 0,
|
|
320
|
+
maxDrawdown: 15,
|
|
321
|
+
drawdownPercent: 0,
|
|
322
|
+
openPositions: 0,
|
|
323
|
+
maxPositions: 10,
|
|
324
|
+
riskLevel: 'low',
|
|
325
|
+
tradingStatus: 'active',
|
|
326
|
+
warnings: [],
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
export const DEFAULT_CONSOLE_METRICS: ConsoleMetrics = {
|
|
330
|
+
nav: 0,
|
|
331
|
+
navChange24h: 0,
|
|
332
|
+
navChangePercent24h: 0,
|
|
333
|
+
totalPnl: 0,
|
|
334
|
+
realizedPnl: 0,
|
|
335
|
+
unrealizedPnl: 0,
|
|
336
|
+
pnlToday: 0,
|
|
337
|
+
pnl7d: 0,
|
|
338
|
+
pnl30d: 0,
|
|
339
|
+
totalTrades: 0,
|
|
340
|
+
tradesToday: 0,
|
|
341
|
+
winRate: 0,
|
|
342
|
+
winCount: 0,
|
|
343
|
+
lossCount: 0,
|
|
344
|
+
avgWin: 0,
|
|
345
|
+
avgLoss: 0,
|
|
346
|
+
profitFactor: 0,
|
|
347
|
+
openPositions: 0,
|
|
348
|
+
totalExposure: 0,
|
|
349
|
+
avgLeverage: 0,
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
// ── Utility Functions ─────────────────────────────────────────────────────────
|
|
353
|
+
|
|
354
|
+
export function calculateRiskLevel(
|
|
355
|
+
exposurePercent: number,
|
|
356
|
+
drawdownPercent: number,
|
|
357
|
+
dailyPnlPercent: number
|
|
358
|
+
): RiskLevel {
|
|
359
|
+
const worstMetric = Math.max(exposurePercent, drawdownPercent, Math.abs(dailyPnlPercent));
|
|
360
|
+
if (worstMetric >= 90) return 'critical';
|
|
361
|
+
if (worstMetric >= 70) return 'high';
|
|
362
|
+
if (worstMetric >= 40) return 'medium';
|
|
363
|
+
return 'low';
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export function formatPnl(pnl: number): string {
|
|
367
|
+
const sign = pnl >= 0 ? '+' : '';
|
|
368
|
+
if (Math.abs(pnl) >= 1000000) {
|
|
369
|
+
return `${sign}$${(pnl / 1000000).toFixed(2)}M`;
|
|
370
|
+
}
|
|
371
|
+
if (Math.abs(pnl) >= 1000) {
|
|
372
|
+
return `${sign}$${(pnl / 1000).toFixed(2)}K`;
|
|
373
|
+
}
|
|
374
|
+
return `${sign}$${pnl.toFixed(2)}`;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
export function formatPercent(value: number, showSign = true): string {
|
|
378
|
+
const sign = showSign && value >= 0 ? '+' : '';
|
|
379
|
+
return `${sign}${value.toFixed(2)}%`;
|
|
380
|
+
}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
2
|
+
// ONE SDK - StableFX On-Chain Forex Types & Constants
|
|
3
|
+
// Shared types for stablecoin foreign exchange pool trading
|
|
4
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
5
|
+
|
|
6
|
+
// ── Capital Split ────────────────────────────────────────────────────────────
|
|
7
|
+
|
|
8
|
+
export const FOREX_CAPITAL_SPLIT = {
|
|
9
|
+
poolReserves: 0.50,
|
|
10
|
+
tradingCapital: 0.50,
|
|
11
|
+
} as const;
|
|
12
|
+
|
|
13
|
+
export function computePoolAllocations(amount: number): {
|
|
14
|
+
tradingCapital: number;
|
|
15
|
+
totalPoolReserves: number;
|
|
16
|
+
clearing: number;
|
|
17
|
+
hedging: number;
|
|
18
|
+
insurance: number;
|
|
19
|
+
} {
|
|
20
|
+
const totalPoolReserves = amount * FOREX_CAPITAL_SPLIT.poolReserves;
|
|
21
|
+
const tradingCapital = amount * FOREX_CAPITAL_SPLIT.tradingCapital;
|
|
22
|
+
return {
|
|
23
|
+
tradingCapital,
|
|
24
|
+
totalPoolReserves,
|
|
25
|
+
clearing: totalPoolReserves * 0.50,
|
|
26
|
+
hedging: totalPoolReserves * 0.30,
|
|
27
|
+
insurance: totalPoolReserves * 0.20,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// ── Cycle Options ────────────────────────────────────────────────────────────
|
|
32
|
+
|
|
33
|
+
export interface ForexCycleOption {
|
|
34
|
+
days: number;
|
|
35
|
+
feeRate: number;
|
|
36
|
+
commissionRate: number;
|
|
37
|
+
label: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const FOREX_CYCLE_OPTIONS: ForexCycleOption[] = [
|
|
41
|
+
{ days: 30, feeRate: 0.10, commissionRate: 0.60, label: '30D' },
|
|
42
|
+
{ days: 60, feeRate: 0.08, commissionRate: 0.70, label: '60D' },
|
|
43
|
+
{ days: 90, feeRate: 0.07, commissionRate: 0.75, label: '90D' },
|
|
44
|
+
{ days: 180, feeRate: 0.05, commissionRate: 0.85, label: '180D' },
|
|
45
|
+
{ days: 360, feeRate: 0.03, commissionRate: 0.90, label: '360D' },
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
// ── Currency Pairs ───────────────────────────────────────────────────────────
|
|
49
|
+
|
|
50
|
+
export interface ForexCurrencyPair {
|
|
51
|
+
id: string;
|
|
52
|
+
base: string;
|
|
53
|
+
quote: string;
|
|
54
|
+
symbol: string;
|
|
55
|
+
flag: string;
|
|
56
|
+
name: string;
|
|
57
|
+
basePrice: number;
|
|
58
|
+
pipSize: number;
|
|
59
|
+
spreadPips: number;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const FOREX_CURRENCY_PAIRS: ForexCurrencyPair[] = [
|
|
63
|
+
{ id: 'USDC_EURC', base: 'USDC', quote: 'EURC', symbol: 'USDC/EURC', flag: '\u{1F1EA}\u{1F1FA}', name: 'Euro', basePrice: 0.9230, pipSize: 0.0001, spreadPips: 1.2 },
|
|
64
|
+
{ id: 'USDC_GBPC', base: 'USDC', quote: 'GBPC', symbol: 'USDC/GBPC', flag: '\u{1F1EC}\u{1F1E7}', name: 'British Pound', basePrice: 0.7890, pipSize: 0.0001, spreadPips: 1.5 },
|
|
65
|
+
{ id: 'USDC_JPYC', base: 'USDC', quote: 'JPYC', symbol: 'USDC/JPYC', flag: '\u{1F1EF}\u{1F1F5}', name: 'Japanese Yen', basePrice: 154.50, pipSize: 0.01, spreadPips: 1.0 },
|
|
66
|
+
{ id: 'USDC_AUDC', base: 'USDC', quote: 'AUDC', symbol: 'USDC/AUDC', flag: '\u{1F1E6}\u{1F1FA}', name: 'Australian Dollar', basePrice: 1.5380, pipSize: 0.0001, spreadPips: 1.8 },
|
|
67
|
+
{ id: 'USDC_CADC', base: 'USDC', quote: 'CADC', symbol: 'USDC/CADC', flag: '\u{1F1E8}\u{1F1E6}', name: 'Canadian Dollar', basePrice: 1.3640, pipSize: 0.0001, spreadPips: 1.5 },
|
|
68
|
+
{ id: 'USDC_CHFC', base: 'USDC', quote: 'CHFC', symbol: 'USDC/CHFC', flag: '\u{1F1E8}\u{1F1ED}', name: 'Swiss Franc', basePrice: 0.8750, pipSize: 0.0001, spreadPips: 1.3 },
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
// ── Pools ────────────────────────────────────────────────────────────────────
|
|
72
|
+
|
|
73
|
+
export type ForexPoolType = 'clearing' | 'hedging' | 'insurance';
|
|
74
|
+
|
|
75
|
+
export interface ForexPool {
|
|
76
|
+
id: ForexPoolType;
|
|
77
|
+
nameKey: string;
|
|
78
|
+
descriptionKey: string;
|
|
79
|
+
allocation: number;
|
|
80
|
+
totalSize: number;
|
|
81
|
+
utilization: number;
|
|
82
|
+
color: string;
|
|
83
|
+
apy7d: number;
|
|
84
|
+
apy30d: number;
|
|
85
|
+
netFlow24h: number;
|
|
86
|
+
txCount24h: number;
|
|
87
|
+
txCountTotal: number;
|
|
88
|
+
totalDeposits: number;
|
|
89
|
+
totalWithdrawals: number;
|
|
90
|
+
profitDistributed: number;
|
|
91
|
+
lastUpdated: number;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export const FOREX_POOL_DEFAULTS: ForexPool[] = [
|
|
95
|
+
{ id: 'clearing', nameKey: 'forex.pool_clearing', descriptionKey: 'forex.pool_clearing_desc', allocation: 0.50, totalSize: 12500000, utilization: 0.78, color: '#3B82F6', apy7d: 12.8, apy30d: 11.5, netFlow24h: 185000, txCount24h: 42, txCountTotal: 12840, totalDeposits: 45200000, totalWithdrawals: 32700000, profitDistributed: 1850000, lastUpdated: Date.now() },
|
|
96
|
+
{ id: 'hedging', nameKey: 'forex.pool_hedging', descriptionKey: 'forex.pool_hedging_desc', allocation: 0.30, totalSize: 7500000, utilization: 0.65, color: '#F59E0B', apy7d: 8.1, apy30d: 7.6, netFlow24h: 72000, txCount24h: 24, txCountTotal: 7620, totalDeposits: 28500000, totalWithdrawals: 21000000, profitDistributed: 980000, lastUpdated: Date.now() },
|
|
97
|
+
{ id: 'insurance', nameKey: 'forex.pool_insurance', descriptionKey: 'forex.pool_insurance_desc', allocation: 0.20, totalSize: 5000000, utilization: 0.42, color: '#10B981', apy7d: 4.8, apy30d: 4.5, netFlow24h: 35000, txCount24h: 14, txCountTotal: 4280, totalDeposits: 15800000, totalWithdrawals: 10800000, profitDistributed: 520000, lastUpdated: Date.now() },
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
// ── Pool Transactions ────────────────────────────────────────────────────────
|
|
101
|
+
|
|
102
|
+
export type ForexPoolTransactionType =
|
|
103
|
+
| 'deposit' | 'withdrawal' | 'profit_distribution'
|
|
104
|
+
| 'loss_absorption' | 'inter_pool_transfer' | 'fee_collection' | 'reserve_rebalance';
|
|
105
|
+
|
|
106
|
+
export interface ForexPoolTransaction {
|
|
107
|
+
id: string;
|
|
108
|
+
poolId: ForexPoolType;
|
|
109
|
+
type: ForexPoolTransactionType;
|
|
110
|
+
amount: number;
|
|
111
|
+
balanceBefore: number;
|
|
112
|
+
balanceAfter: number;
|
|
113
|
+
txHash: string;
|
|
114
|
+
blockNumber: number;
|
|
115
|
+
timestamp: number;
|
|
116
|
+
description: string;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// ── Pool Daily Snapshots ────────────────────────────────────────────────────
|
|
120
|
+
|
|
121
|
+
export interface ForexPoolDailySnapshot {
|
|
122
|
+
poolId: ForexPoolType;
|
|
123
|
+
date: string;
|
|
124
|
+
openBalance: number;
|
|
125
|
+
closeBalance: number;
|
|
126
|
+
deposits: number;
|
|
127
|
+
withdrawals: number;
|
|
128
|
+
netFlow: number;
|
|
129
|
+
dailyPnl: number;
|
|
130
|
+
dailyPnlPct: number;
|
|
131
|
+
cumulativePnl: number;
|
|
132
|
+
utilization: number;
|
|
133
|
+
txCount: number;
|
|
134
|
+
activeUsers: number;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// ── Positions ────────────────────────────────────────────────────────────────
|
|
138
|
+
|
|
139
|
+
export interface ForexPosition {
|
|
140
|
+
id: string;
|
|
141
|
+
pairId: string;
|
|
142
|
+
side: 'BUY' | 'SELL';
|
|
143
|
+
lots: number;
|
|
144
|
+
pips: number;
|
|
145
|
+
entryPrice: number;
|
|
146
|
+
currentPrice: number;
|
|
147
|
+
pnl: number;
|
|
148
|
+
openTime: number;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// ── Investment ───────────────────────────────────────────────────────────────
|
|
152
|
+
|
|
153
|
+
export interface ForexInvestment {
|
|
154
|
+
id: string;
|
|
155
|
+
userId?: string;
|
|
156
|
+
amount: number;
|
|
157
|
+
currentValue: number;
|
|
158
|
+
profit: number;
|
|
159
|
+
status: 'active' | 'completed' | 'pending' | 'redeemed' | 'cancelled';
|
|
160
|
+
selectedPairs: string[];
|
|
161
|
+
cycleDays: number;
|
|
162
|
+
cycleOption: ForexCycleOption;
|
|
163
|
+
feeRate?: number;
|
|
164
|
+
commissionRate?: number;
|
|
165
|
+
startDate: string;
|
|
166
|
+
endDate: string;
|
|
167
|
+
tradingCapital: number;
|
|
168
|
+
totalPoolReserves: number;
|
|
169
|
+
poolAllocations: {
|
|
170
|
+
clearing: number;
|
|
171
|
+
hedging: number;
|
|
172
|
+
insurance: number;
|
|
173
|
+
};
|
|
174
|
+
tradeWeight: number;
|
|
175
|
+
totalLots: number;
|
|
176
|
+
totalPips: number;
|
|
177
|
+
totalTrades: number;
|
|
178
|
+
positions: ForexPosition[];
|
|
179
|
+
tradeHistory: ForexTradeRecord[];
|
|
180
|
+
redeemedAt?: string;
|
|
181
|
+
createdAt?: string;
|
|
182
|
+
updatedAt?: string;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ── Trade Records ────────────────────────────────────────────────────────────
|
|
186
|
+
|
|
187
|
+
export type ForexTradeStatus = 'RFQ' | 'QUOTED' | 'MATCHED' | 'SETTLED' | 'FAILED';
|
|
188
|
+
|
|
189
|
+
export interface ForexTradeRecord {
|
|
190
|
+
id: string;
|
|
191
|
+
timestamp: number;
|
|
192
|
+
pairId: string;
|
|
193
|
+
pairSymbol: string;
|
|
194
|
+
side: 'BUY' | 'SELL';
|
|
195
|
+
rfqPrice: number;
|
|
196
|
+
quotePrice: number;
|
|
197
|
+
matchPrice: number;
|
|
198
|
+
settlePrice: number;
|
|
199
|
+
lots: number;
|
|
200
|
+
pips: number;
|
|
201
|
+
pnl: number;
|
|
202
|
+
status: ForexTradeStatus;
|
|
203
|
+
pvpSettled: boolean;
|
|
204
|
+
clearingFee?: number;
|
|
205
|
+
hedgingCost?: number;
|
|
206
|
+
insuranceReserve?: number;
|
|
207
|
+
txHash?: string;
|
|
208
|
+
blockNumber?: number;
|
|
209
|
+
cycleDay?: number;
|
|
210
|
+
cumulativePnl?: number;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// ── Console Log Types ────────────────────────────────────────────────────────
|
|
214
|
+
|
|
215
|
+
export type ForexLogType =
|
|
216
|
+
| 'RFQ' | 'QUOTE' | 'MATCH' | 'SETTLE' | 'PVP'
|
|
217
|
+
| 'HEDGE' | 'CLEAR' | 'POSITION' | 'PNL' | 'SYSTEM';
|
|
218
|
+
|
|
219
|
+
export interface ForexLogEntry {
|
|
220
|
+
id: string;
|
|
221
|
+
timestamp: number;
|
|
222
|
+
type: ForexLogType;
|
|
223
|
+
message: string;
|
|
224
|
+
data?: Record<string, any>;
|
|
225
|
+
importance: 'low' | 'medium' | 'high';
|
|
226
|
+
pairId?: string;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// ── Agent ────────────────────────────────────────────────────────────────────
|
|
230
|
+
|
|
231
|
+
export interface ForexAgent {
|
|
232
|
+
id: string;
|
|
233
|
+
nameKey: string;
|
|
234
|
+
descriptionKey: string;
|
|
235
|
+
icon: string;
|
|
236
|
+
color: string;
|
|
237
|
+
supportedPairs: string[];
|
|
238
|
+
dailyRoiMin: number;
|
|
239
|
+
dailyRoiMax: number;
|
|
240
|
+
totalManaged: number;
|
|
241
|
+
totalUsers: number;
|
|
242
|
+
winRate: number;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export const FOREX_AGENT: ForexAgent = {
|
|
246
|
+
id: 'stablefx-01',
|
|
247
|
+
nameKey: 'forex.agent_name',
|
|
248
|
+
descriptionKey: 'forex.agent_description',
|
|
249
|
+
icon: '\u{1F4B1}',
|
|
250
|
+
color: '#0EA5E9',
|
|
251
|
+
supportedPairs: FOREX_CURRENCY_PAIRS.map(p => p.id),
|
|
252
|
+
dailyRoiMin: 0.002,
|
|
253
|
+
dailyRoiMax: 0.005,
|
|
254
|
+
totalManaged: 25000000,
|
|
255
|
+
totalUsers: 3847,
|
|
256
|
+
winRate: 72.5,
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
// ── Profit Calculation ───────────────────────────────────────────────────────
|
|
260
|
+
|
|
261
|
+
export function calculateForexNetProfit(
|
|
262
|
+
grossProfit: number,
|
|
263
|
+
cycleOption: ForexCycleOption,
|
|
264
|
+
): { feeAmount: number; postFeeProfit: number; netProfit: number } {
|
|
265
|
+
const feeAmount = grossProfit * cycleOption.feeRate;
|
|
266
|
+
const postFeeProfit = grossProfit - feeAmount;
|
|
267
|
+
const netProfit = postFeeProfit * cycleOption.commissionRate;
|
|
268
|
+
return { feeAmount, postFeeProfit, netProfit };
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export function estimateForexProfit(
|
|
272
|
+
amount: number,
|
|
273
|
+
cycleDays: number,
|
|
274
|
+
agent: ForexAgent = FOREX_AGENT,
|
|
275
|
+
): { grossProfit: number; feeAmount: number; netProfit: number; dailyRate: number } {
|
|
276
|
+
const cycleOption = FOREX_CYCLE_OPTIONS.find(c => c.days === cycleDays) || FOREX_CYCLE_OPTIONS[0];
|
|
277
|
+
const estimatedApy = ((agent.dailyRoiMin + agent.dailyRoiMax) / 2) * 365 * 100;
|
|
278
|
+
const dailyRate = estimatedApy / 100 / 365;
|
|
279
|
+
const grossProfit = amount * dailyRate * cycleDays;
|
|
280
|
+
const { feeAmount, netProfit } = calculateForexNetProfit(grossProfit, cycleOption);
|
|
281
|
+
return { grossProfit, feeAmount, netProfit, dailyRate };
|
|
282
|
+
}
|