@clawnch/clawncher-sdk 0.1.3 → 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/README.md +190 -0
- package/dist/analytics.d.ts +157 -0
- package/dist/analytics.d.ts.map +1 -0
- package/dist/analytics.js +468 -0
- package/dist/analytics.js.map +1 -0
- package/dist/api-deployer.d.ts.map +1 -1
- package/dist/api-deployer.js +38 -35
- package/dist/api-deployer.js.map +1 -1
- package/dist/claimer.d.ts.map +1 -1
- package/dist/claimer.js +9 -7
- package/dist/claimer.js.map +1 -1
- package/dist/errors.d.ts +13 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +50 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -1
- package/dist/liquidity.d.ts +13 -7
- package/dist/liquidity.d.ts.map +1 -1
- package/dist/liquidity.js +143 -46
- package/dist/liquidity.js.map +1 -1
- package/dist/orders.d.ts +338 -0
- package/dist/orders.d.ts.map +1 -0
- package/dist/orders.js +611 -0
- package/dist/orders.js.map +1 -0
- package/dist/permit2.d.ts +258 -0
- package/dist/permit2.d.ts.map +1 -0
- package/dist/permit2.js +520 -0
- package/dist/permit2.js.map +1 -0
- package/dist/price.d.ts +95 -0
- package/dist/price.d.ts.map +1 -0
- package/dist/price.js +207 -0
- package/dist/price.js.map +1 -0
- package/dist/swap.d.ts.map +1 -1
- package/dist/swap.js +21 -19
- package/dist/swap.js.map +1 -1
- package/dist/trader.d.ts +188 -0
- package/dist/trader.d.ts.map +1 -0
- package/dist/trader.js +277 -0
- package/dist/trader.js.map +1 -0
- package/dist/uniswap-abis.d.ts +525 -0
- package/dist/uniswap-abis.d.ts.map +1 -1
- package/dist/uniswap-abis.js +432 -1
- package/dist/uniswap-abis.js.map +1 -1
- package/dist/uniswap-chains.d.ts +77 -0
- package/dist/uniswap-chains.d.ts.map +1 -0
- package/dist/uniswap-chains.js +362 -0
- package/dist/uniswap-chains.js.map +1 -0
- package/dist/uniswap-quoter.d.ts +178 -0
- package/dist/uniswap-quoter.d.ts.map +1 -0
- package/dist/uniswap-quoter.js +432 -0
- package/dist/uniswap-quoter.js.map +1 -0
- package/dist/uniswap-trading.d.ts +203 -0
- package/dist/uniswap-trading.d.ts.map +1 -0
- package/dist/uniswap-trading.js +380 -0
- package/dist/uniswap-trading.js.map +1 -0
- package/dist/watcher.d.ts +117 -2
- package/dist/watcher.d.ts.map +1 -1
- package/dist/watcher.js +147 -2
- package/dist/watcher.js.map +1 -1
- package/package.json +3 -1
package/dist/orders.js
ADDED
|
@@ -0,0 +1,611 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ClawnchOrders — Conditional order engine for autonomous token management.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - Limit orders (buy/sell at a specific ETH price)
|
|
6
|
+
* - Stop-loss orders (sell if price drops below threshold)
|
|
7
|
+
* - Take-profit orders (sell if price rises above threshold)
|
|
8
|
+
* - DCA orders (recurring buys at fixed intervals)
|
|
9
|
+
* - Trailing stop orders (sell when price drops N% from its peak)
|
|
10
|
+
* - TWAP orders (split a large trade into N equal chunks over a time window)
|
|
11
|
+
* - Order chaining (automatically create follow-up orders when one executes)
|
|
12
|
+
*
|
|
13
|
+
* Risk management:
|
|
14
|
+
* - Per-trade risk caps (max % of portfolio per order)
|
|
15
|
+
* - Max drawdown circuit breaker (halt all orders if drawdown exceeds limit)
|
|
16
|
+
* - Cooldown periods (prevent rapid-fire execution after failures)
|
|
17
|
+
*
|
|
18
|
+
* Orders are pure data — they don't execute themselves. The agent's heartbeat
|
|
19
|
+
* checks pending orders against current prices and triggers execution.
|
|
20
|
+
*
|
|
21
|
+
* Storage is pluggable: pass a read/write interface for persistence.
|
|
22
|
+
* The Clawtomaton agent uses its StateStore; standalone users can use fs.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const orders = new ClawnchOrders(storage);
|
|
27
|
+
*
|
|
28
|
+
* // Trailing stop: sell 100% if price drops 15% from peak
|
|
29
|
+
* orders.create({
|
|
30
|
+
* type: 'trailing_stop',
|
|
31
|
+
* token: '0x...',
|
|
32
|
+
* triggerPriceEth: 0, // not used — trailingPct is the trigger
|
|
33
|
+
* action: { side: 'sell', amountPct: 100 },
|
|
34
|
+
* trailing: { pct: 15 },
|
|
35
|
+
* });
|
|
36
|
+
*
|
|
37
|
+
* // TWAP: buy 0.1 ETH worth of tokens, split into 10 chunks over 2 hours
|
|
38
|
+
* orders.create({
|
|
39
|
+
* type: 'twap',
|
|
40
|
+
* token: '0x...',
|
|
41
|
+
* triggerPriceEth: 0,
|
|
42
|
+
* action: { side: 'buy', amountRaw: '0.1' },
|
|
43
|
+
* twap: { totalChunks: 10, windowMs: 2 * 60 * 60 * 1000 },
|
|
44
|
+
* });
|
|
45
|
+
*
|
|
46
|
+
* // Chained: buy + auto-set stop-loss after fill
|
|
47
|
+
* orders.create({
|
|
48
|
+
* type: 'limit_buy',
|
|
49
|
+
* token: '0x...',
|
|
50
|
+
* triggerPriceEth: 0.000005,
|
|
51
|
+
* action: { side: 'buy', amountRaw: '0.01' },
|
|
52
|
+
* chain: [{
|
|
53
|
+
* type: 'stop_loss',
|
|
54
|
+
* triggerPriceEth: 0.000004,
|
|
55
|
+
* action: { side: 'sell', amountPct: 100 },
|
|
56
|
+
* }],
|
|
57
|
+
* });
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
// ============================================================================
|
|
61
|
+
// Default risk config
|
|
62
|
+
// ============================================================================
|
|
63
|
+
const DEFAULT_RISK_CONFIG = {
|
|
64
|
+
maxPositionPct: 25,
|
|
65
|
+
maxDrawdownPct: 30,
|
|
66
|
+
failureCooldownMs: 5 * 60 * 1000, // 5 minutes
|
|
67
|
+
maxExecutionsPerHour: 20,
|
|
68
|
+
circuitBreakerTripped: false,
|
|
69
|
+
circuitBreakerTrippedAt: 0,
|
|
70
|
+
peakPortfolioEth: 0,
|
|
71
|
+
recentExecutions: [],
|
|
72
|
+
lastFailureAt: 0,
|
|
73
|
+
};
|
|
74
|
+
// ============================================================================
|
|
75
|
+
// ClawnchOrders
|
|
76
|
+
// ============================================================================
|
|
77
|
+
export class ClawnchOrders {
|
|
78
|
+
storage;
|
|
79
|
+
riskStorage;
|
|
80
|
+
constructor(storage, riskStorage) {
|
|
81
|
+
this.storage = storage;
|
|
82
|
+
this.riskStorage = riskStorage ?? null;
|
|
83
|
+
}
|
|
84
|
+
// --------------------------------------------------------------------------
|
|
85
|
+
// Order CRUD
|
|
86
|
+
// --------------------------------------------------------------------------
|
|
87
|
+
/**
|
|
88
|
+
* Create a new order.
|
|
89
|
+
*
|
|
90
|
+
* @returns The created order
|
|
91
|
+
*/
|
|
92
|
+
create(params) {
|
|
93
|
+
const orders = this.storage.getOrders();
|
|
94
|
+
const id = `ord_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
95
|
+
// Build trailing stop config
|
|
96
|
+
let trailingConfig;
|
|
97
|
+
if (params.type === 'trailing_stop' && params.trailing) {
|
|
98
|
+
const initialPrice = params.currentPrice ?? params.triggerPriceEth;
|
|
99
|
+
trailingConfig = {
|
|
100
|
+
pct: params.trailing.pct,
|
|
101
|
+
highWaterMark: initialPrice,
|
|
102
|
+
currentTriggerPrice: initialPrice * (1 - params.trailing.pct / 100),
|
|
103
|
+
floorPriceEth: params.trailing.floorPriceEth,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
// Build TWAP config
|
|
107
|
+
let twapConfig;
|
|
108
|
+
if (params.type === 'twap' && params.twap) {
|
|
109
|
+
const totalAmount = parseFloat(params.action.amountRaw ?? '0');
|
|
110
|
+
const chunks = params.twap.totalChunks;
|
|
111
|
+
twapConfig = {
|
|
112
|
+
totalChunks: chunks,
|
|
113
|
+
chunksCompleted: 0,
|
|
114
|
+
windowMs: params.twap.windowMs,
|
|
115
|
+
chunkIntervalMs: Math.floor(params.twap.windowMs / chunks),
|
|
116
|
+
lastChunkAt: 0,
|
|
117
|
+
amountPerChunk: (totalAmount / chunks).toFixed(8),
|
|
118
|
+
maxPriceEth: params.twap.maxPriceEth,
|
|
119
|
+
minPriceEth: params.twap.minPriceEth,
|
|
120
|
+
startedAt: Date.now(),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
const order = {
|
|
124
|
+
id,
|
|
125
|
+
type: params.type,
|
|
126
|
+
status: 'pending',
|
|
127
|
+
token: params.token,
|
|
128
|
+
condition: {
|
|
129
|
+
token: params.token,
|
|
130
|
+
triggerPriceEth: params.triggerPriceEth,
|
|
131
|
+
},
|
|
132
|
+
action: params.action,
|
|
133
|
+
dca: params.dca
|
|
134
|
+
? { ...params.dca, buysCompleted: 0, lastBuyAt: 0 }
|
|
135
|
+
: undefined,
|
|
136
|
+
trailing: trailingConfig,
|
|
137
|
+
twap: twapConfig,
|
|
138
|
+
chain: params.chain,
|
|
139
|
+
createdAt: Date.now(),
|
|
140
|
+
lastCheckedAt: Date.now(),
|
|
141
|
+
executedAt: null,
|
|
142
|
+
expiresAt: params.expiresAt ?? null,
|
|
143
|
+
description: params.description ?? this.describeOrder(params.type, params.triggerPriceEth, params.action, params.trailing, params.twap),
|
|
144
|
+
tag: params.tag,
|
|
145
|
+
createdAtPrice: params.currentPrice,
|
|
146
|
+
};
|
|
147
|
+
orders.push(order);
|
|
148
|
+
this.storage.saveOrders(orders);
|
|
149
|
+
return order;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* List all orders, optionally filtered by status.
|
|
153
|
+
*/
|
|
154
|
+
list(status) {
|
|
155
|
+
const orders = this.storage.getOrders();
|
|
156
|
+
if (!status)
|
|
157
|
+
return orders;
|
|
158
|
+
return orders.filter(o => o.status === status);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* List orders by tag.
|
|
162
|
+
*/
|
|
163
|
+
listByTag(tag) {
|
|
164
|
+
return this.storage.getOrders().filter(o => o.tag === tag);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Cancel an order by ID.
|
|
168
|
+
*/
|
|
169
|
+
cancel(orderId) {
|
|
170
|
+
const orders = this.storage.getOrders();
|
|
171
|
+
const order = orders.find(o => o.id === orderId);
|
|
172
|
+
if (!order || (order.status !== 'pending' && order.status !== 'paused'))
|
|
173
|
+
return false;
|
|
174
|
+
order.status = 'cancelled';
|
|
175
|
+
this.storage.saveOrders(orders);
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Cancel all orders with a given tag.
|
|
180
|
+
*/
|
|
181
|
+
cancelByTag(tag) {
|
|
182
|
+
const orders = this.storage.getOrders();
|
|
183
|
+
let count = 0;
|
|
184
|
+
for (const order of orders) {
|
|
185
|
+
if (order.tag === tag && (order.status === 'pending' || order.status === 'paused')) {
|
|
186
|
+
order.status = 'cancelled';
|
|
187
|
+
count++;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (count > 0)
|
|
191
|
+
this.storage.saveOrders(orders);
|
|
192
|
+
return count;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Pause an order (prevents triggering until resumed).
|
|
196
|
+
*/
|
|
197
|
+
pause(orderId) {
|
|
198
|
+
const orders = this.storage.getOrders();
|
|
199
|
+
const order = orders.find(o => o.id === orderId);
|
|
200
|
+
if (!order || order.status !== 'pending')
|
|
201
|
+
return false;
|
|
202
|
+
order.status = 'paused';
|
|
203
|
+
this.storage.saveOrders(orders);
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Resume a paused order.
|
|
208
|
+
*/
|
|
209
|
+
resume(orderId) {
|
|
210
|
+
const orders = this.storage.getOrders();
|
|
211
|
+
const order = orders.find(o => o.id === orderId);
|
|
212
|
+
if (!order || order.status !== 'paused')
|
|
213
|
+
return false;
|
|
214
|
+
order.status = 'pending';
|
|
215
|
+
this.storage.saveOrders(orders);
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
// --------------------------------------------------------------------------
|
|
219
|
+
// Trigger checking
|
|
220
|
+
// --------------------------------------------------------------------------
|
|
221
|
+
/**
|
|
222
|
+
* Check all pending orders against the current price.
|
|
223
|
+
* Returns orders that should be executed NOW.
|
|
224
|
+
*
|
|
225
|
+
* Does NOT execute them — the caller (agent) does the actual swap.
|
|
226
|
+
*
|
|
227
|
+
* Side effects:
|
|
228
|
+
* - Updates trailing stop high-water marks
|
|
229
|
+
* - Expires orders past their expiry
|
|
230
|
+
* - Marks triggered orders as 'triggered'
|
|
231
|
+
* - Pauses TWAP chunks when price is outside bounds
|
|
232
|
+
*/
|
|
233
|
+
checkTriggers(currentPriceEth) {
|
|
234
|
+
const orders = this.storage.getOrders();
|
|
235
|
+
const now = Date.now();
|
|
236
|
+
const triggered = [];
|
|
237
|
+
// Risk check: if circuit breaker is tripped, return empty
|
|
238
|
+
if (this.isCircuitBreakerTripped()) {
|
|
239
|
+
this.storage.saveOrders(orders); // still save any expiry updates
|
|
240
|
+
return [];
|
|
241
|
+
}
|
|
242
|
+
// Risk check: rate limit
|
|
243
|
+
if (this.isRateLimited()) {
|
|
244
|
+
this.storage.saveOrders(orders);
|
|
245
|
+
return [];
|
|
246
|
+
}
|
|
247
|
+
// Risk check: cooldown after failure
|
|
248
|
+
if (this.isInCooldown()) {
|
|
249
|
+
this.storage.saveOrders(orders);
|
|
250
|
+
return [];
|
|
251
|
+
}
|
|
252
|
+
for (const order of orders) {
|
|
253
|
+
if (order.status !== 'pending')
|
|
254
|
+
continue;
|
|
255
|
+
// Check expiry
|
|
256
|
+
if (order.expiresAt !== null && now > order.expiresAt) {
|
|
257
|
+
order.status = 'expired';
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
order.lastCheckedAt = now;
|
|
261
|
+
switch (order.type) {
|
|
262
|
+
case 'limit_buy':
|
|
263
|
+
// Buy when price drops to or below trigger
|
|
264
|
+
if (currentPriceEth <= order.condition.triggerPriceEth) {
|
|
265
|
+
order.status = 'triggered';
|
|
266
|
+
triggered.push(order);
|
|
267
|
+
}
|
|
268
|
+
break;
|
|
269
|
+
case 'limit_sell':
|
|
270
|
+
case 'take_profit':
|
|
271
|
+
// Sell when price rises to or above trigger
|
|
272
|
+
if (currentPriceEth >= order.condition.triggerPriceEth) {
|
|
273
|
+
order.status = 'triggered';
|
|
274
|
+
triggered.push(order);
|
|
275
|
+
}
|
|
276
|
+
break;
|
|
277
|
+
case 'stop_loss':
|
|
278
|
+
// Sell when price drops to or below trigger
|
|
279
|
+
if (currentPriceEth <= order.condition.triggerPriceEth) {
|
|
280
|
+
order.status = 'triggered';
|
|
281
|
+
triggered.push(order);
|
|
282
|
+
}
|
|
283
|
+
break;
|
|
284
|
+
case 'dca':
|
|
285
|
+
// Execute if enough time has passed since last buy
|
|
286
|
+
if (order.dca) {
|
|
287
|
+
const timeSinceLastBuy = now - order.dca.lastBuyAt;
|
|
288
|
+
if (timeSinceLastBuy >= order.dca.intervalMs) {
|
|
289
|
+
// Check if max buys reached
|
|
290
|
+
if (order.dca.maxBuys !== null && order.dca.buysCompleted >= order.dca.maxBuys) {
|
|
291
|
+
order.status = 'executed'; // All buys done
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
order.status = 'triggered';
|
|
295
|
+
triggered.push(order);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
break;
|
|
300
|
+
case 'trailing_stop':
|
|
301
|
+
if (order.trailing) {
|
|
302
|
+
// Update high-water mark if price has risen
|
|
303
|
+
if (currentPriceEth > order.trailing.highWaterMark) {
|
|
304
|
+
order.trailing.highWaterMark = currentPriceEth;
|
|
305
|
+
order.trailing.currentTriggerPrice = currentPriceEth * (1 - order.trailing.pct / 100);
|
|
306
|
+
// Enforce floor
|
|
307
|
+
if (order.trailing.floorPriceEth != null && order.trailing.currentTriggerPrice < order.trailing.floorPriceEth) {
|
|
308
|
+
order.trailing.currentTriggerPrice = order.trailing.floorPriceEth;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
// Check if price has dropped below the trailing trigger
|
|
312
|
+
if (currentPriceEth <= order.trailing.currentTriggerPrice) {
|
|
313
|
+
order.status = 'triggered';
|
|
314
|
+
triggered.push(order);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
break;
|
|
318
|
+
case 'twap':
|
|
319
|
+
if (order.twap) {
|
|
320
|
+
// Check if TWAP window has expired
|
|
321
|
+
const windowEnd = order.twap.startedAt + order.twap.windowMs;
|
|
322
|
+
if (now > windowEnd && order.twap.chunksCompleted < order.twap.totalChunks) {
|
|
323
|
+
// Window expired but chunks remain — still trigger remaining chunks
|
|
324
|
+
// (agent can decide whether to execute or cancel)
|
|
325
|
+
}
|
|
326
|
+
// Check if all chunks done
|
|
327
|
+
if (order.twap.chunksCompleted >= order.twap.totalChunks) {
|
|
328
|
+
order.status = 'executed';
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
// Check time since last chunk
|
|
332
|
+
const timeSinceLastChunk = now - order.twap.lastChunkAt;
|
|
333
|
+
if (timeSinceLastChunk < order.twap.chunkIntervalMs)
|
|
334
|
+
break;
|
|
335
|
+
// Check price bounds
|
|
336
|
+
if (order.action.side === 'buy') {
|
|
337
|
+
// For buys: skip if price too high
|
|
338
|
+
if (order.twap.maxPriceEth != null && currentPriceEth > order.twap.maxPriceEth)
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
// For sells: skip if price too low
|
|
343
|
+
if (order.twap.minPriceEth != null && currentPriceEth < order.twap.minPriceEth)
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
order.status = 'triggered';
|
|
347
|
+
triggered.push(order);
|
|
348
|
+
}
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
this.storage.saveOrders(orders);
|
|
353
|
+
return triggered;
|
|
354
|
+
}
|
|
355
|
+
// --------------------------------------------------------------------------
|
|
356
|
+
// Execution lifecycle
|
|
357
|
+
// --------------------------------------------------------------------------
|
|
358
|
+
/**
|
|
359
|
+
* Mark an order as executed after the agent performs the swap.
|
|
360
|
+
* For recurring orders (DCA, TWAP), resets to pending if more iterations remain.
|
|
361
|
+
* Handles order chaining — creates follow-up orders automatically.
|
|
362
|
+
*
|
|
363
|
+
* @returns Array of newly created chained orders (empty if none)
|
|
364
|
+
*/
|
|
365
|
+
markExecuted(orderId, result) {
|
|
366
|
+
const orders = this.storage.getOrders();
|
|
367
|
+
const order = orders.find(o => o.id === orderId);
|
|
368
|
+
if (!order)
|
|
369
|
+
return [];
|
|
370
|
+
const chainedOrders = [];
|
|
371
|
+
if (order.type === 'dca' && order.dca) {
|
|
372
|
+
// DCA orders go back to pending after each buy
|
|
373
|
+
order.dca.buysCompleted++;
|
|
374
|
+
order.dca.lastBuyAt = Date.now();
|
|
375
|
+
order.executionResult = result;
|
|
376
|
+
if (order.dca.maxBuys !== null && order.dca.buysCompleted >= order.dca.maxBuys) {
|
|
377
|
+
order.status = 'executed'; // All buys done
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
order.status = 'pending'; // More buys to do
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
else if (order.type === 'twap' && order.twap) {
|
|
384
|
+
// TWAP: increment chunk counter
|
|
385
|
+
order.twap.chunksCompleted++;
|
|
386
|
+
order.twap.lastChunkAt = Date.now();
|
|
387
|
+
order.executionResult = result;
|
|
388
|
+
if (order.twap.chunksCompleted >= order.twap.totalChunks) {
|
|
389
|
+
order.status = 'executed'; // All chunks done
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
order.status = 'pending'; // More chunks to do
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
order.status = 'executed';
|
|
397
|
+
order.executedAt = Date.now();
|
|
398
|
+
order.executionResult = result;
|
|
399
|
+
}
|
|
400
|
+
// Record execution for rate limiting
|
|
401
|
+
this.recordExecution();
|
|
402
|
+
// Handle order chaining — create follow-up orders
|
|
403
|
+
if (order.chain && order.chain.length > 0 && order.status === 'executed') {
|
|
404
|
+
for (const chainDef of order.chain) {
|
|
405
|
+
const chainedOrder = this.create({
|
|
406
|
+
type: chainDef.type,
|
|
407
|
+
token: order.token,
|
|
408
|
+
triggerPriceEth: chainDef.triggerPriceEth,
|
|
409
|
+
action: chainDef.action,
|
|
410
|
+
trailing: chainDef.trailing,
|
|
411
|
+
expiresAt: chainDef.expiresAfterMs != null ? Date.now() + chainDef.expiresAfterMs : undefined,
|
|
412
|
+
description: chainDef.description ?? `[chained from ${order.id}] ${this.describeOrder(chainDef.type, chainDef.triggerPriceEth, chainDef.action, chainDef.trailing)}`,
|
|
413
|
+
tag: order.tag, // inherit parent tag
|
|
414
|
+
});
|
|
415
|
+
chainedOrders.push(chainedOrder);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
this.storage.saveOrders(orders);
|
|
419
|
+
return chainedOrders;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Mark a triggered order back as pending (e.g., if execution failed).
|
|
423
|
+
*/
|
|
424
|
+
markPending(orderId) {
|
|
425
|
+
const orders = this.storage.getOrders();
|
|
426
|
+
const order = orders.find(o => o.id === orderId);
|
|
427
|
+
if (!order || order.status !== 'triggered')
|
|
428
|
+
return;
|
|
429
|
+
order.status = 'pending';
|
|
430
|
+
this.storage.saveOrders(orders);
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Record a failed execution (for cooldown tracking).
|
|
434
|
+
*/
|
|
435
|
+
recordFailure() {
|
|
436
|
+
const risk = this.getRiskConfig();
|
|
437
|
+
risk.lastFailureAt = Date.now();
|
|
438
|
+
this.saveRiskConfig(risk);
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Remove all completed/cancelled/expired orders.
|
|
442
|
+
*/
|
|
443
|
+
cleanup() {
|
|
444
|
+
const orders = this.storage.getOrders();
|
|
445
|
+
const before = orders.length;
|
|
446
|
+
const active = orders.filter(o => o.status === 'pending' || o.status === 'triggered' || o.status === 'paused');
|
|
447
|
+
this.storage.saveOrders(active);
|
|
448
|
+
return before - active.length;
|
|
449
|
+
}
|
|
450
|
+
// --------------------------------------------------------------------------
|
|
451
|
+
// Risk management
|
|
452
|
+
// --------------------------------------------------------------------------
|
|
453
|
+
/**
|
|
454
|
+
* Get the current risk configuration.
|
|
455
|
+
*/
|
|
456
|
+
getRiskConfig() {
|
|
457
|
+
if (this.riskStorage) {
|
|
458
|
+
return this.riskStorage.getRiskConfig() ?? { ...DEFAULT_RISK_CONFIG };
|
|
459
|
+
}
|
|
460
|
+
return { ...DEFAULT_RISK_CONFIG };
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Update risk configuration.
|
|
464
|
+
*/
|
|
465
|
+
updateRiskConfig(updates) {
|
|
466
|
+
const config = this.getRiskConfig();
|
|
467
|
+
Object.assign(config, updates);
|
|
468
|
+
this.saveRiskConfig(config);
|
|
469
|
+
return config;
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Update peak portfolio value for drawdown tracking.
|
|
473
|
+
* Call this with the current portfolio ETH value on each heartbeat.
|
|
474
|
+
*/
|
|
475
|
+
updatePortfolioValue(currentValueEth) {
|
|
476
|
+
const risk = this.getRiskConfig();
|
|
477
|
+
// Update peak
|
|
478
|
+
if (currentValueEth > risk.peakPortfolioEth) {
|
|
479
|
+
risk.peakPortfolioEth = currentValueEth;
|
|
480
|
+
}
|
|
481
|
+
// Calculate drawdown
|
|
482
|
+
const drawdownPct = risk.peakPortfolioEth > 0
|
|
483
|
+
? ((risk.peakPortfolioEth - currentValueEth) / risk.peakPortfolioEth) * 100
|
|
484
|
+
: 0;
|
|
485
|
+
// Check circuit breaker
|
|
486
|
+
if (drawdownPct >= risk.maxDrawdownPct && !risk.circuitBreakerTripped) {
|
|
487
|
+
risk.circuitBreakerTripped = true;
|
|
488
|
+
risk.circuitBreakerTrippedAt = Date.now();
|
|
489
|
+
}
|
|
490
|
+
this.saveRiskConfig(risk);
|
|
491
|
+
return { drawdownPct, circuitBreakerTripped: risk.circuitBreakerTripped };
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Reset the circuit breaker (manual override by agent/user).
|
|
495
|
+
*/
|
|
496
|
+
resetCircuitBreaker() {
|
|
497
|
+
const risk = this.getRiskConfig();
|
|
498
|
+
risk.circuitBreakerTripped = false;
|
|
499
|
+
risk.circuitBreakerTrippedAt = 0;
|
|
500
|
+
// Reset peak to current (prevents immediate re-trip)
|
|
501
|
+
// Caller should provide current portfolio value if they want a new baseline
|
|
502
|
+
this.saveRiskConfig(risk);
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Check if a proposed order would exceed position size limits.
|
|
506
|
+
* @param amountEth - The ETH value of the proposed order
|
|
507
|
+
* @param portfolioEth - Current total portfolio value in ETH
|
|
508
|
+
* @returns true if the order is within limits
|
|
509
|
+
*/
|
|
510
|
+
checkPositionSize(amountEth, portfolioEth) {
|
|
511
|
+
const risk = this.getRiskConfig();
|
|
512
|
+
const maxAllowedEth = portfolioEth * (risk.maxPositionPct / 100);
|
|
513
|
+
if (amountEth > maxAllowedEth) {
|
|
514
|
+
return {
|
|
515
|
+
allowed: false,
|
|
516
|
+
reason: `Order size ${amountEth.toFixed(6)} ETH exceeds max position size ${maxAllowedEth.toFixed(6)} ETH (${risk.maxPositionPct}% of portfolio)`,
|
|
517
|
+
maxAllowedEth,
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
return { allowed: true, maxAllowedEth };
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Get a risk summary for display in agent prompt.
|
|
524
|
+
*/
|
|
525
|
+
getRiskSummary() {
|
|
526
|
+
const risk = this.getRiskConfig();
|
|
527
|
+
const lines = [];
|
|
528
|
+
if (risk.circuitBreakerTripped) {
|
|
529
|
+
lines.push(`CIRCUIT BREAKER TRIPPED at ${new Date(risk.circuitBreakerTrippedAt).toISOString()}`);
|
|
530
|
+
lines.push(`All orders halted. Use manage_orders action=reset_circuit_breaker to resume.`);
|
|
531
|
+
}
|
|
532
|
+
const drawdownPct = risk.peakPortfolioEth > 0
|
|
533
|
+
? `${((risk.peakPortfolioEth - risk.peakPortfolioEth) / risk.peakPortfolioEth * 100).toFixed(1)}%`
|
|
534
|
+
: 'N/A';
|
|
535
|
+
lines.push(`Peak portfolio: ${risk.peakPortfolioEth.toFixed(6)} ETH`);
|
|
536
|
+
lines.push(`Max position: ${risk.maxPositionPct}% | Max drawdown: ${risk.maxDrawdownPct}%`);
|
|
537
|
+
lines.push(`Rate limit: ${risk.recentExecutions.length}/${risk.maxExecutionsPerHour} executions/hr`);
|
|
538
|
+
if (risk.lastFailureAt > 0) {
|
|
539
|
+
const cooldownRemaining = Math.max(0, risk.failureCooldownMs - (Date.now() - risk.lastFailureAt));
|
|
540
|
+
if (cooldownRemaining > 0) {
|
|
541
|
+
lines.push(`Cooldown: ${Math.ceil(cooldownRemaining / 1000)}s remaining after last failure`);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
return lines.join('\n');
|
|
545
|
+
}
|
|
546
|
+
// --------------------------------------------------------------------------
|
|
547
|
+
// Internal risk helpers
|
|
548
|
+
// --------------------------------------------------------------------------
|
|
549
|
+
isCircuitBreakerTripped() {
|
|
550
|
+
const risk = this.getRiskConfig();
|
|
551
|
+
return risk.circuitBreakerTripped;
|
|
552
|
+
}
|
|
553
|
+
isRateLimited() {
|
|
554
|
+
const risk = this.getRiskConfig();
|
|
555
|
+
const oneHourAgo = Date.now() - 60 * 60 * 1000;
|
|
556
|
+
const recentCount = risk.recentExecutions.filter(t => t > oneHourAgo).length;
|
|
557
|
+
return recentCount >= risk.maxExecutionsPerHour;
|
|
558
|
+
}
|
|
559
|
+
isInCooldown() {
|
|
560
|
+
const risk = this.getRiskConfig();
|
|
561
|
+
if (risk.lastFailureAt === 0)
|
|
562
|
+
return false;
|
|
563
|
+
return Date.now() - risk.lastFailureAt < risk.failureCooldownMs;
|
|
564
|
+
}
|
|
565
|
+
recordExecution() {
|
|
566
|
+
if (!this.riskStorage)
|
|
567
|
+
return;
|
|
568
|
+
const risk = this.getRiskConfig();
|
|
569
|
+
risk.recentExecutions.push(Date.now());
|
|
570
|
+
// Keep only last hour
|
|
571
|
+
const oneHourAgo = Date.now() - 60 * 60 * 1000;
|
|
572
|
+
risk.recentExecutions = risk.recentExecutions.filter(t => t > oneHourAgo);
|
|
573
|
+
this.saveRiskConfig(risk);
|
|
574
|
+
}
|
|
575
|
+
saveRiskConfig(config) {
|
|
576
|
+
if (this.riskStorage) {
|
|
577
|
+
this.riskStorage.saveRiskConfig(config);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
// --------------------------------------------------------------------------
|
|
581
|
+
// Helpers
|
|
582
|
+
// --------------------------------------------------------------------------
|
|
583
|
+
describeOrder(type, triggerPrice, action, trailing, twap) {
|
|
584
|
+
const amt = action.amountPct ? `${action.amountPct}% of holdings` : action.amountRaw ?? '?';
|
|
585
|
+
switch (type) {
|
|
586
|
+
case 'limit_buy':
|
|
587
|
+
return `Buy ${amt} when price ≤ ${triggerPrice} ETH`;
|
|
588
|
+
case 'limit_sell':
|
|
589
|
+
return `Sell ${amt} when price ≥ ${triggerPrice} ETH`;
|
|
590
|
+
case 'stop_loss':
|
|
591
|
+
return `Stop-loss: sell ${amt} when price ≤ ${triggerPrice} ETH`;
|
|
592
|
+
case 'take_profit':
|
|
593
|
+
return `Take-profit: sell ${amt} when price ≥ ${triggerPrice} ETH`;
|
|
594
|
+
case 'dca':
|
|
595
|
+
return `DCA: buy ${amt} at intervals`;
|
|
596
|
+
case 'trailing_stop': {
|
|
597
|
+
const pct = trailing?.pct ?? '?';
|
|
598
|
+
const floor = trailing?.floorPriceEth != null ? ` (floor: ${trailing.floorPriceEth} ETH)` : '';
|
|
599
|
+
return `Trailing stop: sell ${amt} if price drops ${pct}% from peak${floor}`;
|
|
600
|
+
}
|
|
601
|
+
case 'twap': {
|
|
602
|
+
const chunks = twap?.totalChunks ?? '?';
|
|
603
|
+
const windowHrs = twap ? (twap.windowMs / (60 * 60 * 1000)).toFixed(1) : '?';
|
|
604
|
+
return `TWAP: ${action.side} ${amt} in ${chunks} chunks over ${windowHrs}h`;
|
|
605
|
+
}
|
|
606
|
+
default:
|
|
607
|
+
return `${type}: ${action.side} ${amt} at ${triggerPrice} ETH`;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
//# sourceMappingURL=orders.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orders.js","sourceRoot":"","sources":["../src/orders.ts"],"names":[],"mappings":"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"}
|