@steerprotocol/strategy-utils 3.1.1 → 3.1.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/assembly/utils/triggers.ts +206 -59
- package/package.json +1 -1
|
@@ -9,28 +9,39 @@ import { Position } from "./types";
|
|
|
9
9
|
// if (!shouldTriggerExecution(trigger, triggerObj, _positions, _currentTick, _timeSinceLastExecution)) return 'continue'
|
|
10
10
|
|
|
11
11
|
// Gets active range from the output of LM.getPositions()
|
|
12
|
-
export function parseActiveRange(_positions: string): Position {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
12
|
+
// export function parseActiveRange(_positions: string): Position {
|
|
13
|
+
// // _positions will be '[[#,#,#],[#,#,#],[#,#,#]]' presumably. lower, upper, weight
|
|
14
|
+
// // clean up our list by removing spaces and brackets
|
|
15
|
+
// let positions = _positions.replaceAll(' ','');
|
|
16
|
+
// positions = positions.replaceAll('[','');
|
|
17
|
+
// let rangeArray = positions.split(']',2);
|
|
18
|
+
// let startTick = rangeArray[0].split(',')[0];
|
|
19
|
+
// let endRange = rangeArray[1].split(']',2);
|
|
20
|
+
// const endTicks = endRange[0].split(',');
|
|
21
|
+
// let endTick = endTicks[endTicks.length-1]
|
|
22
|
+
// // if trailing comma
|
|
23
|
+
// if (endTick == '') endTick = endTicks[endTicks.length-2]
|
|
24
|
+
// const strArrays = [startTick, endTick];
|
|
25
|
+
// // check null
|
|
26
|
+
// if (strArrays[0] == '' || strArrays[0] == null || strArrays[1] == '' || strArrays[1] == null) {
|
|
27
|
+
// return new Position(0, 0, 0);
|
|
28
|
+
// }
|
|
29
|
+
// // else return normal
|
|
30
|
+
// const lowerTick = i32(parseInt(strArrays[0]));
|
|
31
|
+
// const upperTick = i32(parseInt(strArrays[1]));
|
|
32
|
+
// // weights shouldn't matter in this context, we just want the total active range
|
|
33
|
+
// return new Position(lowerTick, upperTick, 100);
|
|
34
|
+
// }
|
|
35
|
+
|
|
36
|
+
export function parseActiveRange(_positions: Array<Position>): Position {
|
|
37
|
+
|
|
38
|
+
if (_positions.length == 0) return new Position(0, 0, 0);
|
|
39
|
+
// get first pos start tick and last pos end
|
|
40
|
+
let startTick = _positions[0].startTick
|
|
41
|
+
let endTick = _positions[_positions.length - 1].endTick
|
|
42
|
+
|
|
32
43
|
// weights shouldn't matter in this context, we just want the total active range
|
|
33
|
-
return new Position(
|
|
44
|
+
return new Position(startTick, endTick, 100);
|
|
34
45
|
}
|
|
35
46
|
|
|
36
47
|
export function emptyCurrentPosition(currentPosition: Position): boolean {
|
|
@@ -191,9 +202,9 @@ export function getTriggerExpectedDataTypes(triggerStyle: string): string[] {
|
|
|
191
202
|
export function shouldTriggerExecution(
|
|
192
203
|
_triggerStyle: string,
|
|
193
204
|
triggerOptions: TriggerConfigHelper,
|
|
194
|
-
dataConnector1:
|
|
195
|
-
dataConnector2:
|
|
196
|
-
dataConnector3:
|
|
205
|
+
dataConnector1: Array<Position>,
|
|
206
|
+
dataConnector2: i64,
|
|
207
|
+
dataConnector3: i64) : boolean {
|
|
197
208
|
|
|
198
209
|
// possible dc inputs
|
|
199
210
|
let currentPositionRange: Position;
|
|
@@ -208,34 +219,34 @@ export function shouldTriggerExecution(
|
|
|
208
219
|
case TriggerStyle.DistanceFromCenterOfPositions:
|
|
209
220
|
// parse ulm positions [0], current tick [1]
|
|
210
221
|
// @ts-ignore
|
|
211
|
-
timeSinceLastExecution = i64(
|
|
222
|
+
timeSinceLastExecution = i64((dataConnector3))
|
|
212
223
|
if (timeSinceLastExecution >= i64(triggerOptions.elapsedTendTime)) return true
|
|
213
224
|
currentPositionRange = parseActiveRange(dataConnector1)
|
|
214
|
-
currentTick = i64(
|
|
225
|
+
currentTick = i64((dataConnector2))
|
|
215
226
|
return triggerFromDistance(currentPositionRange, triggerOptions.tickDistanceFromCenter, currentTick)
|
|
216
227
|
|
|
217
228
|
case TriggerStyle.PercentageChangeFromPositionRange:
|
|
218
229
|
// parse ulm positions [0], current tick [1]
|
|
219
|
-
timeSinceLastExecution = i64(
|
|
230
|
+
timeSinceLastExecution = i64((dataConnector3))
|
|
220
231
|
if (timeSinceLastExecution >= i64(triggerOptions.elapsedTendTime)) return true
|
|
221
232
|
currentPositionRange= parseActiveRange(dataConnector1)
|
|
222
|
-
currentTick = i64(
|
|
233
|
+
currentTick = i64((dataConnector2))
|
|
223
234
|
return triggerFromPercentage(currentPositionRange, triggerOptions.percentageOfPositionRangeToTrigger, currentTick)
|
|
224
235
|
|
|
225
236
|
case TriggerStyle.PositionsInactive:
|
|
226
237
|
// parse ulm positions [0], current tick [1]
|
|
227
|
-
timeSinceLastExecution = i64(
|
|
238
|
+
timeSinceLastExecution = i64((dataConnector3))
|
|
228
239
|
if (timeSinceLastExecution >= i64(triggerOptions.elapsedTendTime)) return true
|
|
229
240
|
currentPositionRange = parseActiveRange(dataConnector1)
|
|
230
|
-
currentTick = i64(
|
|
241
|
+
currentTick = i64((dataConnector2))
|
|
231
242
|
return triggerPositionsInactive(currentPositionRange, currentTick)
|
|
232
243
|
|
|
233
244
|
case TriggerStyle.PricePastPositions:
|
|
234
245
|
// parse ulm positions [0], current tick [1]
|
|
235
|
-
timeSinceLastExecution = i64(
|
|
246
|
+
timeSinceLastExecution = i64((dataConnector3))
|
|
236
247
|
if (timeSinceLastExecution >= i64(triggerOptions.elapsedTendTime)) return true
|
|
237
248
|
currentPositionRange = parseActiveRange(dataConnector1)
|
|
238
|
-
currentTick = i64(
|
|
249
|
+
currentTick = i64((dataConnector2))
|
|
239
250
|
return triggerPricePastPositions(currentPositionRange, currentTick, triggerOptions.triggerWhenOver)
|
|
240
251
|
default:
|
|
241
252
|
return true
|
|
@@ -281,17 +292,18 @@ function getTriggerName(trigger: TriggerStyle): string {
|
|
|
281
292
|
// }`
|
|
282
293
|
}
|
|
283
294
|
|
|
284
|
-
@serializable
|
|
285
|
-
export class TriggerInfo {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
export function triggerPropertyHelper(
|
|
295
|
+
// @serializable
|
|
296
|
+
// export class TriggerInfo {
|
|
297
|
+
// name: string = '';
|
|
298
|
+
// expectedDataTypes: string[] = [];
|
|
299
|
+
// constructor (_name: string, _expectedDataTypes: string[]) {
|
|
300
|
+
// this.name = _name
|
|
301
|
+
// this.expectedDataTypes = _expectedDataTypes
|
|
302
|
+
// }
|
|
303
|
+
// }
|
|
304
|
+
|
|
305
|
+
export function triggerPropertyHelper(): string {
|
|
306
|
+
// export function triggerPropertyHelper(strategyDataTypes: string[], omit: TriggerStyle[] = []): string {
|
|
295
307
|
// const triggerList = [
|
|
296
308
|
// TriggerStyle.DistanceFromCenterOfPositions,
|
|
297
309
|
// TriggerStyle.None,
|
|
@@ -300,12 +312,12 @@ export function triggerPropertyHelper(strategyDataTypes: string[], omit: Trigger
|
|
|
300
312
|
// TriggerStyle.PricePastPositions,
|
|
301
313
|
// ];
|
|
302
314
|
|
|
303
|
-
const triggersObjects:
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
315
|
+
const triggersObjects: string[] = [
|
|
316
|
+
'Current Price set distance from center of positions',
|
|
317
|
+
'Price leaves active range',
|
|
318
|
+
'Price moves percentage of active range away',
|
|
319
|
+
'Price moves one way past positions',
|
|
320
|
+
'None',
|
|
309
321
|
];
|
|
310
322
|
|
|
311
323
|
const triggerStrings = [
|
|
@@ -316,20 +328,155 @@ export function triggerPropertyHelper(strategyDataTypes: string[], omit: Trigger
|
|
|
316
328
|
'None'
|
|
317
329
|
]
|
|
318
330
|
|
|
331
|
+
// return `"triggerStyle": {
|
|
332
|
+
// "enumNames": ${JSON.stringify(triggerStrings)},
|
|
333
|
+
// "enum": ${JSON.stringify(triggersObjects)},
|
|
334
|
+
// "type": "string",
|
|
335
|
+
// "title": "Logic to trigger new positions",
|
|
336
|
+
// "default": "None"
|
|
337
|
+
// }`;
|
|
338
|
+
|
|
319
339
|
return `"triggerStyle": {
|
|
320
|
-
"enumNames":
|
|
321
|
-
|
|
340
|
+
"enumNames": [
|
|
341
|
+
"Trigger when price moves set distance away from center of liquidity range",
|
|
342
|
+
"Trigger when price leaves active liquidity range",
|
|
343
|
+
"Trigger when price moves a proportion of active liquidity range away",
|
|
344
|
+
"Trigger when price moves out of active range only in one direction",
|
|
345
|
+
"None"
|
|
346
|
+
],
|
|
347
|
+
"enum": [
|
|
348
|
+
"Current Price set distance from center of positions",
|
|
349
|
+
"Price leaves active range",
|
|
350
|
+
"Price moves percentage of active range away",
|
|
351
|
+
"Price moves one way past positions",
|
|
352
|
+
"None"
|
|
353
|
+
],
|
|
354
|
+
"type": "string",
|
|
322
355
|
"title": "Logic to trigger new positions",
|
|
323
|
-
"default":
|
|
324
|
-
|
|
356
|
+
"default": "None"
|
|
357
|
+
}`
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
export function configDefinitions(): string {
|
|
361
|
+
return `
|
|
362
|
+
"elapsedTendTime": {
|
|
363
|
+
"type": "number",
|
|
364
|
+
"title": "Max time between tends",
|
|
365
|
+
"description": "If trigger conditions have not been met for this period of time, the strategy will execute regardless of trigger logic to update vault accounting.",
|
|
366
|
+
"default": 1209600
|
|
367
|
+
},
|
|
368
|
+
"bins": {
|
|
369
|
+
"type": "number",
|
|
370
|
+
"title": "Positions",
|
|
371
|
+
"description": "The max number of positions the strategy will make to achieve the desired curve.",
|
|
372
|
+
"detailedDescription": "The strategy will attempt to make this number of positions, but can be limited by available range and pool spacing"
|
|
373
|
+
},
|
|
374
|
+
"reflect": {
|
|
375
|
+
"title": "Reflect Curve Over Y-Axis",
|
|
376
|
+
"type": "boolean",
|
|
377
|
+
"default": false
|
|
378
|
+
},
|
|
379
|
+
"invert": {
|
|
380
|
+
"title": "Invert Curve Over X-Axis",
|
|
381
|
+
"type": "boolean",
|
|
382
|
+
"default": false
|
|
383
|
+
}`
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
export function triggerDependency(): string {
|
|
387
|
+
return `"triggerStyle": {
|
|
388
|
+
"oneOf": [
|
|
389
|
+
{
|
|
390
|
+
"properties": {
|
|
391
|
+
"triggerStyle": {
|
|
392
|
+
"const": "None"
|
|
393
|
+
}
|
|
394
|
+
},
|
|
395
|
+
"required": []
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
"properties": {
|
|
399
|
+
"triggerStyle": {
|
|
400
|
+
"const": "Current Price set distance from center of positions"
|
|
401
|
+
},
|
|
402
|
+
"tickDistanceFromCenter": {
|
|
403
|
+
"type": "integer",
|
|
404
|
+
"title": "Tick Distance",
|
|
405
|
+
"description": "The number of basis points (ticks) away from the central price of existing positions",
|
|
406
|
+
"detailedDescription": "The trigger mechanism for new positions is based on a fixed number of ticks from the midpoint of the active range. For instance, with a position range of 0-100 and a tick distance set at 75, the trigger points are calculated 75 ticks on either side of the central tick of our positions, which is 50. This establishes a trigger range extending from -25 to 125. Any current tick falling within this range will not prompt execution. The center of this trigger range is dynamically adjusted based on the locations of future positions."
|
|
407
|
+
},
|
|
408
|
+
"elapsedTendTime": {
|
|
409
|
+
"$ref": "#/definitions/elapsedTendTime"
|
|
410
|
+
}
|
|
411
|
+
},
|
|
412
|
+
"required": [
|
|
413
|
+
"tickDistanceFromCenter",
|
|
414
|
+
"elapsedTendTime"
|
|
415
|
+
]
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
"properties": {
|
|
419
|
+
"triggerStyle": {
|
|
420
|
+
"const": "Price leaves active range"
|
|
421
|
+
},
|
|
422
|
+
"elapsedTendTime": {
|
|
423
|
+
"$ref": "#/definitions/elapsedTendTime"
|
|
424
|
+
}
|
|
425
|
+
},
|
|
426
|
+
"required": [
|
|
427
|
+
"elapsedTendTime"
|
|
428
|
+
]
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
"properties": {
|
|
432
|
+
"triggerStyle": {
|
|
433
|
+
"const": "Price moves percentage of active range away"
|
|
434
|
+
},
|
|
435
|
+
"percentageOfPositionRangeToTrigger": {
|
|
436
|
+
"type": "number",
|
|
437
|
+
"title": "Percentage of Range",
|
|
438
|
+
"description": "Specify the percentage of the total range at which to initiate new positions, where 100% or a value of 1 corresponds to the edge of the range.",
|
|
439
|
+
"detailedDescription": "For a position with a range spanning from 0 to 100 ticks, setting this value to 1 will activate the trigger at the outermost bounds of the range. If the value is set to 0.5, the trigger range narrows to between 25 and 75 ticks. Conversely, setting the value to 2 expands the trigger range, extending it from -50 to 150 ticks."
|
|
440
|
+
},
|
|
441
|
+
"elapsedTendTime": {
|
|
442
|
+
"$ref": "#/definitions/elapsedTendTime"
|
|
443
|
+
}
|
|
444
|
+
},
|
|
445
|
+
"required": [
|
|
446
|
+
"percentageOfPositionRangeToTrigger",
|
|
447
|
+
"elapsedTendTime"
|
|
448
|
+
]
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
"properties": {
|
|
452
|
+
"triggerStyle": {
|
|
453
|
+
"const": "Price moves one way past positions"
|
|
454
|
+
},
|
|
455
|
+
"triggerWhenOver": {
|
|
456
|
+
"type": "boolean",
|
|
457
|
+
"title": "Price Moves Higher",
|
|
458
|
+
"description": "Set 'True' to initiate new positions when the current price (tick) exceeds the level of existing positions. Conversely, mark it as 'False' if new positions should be established when the price is lower than the current positions.",
|
|
459
|
+
"detailedDescription": "When the existing position spans from 0 to 100 ticks, setting the parameter to 'True' will prompt the strategy to execute only if the current tick exceeds 100. In any scenario where the current tick is less than or equal to 100, the strategy will recommend to continue without executing new execution."
|
|
460
|
+
},
|
|
461
|
+
"elapsedTendTime": {
|
|
462
|
+
"$ref": "#/definitions/elapsedTendTime"
|
|
463
|
+
}
|
|
464
|
+
},
|
|
465
|
+
"required": [
|
|
466
|
+
"triggerWhenOver",
|
|
467
|
+
"elapsedTendTime"
|
|
468
|
+
]
|
|
469
|
+
}
|
|
470
|
+
]
|
|
471
|
+
}`
|
|
325
472
|
}
|
|
326
473
|
|
|
327
|
-
export function allOfTrigger(
|
|
474
|
+
export function allOfTrigger(): string {
|
|
328
475
|
return `{
|
|
329
476
|
"if": {
|
|
330
477
|
"properties": {
|
|
331
478
|
"triggerStyle": {
|
|
332
|
-
"const":
|
|
479
|
+
"const": "None"
|
|
333
480
|
}
|
|
334
481
|
}
|
|
335
482
|
},
|
|
@@ -341,7 +488,7 @@ export function triggerPropertyHelper(strategyDataTypes: string[], omit: Trigger
|
|
|
341
488
|
"if": {
|
|
342
489
|
"properties": {
|
|
343
490
|
"triggerStyle": {
|
|
344
|
-
"const":
|
|
491
|
+
"const": "Current Price set distance from center of positions"
|
|
345
492
|
}
|
|
346
493
|
}
|
|
347
494
|
},
|
|
@@ -367,7 +514,7 @@ export function triggerPropertyHelper(strategyDataTypes: string[], omit: Trigger
|
|
|
367
514
|
"if": {
|
|
368
515
|
"properties": {
|
|
369
516
|
"triggerStyle": {
|
|
370
|
-
"const":
|
|
517
|
+
"const": "Price leaves active range"
|
|
371
518
|
}
|
|
372
519
|
}
|
|
373
520
|
},
|
|
@@ -387,7 +534,7 @@ export function triggerPropertyHelper(strategyDataTypes: string[], omit: Trigger
|
|
|
387
534
|
"if": {
|
|
388
535
|
"properties": {
|
|
389
536
|
"triggerStyle": {
|
|
390
|
-
"const":
|
|
537
|
+
"const": "Price moves percentage of active range away"
|
|
391
538
|
}
|
|
392
539
|
}
|
|
393
540
|
},
|
|
@@ -413,7 +560,7 @@ export function triggerPropertyHelper(strategyDataTypes: string[], omit: Trigger
|
|
|
413
560
|
"if": {
|
|
414
561
|
"properties": {
|
|
415
562
|
"triggerStyle": {
|
|
416
|
-
"const":
|
|
563
|
+
"const": "Price moves one way past positions"
|
|
417
564
|
}
|
|
418
565
|
}
|
|
419
566
|
},
|