@senpi/trading-recipe 1.0.57 → 1.0.58

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.
@@ -20,6 +20,7 @@ import { tmpdir } from "node:os";
20
20
  import { join } from "node:path";
21
21
  import {
22
22
  createScannerRuntimeModule,
23
+ buildCompositionFromScanners,
23
24
  emergingMoversScanner,
24
25
  } from "../dist/scanners/index.js";
25
26
 
@@ -187,7 +188,7 @@ async function main() {
187
188
 
188
189
  const module = createScannerRuntimeModule({
189
190
  stateDir,
190
- scanners: [emergingMoversScanner],
191
+ ...buildCompositionFromScanners([emergingMoversScanner]),
191
192
  strategies: [
192
193
  {
193
194
  id: "wolf",
@@ -218,6 +219,7 @@ async function main() {
218
219
  },
219
220
  ],
220
221
  providers: {
222
+ getInstruments: async () => [],
221
223
  getSmData: async () => {
222
224
  const data = SCAN_DATA[scanIndex]();
223
225
  scanIndex++;
@@ -13,6 +13,7 @@ import { tmpdir } from "node:os";
13
13
  import { join } from "node:path";
14
14
  import {
15
15
  createScannerRuntimeModule,
16
+ buildCompositionFromScanners,
16
17
  liquidationWatchdogScanner,
17
18
  } from "../dist/scanners/index.js";
18
19
  import { StateManager } from "../dist/state/index.js";
@@ -21,31 +22,41 @@ import { StateManager } from "../dist/state/index.js";
21
22
 
22
23
  function makeClearingHouseState({ bufferPct, positions }) {
23
24
  // bufferPct controls how much margin room is left:
24
- // buffer = (accountValue - crossMaintenanceMargin) / accountValue * 100
25
- // → crossMaintenanceMargin = accountValue * (1 - bufferPct / 100)
25
+ // buffer = (withdrawable / accountValue) * 100
26
+ // → withdrawable = accountValue * (bufferPct / 100)
26
27
  const accountValue = 10_000;
27
- const crossMaintenanceMargin = accountValue * (1 - bufferPct / 100);
28
+ const withdrawable = accountValue * (bufferPct / 100);
29
+ const totalMarginUsed = accountValue - withdrawable;
28
30
  return {
29
31
  accountValue,
30
- totalMarginUsed: crossMaintenanceMargin,
31
- crossMaintenanceMargin,
32
- availableBalance: accountValue - crossMaintenanceMargin,
32
+ withdrawable,
33
+ totalMarginUsed,
34
+ totalUnrealizedPnl: 0,
35
+ totalNtlPos: 0,
33
36
  positions: positions ?? [],
34
37
  };
35
38
  }
36
39
 
37
40
  function makePosition({ asset, direction, markPrice, liqPrice, roe, marginType }) {
41
+ // Scanner expects StrategyOpenPosition from types/strategy.ts:
42
+ // coin, dex, szi, entryPx, leverage, leverageType, unrealizedPnl, marginUsed, liquidationPx, returnOnEquity
43
+ // szi sign encodes direction: positive = LONG, negative = SHORT
44
+ // returnOnEquity is a ratio (e.g. 0.05 for 5%), scanner multiplies by 100
45
+ const dir = direction ?? "LONG";
46
+ const szi = dir === "SHORT" ? -1 : 1;
47
+ const entryPx = markPrice * 0.95;
48
+ const unrealizedPnl = (markPrice - entryPx) * szi;
38
49
  return {
39
- asset,
40
- direction: direction ?? "LONG",
41
- size: 1,
42
- entryPrice: markPrice * 0.95,
43
- markPrice,
44
- liquidationPrice: liqPrice ?? null,
45
- unrealizedPnl: markPrice * 0.05,
46
- roe: roe ?? 5,
50
+ coin: asset,
51
+ dex: "",
52
+ szi,
53
+ entryPx,
47
54
  leverage: 5,
48
- marginType: marginType ?? "cross",
55
+ leverageType: marginType ?? "cross",
56
+ unrealizedPnl,
57
+ marginUsed: entryPx / 5,
58
+ liquidationPx: liqPrice ?? null,
59
+ returnOnEquity: (roe ?? 5) / 100,
49
60
  };
50
61
  }
51
62
 
@@ -79,7 +90,7 @@ async function scenarioWithoutDslStates() {
79
90
 
80
91
  const module = createScannerRuntimeModule({
81
92
  stateDir,
82
- scanners: [liquidationWatchdogScanner],
93
+ ...buildCompositionFromScanners([liquidationWatchdogScanner]),
83
94
  strategies: [
84
95
  {
85
96
  id: "wallet-001",
@@ -227,7 +238,7 @@ async function scenarioWithDslStates() {
227
238
  });
228
239
 
229
240
  // Verify StateManager has the states
230
- const loaded = stateManager.listDslStates("wallet-002");
241
+ const loaded = await stateManager.listDslStates("wallet-002");
231
242
  console.log(" StateManager DSL states loaded:", loaded.length);
232
243
  console.assert(loaded.length === 2, "Expected 2 DSL states in StateManager");
233
244
 
@@ -243,7 +254,7 @@ async function scenarioWithDslStates() {
243
254
  // Wire getDslStatesForStrategy to read from the StateManager — same as Runtime does
244
255
  const module = createScannerRuntimeModule({
245
256
  stateDir,
246
- scanners: [liquidationWatchdogScanner],
257
+ ...buildCompositionFromScanners([liquidationWatchdogScanner]),
247
258
  strategies: [
248
259
  {
249
260
  id: "wallet-002",
@@ -3,6 +3,7 @@ import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import {
5
5
  createScannerRuntimeModule,
6
+ buildCompositionFromScanners,
6
7
  oiTrackerScanner,
7
8
  } from "../dist/scanners/index.js";
8
9
 
@@ -39,7 +40,7 @@ async function main() {
39
40
 
40
41
  const module = createScannerRuntimeModule({
41
42
  stateDir,
42
- scanners: [oiTrackerScanner],
43
+ ...buildCompositionFromScanners([oiTrackerScanner]),
43
44
  strategies: [
44
45
  {
45
46
  id: "alpha",
@@ -2,7 +2,7 @@
2
2
  "id": "trading-recipe",
3
3
  "name": "Senpi Trading Recipe",
4
4
  "description": "Senpi trading recipe plugin for OpenClaw",
5
- "version": "1.0.57",
5
+ "version": "1.0.58",
6
6
  "configSchema": {
7
7
  "type": "object",
8
8
  "additionalProperties": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@senpi/trading-recipe",
3
- "version": "1.0.57",
3
+ "version": "1.0.58",
4
4
  "description": "Trading recipe plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",