@senpi/runtime 3.0.118 → 3.0.123

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.
Files changed (89) hide show
  1. package/dist/actions/open-position/open-position.action.d.ts.map +1 -1
  2. package/dist/actions/open-position/open-position.action.js +9 -0
  3. package/dist/actions/open-position/open-position.action.js.map +1 -1
  4. package/dist/cli/guide-commands.d.ts.map +1 -1
  5. package/dist/cli/guide-commands.js +16 -8
  6. package/dist/cli/guide-commands.js.map +1 -1
  7. package/dist/constants/dsl/index.d.ts +17 -6
  8. package/dist/constants/dsl/index.d.ts.map +1 -1
  9. package/dist/constants/dsl/index.js +17 -6
  10. package/dist/constants/dsl/index.js.map +1 -1
  11. package/dist/dsl/engine/floors.d.ts +25 -1
  12. package/dist/dsl/engine/floors.d.ts.map +1 -1
  13. package/dist/dsl/engine/floors.js +38 -6
  14. package/dist/dsl/engine/floors.js.map +1 -1
  15. package/dist/dsl/engine/index.d.ts +1 -1
  16. package/dist/dsl/engine/index.d.ts.map +1 -1
  17. package/dist/dsl/engine/index.js +1 -1
  18. package/dist/dsl/engine/index.js.map +1 -1
  19. package/dist/dsl/engine/round.d.ts +22 -2
  20. package/dist/dsl/engine/round.d.ts.map +1 -1
  21. package/dist/dsl/engine/round.js +78 -5
  22. package/dist/dsl/engine/round.js.map +1 -1
  23. package/dist/dsl/engine/tick.d.ts.map +1 -1
  24. package/dist/dsl/engine/tick.js +31 -16
  25. package/dist/dsl/engine/tick.js.map +1 -1
  26. package/dist/dsl/events/initial-state.d.ts +1 -1
  27. package/dist/dsl/events/initial-state.d.ts.map +1 -1
  28. package/dist/dsl/events/initial-state.js +4 -7
  29. package/dist/dsl/events/initial-state.js.map +1 -1
  30. package/dist/dsl/monitor/exchange-sync.d.ts +8 -3
  31. package/dist/dsl/monitor/exchange-sync.d.ts.map +1 -1
  32. package/dist/dsl/monitor/exchange-sync.js +16 -4
  33. package/dist/dsl/monitor/exchange-sync.js.map +1 -1
  34. package/dist/dsl/monitor/process-one-position.d.ts.map +1 -1
  35. package/dist/dsl/monitor/process-one-position.js +88 -3
  36. package/dist/dsl/monitor/process-one-position.js.map +1 -1
  37. package/dist/dsl/plugin/index.d.ts +8 -4
  38. package/dist/dsl/plugin/index.d.ts.map +1 -1
  39. package/dist/dsl/plugin/index.js +8 -4
  40. package/dist/dsl/plugin/index.js.map +1 -1
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +168 -7
  43. package/dist/index.js.map +1 -1
  44. package/dist/runtime/boot-skip.d.ts +73 -0
  45. package/dist/runtime/boot-skip.d.ts.map +1 -0
  46. package/dist/runtime/boot-skip.js +113 -0
  47. package/dist/runtime/boot-skip.js.map +1 -0
  48. package/dist/runtime/create-runtime-context.d.ts +2 -0
  49. package/dist/runtime/create-runtime-context.d.ts.map +1 -1
  50. package/dist/runtime/create-runtime-context.js +1 -0
  51. package/dist/runtime/create-runtime-context.js.map +1 -1
  52. package/dist/runtime/lifecycle-events.d.ts +42 -1
  53. package/dist/runtime/lifecycle-events.d.ts.map +1 -1
  54. package/dist/runtime/lifecycle-events.js +81 -1
  55. package/dist/runtime/lifecycle-events.js.map +1 -1
  56. package/dist/runtime/lifecycle-reaper.d.ts +202 -0
  57. package/dist/runtime/lifecycle-reaper.d.ts.map +1 -0
  58. package/dist/runtime/lifecycle-reaper.js +390 -0
  59. package/dist/runtime/lifecycle-reaper.js.map +1 -0
  60. package/dist/runtime/run.d.ts +5 -0
  61. package/dist/runtime/run.d.ts.map +1 -1
  62. package/dist/runtime/run.js +1 -0
  63. package/dist/runtime/run.js.map +1 -1
  64. package/dist/runtime/runtime.d.ts +2 -0
  65. package/dist/runtime/runtime.d.ts.map +1 -1
  66. package/dist/runtime/runtime.js +1 -0
  67. package/dist/runtime/runtime.js.map +1 -1
  68. package/dist/runtime/update-apply-deps.d.ts +23 -2
  69. package/dist/runtime/update-apply-deps.d.ts.map +1 -1
  70. package/dist/runtime/update-apply-deps.js +11 -5
  71. package/dist/runtime/update-apply-deps.js.map +1 -1
  72. package/dist/skills-manager/manifest.d.ts.map +1 -1
  73. package/dist/skills-manager/manifest.js +1 -0
  74. package/dist/skills-manager/manifest.js.map +1 -1
  75. package/dist/skills-manager/skills-manifest.json +1 -0
  76. package/dist/types/dsl/index.d.ts +1 -1
  77. package/dist/types/dsl/index.d.ts.map +1 -1
  78. package/dist/types/runtime.d.ts +8 -0
  79. package/dist/types/runtime.d.ts.map +1 -1
  80. package/dist/utils/event-catalog.d.ts +91 -0
  81. package/dist/utils/event-catalog.d.ts.map +1 -1
  82. package/dist/utils/event-catalog.js +13 -0
  83. package/dist/utils/event-catalog.js.map +1 -1
  84. package/dist/utils/keyed-mutex.d.ts +3 -2
  85. package/dist/utils/keyed-mutex.d.ts.map +1 -1
  86. package/dist/utils/keyed-mutex.js +3 -2
  87. package/dist/utils/keyed-mutex.js.map +1 -1
  88. package/openclaw.plugin.json +1 -1
  89. package/package.json +1 -1
