@autonomaai/agent-core 1.0.2
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/dist/base-agent.d.ts +112 -0
- package/dist/base-agent.d.ts.map +1 -0
- package/dist/base-agent.js +173 -0
- package/dist/base-agent.js.map +1 -0
- package/dist/core.d.ts +81 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +633 -0
- package/dist/core.js.map +1 -0
- package/dist/error-handler.d.ts +78 -0
- package/dist/error-handler.d.ts.map +1 -0
- package/dist/error-handler.js +129 -0
- package/dist/error-handler.js.map +1 -0
- package/dist/factory.d.ts +60 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +621 -0
- package/dist/factory.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/streaming.d.ts +24 -0
- package/dist/streaming.d.ts.map +1 -0
- package/dist/streaming.js +36 -0
- package/dist/streaming.js.map +1 -0
- package/dist/trading/formatters.d.ts +167 -0
- package/dist/trading/formatters.d.ts.map +1 -0
- package/dist/trading/formatters.js +271 -0
- package/dist/trading/formatters.js.map +1 -0
- package/dist/trading/index.d.ts +9 -0
- package/dist/trading/index.d.ts.map +1 -0
- package/dist/trading/index.js +10 -0
- package/dist/trading/index.js.map +1 -0
- package/dist/trading/types.d.ts +205 -0
- package/dist/trading/types.d.ts.map +1 -0
- package/dist/trading/types.js +7 -0
- package/dist/trading/types.js.map +1 -0
- package/dist/trading/utils.d.ts +120 -0
- package/dist/trading/utils.d.ts.map +1 -0
- package/dist/trading/utils.js +291 -0
- package/dist/trading/utils.js.map +1 -0
- package/dist/trading/validation.d.ts +40 -0
- package/dist/trading/validation.d.ts.map +1 -0
- package/dist/trading/validation.js +247 -0
- package/dist/trading/validation.js.map +1 -0
- package/dist/types.d.ts +282 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +21 -0
- package/dist/types.js.map +1 -0
- package/package.json +57 -0
- package/src/base-agent.ts +263 -0
- package/src/core.ts +792 -0
- package/src/error-handler.ts +166 -0
- package/src/factory.ts +687 -0
- package/src/global.d.ts +12 -0
- package/src/index.ts +24 -0
- package/src/streaming.ts +50 -0
- package/src/trading/formatters.ts +363 -0
- package/src/trading/index.ts +10 -0
- package/src/trading/types.ts +263 -0
- package/src/trading/utils.ts +355 -0
- package/src/trading/validation.ts +321 -0
- package/src/types.ts +402 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @autonoma/agent-core
|
|
3
|
+
*
|
|
4
|
+
* Standardized agent core for autonoma AI trading platform.
|
|
5
|
+
* Provides consistent agent architecture with LangGraph + AgentKit integration.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Core agent implementation
|
|
9
|
+
export { StandardAgent, AgentUtils } from './core.js';
|
|
10
|
+
|
|
11
|
+
// Base agent class for reusability
|
|
12
|
+
export { BaseAgent } from './base-agent.js';
|
|
13
|
+
|
|
14
|
+
// Agent factory functions
|
|
15
|
+
export * from './factory.js';
|
|
16
|
+
|
|
17
|
+
// Type definitions
|
|
18
|
+
export * from './types.js';
|
|
19
|
+
|
|
20
|
+
// Streaming helpers
|
|
21
|
+
export * from './streaming.js';
|
|
22
|
+
|
|
23
|
+
// Standardized error handling
|
|
24
|
+
export * from './error-handler.js';
|
package/src/streaming.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight streaming event store for agents.
|
|
3
|
+
* Agents publish partial responses so external subscribers can poll for streaming updates.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export type StreamingEventType = 'start' | 'progress' | 'done' | 'error';
|
|
7
|
+
|
|
8
|
+
export interface StreamingEvent {
|
|
9
|
+
sessionId: string;
|
|
10
|
+
type: StreamingEventType;
|
|
11
|
+
content: string;
|
|
12
|
+
timestamp: string;
|
|
13
|
+
metadata?: Record<string, any>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
class StreamingService {
|
|
17
|
+
private events = new Map<string, StreamingEvent[]>();
|
|
18
|
+
private readonly maxEventsPerSession = 50;
|
|
19
|
+
|
|
20
|
+
publish(sessionId: string, event: Omit<StreamingEvent, 'sessionId' | 'timestamp'> & { timestamp?: string }): void {
|
|
21
|
+
const timestamp = event.timestamp || new Date().toISOString();
|
|
22
|
+
const payload: StreamingEvent = {
|
|
23
|
+
sessionId,
|
|
24
|
+
content: event.content,
|
|
25
|
+
type: event.type,
|
|
26
|
+
metadata: event.metadata,
|
|
27
|
+
timestamp
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const existing = this.events.get(sessionId) || [];
|
|
31
|
+
existing.push(payload);
|
|
32
|
+
if (existing.length > this.maxEventsPerSession) {
|
|
33
|
+
existing.shift();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
this.events.set(sessionId, existing);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
consume(sessionId: string): StreamingEvent[] {
|
|
40
|
+
const stored = this.events.get(sessionId) || [];
|
|
41
|
+
this.events.delete(sessionId);
|
|
42
|
+
return stored;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
clear(sessionId: string): void {
|
|
46
|
+
this.events.delete(sessionId);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const streamingService = new StreamingService();
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trading Formatters for autonoma Agent Core
|
|
3
|
+
*
|
|
4
|
+
* Formatting utilities for displaying trading data in a consistent manner.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Order, Position, Portfolio, TokenPrice, YieldOpportunity } from './types.js';
|
|
8
|
+
|
|
9
|
+
// =============================================================================
|
|
10
|
+
// Number Formatting
|
|
11
|
+
// =============================================================================
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Format currency amount with appropriate decimal places
|
|
15
|
+
*/
|
|
16
|
+
export function formatCurrency(
|
|
17
|
+
amount: number,
|
|
18
|
+
currency: string = 'USD',
|
|
19
|
+
decimals?: number
|
|
20
|
+
): string {
|
|
21
|
+
// Auto-determine decimal places based on amount
|
|
22
|
+
if (decimals === undefined) {
|
|
23
|
+
if (amount >= 1000) decimals = 0;
|
|
24
|
+
else if (amount >= 1) decimals = 2;
|
|
25
|
+
else if (amount >= 0.01) decimals = 4;
|
|
26
|
+
else decimals = 8;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return new Intl.NumberFormat('en-US', {
|
|
30
|
+
style: 'currency',
|
|
31
|
+
currency: currency,
|
|
32
|
+
minimumFractionDigits: decimals,
|
|
33
|
+
maximumFractionDigits: decimals
|
|
34
|
+
}).format(amount);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Format cryptocurrency amount with appropriate precision
|
|
39
|
+
*/
|
|
40
|
+
export function formatCrypto(amount: number, symbol: string, decimals?: number): string {
|
|
41
|
+
if (decimals === undefined) {
|
|
42
|
+
// Common crypto decimal places
|
|
43
|
+
const cryptoDecimals: Record<string, number> = {
|
|
44
|
+
'BTC': 8,
|
|
45
|
+
'ETH': 6,
|
|
46
|
+
'USDT': 2,
|
|
47
|
+
'USDC': 2,
|
|
48
|
+
'BNB': 4,
|
|
49
|
+
'SOL': 4,
|
|
50
|
+
'ADA': 6,
|
|
51
|
+
'DOT': 4
|
|
52
|
+
};
|
|
53
|
+
decimals = cryptoDecimals[symbol.toUpperCase()] || 6;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return `${amount.toFixed(decimals)} ${symbol}`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Format percentage with color coding
|
|
61
|
+
*/
|
|
62
|
+
export function formatPercentage(
|
|
63
|
+
value: number,
|
|
64
|
+
decimals: number = 2,
|
|
65
|
+
showSign: boolean = true
|
|
66
|
+
): { text: string; color: 'green' | 'red' | 'gray' } {
|
|
67
|
+
const sign = showSign && value >= 0 ? '+' : '';
|
|
68
|
+
const text = `${sign}${value.toFixed(decimals)}%`;
|
|
69
|
+
|
|
70
|
+
let color: 'green' | 'red' | 'gray';
|
|
71
|
+
if (value > 0) color = 'green';
|
|
72
|
+
else if (value < 0) color = 'red';
|
|
73
|
+
else color = 'gray';
|
|
74
|
+
|
|
75
|
+
return { text, color };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Format large numbers with appropriate units (K, M, B)
|
|
80
|
+
*/
|
|
81
|
+
export function formatLargeNumber(value: number, decimals: number = 1): string {
|
|
82
|
+
const units = [
|
|
83
|
+
{ threshold: 1e12, suffix: 'T' },
|
|
84
|
+
{ threshold: 1e9, suffix: 'B' },
|
|
85
|
+
{ threshold: 1e6, suffix: 'M' },
|
|
86
|
+
{ threshold: 1e3, suffix: 'K' }
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
for (const unit of units) {
|
|
90
|
+
if (Math.abs(value) >= unit.threshold) {
|
|
91
|
+
return `${(value / unit.threshold).toFixed(decimals)}${unit.suffix}`;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return value.toFixed(decimals);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// =============================================================================
|
|
99
|
+
// Date & Time Formatting
|
|
100
|
+
// =============================================================================
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Format date for trading displays
|
|
104
|
+
*/
|
|
105
|
+
export function formatTradingDate(date: Date): string {
|
|
106
|
+
return new Intl.DateTimeFormat('en-US', {
|
|
107
|
+
month: 'short',
|
|
108
|
+
day: '2-digit',
|
|
109
|
+
hour: '2-digit',
|
|
110
|
+
minute: '2-digit',
|
|
111
|
+
hour12: false
|
|
112
|
+
}).format(date);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Format relative time (e.g., "2 minutes ago")
|
|
117
|
+
*/
|
|
118
|
+
export function formatRelativeTime(date: Date): string {
|
|
119
|
+
const now = new Date();
|
|
120
|
+
const diffMs = now.getTime() - date.getTime();
|
|
121
|
+
const diffSeconds = Math.floor(diffMs / 1000);
|
|
122
|
+
const diffMinutes = Math.floor(diffSeconds / 60);
|
|
123
|
+
const diffHours = Math.floor(diffMinutes / 60);
|
|
124
|
+
const diffDays = Math.floor(diffHours / 24);
|
|
125
|
+
|
|
126
|
+
if (diffSeconds < 60) return 'just now';
|
|
127
|
+
if (diffMinutes < 60) return `${diffMinutes}m ago`;
|
|
128
|
+
if (diffHours < 24) return `${diffHours}h ago`;
|
|
129
|
+
if (diffDays < 7) return `${diffDays}d ago`;
|
|
130
|
+
|
|
131
|
+
return formatTradingDate(date);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Format duration in human readable format
|
|
136
|
+
*/
|
|
137
|
+
export function formatDuration(milliseconds: number): string {
|
|
138
|
+
const seconds = Math.floor(milliseconds / 1000);
|
|
139
|
+
const minutes = Math.floor(seconds / 60);
|
|
140
|
+
const hours = Math.floor(minutes / 60);
|
|
141
|
+
const days = Math.floor(hours / 24);
|
|
142
|
+
|
|
143
|
+
if (days > 0) return `${days}d ${hours % 24}h`;
|
|
144
|
+
if (hours > 0) return `${hours}h ${minutes % 60}m`;
|
|
145
|
+
if (minutes > 0) return `${minutes}m ${seconds % 60}s`;
|
|
146
|
+
return `${seconds}s`;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// =============================================================================
|
|
150
|
+
// Trading Object Formatting
|
|
151
|
+
// =============================================================================
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Format order for display
|
|
155
|
+
*/
|
|
156
|
+
export function formatOrder(order: Order): {
|
|
157
|
+
id: string;
|
|
158
|
+
symbol: string;
|
|
159
|
+
side: string;
|
|
160
|
+
type: string;
|
|
161
|
+
amount: string;
|
|
162
|
+
price: string;
|
|
163
|
+
status: string;
|
|
164
|
+
filled: string;
|
|
165
|
+
time: string;
|
|
166
|
+
} {
|
|
167
|
+
return {
|
|
168
|
+
id: order.id.slice(0, 8),
|
|
169
|
+
symbol: order.symbol,
|
|
170
|
+
side: order.side.toUpperCase(),
|
|
171
|
+
type: order.type.toUpperCase(),
|
|
172
|
+
amount: formatCrypto(order.quantity, order.symbol.split('/')[0] ?? ''),
|
|
173
|
+
price: order.price ? formatCurrency(order.price) : 'Market',
|
|
174
|
+
status: order.status.toUpperCase(),
|
|
175
|
+
filled: `${((order.filledQuantity / order.quantity) * 100).toFixed(1)}%`,
|
|
176
|
+
time: formatRelativeTime(order.createdAt)
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Format position for display
|
|
182
|
+
*/
|
|
183
|
+
export function formatPosition(position: Position): {
|
|
184
|
+
symbol: string;
|
|
185
|
+
quantity: string;
|
|
186
|
+
avgPrice: string;
|
|
187
|
+
marketValue: string;
|
|
188
|
+
pnl: { text: string; color: 'green' | 'red' | 'gray' };
|
|
189
|
+
change: { text: string; color: 'green' | 'red' | 'gray' };
|
|
190
|
+
} {
|
|
191
|
+
const currentPrice = position.marketValue / position.quantity;
|
|
192
|
+
const change = ((currentPrice - position.averagePrice) / position.averagePrice) * 100;
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
symbol: position.symbol,
|
|
196
|
+
quantity: formatCrypto(position.quantity, position.symbol.split('/')[0] ?? ''),
|
|
197
|
+
avgPrice: formatCurrency(position.averagePrice),
|
|
198
|
+
marketValue: formatCurrency(position.marketValue),
|
|
199
|
+
pnl: formatPercentage(position.unrealizedPnL),
|
|
200
|
+
change: formatPercentage(change)
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Format portfolio summary
|
|
206
|
+
*/
|
|
207
|
+
export function formatPortfolioSummary(portfolio: Portfolio): {
|
|
208
|
+
totalValue: string;
|
|
209
|
+
cash: string;
|
|
210
|
+
invested: string;
|
|
211
|
+
dayPnL: { text: string; color: 'green' | 'red' | 'gray' };
|
|
212
|
+
totalPnL: { text: string; color: 'green' | 'red' | 'gray' };
|
|
213
|
+
lastUpdate: string;
|
|
214
|
+
} {
|
|
215
|
+
const investedValue = portfolio.totalValue - portfolio.cash;
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
totalValue: formatCurrency(portfolio.totalValue),
|
|
219
|
+
cash: formatCurrency(portfolio.cash),
|
|
220
|
+
invested: formatCurrency(investedValue),
|
|
221
|
+
dayPnL: formatPercentage(portfolio.dayPnL),
|
|
222
|
+
totalPnL: formatPercentage(portfolio.totalPnL),
|
|
223
|
+
lastUpdate: formatRelativeTime(portfolio.lastUpdate)
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Format token price for display
|
|
229
|
+
*/
|
|
230
|
+
export function formatTokenPrice(price: TokenPrice): {
|
|
231
|
+
symbol: string;
|
|
232
|
+
price: string;
|
|
233
|
+
change: { text: string; color: 'green' | 'red' | 'gray' };
|
|
234
|
+
volume: string;
|
|
235
|
+
marketCap: string;
|
|
236
|
+
lastUpdate: string;
|
|
237
|
+
} {
|
|
238
|
+
return {
|
|
239
|
+
symbol: price.symbol,
|
|
240
|
+
price: formatCurrency(price.price),
|
|
241
|
+
change: formatPercentage(price.change24h),
|
|
242
|
+
volume: formatLargeNumber(price.volume24h),
|
|
243
|
+
marketCap: price.marketCap ? formatLargeNumber(price.marketCap) : 'N/A',
|
|
244
|
+
lastUpdate: formatRelativeTime(price.timestamp)
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Format yield opportunity for display
|
|
250
|
+
*/
|
|
251
|
+
export function formatYieldOpportunity(opportunity: YieldOpportunity): {
|
|
252
|
+
protocol: string;
|
|
253
|
+
pool: string;
|
|
254
|
+
apy: { text: string; color: 'green' | 'red' | 'gray' };
|
|
255
|
+
tvl: string;
|
|
256
|
+
risk: { text: string; color: 'green' | 'yellow' | 'red' };
|
|
257
|
+
category: string;
|
|
258
|
+
blockchain: string;
|
|
259
|
+
minDeposit: string;
|
|
260
|
+
} {
|
|
261
|
+
const riskColors = {
|
|
262
|
+
low: 'green' as const,
|
|
263
|
+
medium: 'yellow' as const,
|
|
264
|
+
high: 'red' as const
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
return {
|
|
268
|
+
protocol: opportunity.protocol,
|
|
269
|
+
pool: opportunity.pool,
|
|
270
|
+
apy: { text: `${opportunity.apy.toFixed(2)}%`, color: 'green' },
|
|
271
|
+
tvl: formatLargeNumber(opportunity.tvl),
|
|
272
|
+
risk: { text: opportunity.risk.toUpperCase(), color: riskColors[opportunity.risk] },
|
|
273
|
+
category: opportunity.category.charAt(0).toUpperCase() + opportunity.category.slice(1),
|
|
274
|
+
blockchain: opportunity.blockchain,
|
|
275
|
+
minDeposit: opportunity.minimumDeposit ? formatCurrency(opportunity.minimumDeposit) : 'No minimum'
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// =============================================================================
|
|
280
|
+
// Status & Badge Formatting
|
|
281
|
+
// =============================================================================
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Format order status with color coding
|
|
285
|
+
*/
|
|
286
|
+
export function formatOrderStatus(status: string): {
|
|
287
|
+
text: string;
|
|
288
|
+
color: 'green' | 'yellow' | 'red' | 'blue' | 'gray';
|
|
289
|
+
} {
|
|
290
|
+
const statusMap = {
|
|
291
|
+
pending: { text: 'PENDING', color: 'yellow' as const },
|
|
292
|
+
open: { text: 'OPEN', color: 'blue' as const },
|
|
293
|
+
filled: { text: 'FILLED', color: 'green' as const },
|
|
294
|
+
canceled: { text: 'CANCELED', color: 'gray' as const },
|
|
295
|
+
rejected: { text: 'REJECTED', color: 'red' as const }
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
return statusMap[status.toLowerCase() as keyof typeof statusMap] ||
|
|
299
|
+
{ text: status.toUpperCase(), color: 'gray' };
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Format risk level with color coding
|
|
304
|
+
*/
|
|
305
|
+
export function formatRiskLevel(risk: string): {
|
|
306
|
+
text: string;
|
|
307
|
+
color: 'green' | 'yellow' | 'red';
|
|
308
|
+
icon: string;
|
|
309
|
+
} {
|
|
310
|
+
const riskMap = {
|
|
311
|
+
low: { text: 'LOW RISK', color: 'green' as const, icon: '🟢' },
|
|
312
|
+
medium: { text: 'MEDIUM RISK', color: 'yellow' as const, icon: '🟡' },
|
|
313
|
+
high: { text: 'HIGH RISK', color: 'red' as const, icon: '🔴' }
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
return riskMap[risk.toLowerCase() as keyof typeof riskMap] ||
|
|
317
|
+
{ text: risk.toUpperCase(), color: 'yellow', icon: '⚪' };
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// =============================================================================
|
|
321
|
+
// Chart Data Formatting
|
|
322
|
+
// =============================================================================
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Format data for chart display
|
|
326
|
+
*/
|
|
327
|
+
export function formatChartData(
|
|
328
|
+
data: Array<{ timestamp: Date; value: number }>,
|
|
329
|
+
type: 'price' | 'percentage' | 'volume'
|
|
330
|
+
): Array<{ x: string; y: number; formatted: string }> {
|
|
331
|
+
return data.map(point => ({
|
|
332
|
+
x: point.timestamp.toISOString(),
|
|
333
|
+
y: point.value,
|
|
334
|
+
formatted: type === 'price' ? formatCurrency(point.value) :
|
|
335
|
+
type === 'percentage' ? formatPercentage(point.value).text :
|
|
336
|
+
formatLargeNumber(point.value)
|
|
337
|
+
}));
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Format trading session summary
|
|
342
|
+
*/
|
|
343
|
+
export function formatTradingSession(session: {
|
|
344
|
+
duration: number;
|
|
345
|
+
trades: number;
|
|
346
|
+
pnl: number;
|
|
347
|
+
winRate: number;
|
|
348
|
+
avgTradeSize: number;
|
|
349
|
+
}): {
|
|
350
|
+
duration: string;
|
|
351
|
+
trades: string;
|
|
352
|
+
pnl: { text: string; color: 'green' | 'red' | 'gray' };
|
|
353
|
+
winRate: { text: string; color: 'green' | 'red' | 'gray' };
|
|
354
|
+
avgTradeSize: string;
|
|
355
|
+
} {
|
|
356
|
+
return {
|
|
357
|
+
duration: formatDuration(session.duration),
|
|
358
|
+
trades: session.trades.toString(),
|
|
359
|
+
pnl: formatPercentage(session.pnl),
|
|
360
|
+
winRate: formatPercentage(session.winRate, 1),
|
|
361
|
+
avgTradeSize: formatCurrency(session.avgTradeSize)
|
|
362
|
+
};
|
|
363
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trading Utilities for autonoma Agents
|
|
3
|
+
*
|
|
4
|
+
* Common trading functions, types, and utilities used across trading agents.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export * from './types.js';
|
|
8
|
+
export * from './utils.js';
|
|
9
|
+
export * from './validation.js';
|
|
10
|
+
// Formatters exports removed to avoid conflicts with utils
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trading Types for autonoma Agent Core
|
|
3
|
+
*
|
|
4
|
+
* Standardized trading types used across all trading agents.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// =============================================================================
|
|
8
|
+
// Market Data Types
|
|
9
|
+
// =============================================================================
|
|
10
|
+
|
|
11
|
+
export interface TokenPrice {
|
|
12
|
+
symbol: string;
|
|
13
|
+
price: number;
|
|
14
|
+
change24h: number;
|
|
15
|
+
volume24h: number;
|
|
16
|
+
marketCap?: number;
|
|
17
|
+
timestamp: Date;
|
|
18
|
+
source: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface OHLCV {
|
|
22
|
+
open: number;
|
|
23
|
+
high: number;
|
|
24
|
+
low: number;
|
|
25
|
+
close: number;
|
|
26
|
+
volume: number;
|
|
27
|
+
timestamp: Date;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface OrderBook {
|
|
31
|
+
symbol: string;
|
|
32
|
+
bids: OrderBookLevel[];
|
|
33
|
+
asks: OrderBookLevel[];
|
|
34
|
+
timestamp: Date;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface OrderBookLevel {
|
|
38
|
+
price: number;
|
|
39
|
+
quantity: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// =============================================================================
|
|
43
|
+
// Trading Order Types
|
|
44
|
+
// =============================================================================
|
|
45
|
+
|
|
46
|
+
export type OrderSide = 'buy' | 'sell';
|
|
47
|
+
export type OrderType = 'market' | 'limit' | 'stop' | 'stop-limit';
|
|
48
|
+
export type OrderStatus = 'pending' | 'open' | 'filled' | 'canceled' | 'rejected';
|
|
49
|
+
export type TimeInForce = 'GTC' | 'IOC' | 'FOK' | 'DAY';
|
|
50
|
+
|
|
51
|
+
export interface Order {
|
|
52
|
+
id: string;
|
|
53
|
+
symbol: string;
|
|
54
|
+
side: OrderSide;
|
|
55
|
+
type: OrderType;
|
|
56
|
+
quantity: number;
|
|
57
|
+
price?: number;
|
|
58
|
+
stopPrice?: number;
|
|
59
|
+
timeInForce: TimeInForce;
|
|
60
|
+
status: OrderStatus;
|
|
61
|
+
filledQuantity: number;
|
|
62
|
+
averagePrice?: number;
|
|
63
|
+
createdAt: Date;
|
|
64
|
+
updatedAt: Date;
|
|
65
|
+
exchange: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface OrderRequest {
|
|
69
|
+
symbol: string;
|
|
70
|
+
side: OrderSide;
|
|
71
|
+
type: OrderType;
|
|
72
|
+
quantity: number;
|
|
73
|
+
price?: number;
|
|
74
|
+
stopPrice?: number;
|
|
75
|
+
timeInForce?: TimeInForce;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// =============================================================================
|
|
79
|
+
// Portfolio & Position Types
|
|
80
|
+
// =============================================================================
|
|
81
|
+
|
|
82
|
+
export interface Position {
|
|
83
|
+
symbol: string;
|
|
84
|
+
quantity: number;
|
|
85
|
+
averagePrice: number;
|
|
86
|
+
marketValue: number;
|
|
87
|
+
unrealizedPnL: number;
|
|
88
|
+
realizedPnL: number;
|
|
89
|
+
costBasis: number;
|
|
90
|
+
exchange: string;
|
|
91
|
+
lastUpdate: Date;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface Portfolio {
|
|
95
|
+
id: string;
|
|
96
|
+
totalValue: number;
|
|
97
|
+
cash: number;
|
|
98
|
+
positions: Position[];
|
|
99
|
+
totalPnL: number;
|
|
100
|
+
dayPnL: number;
|
|
101
|
+
lastUpdate: Date;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// =============================================================================
|
|
105
|
+
// DeFi Specific Types
|
|
106
|
+
// =============================================================================
|
|
107
|
+
|
|
108
|
+
export interface YieldOpportunity {
|
|
109
|
+
protocol: string;
|
|
110
|
+
pool: string;
|
|
111
|
+
token: string;
|
|
112
|
+
apy: number;
|
|
113
|
+
tvl: number;
|
|
114
|
+
risk: 'low' | 'medium' | 'high';
|
|
115
|
+
blockchain: string;
|
|
116
|
+
category: 'lending' | 'liquidity' | 'staking' | 'farming';
|
|
117
|
+
minimumDeposit?: number;
|
|
118
|
+
lockPeriod?: number; // in days
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface LiquidityPool {
|
|
122
|
+
id: string;
|
|
123
|
+
protocol: string;
|
|
124
|
+
tokens: string[];
|
|
125
|
+
reserves: number[];
|
|
126
|
+
fee: number;
|
|
127
|
+
apy: number;
|
|
128
|
+
volume24h: number;
|
|
129
|
+
tvl: number;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface StakingPosition {
|
|
133
|
+
protocol: string;
|
|
134
|
+
token: string;
|
|
135
|
+
amount: number;
|
|
136
|
+
apy: number;
|
|
137
|
+
claimableRewards: number;
|
|
138
|
+
lockEndDate?: Date;
|
|
139
|
+
autoCompound: boolean;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// =============================================================================
|
|
143
|
+
// Risk Management Types
|
|
144
|
+
// =============================================================================
|
|
145
|
+
|
|
146
|
+
export interface RiskLimits {
|
|
147
|
+
maxPositionSize: number; // as percentage of portfolio
|
|
148
|
+
maxDailyLoss: number; // in USD
|
|
149
|
+
maxDrawdown: number; // as percentage
|
|
150
|
+
maxLeverage: number;
|
|
151
|
+
blacklistedSymbols: string[];
|
|
152
|
+
allowedExchanges: string[];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export interface RiskMetrics {
|
|
156
|
+
portfolioVar: number; // Value at Risk
|
|
157
|
+
sharpeRatio: number;
|
|
158
|
+
maxDrawdown: number;
|
|
159
|
+
volatility: number;
|
|
160
|
+
beta: number;
|
|
161
|
+
alpha: number;
|
|
162
|
+
positionConcentration: number;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// =============================================================================
|
|
166
|
+
// Trading Strategy Types
|
|
167
|
+
// =============================================================================
|
|
168
|
+
|
|
169
|
+
export interface StrategyConfig {
|
|
170
|
+
name: string;
|
|
171
|
+
type: 'market_making' | 'arbitrage' | 'yield_farming' | 'momentum' | 'mean_reversion';
|
|
172
|
+
enabled: boolean;
|
|
173
|
+
parameters: Record<string, any>;
|
|
174
|
+
riskLimits: RiskLimits;
|
|
175
|
+
targetAllocation: number; // percentage of portfolio
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export interface StrategyPerformance {
|
|
179
|
+
strategyName: string;
|
|
180
|
+
totalTrades: number;
|
|
181
|
+
winRate: number;
|
|
182
|
+
totalPnL: number;
|
|
183
|
+
sharpeRatio: number;
|
|
184
|
+
maxDrawdown: number;
|
|
185
|
+
averageHoldTime: number; // in hours
|
|
186
|
+
lastExecuted: Date;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// =============================================================================
|
|
190
|
+
// Exchange Integration Types
|
|
191
|
+
// =============================================================================
|
|
192
|
+
|
|
193
|
+
export interface ExchangeConfig {
|
|
194
|
+
name: string;
|
|
195
|
+
apiKey: string;
|
|
196
|
+
apiSecret: string;
|
|
197
|
+
passphrase?: string;
|
|
198
|
+
sandbox: boolean;
|
|
199
|
+
rateLimit: number; // requests per second
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export interface ExchangeStatus {
|
|
203
|
+
name: string;
|
|
204
|
+
connected: boolean;
|
|
205
|
+
lastHeartbeat: Date;
|
|
206
|
+
latency: number; // in milliseconds
|
|
207
|
+
orderCount24h: number;
|
|
208
|
+
rateLimitRemaining: number;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// =============================================================================
|
|
212
|
+
// Market Making Specific Types
|
|
213
|
+
// =============================================================================
|
|
214
|
+
|
|
215
|
+
export interface MarketMakingConfig {
|
|
216
|
+
symbol: string;
|
|
217
|
+
bidSpread: number; // as percentage
|
|
218
|
+
askSpread: number; // as percentage
|
|
219
|
+
orderAmount: number; // base currency
|
|
220
|
+
maxInventory: number;
|
|
221
|
+
skewFactor: number; // inventory skew adjustment
|
|
222
|
+
minOrderGap: number; // minimum gap between orders
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export interface SpreadAnalysis {
|
|
226
|
+
symbol: string;
|
|
227
|
+
currentSpread: number;
|
|
228
|
+
averageSpread24h: number;
|
|
229
|
+
spreadVolatility: number;
|
|
230
|
+
optimalSpread: number;
|
|
231
|
+
competitorAnalysis: {
|
|
232
|
+
topBid: number;
|
|
233
|
+
topAsk: number;
|
|
234
|
+
bidDepth: number;
|
|
235
|
+
askDepth: number;
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// =============================================================================
|
|
240
|
+
// Utility Types
|
|
241
|
+
// =============================================================================
|
|
242
|
+
|
|
243
|
+
export interface TimeFrame {
|
|
244
|
+
value: number;
|
|
245
|
+
unit: 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month';
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export interface PriceRange {
|
|
249
|
+
min: number;
|
|
250
|
+
max: number;
|
|
251
|
+
current: number;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export interface TradingSession {
|
|
255
|
+
id: string;
|
|
256
|
+
startTime: Date;
|
|
257
|
+
endTime?: Date;
|
|
258
|
+
initialBalance: number;
|
|
259
|
+
currentBalance: number;
|
|
260
|
+
totalTrades: number;
|
|
261
|
+
pnl: number;
|
|
262
|
+
strategies: string[];
|
|
263
|
+
}
|