jcc_hyper_tool 0.1.1
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/LICENSE +21 -0
- package/README.md +394 -0
- package/dist/cli/confirm.d.ts +2 -0
- package/dist/cli/confirm.d.ts.map +1 -0
- package/dist/cli/confirm.js +22 -0
- package/dist/cli/confirm.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +189 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/perpKline.d.ts +19 -0
- package/dist/cli/perpKline.d.ts.map +1 -0
- package/dist/cli/perpKline.js +39 -0
- package/dist/cli/perpKline.js.map +1 -0
- package/dist/cli/stateCli.d.ts +3 -0
- package/dist/cli/stateCli.d.ts.map +1 -0
- package/dist/cli/stateCli.js +158 -0
- package/dist/cli/stateCli.js.map +1 -0
- package/dist/cli/strategyCli.d.ts +3 -0
- package/dist/cli/strategyCli.d.ts.map +1 -0
- package/dist/cli/strategyCli.js +198 -0
- package/dist/cli/strategyCli.js.map +1 -0
- package/dist/cli/tradingCli.d.ts +3 -0
- package/dist/cli/tradingCli.d.ts.map +1 -0
- package/dist/cli/tradingCli.js +587 -0
- package/dist/cli/tradingCli.js.map +1 -0
- package/dist/cli/util.d.ts +28 -0
- package/dist/cli/util.d.ts.map +1 -0
- package/dist/cli/util.js +62 -0
- package/dist/cli/util.js.map +1 -0
- package/dist/core/config.d.ts +32 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +101 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/errors.d.ts +9 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +17 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/hyperliquid/asset.d.ts +24 -0
- package/dist/core/hyperliquid/asset.d.ts.map +1 -0
- package/dist/core/hyperliquid/asset.js +88 -0
- package/dist/core/hyperliquid/asset.js.map +1 -0
- package/dist/core/hyperliquid/candles.d.ts +24 -0
- package/dist/core/hyperliquid/candles.d.ts.map +1 -0
- package/dist/core/hyperliquid/candles.js +113 -0
- package/dist/core/hyperliquid/candles.js.map +1 -0
- package/dist/core/hyperliquid/client.d.ts +36 -0
- package/dist/core/hyperliquid/client.d.ts.map +1 -0
- package/dist/core/hyperliquid/client.js +92 -0
- package/dist/core/hyperliquid/client.js.map +1 -0
- package/dist/core/hyperliquid/exchange.d.ts +14 -0
- package/dist/core/hyperliquid/exchange.d.ts.map +1 -0
- package/dist/core/hyperliquid/exchange.js +42 -0
- package/dist/core/hyperliquid/exchange.js.map +1 -0
- package/dist/core/hyperliquid/exchangeParse.d.ts +7 -0
- package/dist/core/hyperliquid/exchangeParse.d.ts.map +1 -0
- package/dist/core/hyperliquid/exchangeParse.js +44 -0
- package/dist/core/hyperliquid/exchangeParse.js.map +1 -0
- package/dist/core/hyperliquid/float.d.ts +6 -0
- package/dist/core/hyperliquid/float.d.ts.map +1 -0
- package/dist/core/hyperliquid/float.js +24 -0
- package/dist/core/hyperliquid/float.js.map +1 -0
- package/dist/core/hyperliquid/klineCoin.d.ts +10 -0
- package/dist/core/hyperliquid/klineCoin.d.ts.map +1 -0
- package/dist/core/hyperliquid/klineCoin.js +90 -0
- package/dist/core/hyperliquid/klineCoin.js.map +1 -0
- package/dist/core/hyperliquid/orders.d.ts +91 -0
- package/dist/core/hyperliquid/orders.d.ts.map +1 -0
- package/dist/core/hyperliquid/orders.js +116 -0
- package/dist/core/hyperliquid/orders.js.map +1 -0
- package/dist/core/hyperliquid/prefixedPerpCoin.d.ts +3 -0
- package/dist/core/hyperliquid/prefixedPerpCoin.d.ts.map +1 -0
- package/dist/core/hyperliquid/prefixedPerpCoin.js +10 -0
- package/dist/core/hyperliquid/prefixedPerpCoin.js.map +1 -0
- package/dist/core/hyperliquid/signed-exchange.d.ts +10 -0
- package/dist/core/hyperliquid/signed-exchange.d.ts.map +1 -0
- package/dist/core/hyperliquid/signed-exchange.js +23 -0
- package/dist/core/hyperliquid/signed-exchange.js.map +1 -0
- package/dist/core/hyperliquid/signing.d.ts +23 -0
- package/dist/core/hyperliquid/signing.d.ts.map +1 -0
- package/dist/core/hyperliquid/signing.js +65 -0
- package/dist/core/hyperliquid/signing.js.map +1 -0
- package/dist/core/hyperliquid/types.d.ts +11 -0
- package/dist/core/hyperliquid/types.d.ts.map +1 -0
- package/dist/core/hyperliquid/types.js +2 -0
- package/dist/core/hyperliquid/types.js.map +1 -0
- package/dist/core/hyperliquid/watchOrders.d.ts +10 -0
- package/dist/core/hyperliquid/watchOrders.d.ts.map +1 -0
- package/dist/core/hyperliquid/watchOrders.js +38 -0
- package/dist/core/hyperliquid/watchOrders.js.map +1 -0
- package/dist/core/state/bracketReconcile.d.ts +23 -0
- package/dist/core/state/bracketReconcile.d.ts.map +1 -0
- package/dist/core/state/bracketReconcile.js +297 -0
- package/dist/core/state/bracketReconcile.js.map +1 -0
- package/dist/core/state/cancelOpenPlan.d.ts +23 -0
- package/dist/core/state/cancelOpenPlan.d.ts.map +1 -0
- package/dist/core/state/cancelOpenPlan.js +126 -0
- package/dist/core/state/cancelOpenPlan.js.map +1 -0
- package/dist/core/state/gcTradeState.d.ts +13 -0
- package/dist/core/state/gcTradeState.d.ts.map +1 -0
- package/dist/core/state/gcTradeState.js +48 -0
- package/dist/core/state/gcTradeState.js.map +1 -0
- package/dist/core/state/gridReconcile.d.ts +46 -0
- package/dist/core/state/gridReconcile.d.ts.map +1 -0
- package/dist/core/state/gridReconcile.js +307 -0
- package/dist/core/state/gridReconcile.js.map +1 -0
- package/dist/core/state/intentFactory.d.ts +58 -0
- package/dist/core/state/intentFactory.d.ts.map +1 -0
- package/dist/core/state/intentFactory.js +95 -0
- package/dist/core/state/intentFactory.js.map +1 -0
- package/dist/core/state/present.d.ts +17 -0
- package/dist/core/state/present.d.ts.map +1 -0
- package/dist/core/state/present.js +100 -0
- package/dist/core/state/present.js.map +1 -0
- package/dist/core/state/runCancelOpen.d.ts +32 -0
- package/dist/core/state/runCancelOpen.d.ts.map +1 -0
- package/dist/core/state/runCancelOpen.js +101 -0
- package/dist/core/state/runCancelOpen.js.map +1 -0
- package/dist/core/state/runReconcile.d.ts +20 -0
- package/dist/core/state/runReconcile.d.ts.map +1 -0
- package/dist/core/state/runReconcile.js +248 -0
- package/dist/core/state/runReconcile.js.map +1 -0
- package/dist/core/state/schema.d.ts +1161 -0
- package/dist/core/state/schema.d.ts.map +1 -0
- package/dist/core/state/schema.js +151 -0
- package/dist/core/state/schema.js.map +1 -0
- package/dist/core/state/snapshot.d.ts +22 -0
- package/dist/core/state/snapshot.d.ts.map +1 -0
- package/dist/core/state/snapshot.js +115 -0
- package/dist/core/state/snapshot.js.map +1 -0
- package/dist/core/state/statePaths.d.ts +2 -0
- package/dist/core/state/statePaths.d.ts.map +1 -0
- package/dist/core/state/statePaths.js +7 -0
- package/dist/core/state/statePaths.js.map +1 -0
- package/dist/core/state/store.d.ts +12 -0
- package/dist/core/state/store.d.ts.map +1 -0
- package/dist/core/state/store.js +95 -0
- package/dist/core/state/store.js.map +1 -0
- package/dist/core/state/types.d.ts +40 -0
- package/dist/core/state/types.d.ts.map +1 -0
- package/dist/core/state/types.js +2 -0
- package/dist/core/state/types.js.map +1 -0
- package/dist/core/trading.d.ts +8 -0
- package/dist/core/trading.d.ts.map +1 -0
- package/dist/core/trading.js +22 -0
- package/dist/core/trading.js.map +1 -0
- package/dist/core/wallet.d.ts +3 -0
- package/dist/core/wallet.d.ts.map +1 -0
- package/dist/core/wallet.js +14 -0
- package/dist/core/wallet.js.map +1 -0
- package/dist/daemon/index.d.ts +3 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +104 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/meta/version.d.ts +2 -0
- package/dist/meta/version.d.ts.map +1 -0
- package/dist/meta/version.js +12 -0
- package/dist/meta/version.js.map +1 -0
- package/dist/strategies/grid.d.ts +46 -0
- package/dist/strategies/grid.d.ts.map +1 -0
- package/dist/strategies/grid.js +101 -0
- package/dist/strategies/grid.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { annotateGridSides, gridPriceLevels } from "../../strategies/grid.js";
|
|
3
|
+
export function createBracketIntentRecord(params) {
|
|
4
|
+
const id = randomUUID();
|
|
5
|
+
return {
|
|
6
|
+
kind: "bracket",
|
|
7
|
+
id,
|
|
8
|
+
createdAtMs: params.nowMs,
|
|
9
|
+
updatedAtMs: params.nowMs,
|
|
10
|
+
coin: params.coin,
|
|
11
|
+
dex: params.dex,
|
|
12
|
+
network: params.network,
|
|
13
|
+
entrySide: params.entrySide,
|
|
14
|
+
entryLimitPx: params.entryLimitPx,
|
|
15
|
+
entrySz: params.entrySz,
|
|
16
|
+
tif: params.tif,
|
|
17
|
+
entryReduceOnly: params.entryReduceOnly,
|
|
18
|
+
tpTriggerPx: params.tpTriggerPx,
|
|
19
|
+
slTriggerPx: params.slTriggerPx,
|
|
20
|
+
tpslIsMarket: params.tpslIsMarket ?? true,
|
|
21
|
+
tpslLimitPx: params.tpslLimitPx,
|
|
22
|
+
protectionReduceOnly: params.protectionReduceOnly ?? true,
|
|
23
|
+
phase: "planned",
|
|
24
|
+
expiresAtMs: params.expiresAtMs,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export function createGridIntentRecord(params) {
|
|
28
|
+
const prices = gridPriceLevels(params.lower, params.upper, params.grids, params.bias);
|
|
29
|
+
const annotated = annotateGridSides(prices, params.lower, params.upper, params.bias);
|
|
30
|
+
const legs = annotated.map((r, index) => ({
|
|
31
|
+
index,
|
|
32
|
+
px: r.px,
|
|
33
|
+
isBuy: r.isBuy,
|
|
34
|
+
legPhase: "pending",
|
|
35
|
+
}));
|
|
36
|
+
const id = randomUUID();
|
|
37
|
+
return {
|
|
38
|
+
kind: "grid",
|
|
39
|
+
id,
|
|
40
|
+
createdAtMs: params.nowMs,
|
|
41
|
+
updatedAtMs: params.nowMs,
|
|
42
|
+
coin: params.coin,
|
|
43
|
+
dex: params.dex,
|
|
44
|
+
network: params.network,
|
|
45
|
+
lower: params.lower,
|
|
46
|
+
upper: params.upper,
|
|
47
|
+
grids: params.grids,
|
|
48
|
+
orderSz: params.orderSz,
|
|
49
|
+
bias: params.bias,
|
|
50
|
+
tif: params.tif,
|
|
51
|
+
reduceOnly: params.reduceOnly,
|
|
52
|
+
maxOrders: params.maxOrders,
|
|
53
|
+
...(typeof params.replenishGapPx === "number" &&
|
|
54
|
+
Number.isFinite(params.replenishGapPx) &&
|
|
55
|
+
params.replenishGapPx > 0
|
|
56
|
+
? { replenishGapPx: params.replenishGapPx }
|
|
57
|
+
: {}),
|
|
58
|
+
legs,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export function createStandaloneTpslIntentRecord(params) {
|
|
62
|
+
const id = randomUUID();
|
|
63
|
+
return {
|
|
64
|
+
kind: "standalone_tpsl",
|
|
65
|
+
id,
|
|
66
|
+
createdAtMs: params.nowMs,
|
|
67
|
+
updatedAtMs: params.nowMs,
|
|
68
|
+
coin: params.coin,
|
|
69
|
+
dex: params.dex,
|
|
70
|
+
side: params.side,
|
|
71
|
+
sz: params.sz,
|
|
72
|
+
triggerPx: params.triggerPx,
|
|
73
|
+
tpsl: params.tpsl,
|
|
74
|
+
isMarket: params.isMarket,
|
|
75
|
+
limitPx: params.limitPx,
|
|
76
|
+
reduceOnly: params.reduceOnly,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export function createSingleLimitIntentRecord(params) {
|
|
80
|
+
const id = randomUUID();
|
|
81
|
+
return {
|
|
82
|
+
kind: "single_limit",
|
|
83
|
+
id,
|
|
84
|
+
createdAtMs: params.nowMs,
|
|
85
|
+
updatedAtMs: params.nowMs,
|
|
86
|
+
coin: params.coin,
|
|
87
|
+
dex: params.dex,
|
|
88
|
+
entrySide: params.entrySide,
|
|
89
|
+
limitPx: params.limitPx,
|
|
90
|
+
sz: params.sz,
|
|
91
|
+
tif: params.tif,
|
|
92
|
+
reduceOnly: params.reduceOnly,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=intentFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intentFactory.js","sourceRoot":"","sources":["../../../src/core/state/intentFactory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IntentRecord, TradeStateFile } from "./schema.js";
|
|
2
|
+
export type TaskSummary = {
|
|
3
|
+
id: string;
|
|
4
|
+
kind: IntentRecord["kind"];
|
|
5
|
+
coin: string;
|
|
6
|
+
dex?: string;
|
|
7
|
+
phase?: string;
|
|
8
|
+
summaryLine: string;
|
|
9
|
+
nextHints: string[];
|
|
10
|
+
detail?: Record<string, unknown>;
|
|
11
|
+
};
|
|
12
|
+
export declare function summarizeIntent(i: IntentRecord): TaskSummary;
|
|
13
|
+
export declare function formatStateList(file: TradeStateFile): {
|
|
14
|
+
tasks: TaskSummary[];
|
|
15
|
+
updatedAtMs: number;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=present.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"present.d.ts","sourceRoot":"","sources":["../../../src/core/state/present.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEhE,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,CAAC;AAsFF,wBAAgB,eAAe,CAAC,CAAC,EAAE,YAAY,GAAG,WAAW,CAW5D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG;IACrD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB,CAIA"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
function bracketLine(i) {
|
|
2
|
+
const d = {
|
|
3
|
+
entry: { side: i.entrySide, px: i.entryLimitPx, sz: i.entrySz, oid: i.entryOid ?? null },
|
|
4
|
+
tp: { px: i.tpTriggerPx, oid: i.tpOid ?? null },
|
|
5
|
+
sl: { px: i.slTriggerPx, oid: i.slOid ?? null },
|
|
6
|
+
};
|
|
7
|
+
const hints = [];
|
|
8
|
+
if (i.phase === "planned") {
|
|
9
|
+
hints.push("Place entry limit order, then reconcile.");
|
|
10
|
+
}
|
|
11
|
+
else if (i.phase === "entry_pending" || i.phase === "entry_partial") {
|
|
12
|
+
hints.push("Wait for entry to fill; TP/SL activate only after entry is filled.");
|
|
13
|
+
}
|
|
14
|
+
else if (i.phase === "entry_filled") {
|
|
15
|
+
hints.push("Place TP/SL protection pair (reduce-only by default).");
|
|
16
|
+
}
|
|
17
|
+
else if (i.phase === "protection_active") {
|
|
18
|
+
hints.push("Protection working; when TP or SL fills, the other side will be cancelled.");
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
id: i.id,
|
|
22
|
+
kind: "bracket",
|
|
23
|
+
coin: i.coin,
|
|
24
|
+
dex: i.dex,
|
|
25
|
+
phase: i.phase,
|
|
26
|
+
summaryLine: `bracket ${i.coin} [${i.phase}] entry ${i.entrySide} @${i.entryLimitPx} sz=${i.entrySz}`,
|
|
27
|
+
nextHints: hints,
|
|
28
|
+
detail: d,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function gridLine(i) {
|
|
32
|
+
const counts = {};
|
|
33
|
+
for (const l of i.legs) {
|
|
34
|
+
counts[l.legPhase] = (counts[l.legPhase] ?? 0) + 1;
|
|
35
|
+
}
|
|
36
|
+
const hint = i.legs.every((l) => l.legPhase === "filled") ||
|
|
37
|
+
i.legs.every((l) => l.legPhase !== "open" && l.legPhase !== "partial")
|
|
38
|
+
? "Grid legs settled or idle; review fills before re-running."
|
|
39
|
+
: "Run reconcile to refresh leg states from open orders.";
|
|
40
|
+
return {
|
|
41
|
+
id: i.id,
|
|
42
|
+
kind: "grid",
|
|
43
|
+
coin: i.coin,
|
|
44
|
+
dex: i.dex,
|
|
45
|
+
phase: `grid:${i.legs.filter((l) => l.legPhase === "filled").length}/${i.legs.length} filled`,
|
|
46
|
+
summaryLine: `grid ${i.coin} levels=${i.grids} [${Object.entries(counts)
|
|
47
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
48
|
+
.join(", ")}]`,
|
|
49
|
+
nextHints: [hint],
|
|
50
|
+
detail: { legs: i.legs.length, counts },
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function tpslStandaloneLine(i) {
|
|
54
|
+
return {
|
|
55
|
+
id: i.id,
|
|
56
|
+
kind: "standalone_tpsl",
|
|
57
|
+
coin: i.coin,
|
|
58
|
+
dex: i.dex,
|
|
59
|
+
phase: i.oid ? "submitted" : "planned",
|
|
60
|
+
summaryLine: `tpsl ${i.coin} ${i.side} ${i.tpsl} trig=${i.triggerPx} sz=${i.sz} oid=${i.oid ?? "n/a"}`,
|
|
61
|
+
nextHints: [
|
|
62
|
+
i.oid
|
|
63
|
+
? "Trigger order on book; reconcile updates are optional for standalone TP/SL."
|
|
64
|
+
: "Dry-run / pending submission.",
|
|
65
|
+
],
|
|
66
|
+
detail: { tpsl: i.tpsl, triggerPx: i.triggerPx, isMarket: i.isMarket },
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function singleLine(i) {
|
|
70
|
+
return {
|
|
71
|
+
id: i.id,
|
|
72
|
+
kind: "single_limit",
|
|
73
|
+
coin: i.coin,
|
|
74
|
+
dex: i.dex,
|
|
75
|
+
phase: i.oid ? "live" : "planned",
|
|
76
|
+
summaryLine: `limit ${i.coin} ${i.entrySide} @${i.limitPx} sz=${i.sz} oid=${i.oid ?? "n/a"}`,
|
|
77
|
+
nextHints: i.oid
|
|
78
|
+
? ["Order submitted; track via open orders / reconcile."]
|
|
79
|
+
: ["Dry-run or pending placement."],
|
|
80
|
+
detail: { oid: i.oid ?? null },
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
export function summarizeIntent(i) {
|
|
84
|
+
if (i.kind === "bracket") {
|
|
85
|
+
return bracketLine(i);
|
|
86
|
+
}
|
|
87
|
+
if (i.kind === "grid") {
|
|
88
|
+
return gridLine(i);
|
|
89
|
+
}
|
|
90
|
+
if (i.kind === "standalone_tpsl") {
|
|
91
|
+
return tpslStandaloneLine(i);
|
|
92
|
+
}
|
|
93
|
+
return singleLine(i);
|
|
94
|
+
}
|
|
95
|
+
export function formatStateList(file) {
|
|
96
|
+
const tasks = Object.values(file.intents).map(summarizeIntent);
|
|
97
|
+
tasks.sort((a, b) => a.id.localeCompare(b.id));
|
|
98
|
+
return { tasks, updatedAtMs: file.updatedAtMs };
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=present.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"present.js","sourceRoot":"","sources":["../../../src/core/state/present.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { EffectiveConfig } from "../config.js";
|
|
2
|
+
import type { JsonValue } from "../hyperliquid/types.js";
|
|
3
|
+
export type StateCancelOpenMode = "dry" | "live";
|
|
4
|
+
export type StateCancelOpenWireRow = {
|
|
5
|
+
coin: string;
|
|
6
|
+
dex: string | null;
|
|
7
|
+
assetIndex: number;
|
|
8
|
+
oids: number[];
|
|
9
|
+
action: Record<string, unknown>;
|
|
10
|
+
};
|
|
11
|
+
export type StateCancelOpenResult = {
|
|
12
|
+
mode: StateCancelOpenMode;
|
|
13
|
+
candidatesFromState: number[];
|
|
14
|
+
openOidsOnExchange: number[];
|
|
15
|
+
willCancel: number[];
|
|
16
|
+
skippedNotOpen: number[];
|
|
17
|
+
actionsPlanned?: StateCancelOpenWireRow[];
|
|
18
|
+
actionsExecuted?: Array<StateCancelOpenWireRow & {
|
|
19
|
+
response: JsonValue;
|
|
20
|
+
}>;
|
|
21
|
+
gcRemovedIntentIds: string[];
|
|
22
|
+
};
|
|
23
|
+
export declare function runStateCancelOpen(opts: {
|
|
24
|
+
statePath: string;
|
|
25
|
+
cfg: EffectiveConfig;
|
|
26
|
+
mode: StateCancelOpenMode;
|
|
27
|
+
assumeYes: boolean;
|
|
28
|
+
intentFilter?: string;
|
|
29
|
+
confirmLive?: (prompt: string) => Promise<void>;
|
|
30
|
+
nowMs?: number;
|
|
31
|
+
}): Promise<StateCancelOpenResult>;
|
|
32
|
+
//# sourceMappingURL=runCancelOpen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runCancelOpen.d.ts","sourceRoot":"","sources":["../../../src/core/state/runCancelOpen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAQpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAiCzD,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,MAAM,CAAC;AAEjD,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,CAAC,EAAE,sBAAsB,EAAE,CAAC;IAC1C,eAAe,CAAC,EAAE,KAAK,CAAC,sBAAsB,GAAG;QAAE,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAC1E,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B,CAAC;AAEF,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,eAAe,CAAC;IACrB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAsFjC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { requireUserContext } from "../config.js";
|
|
2
|
+
import { ConfigError } from "../errors.js";
|
|
3
|
+
import { perpCoinToExchangeAssetId } from "../hyperliquid/asset.js";
|
|
4
|
+
import { HyperliquidInfoClient } from "../hyperliquid/client.js";
|
|
5
|
+
import { HyperliquidExchangeClient } from "../hyperliquid/exchange.js";
|
|
6
|
+
import { buildCancelOrdersAction } from "../hyperliquid/orders.js";
|
|
7
|
+
import { buildSignedExchangePayload } from "../hyperliquid/signed-exchange.js";
|
|
8
|
+
import { requireTraderWallet } from "../trading.js";
|
|
9
|
+
import { planStateCancelOpen } from "./cancelOpenPlan.js";
|
|
10
|
+
import { garbageCollectTradeState } from "./gcTradeState.js";
|
|
11
|
+
import { normalizeOpenOrders } from "./snapshot.js";
|
|
12
|
+
import { readOrCreateTradeStateFile, writeTradeStateFileAtomic } from "./store.js";
|
|
13
|
+
function isMainnet(cfg) {
|
|
14
|
+
return cfg.network === "mainnet";
|
|
15
|
+
}
|
|
16
|
+
async function resolveAssetIndex(cfg, coin, dex) {
|
|
17
|
+
const info = new HyperliquidInfoClient({ infoOrigin: cfg.infoOrigin });
|
|
18
|
+
const meta = await info.meta(dex);
|
|
19
|
+
const perpDexs = dex ? await info.perpDexs() : undefined;
|
|
20
|
+
return perpCoinToExchangeAssetId({ coin, meta, dex, perpDexs });
|
|
21
|
+
}
|
|
22
|
+
async function postSigned(cfg, wallet, action) {
|
|
23
|
+
const ex = new HyperliquidExchangeClient({ apiOrigin: cfg.infoOrigin });
|
|
24
|
+
const body = await buildSignedExchangePayload(wallet, action, { isMainnet: isMainnet(cfg) });
|
|
25
|
+
return ex.exchange(body);
|
|
26
|
+
}
|
|
27
|
+
export async function runStateCancelOpen(opts) {
|
|
28
|
+
const nowMs = opts.nowMs ?? Date.now();
|
|
29
|
+
const prior = await readOrCreateTradeStateFile(opts.statePath, nowMs);
|
|
30
|
+
const user = requireUserContext(opts.cfg);
|
|
31
|
+
const info = new HyperliquidInfoClient({ infoOrigin: user.infoOrigin });
|
|
32
|
+
let openNorm = normalizeOpenOrders(await info.openOrders(user.userAddress));
|
|
33
|
+
const plan = planStateCancelOpen({
|
|
34
|
+
state: prior,
|
|
35
|
+
openOrders: openNorm,
|
|
36
|
+
intentFilter: opts.intentFilter,
|
|
37
|
+
});
|
|
38
|
+
const buildResolvedActions = async () => {
|
|
39
|
+
const rows = [];
|
|
40
|
+
for (const g of plan.cancelGroups) {
|
|
41
|
+
const assetIndex = await resolveAssetIndex(opts.cfg, g.coin, g.dex);
|
|
42
|
+
rows.push({
|
|
43
|
+
coin: g.coin,
|
|
44
|
+
dex: g.dex ?? null,
|
|
45
|
+
assetIndex,
|
|
46
|
+
oids: g.oids,
|
|
47
|
+
action: buildCancelOrdersAction(assetIndex, g.oids),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return rows;
|
|
51
|
+
};
|
|
52
|
+
const base = {
|
|
53
|
+
candidatesFromState: plan.candidatesFromState,
|
|
54
|
+
openOidsOnExchange: plan.openOidsOnExchange,
|
|
55
|
+
willCancel: plan.willCancel,
|
|
56
|
+
skippedNotOpen: plan.skippedNotOpen,
|
|
57
|
+
};
|
|
58
|
+
if (opts.mode === "dry") {
|
|
59
|
+
const actionsPlanned = await buildResolvedActions();
|
|
60
|
+
const gc = garbageCollectTradeState({ state: prior, openOrders: openNorm, nowMs });
|
|
61
|
+
await writeTradeStateFileAtomic(opts.statePath, gc.next);
|
|
62
|
+
return {
|
|
63
|
+
mode: "dry",
|
|
64
|
+
...base,
|
|
65
|
+
actionsPlanned,
|
|
66
|
+
gcRemovedIntentIds: gc.removedIntentIds,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const actionsExecuted = [];
|
|
70
|
+
if (plan.willCancel.length > 0) {
|
|
71
|
+
const planned = await buildResolvedActions();
|
|
72
|
+
if (!opts.assumeYes) {
|
|
73
|
+
if (!opts.confirmLive) {
|
|
74
|
+
throw new ConfigError("LIVE cancel-open requires --assume-yes or an interactive confirm hook.");
|
|
75
|
+
}
|
|
76
|
+
await opts.confirmLive("LIVE cancel-open will submit cancellations. Type YES to continue:\n");
|
|
77
|
+
}
|
|
78
|
+
const trader = requireTraderWallet(opts.cfg);
|
|
79
|
+
for (const row of planned) {
|
|
80
|
+
const resp = await postSigned(opts.cfg, trader.wallet, row.action);
|
|
81
|
+
actionsExecuted.push({
|
|
82
|
+
coin: row.coin,
|
|
83
|
+
dex: row.dex,
|
|
84
|
+
assetIndex: row.assetIndex,
|
|
85
|
+
oids: row.oids,
|
|
86
|
+
action: row.action,
|
|
87
|
+
response: resp,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
openNorm = normalizeOpenOrders(await info.openOrders(user.userAddress));
|
|
91
|
+
}
|
|
92
|
+
const gc = garbageCollectTradeState({ state: prior, openOrders: openNorm, nowMs });
|
|
93
|
+
await writeTradeStateFileAtomic(opts.statePath, gc.next);
|
|
94
|
+
return {
|
|
95
|
+
mode: "live",
|
|
96
|
+
...base,
|
|
97
|
+
actionsExecuted,
|
|
98
|
+
gcRemovedIntentIds: gc.removedIntentIds,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=runCancelOpen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runCancelOpen.js","sourceRoot":"","sources":["../../../src/core/state/runCancelOpen.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAE/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,0BAA0B,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAEnF,SAAS,SAAS,CAAC,GAAoB;IACrC,OAAO,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC;AACnC,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,GAAoB,EACpB,IAAY,EACZ,GAAY;IAEZ,MAAM,IAAI,GAAG,IAAI,qBAAqB,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;IACvE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACzD,OAAO,yBAAyB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;AAClE,CAAC;AAED,KAAK,UAAU,UAAU,CACvB,GAAoB,EACpB,MAAwD,EACxD,MAA+B;IAE/B,MAAM,EAAE,GAAG,IAAI,yBAAyB,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;IACxE,MAAM,IAAI,GAAG,MAAM,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC7F,OAAO,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC;AAuBD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAQxC;IACC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;IACvC,MAAM,KAAK,GAAG,MAAM,0BAA0B,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACtE,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,IAAI,qBAAqB,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IACxE,IAAI,QAAQ,GAAG,mBAAmB,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAE5E,MAAM,IAAI,GAAG,mBAAmB,CAAC;QAC/B,KAAK,EAAE,KAAK;QACZ,UAAU,EAAE,QAAQ;QACpB,YAAY,EAAE,IAAI,CAAC,YAAY;KAChC,CAAC,CAAC;IAEH,MAAM,oBAAoB,GAAG,KAAK,IAAuC,EAAE;QACzE,MAAM,IAAI,GAA6B,EAAE,CAAC;QAC1C,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YAClC,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;YACpE,IAAI,CAAC,IAAI,CAAC;gBACR,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,IAAI;gBAClB,UAAU;gBACV,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,MAAM,EAAE,uBAAuB,CAAC,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC;aACpD,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG;QACX,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;QAC7C,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;QAC3C,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,cAAc,EAAE,IAAI,CAAC,cAAc;KACpC,CAAC;IAEF,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACxB,MAAM,cAAc,GAAG,MAAM,oBAAoB,EAAE,CAAC;QACpD,MAAM,EAAE,GAAG,wBAAwB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QACnF,MAAM,yBAAyB,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;QACzD,OAAO;YACL,IAAI,EAAE,KAAK;YACX,GAAG,IAAI;YACP,cAAc;YACd,kBAAkB,EAAE,EAAE,CAAC,gBAAgB;SACxC,CAAC;IACJ,CAAC;IAED,MAAM,eAAe,GAA4D,EAAE,CAAC;IAEpF,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,MAAM,oBAAoB,EAAE,CAAC;QAE7C,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACtB,MAAM,IAAI,WAAW,CACnB,wEAAwE,CACzE,CAAC;YACJ,CAAC;YACD,MAAM,IAAI,CAAC,WAAW,CAAC,qEAAqE,CAAC,CAAC;QAChG,CAAC;QAED,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7C,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;YACnE,eAAe,CAAC,IAAI,CAAC;gBACnB,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,GAAG,EAAE,GAAG,CAAC,GAAG;gBACZ,UAAU,EAAE,GAAG,CAAC,UAAU;gBAC1B,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;QACL,CAAC;QAED,QAAQ,GAAG,mBAAmB,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,EAAE,GAAG,wBAAwB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IACnF,MAAM,yBAAyB,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;IAEzD,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,GAAG,IAAI;QACP,eAAe;QACf,kBAAkB,EAAE,EAAE,CAAC,gBAAgB;KACxC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { EffectiveConfig } from "../config.js";
|
|
2
|
+
import { type ReconcileMode } from "./bracketReconcile.js";
|
|
3
|
+
import type { TradeStateFile } from "./schema.js";
|
|
4
|
+
import type { ReconcileAction } from "./types.js";
|
|
5
|
+
export type RunReconcileOptions = {
|
|
6
|
+
statePath: string;
|
|
7
|
+
cfg: EffectiveConfig;
|
|
8
|
+
mode: ReconcileMode;
|
|
9
|
+
assumeYes: boolean;
|
|
10
|
+
intentFilter?: string;
|
|
11
|
+
nowMs?: number;
|
|
12
|
+
confirmLive?: (prompt: string) => Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
export type RunReconcileResult = {
|
|
15
|
+
state: TradeStateFile;
|
|
16
|
+
actionsExecuted: ReconcileAction[];
|
|
17
|
+
dryPlan: ReconcileAction[];
|
|
18
|
+
};
|
|
19
|
+
export declare function runTradeReconcile(opts: RunReconcileOptions): Promise<RunReconcileResult>;
|
|
20
|
+
//# sourceMappingURL=runReconcile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runReconcile.d.ts","sourceRoot":"","sources":["../../../src/core/state/runReconcile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAgBpD,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,uBAAuB,CAAC;AAQ/B,OAAO,KAAK,EAAqC,cAAc,EAAE,MAAM,aAAa,CAAC;AAGrF,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,YAAY,CAAC;AAsCjE,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,eAAe,CAAC;IACrB,IAAI,EAAE,aAAa,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,cAAc,CAAC;IACtB,eAAe,EAAE,eAAe,EAAE,CAAC;IACnC,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA4P9F"}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { requireUserContext } from "../config.js";
|
|
2
|
+
import { ConfigError } from "../errors.js";
|
|
3
|
+
import { perpCoinToExchangeAssetId } from "../hyperliquid/asset.js";
|
|
4
|
+
import { HyperliquidInfoClient } from "../hyperliquid/client.js";
|
|
5
|
+
import { HyperliquidExchangeClient } from "../hyperliquid/exchange.js";
|
|
6
|
+
import { extractOrderOidsFromExchangeResponse } from "../hyperliquid/exchangeParse.js";
|
|
7
|
+
import { buildBracketProtectionOrderAction, buildCancelOrdersAction, buildPlaceOrderAction, } from "../hyperliquid/orders.js";
|
|
8
|
+
import { buildSignedExchangePayload } from "../hyperliquid/signed-exchange.js";
|
|
9
|
+
import { requireTraderWallet } from "../trading.js";
|
|
10
|
+
import { mergeBracketDedupe, reconcileBracketIntent, } from "./bracketReconcile.js";
|
|
11
|
+
import { garbageCollectTradeState } from "./gcTradeState.js";
|
|
12
|
+
import { applyGridCounterOrderSuccess, mergeGridReplenishDedupe, parseUserFills, reconcileGridIntent, } from "./gridReconcile.js";
|
|
13
|
+
import { normalizeOpenOrders, signedPositionSizeForCoin } from "./snapshot.js";
|
|
14
|
+
import { readOrCreateTradeStateFile, writeTradeStateFileAtomic } from "./store.js";
|
|
15
|
+
function isMainnet(cfg) {
|
|
16
|
+
return cfg.network === "mainnet";
|
|
17
|
+
}
|
|
18
|
+
function dedupeKeysForCancelEntry(intent) {
|
|
19
|
+
if (intent.phase === "expired") {
|
|
20
|
+
return ["cancel_entry_ttl"];
|
|
21
|
+
}
|
|
22
|
+
return ["cancel_entry_user"];
|
|
23
|
+
}
|
|
24
|
+
function narrowDedupeForCancelOrder(a) {
|
|
25
|
+
return a.reason === "tp_filled" ? `cancel_sl_after_tp:${a.oid}` : `cancel_tp_after_sl:${a.oid}`;
|
|
26
|
+
}
|
|
27
|
+
async function resolveAssetIndex(cfg, coin, dex) {
|
|
28
|
+
const info = new HyperliquidInfoClient({ infoOrigin: cfg.infoOrigin });
|
|
29
|
+
const meta = await info.meta(dex);
|
|
30
|
+
const perpDexs = dex ? await info.perpDexs() : undefined;
|
|
31
|
+
return perpCoinToExchangeAssetId({ coin, meta, dex, perpDexs });
|
|
32
|
+
}
|
|
33
|
+
async function postSigned(cfg, wallet, action) {
|
|
34
|
+
const ex = new HyperliquidExchangeClient({ apiOrigin: cfg.infoOrigin });
|
|
35
|
+
const body = await buildSignedExchangePayload(wallet, action, { isMainnet: isMainnet(cfg) });
|
|
36
|
+
return ex.exchange(body);
|
|
37
|
+
}
|
|
38
|
+
export async function runTradeReconcile(opts) {
|
|
39
|
+
const nowMs = opts.nowMs ?? Date.now();
|
|
40
|
+
const prior = await readOrCreateTradeStateFile(opts.statePath, nowMs);
|
|
41
|
+
const user = requireUserContext(opts.cfg);
|
|
42
|
+
const info = new HyperliquidInfoClient({ infoOrigin: user.infoOrigin });
|
|
43
|
+
const rawOpen = await info.openOrders(user.userAddress);
|
|
44
|
+
let openNorm = normalizeOpenOrders(rawOpen);
|
|
45
|
+
const ch = await info.clearinghouseState(user.userAddress);
|
|
46
|
+
const needsUserFills = Object.values(prior.intents).some((i) => i.kind === "grid");
|
|
47
|
+
let userFillsRaw;
|
|
48
|
+
if (needsUserFills) {
|
|
49
|
+
userFillsRaw = await info.userFills(user.userAddress);
|
|
50
|
+
}
|
|
51
|
+
const collected = [];
|
|
52
|
+
const dryPlan = [];
|
|
53
|
+
const executed = [];
|
|
54
|
+
const nextIntents = { ...prior.intents };
|
|
55
|
+
let chSnap = ch;
|
|
56
|
+
let liveConfirmed = false;
|
|
57
|
+
for (const [id, intent] of Object.entries(prior.intents)) {
|
|
58
|
+
if (opts.intentFilter && id !== opts.intentFilter) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (intent.kind === "grid") {
|
|
62
|
+
const fillRows = parseUserFills(userFillsRaw ?? null);
|
|
63
|
+
const r = reconcileGridIntent(intent, { nowMs, openOrders: openNorm }, { fillRows, mode: opts.mode });
|
|
64
|
+
collected.push(...r.events);
|
|
65
|
+
if (opts.mode === "dry") {
|
|
66
|
+
dryPlan.push(...r.actions);
|
|
67
|
+
nextIntents[id] = mergeGridReplenishDedupe(r.intent, r.dedupeToCommit, "dry", nowMs);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (r.actions.length === 0) {
|
|
71
|
+
nextIntents[id] = r.intent;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const trader = requireTraderWallet(opts.cfg);
|
|
75
|
+
if (!opts.assumeYes) {
|
|
76
|
+
if (!opts.confirmLive) {
|
|
77
|
+
throw new ConfigError("LIVE reconcile requires --assume-yes or an interactive confirm hook.");
|
|
78
|
+
}
|
|
79
|
+
if (!liveConfirmed) {
|
|
80
|
+
await opts.confirmLive("LIVE reconcile will submit exchange actions. Type YES to continue:\n");
|
|
81
|
+
liveConfirmed = true;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
let assetIndexCache;
|
|
85
|
+
let gridWorking = r.intent;
|
|
86
|
+
for (const act of r.actions) {
|
|
87
|
+
if (act.kind !== "place_grid_counter" && act.kind !== "place_grid_pending_leg") {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (assetIndexCache === undefined) {
|
|
91
|
+
assetIndexCache = await resolveAssetIndex(opts.cfg, gridWorking.coin, gridWorking.dex);
|
|
92
|
+
}
|
|
93
|
+
const leg = gridWorking.legs[act.legIndex];
|
|
94
|
+
if (!leg) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const action = buildPlaceOrderAction({
|
|
98
|
+
assetIndex: assetIndexCache,
|
|
99
|
+
isBuy: leg.isBuy,
|
|
100
|
+
limitPx: leg.px,
|
|
101
|
+
sz: gridWorking.orderSz,
|
|
102
|
+
reduceOnly: gridWorking.reduceOnly,
|
|
103
|
+
tif: gridWorking.tif,
|
|
104
|
+
});
|
|
105
|
+
const resp = await postSigned(opts.cfg, trader.wallet, action);
|
|
106
|
+
const oids = extractOrderOidsFromExchangeResponse(resp);
|
|
107
|
+
const placedOid = oids[0];
|
|
108
|
+
if (typeof placedOid !== "number" || !Number.isFinite(placedOid)) {
|
|
109
|
+
const label = act.kind === "place_grid_pending_leg" ? "pending grid leg" : "grid counter limit";
|
|
110
|
+
throw new ConfigError(`LIVE grid: exchange did not return an order id for ${label}.`);
|
|
111
|
+
}
|
|
112
|
+
gridWorking = applyGridCounterOrderSuccess(gridWorking, act.legIndex, placedOid, nowMs);
|
|
113
|
+
gridWorking = mergeGridReplenishDedupe(gridWorking, [act.replenishDedupeKey], "live", nowMs);
|
|
114
|
+
executed.push(act);
|
|
115
|
+
const rawOpenNext = await info.openOrders(user.userAddress);
|
|
116
|
+
openNorm = normalizeOpenOrders(rawOpenNext);
|
|
117
|
+
chSnap = await info.clearinghouseState(user.userAddress);
|
|
118
|
+
}
|
|
119
|
+
nextIntents[id] = gridWorking;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (intent.kind === "single_limit" || intent.kind === "standalone_tpsl") {
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
let working = intent;
|
|
126
|
+
const pos = signedPositionSizeForCoin(chSnap, working.coin);
|
|
127
|
+
const snap = {
|
|
128
|
+
nowMs,
|
|
129
|
+
openOrders: openNorm,
|
|
130
|
+
positionSigned: pos,
|
|
131
|
+
};
|
|
132
|
+
const r = reconcileBracketIntent(working, snap, opts.mode);
|
|
133
|
+
working = r.intent;
|
|
134
|
+
collected.push(...r.events);
|
|
135
|
+
if (opts.mode === "dry") {
|
|
136
|
+
dryPlan.push(...r.actions);
|
|
137
|
+
if (r.dedupeToCommit.length > 0) {
|
|
138
|
+
working = mergeBracketDedupe(working, r.dedupeToCommit, "dry", nowMs);
|
|
139
|
+
}
|
|
140
|
+
nextIntents[id] = working;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (r.actions.length > 0) {
|
|
144
|
+
const trader = requireTraderWallet(opts.cfg);
|
|
145
|
+
if (!opts.assumeYes) {
|
|
146
|
+
if (!opts.confirmLive) {
|
|
147
|
+
throw new ConfigError("LIVE reconcile requires --assume-yes or an interactive confirm hook.");
|
|
148
|
+
}
|
|
149
|
+
if (!liveConfirmed) {
|
|
150
|
+
await opts.confirmLive("LIVE reconcile will submit exchange actions. Type YES to continue:\n");
|
|
151
|
+
liveConfirmed = true;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
let assetIndexCache;
|
|
155
|
+
for (const act of r.actions) {
|
|
156
|
+
if (assetIndexCache === undefined) {
|
|
157
|
+
assetIndexCache = await resolveAssetIndex(opts.cfg, working.coin, working.dex);
|
|
158
|
+
}
|
|
159
|
+
const assetIndex = assetIndexCache;
|
|
160
|
+
if (act.kind === "place_entry_limit") {
|
|
161
|
+
const action = buildPlaceOrderAction({
|
|
162
|
+
assetIndex,
|
|
163
|
+
isBuy: working.entrySide === "buy",
|
|
164
|
+
limitPx: working.entryLimitPx,
|
|
165
|
+
sz: working.entrySz,
|
|
166
|
+
reduceOnly: Boolean(working.entryReduceOnly),
|
|
167
|
+
tif: working.tif,
|
|
168
|
+
});
|
|
169
|
+
const resp = await postSigned(opts.cfg, trader.wallet, action);
|
|
170
|
+
const oids = extractOrderOidsFromExchangeResponse(resp);
|
|
171
|
+
const oid = oids[0];
|
|
172
|
+
if (typeof oid === "number") {
|
|
173
|
+
working = {
|
|
174
|
+
...working,
|
|
175
|
+
entryOid: oid,
|
|
176
|
+
phase: "entry_pending",
|
|
177
|
+
updatedAtMs: nowMs,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
executed.push(act);
|
|
181
|
+
working = mergeBracketDedupe(working, ["place_entry"], "live", nowMs);
|
|
182
|
+
}
|
|
183
|
+
else if (act.kind === "place_protection_pair") {
|
|
184
|
+
const closeIsBuy = working.entrySide === "sell";
|
|
185
|
+
const isMarket = working.tpslIsMarket;
|
|
186
|
+
const limTp = working.tpslLimitPx ?? working.tpTriggerPx;
|
|
187
|
+
const limSl = working.tpslLimitPx ?? working.slTriggerPx;
|
|
188
|
+
const action = buildBracketProtectionOrderAction({
|
|
189
|
+
assetIndex,
|
|
190
|
+
closeIsBuy,
|
|
191
|
+
sz: working.entrySz,
|
|
192
|
+
reduceOnly: working.protectionReduceOnly !== false,
|
|
193
|
+
tpTriggerPx: working.tpTriggerPx,
|
|
194
|
+
slTriggerPx: working.slTriggerPx,
|
|
195
|
+
isMarket,
|
|
196
|
+
wireLimitPxTp: limTp,
|
|
197
|
+
wireLimitPxSl: limSl,
|
|
198
|
+
});
|
|
199
|
+
const resp = await postSigned(opts.cfg, trader.wallet, action);
|
|
200
|
+
const oids = extractOrderOidsFromExchangeResponse(resp);
|
|
201
|
+
const tpOid = oids[0];
|
|
202
|
+
const slOid = oids[1];
|
|
203
|
+
working = {
|
|
204
|
+
...working,
|
|
205
|
+
tpOid,
|
|
206
|
+
slOid,
|
|
207
|
+
protectionPlaced: true,
|
|
208
|
+
phase: "protection_active",
|
|
209
|
+
updatedAtMs: nowMs,
|
|
210
|
+
};
|
|
211
|
+
executed.push(act);
|
|
212
|
+
working = mergeBracketDedupe(working, ["place_protection"], "live", nowMs);
|
|
213
|
+
}
|
|
214
|
+
else if (act.kind === "cancel_intent_entry" || act.kind === "cancel_order") {
|
|
215
|
+
const cancelBody = buildCancelOrdersAction(assetIndex, [act.oid]);
|
|
216
|
+
await postSigned(opts.cfg, trader.wallet, cancelBody);
|
|
217
|
+
executed.push(act);
|
|
218
|
+
const keys = act.kind === "cancel_order"
|
|
219
|
+
? [narrowDedupeForCancelOrder(act)]
|
|
220
|
+
: dedupeKeysForCancelEntry(working);
|
|
221
|
+
working = mergeBracketDedupe(working, keys, "live", nowMs);
|
|
222
|
+
}
|
|
223
|
+
const rawOpenNext = await info.openOrders(user.userAddress);
|
|
224
|
+
openNorm = normalizeOpenOrders(rawOpenNext);
|
|
225
|
+
chSnap = await info.clearinghouseState(user.userAddress);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
nextIntents[id] = working;
|
|
229
|
+
}
|
|
230
|
+
const nextState = {
|
|
231
|
+
version: 1,
|
|
232
|
+
updatedAtMs: nowMs,
|
|
233
|
+
intents: nextIntents,
|
|
234
|
+
events: [...prior.events, ...collected],
|
|
235
|
+
};
|
|
236
|
+
const gc = garbageCollectTradeState({
|
|
237
|
+
state: nextState,
|
|
238
|
+
openOrders: openNorm,
|
|
239
|
+
nowMs,
|
|
240
|
+
});
|
|
241
|
+
await writeTradeStateFileAtomic(opts.statePath, gc.next);
|
|
242
|
+
return {
|
|
243
|
+
state: gc.next,
|
|
244
|
+
actionsExecuted: executed,
|
|
245
|
+
dryPlan,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=runReconcile.js.map
|