@@ -1,9 +1,82 @@
1
1
  /**
2
- * Price rounding for DSL price levels.
2
+ * Rounding for DSL protective price levels (stops).
3
3
  */
4
- import { PRICE_DECIMALS } from "../../constants/dsl/index.js";
5
- export function roundTo(value, decimals = PRICE_DECIMALS) {
6
- const f = 10 ** decimals;
7
- return Math.round(value * f) / f;
4
+ /** Hyperliquid's price rule: significant figures, then a per-asset decimal cap. */
5
+ const SIG_FIGS = 5;
6
+ /**
7
+ * `6 - szDecimals` is the perp decimal cap; 6 is its loosest value and the runtime has no
8
+ * per-asset `szDecimals`, so this is the tightest bound we can assert without one.
9
+ */
10
+ const MAX_DECIMALS = 6;
11
+ /** Decimal exponent of `value`, read off its shortest exponential form so no rounding can bump it. */
12
+ function decimalExponent(value) {
13
+ const s = value.toExponential();
14
+ return Number(s.slice(s.indexOf("e") + 1));
15
+ }
16
+ /**
17
+ * Quantise to `SIG_FIGS`, biased away from the mark.
18
+ *
19
+ * `Number(value.toPrecision(n))` is used rather than `Math.floor(value * 10 ** k)` because the
20
+ * latter carries binary floating-point artifacts (`8.29 * 1e4 === 82899.99999999999`) that
21
+ * silently drift the level by a tick. `toPrecision` gives the NEAREST grid value; we step one
22
+ * unit in the last place only when that landed on the wrong side.
23
+ */
24
+ function toSignificantFigures(value, roundDown) {
25
+ const nearest = Number(value.toPrecision(SIG_FIGS));
26
+ if (nearest === value)
27
+ return value;
28
+ const ulp = 10 ** (decimalExponent(value) - (SIG_FIGS - 1));
29
+ if (roundDown && nearest > value)
30
+ return Number((nearest - ulp).toPrecision(SIG_FIGS));
31
+ if (!roundDown && nearest < value)
32
+ return Number((nearest + ulp).toPrecision(SIG_FIGS));
33
+ return nearest;
34
+ }
35
+ /**
36
+ * Quantise to `MAX_DECIMALS`, biased away from the mark. Same nearest-then-step approach.
37
+ *
38
+ * Below the 1e-6 grid there is no representable protective level at all: rounding down gives 0,
39
+ * which is no stop, and rounding up gives 1e-6, which for a SHORT can sit multiples above the
40
+ * level asked for. Both are worse than passing the significant-figure value through and letting
41
+ * the venue's own validation answer. No Hyperliquid perp trades there, so this is a deliberate
42
+ * decision about an unreachable input rather than a supported price range — and it is why the
43
+ * "at most 6 decimals" guarantee is stated for inputs at or above 1e-6.
44
+ */
45
+ function toMaxDecimals(value, roundDown) {
46
+ const scale = 10 ** MAX_DECIMALS;
47
+ if (value < 1 / scale)
48
+ return value;
49
+ let units = Math.round(Number(value.toFixed(MAX_DECIMALS)) * scale);
50
+ if (roundDown && units / scale > value)
51
+ units -= 1;
52
+ if (!roundDown && units / scale < value)
53
+ units += 1;
54
+ return units / scale;
55
+ }
56
+ /**
57
+ * Round a protective price level onto Hyperliquid's price grid, biased AWAY from the mark.
58
+ *
59
+ * A LONG's stop sits below the mark so it rounds down; a SHORT's sits above so it rounds up.
60
+ * THIS service's rounding may then only ever loosen a stop, never tighten it and never move it
61
+ * across the mark: the trading engine rejects `slTriggerPrice >= currentPrice` for a LONG (and
62
+ * `<=` for a SHORT) as "would execute immediately", and a rejected stop leaves the position with
63
+ * no exchange-side protection at all.
64
+ *
65
+ * It is not an end-to-end guarantee. The trading engine re-rounds what we send with
66
+ * `roundToDecimals(price, 6 - szDecimals)`, which is round-to-NEAREST (`utils.go:133-136`), so
67
+ * for an asset whose `szDecimals` forces fewer than 6 decimals it can still move a LONG floor
68
+ * back up by half a venue tick. Reading per-asset `szDecimals` is what would close that; until
69
+ * then the residual degrades to a rejection, which the phase-2 breach path now turns into an
70
+ * exit rather than a silent no-stop.
71
+ *
72
+ * Non-finite, zero and negative inputs are returned unchanged — there is no meaningful grid
73
+ * for them, and silently manufacturing a level would be worse than passing the caller's own
74
+ * value through to its validation.
75
+ */
76
+ export function roundProtectiveLevel(value, direction) {
77
+ if (!Number.isFinite(value) || value <= 0)
78
+ return value;
79
+ const roundDown = direction === "LONG";
80
+ return toMaxDecimals(toSignificantFigures(value, roundDown), roundDown);
8
81
  }
9
82
  //# sourceMappingURL=round.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"round.js","sourceRoot":"","sources":["../../../src/dsl/engine/round.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,MAAM,UAAU,OAAO,CAAC,KAAa,EAAE,WAAmB,cAAc;IACtE,MAAM,CAAC,GAAG,EAAE,IAAI,QAAQ,CAAC;IACzB,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"round.js","sourceRoot":"","sources":["../../../src/dsl/engine/round.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,mFAAmF;AACnF,MAAM,QAAQ,GAAG,CAAC,CAAC;AACnB;;;GAGG;AACH,MAAM,YAAY,GAAG,CAAC,CAAC;AAEvB,sGAAsG;AACtG,SAAS,eAAe,CAAC,KAAa;IACpC,MAAM,CAAC,GAAG,KAAK,CAAC,aAAa,EAAE,CAAC;IAChC,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,oBAAoB,CAAC,KAAa,EAAE,SAAkB;IAC7D,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpD,IAAI,OAAO,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IACpC,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC;IAC5D,IAAI,SAAS,IAAI,OAAO,GAAG,KAAK;QAAE,OAAO,MAAM,CAAC,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;IACvF,IAAI,CAAC,SAAS,IAAI,OAAO,GAAG,KAAK;QAAE,OAAO,MAAM,CAAC,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,aAAa,CAAC,KAAa,EAAE,SAAkB;IACtD,MAAM,KAAK,GAAG,EAAE,IAAI,YAAY,CAAC;IACjC,IAAI,KAAK,GAAG,CAAC,GAAG,KAAK;QAAE,OAAO,KAAK,CAAC;IACpC,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;IACpE,IAAI,SAAS,IAAI,KAAK,GAAG,KAAK,GAAG,KAAK;QAAE,KAAK,IAAI,CAAC,CAAC;IACnD,IAAI,CAAC,SAAS,IAAI,KAAK,GAAG,KAAK,GAAG,KAAK;QAAE,KAAK,IAAI,CAAC,CAAC;IACpD,OAAO,KAAK,GAAG,KAAK,CAAC;AACvB,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAa,EAAE,SAA2B;IAC7E,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACxD,MAAM,SAAS,GAAG,SAAS,KAAK,MAAM,CAAC;IACvC,OAAO,aAAa,CAAC,oBAAoB,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC;AAC1E,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tick.d.ts","sourceRoot":"","sources":["../../../src/dsl/engine/tick.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAexE,wBAAgB,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,aAAa,CAyMlF"}
1
+ {"version":3,"file":"tick.d.ts","sourceRoot":"","sources":["../../../src/dsl/engine/tick.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAgBxE,wBAAgB,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,aAAa,CAwNlF"}
@@ -2,7 +2,7 @@
2
2
  * Pure DSL tick: state + price → next state and actions.
3
3
  */
4
4
  import { CLOSE_REASON } from "../../constants/dsl/index.js";
5
- import { computeCurrentROE, computeTierFloor, effectiveFloor, isBreach, resolveBreachesRequired, tierIndexFromPrice, } from "./floors.js";
5
+ import { computeCurrentROE, computeTierFloor, effectiveFloor, hasRestingStopAtFloor, isBreach, resolveBreachesRequired, tierIndexFromPrice, } from "./floors.js";
6
6
  import { updateHighWater, writeDerivedFields } from "./state-updates.js";
7
7
  import { createLogger } from "../../utils/logger.js";
8
8
  const log = createLogger("[senpi-core][dsl-tick]");
@@ -25,23 +25,38 @@ export function dslTick(state, price, now) {
25
25
  let closeReason;
26
26
  const newTierIndexForBreach = tierIndexFromPrice(next, price);
27
27
  const prevTierIndexForBreach = next.currentTierIndex ?? -1;
28
- if (next.phase === 1) {
29
- if (isBreach(next, price)) {
30
- const breachesRequired = resolveBreachesRequired(next);
31
- const newCount = (next.currentBreachCount ?? 0) + 1;
32
- next = { ...next, currentBreachCount: newCount };
33
- if (newCount >= breachesRequired) {
34
- action = "close";
35
- closeReason = CLOSE_REASON.DSL_BREACH;
36
- next = { ...next, floorPrice: prevFloorPrice };
37
- }
38
- }
39
- else {
40
- const advancingTier = newTierIndexForBreach > prevTierIndexForBreach;
41
- if (!advancingTier)
42
- next = { ...next, currentBreachCount: 0 };
28
+ // Breach detection runs in BOTH phases. In phase 2 the exchange stop is normally what exits,
29
+ // but a stop the venue rejected (a level rounded onto the mark, say) leaves the floor on the
30
+ // wrong side of the mark with nothing resting behind it — which is a breach by definition, and
31
+ // dsl-engine cannot close a position, so the runtime is the only thing that can. This sits
32
+ // ahead of the `handoffStatus === "ok"` early return so a backend-owned position surfaces a
33
+ // breach too; `consecutiveBreachesRequired` still gives a resting stop time to fill first.
34
+ //
35
+ // The breach is COUNTED either way; only the close is withheld when a stop is already resting
36
+ // at the floor. Raising a close there would return at the `action === "close"` early return
37
+ // below, which skips the time cuts, the tier advance and the floor recompute — and the whole
38
+ // downstream half of the monitor tick, SL sync and heartbeat included — on every tick the mark
39
+ // spends at or under the floor. A stale `slOrderId` (a stop cancelled at the venue is never
40
+ // cleared, since the tick's `getOrderStatus` check only clears on `filled`) would then take
41
+ // `hard_timeout` down with it.
42
+ if (isBreach(next, price)) {
43
+ const breachesRequired = resolveBreachesRequired(next);
44
+ // Clamped at the threshold. In phase 1 the close bounded this; in phase 2 a withheld close
45
+ // does not, and an unbounded counter renders as `18432/1` in `senpi dsl` and fires the
46
+ // `breach_detected` span event on every tick it grows.
47
+ const newCount = Math.min((next.currentBreachCount ?? 0) + 1, breachesRequired);
48
+ next = { ...next, currentBreachCount: newCount };
49
+ if (newCount >= breachesRequired && !hasRestingStopAtFloor(next)) {
50
+ action = "close";
51
+ closeReason = CLOSE_REASON.DSL_BREACH;
52
+ next = { ...next, floorPrice: prevFloorPrice };
43
53
  }
44
54
  }
55
+ else {
56
+ const advancingTier = newTierIndexForBreach > prevTierIndexForBreach;
57
+ if (!advancingTier)
58
+ next = { ...next, currentBreachCount: 0 };
59
+ }
45
60
  if (action === "none") {
46
61
  const currentROE = computeCurrentROE(next, price);
47
62
  if (next.hardTimeout?.enabled) {
@@ -1 +1 @@
1
- {"version":3,"file":"tick.js","sourceRoot":"","sources":["../../../src/dsl/engine/tick.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tick.js","sourceRoot":"","sources":["../../../src/dsl/engine/tick.ts"],"names":[],"mappings":"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"}
@@ -22,6 +22,6 @@ export interface NotifiedStopCarry {
22
22
  /** Breakeven latch; once true the "you can no longer lose" push is spent. */
23
23
  stopBreakevenAnnounced?: boolean;
24
24
  }
25
- export declare function phase1FloorFromPreset(entryPrice: number, direction: string, maxLossPct: number, leverage: number): number;
25
+ export declare function phase1FloorFromPreset(entryPrice: number, direction: "LONG" | "SHORT", maxLossPct: number, leverage: number): number;
26
26
  export declare function buildInitialState(event: PositionOpenedEvent, preset: DslPluginConfig["presets"][string], phase1Floor: number, triggerReason: DslCreatedTriggerReason, carry?: NotifiedStopCarry): DslState;
27
27
  //# sourceMappingURL=initial-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"initial-state.d.ts","sourceRoot":"","sources":["../../../src/dsl/events/initial-state.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EACV,uBAAuB,EACvB,eAAe,EACf,QAAQ,EACR,mBAAmB,EACpB,MAAM,0BAA0B,CAAC;AAYlC;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IAChC,2EAA2E;IAC3E,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uEAAuE;IACvE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,6EAA6E;IAC7E,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,MAAM,CAIR;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,mBAAmB,EAC1B,MAAM,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAC1C,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,uBAAuB,EACtC,KAAK,CAAC,EAAE,iBAAiB,GACxB,QAAQ,CA8FV"}
1
+ {"version":3,"file":"initial-state.d.ts","sourceRoot":"","sources":["../../../src/dsl/events/initial-state.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EACV,uBAAuB,EACvB,eAAe,EACf,QAAQ,EACR,mBAAmB,EACpB,MAAM,0BAA0B,CAAC;AAQlC;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IAChC,2EAA2E;IAC3E,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uEAAuE;IACvE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,6EAA6E;IAC7E,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAAG,OAAO,EAC3B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,MAAM,CAIR;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,mBAAmB,EAC1B,MAAM,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAC1C,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,uBAAuB,EACtC,KAAK,CAAC,EAAE,iBAAiB,GACxB,QAAQ,CA8FV"}
@@ -2,19 +2,16 @@
2
2
  * Build initial DslState from position.opened event and resolved preset.
3
3
  */
4
4
  import { randomUUID } from "node:crypto";
5
- import { DSL_STATE_VERSION, PRICE_DECIMALS } from "../../constants/dsl/index.js";
5
+ import { DSL_STATE_VERSION } from "../../constants/dsl/index.js";
6
+ import { roundProtectiveLevel } from "../engine/round.js";
6
7
  function now() {
7
8
  return new Date().toISOString();
8
9
  }
9
- function round(v, d) {
10
- const f = 10 ** d;
11
- return Math.round(v * f) / f;
12
- }
13
10
  export function phase1FloorFromPreset(entryPrice, direction, maxLossPct, leverage) {
14
11
  const pct = maxLossPct / 100 / leverage;
15
12
  if (direction === "LONG")
16
- return round(entryPrice * (1 - pct), PRICE_DECIMALS);
17
- return round(entryPrice * (1 + pct), PRICE_DECIMALS);
13
+ return roundProtectiveLevel(entryPrice * (1 - pct), direction);
14
+ return roundProtectiveLevel(entryPrice * (1 + pct), direction);
18
15
  }
19
16
  export function buildInitialState(event, preset, phase1Floor, triggerReason, carry) {
20
17
  const asset = event.coin;
@@ -1 +1 @@
1
- {"version":3,"file":"initial-state.js","sourceRoot":"","sources":["../../../src/dsl/events/initial-state.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"initial-state.js","sourceRoot":"","sources":["../../../src/dsl/events/initial-state.ts"],"names":[],"mappings":"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"}
@@ -2,9 +2,14 @@
2
2
  * When to call editPosition to align exchange SL with dsl.engine exchangeStopLossTriggerPx.
3
3
  */
4
4
  import type { DslState, DslTickResult } from "../../types/dsl/index.js";
5
- /** Minimum absolute price delta (USD) to treat as a meaningful SL move. */
6
- export declare const SL_SYNC_MIN_DELTA_ABS = 0.0001;
7
- /** Minimum relative delta vs trigger price (e.g. 0.0001 = 0.01%) so high-priced assets do not spam edits. */
5
+ /**
6
+ * Minimum relative delta vs trigger price (0.0001 = 0.01%) so high-priced assets do not spam
7
+ * edits. Purely relative on purpose: this used to be `max(0.0001 USD, 0.01%)`, and the absolute
8
+ * term won that max for every asset under $1 — 2.5% of PUMP's price, 11% of BOME's — so on a
9
+ * cheap coin no ratchet short of a double-digit move re-synced and the trailing stop stayed
10
+ * frozen at whatever level it was first placed at, which is the one place the user needs it to
11
+ * move.
12
+ */
8
13
  export declare const SL_SYNC_MIN_DELTA_RELATIVE = 0.0001;
9
14
  /**
10
15
  * Whether to call `editPosition` to align the exchange SL with `exchangeStopLossTriggerPx`.
@@ -1 +1 @@
1
- {"version":3,"file":"exchange-sync.d.ts","sourceRoot":"","sources":["../../../src/dsl/monitor/exchange-sync.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGxE,2EAA2E;AAC3E,eAAO,MAAM,qBAAqB,SAAS,CAAC;AAC5C,6GAA6G;AAC7G,eAAO,MAAM,0BAA0B,SAAS,CAAC;AAMjD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAcnF"}
1
+ {"version":3,"file":"exchange-sync.d.ts","sourceRoot":"","sources":["../../../src/dsl/monitor/exchange-sync.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGxE;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,SAAS,CAAC;AAYjD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAcnF"}
@@ -2,12 +2,24 @@
2
2
  * When to call editPosition to align exchange SL with dsl.engine exchangeStopLossTriggerPx.
3
3
  */
4
4
  import { exchangeStopLossTriggerPx } from "../engine/exchange-stop.js";
5
- /** Minimum absolute price delta (USD) to treat as a meaningful SL move. */
6
- export const SL_SYNC_MIN_DELTA_ABS = 0.0001;
7
- /** Minimum relative delta vs trigger price (e.g. 0.0001 = 0.01%) so high-priced assets do not spam edits. */
5
+ /**
6
+ * Minimum relative delta vs trigger price (0.0001 = 0.01%) so high-priced assets do not spam
7
+ * edits. Purely relative on purpose: this used to be `max(0.0001 USD, 0.01%)`, and the absolute
8
+ * term won that max for every asset under $1 — 2.5% of PUMP's price, 11% of BOME's — so on a
9
+ * cheap coin no ratchet short of a double-digit move re-synced and the trailing stop stayed
10
+ * frozen at whatever level it was first placed at, which is the one place the user needs it to
11
+ * move.
12
+ */
8
13
  export const SL_SYNC_MIN_DELTA_RELATIVE = 0.0001;
9
14
  function slSyncMinDeltaForPrice(triggerPx) {
10
- return Math.max(SL_SYNC_MIN_DELTA_ABS, Math.abs(triggerPx) * SL_SYNC_MIN_DELTA_RELATIVE);
15
+ // A non-positive trigger has no relative scale to measure against. Unreachable on any live
16
+ // path — `exchangeStopLossTriggerPx` returns a floor derived from a positive entry price —
17
+ // and the choice between the two behaviours is academic: 0 re-sends `triggerPx: 0` to the
18
+ // venue every tick, and Infinity freezes the stop. 0 is kept because a venue rejection is
19
+ // visible in `slSyncFailureCount` and the logs, where a frozen stop is silent.
20
+ if (!(triggerPx > 0))
21
+ return 0;
22
+ return triggerPx * SL_SYNC_MIN_DELTA_RELATIVE;
11
23
  }
12
24
  /**
13
25
  * Whether to call `editPosition` to align the exchange SL with `exchangeStopLossTriggerPx`.
@@ -1 +1 @@
1
- {"version":3,"file":"exchange-sync.js","sourceRoot":"","sources":["../../../src/dsl/monitor/exchange-sync.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAEvE,2EAA2E;AAC3E,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAC5C,6GAA6G;AAC7G,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAEjD,SAAS,sBAAsB,CAAC,SAAiB;IAC/C,OAAO,IAAI,CAAC,GAAG,CAAC,qBAAqB,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,0BAA0B,CAAC,CAAC;AAC3F,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAqB,EAAE,IAAc;IACxE,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9C,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IACxC,IAAI,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACpD,IAAI,MAAM,CAAC,YAAY;QAAE,OAAO,IAAI,CAAC;IACrC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,yFAAyF;QACzF,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,YAAY;QAAE,OAAO,KAAK,CAAC;IACvC,MAAM,SAAS,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAC;IACnD,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,oBAAoB,IAAI,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;AAC3E,CAAC"}
1
+ {"version":3,"file":"exchange-sync.js","sourceRoot":"","sources":["../../../src/dsl/monitor/exchange-sync.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAEvE;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAEjD,SAAS,sBAAsB,CAAC,SAAiB;IAC/C,2FAA2F;IAC3F,2FAA2F;IAC3F,0FAA0F;IAC1F,0FAA0F;IAC1F,+EAA+E;IAC/E,IAAI,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IAC/B,OAAO,SAAS,GAAG,0BAA0B,CAAC;AAChD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAqB,EAAE,IAAc;IACxE,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9C,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IACxC,IAAI,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACpD,IAAI,MAAM,CAAC,YAAY;QAAE,OAAO,IAAI,CAAC;IACrC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,yFAAyF;QACzF,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,YAAY;QAAE,OAAO,KAAK,CAAC;IACvC,MAAM,SAAS,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAC;IACnD,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,oBAAoB,IAAI,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;AAC3E,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"process-one-position.d.ts","sourceRoot":"","sources":["../../../src/dsl/monitor/process-one-position.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAkB,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAqBzD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAiB/C;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,CAAC,EAAE,QAAQ,GACV;IAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAYvD;AAuGD,MAAM,WAAW,qBAAqB;IACpC,4FAA4F;IAC5F,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC3C,GAAG,EAAE,aAAa,CAAC;IACnB,uBAAuB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACnD,6DAA6D;IAC7D,cAAc,CAAC,EAAE,OAAO,sBAAsB,EAAE,cAAc,CAAC;IAC/D,oDAAoD;IACpD,wBAAwB,CAAC,EAAE,OAAO,sBAAsB,EAAE,wBAAwB,CAAC;CACpF;AAED,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,qBAAqB,EAC1B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,QAAQ,EACf,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,IAAI,EAAE,IAAI,GACT,OAAO,CAAC,IAAI,CAAC,CA8wBf"}
1
+ {"version":3,"file":"process-one-position.d.ts","sourceRoot":"","sources":["../../../src/dsl/monitor/process-one-position.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAkB,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAqBzD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAiB/C;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,CAAC,EAAE,QAAQ,GACV;IAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAYvD;AAuGD,MAAM,WAAW,qBAAqB;IACpC,4FAA4F;IAC5F,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC3C,GAAG,EAAE,aAAa,CAAC;IACnB,uBAAuB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACnD,6DAA6D;IAC7D,cAAc,CAAC,EAAE,OAAO,sBAAsB,EAAE,cAAc,CAAC;IAC/D,oDAAoD;IACpD,wBAAwB,CAAC,EAAE,OAAO,sBAAsB,EAAE,wBAAwB,CAAC;CACpF;AAiCD,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,qBAAqB,EAC1B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,QAAQ,EACf,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,IAAI,EAAE,IAAI,GACT,OAAO,CAAC,IAAI,CAAC,CA8zBf"}
@@ -109,6 +109,36 @@ function failureContext(state, tickId) {
109
109
  tickId,
110
110
  };
111
111
  }
112
+ /**
113
+ * Venue statuses that mean the stop is definitively GONE from the book — cancelled by the user,
114
+ * by the venue, or rejected outright.
115
+ *
116
+ * Must stay in step with the backend's `classifySLOrderStatus`
117
+ * (dsl-engine `pkg/service/sl_order_status.go`). Deliberately NOT the inverse of
118
+ * `LIVE_VENUE_SL_STATUSES`: "not known-live" is a far bigger set than "known-dead" — it holds
119
+ * every status we have not seen yet, plus the empty one — and treating an unfamiliar status as
120
+ * dead would have the runtime place a second stop on top of a live one. Anything unlisted is
121
+ * UNKNOWN and changes nothing. Partially-filled and lifecycle-ended statuses are also not
122
+ * "gone": the fill check above and the reconcile path own those.
123
+ */
124
+ const GONE_VENUE_SL_STATUSES = new Set([
125
+ "canceled",
126
+ "cancelled",
127
+ "margincanceled",
128
+ "selftradecanceled",
129
+ "openinterestcapcanceled",
130
+ "vaultwithdrawalcanceled",
131
+ "scheduledcancel",
132
+ ]);
133
+ function isGoneVenueSlStatus(status) {
134
+ if (status == null)
135
+ return false;
136
+ // `parseExecutionOrderStatus` already lowercases; normalise again so a caller that does not
137
+ // cannot silently turn a cancellation into an unknown. Trim as well as lowercase, so this
138
+ // matches dsl-engine `normalizeOrderStatus` exactly rather than approximately.
139
+ const s = status.trim().toLowerCase();
140
+ return GONE_VENUE_SL_STATUSES.has(s) || s.endsWith("rejected");
141
+ }
112
142
  export async function processOnePosition(ctx, key, state, price, span) {
113
143
  const { tickId, ts, now: isoNow, stateManager, strategyStates, bus, isSlPlacementInProgress = () => false } = ctx;
114
144
  const strategy = strategyStates.get(state.address);
@@ -176,6 +206,26 @@ export async function processOnePosition(ctx, key, state, price, span) {
176
206
  }));
177
207
  return;
178
208
  }
209
+ if (isGoneVenueSlStatus(status?.status)) {
210
+ // The stop is off the book but the position is still open, and nothing else clears the
211
+ // id: `shouldSyncExchangeSl` short-circuits while `slOrderId != null`, and
212
+ // `hasRestingStopAtFloor` reads it as protection. Left alone, the position runs to
213
+ // liquidation with the breach counter pinned. Clearing BOTH fields re-arms it on this
214
+ // same tick — the id makes the sync fire, the floor makes the breach check honest.
215
+ // Same manoeuvre as dsl-engine's `rearmGoneStop`.
216
+ logger.warn("[dsl] exchange SL is gone from the venue, re-arming", {
217
+ tickId,
218
+ key,
219
+ asset: state.asset,
220
+ slOrderId: state.slOrderId,
221
+ lastSyncedFloorPrice: state.lastSyncedFloorPrice,
222
+ venueStatus: status?.status ?? null,
223
+ phase: state.phase,
224
+ });
225
+ recordDslDegradation({ failure: "sl_gone" });
226
+ await setIfStillActive(stateManager, key, state.address, state.asset, (current) => ({ ...current, slOrderId: null, lastSyncedFloorPrice: null }), { tickId, skipMessage: "[dsl] skip gone-SL clear: state already cleared (concurrent close)" });
227
+ state = { ...state, slOrderId: null, lastSyncedFloorPrice: null };
228
+ }
179
229
  }
180
230
  catch (e) {
181
231
  logger.warn("getOrderStatus failed, skipping SL-hit check", { asset: state.asset, err: e });
@@ -366,13 +416,34 @@ export async function processOnePosition(ctx, key, state, price, span) {
366
416
  span.setAttribute("senpi.dsl.current_roe", next.currentROE);
367
417
  span.setAttribute("senpi.dsl.floor_price", next.floorPrice);
368
418
  if (closeReasonToUse === CLOSE_REASON.DSL_BREACH && next.phase === 2) {
369
- logger.warn("[dsl] ignoring spurious dsl_breach close in phase 2 (exchange SL should exit)", {
419
+ // Whether the resting exchange stop should be left to do the exiting is decided in
420
+ // `dslTick` (`hasRestingStopAtFloor`), so that a suppressed breach still runs the rest of
421
+ // the tick. Reaching here means no stop is resting at the floor.
422
+ //
423
+ // The position-opened handler may be mid-flight placing the initial stop; give it this
424
+ // tick. The SL-sync site has the same guard, but it runs after this close path.
425
+ if (isSlPlacementInProgress(key)) {
426
+ logger.info("[dsl] deferring phase 2 breach close: initial SL placement in progress", {
427
+ tickId,
428
+ key,
429
+ asset: state.asset,
430
+ floorPrice: next.floorPrice,
431
+ });
432
+ // dslTick stamped closeReason onto the state persisted above; the position is staying
433
+ // open, so clear it rather than leave a live position carrying a close reason.
434
+ await setIfStillActive(stateManager, key, state.address, state.asset, (current) => ({ ...current, closeReason: null }), { tickId, skipMessage: "[dsl] skip deferred-breach clear: state already cleared (concurrent close)" });
435
+ return;
436
+ }
437
+ logger.warn("[dsl] phase 2 breach with no stop resting at the floor: closing from the runtime", {
370
438
  tickId,
371
439
  key,
372
440
  asset: state.asset,
441
+ slOrderId: next.slOrderId,
442
+ lastSyncedFloorPrice: next.lastSyncedFloorPrice,
443
+ floorPrice: next.floorPrice,
444
+ handoffStatus: next.handoffStatus,
445
+ phase: next.phase,
373
446
  });
374
- await setIfStillActive(stateManager, key, state.address, state.asset, (current) => ({ ...current, closeReason: null }), { tickId, skipMessage: "[dsl] skip spurious-breach clear: state already cleared (concurrent close)" });
375
- return;
376
447
  }
377
448
  logger.info("[dsl] dsl close: sending closePosition to exchange", {
378
449
  tickId,
@@ -813,8 +884,18 @@ async function attemptHandoffRegistration(ctx, key, next, _original, strategy) {
813
884
  adoptedId: adopted.id,
814
885
  status: adopted.status,
815
886
  });
887
+ // Mirror the backend's stop NOW, not on the next tick's handleHandoffOk poll. The
888
+ // phase-2 breach close at the top of the tick reads slOrderId / lastSyncedFloorPrice to
889
+ // decide whether anything is protecting this position, and it runs BEFORE handleHandoffOk
890
+ // — so leaving them at their phase-1 values for one tick means the next breach closes a
891
+ // position the backend is already protecting, racing its stop at the same price.
892
+ // Only those two fields: the tier/high-water state a just-created backend row reports is
893
+ // its own freshly evaluated view, and merging it here would walk back a local ratchet.
894
+ const adoptedSl = mapEnginePositionToStateFields(adopted);
816
895
  const updated = {
817
896
  ...next,
897
+ slOrderId: adoptedSl.slOrderId,
898
+ lastSyncedFloorPrice: adoptedSl.lastSyncedFloorPrice,
818
899
  handoffStatus: "ok",
819
900
  backendDslPositionId: adopted.id,
820
901
  lastBackendDslTick: ts,
@@ -874,8 +955,12 @@ async function attemptHandoffRegistration(ctx, key, next, _original, strategy) {
874
955
  });
875
956
  return;
876
957
  }
958
+ // Mirror the backend's stop on the registration tick itself — see the adopt site above.
959
+ const registeredSl = mapEnginePositionToStateFields(result.position);
877
960
  const updated = {
878
961
  ...next,
962
+ slOrderId: registeredSl.slOrderId,
963
+ lastSyncedFloorPrice: registeredSl.lastSyncedFloorPrice,
879
964
  handoffStatus: "ok",
880
965
  backendDslPositionId: result.position.id,
881
966
  lastBackendDslTick: ts,