@reefclaw/connect 0.1.9 → 0.1.10
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/assets/plugin/ccxt/binance-private.d.ts +21 -0
- package/assets/plugin/ccxt/binance-private.js +132 -22
- package/assets/plugin/config/plugin-config-io.d.ts +6 -0
- package/assets/plugin/config/tool-gate.js +3 -0
- package/assets/plugin/exchange-adapter.d.ts +16 -0
- package/assets/plugin/index.js +551 -54
- package/assets/plugin/lifecycle/trading-operation-lock.d.ts +17 -0
- package/assets/plugin/lifecycle/trading-operation-lock.js +14 -0
- package/assets/plugin/live/bracket-id.d.ts +2 -3
- package/assets/plugin/live/bracket-id.js +22 -9
- package/assets/plugin/live/live-adapter.d.ts +24 -1
- package/assets/plugin/live/live-adapter.js +114 -2
- package/assets/plugin/live/local-signal-service.js +11 -6
- package/assets/plugin/live/local-strategy-evaluator.js +4 -0
- package/assets/plugin/live/proposal-decision-listener.d.ts +6 -0
- package/assets/plugin/live/proposal-decision-listener.js +4 -0
- package/assets/plugin/live/stop-watcher.d.ts +27 -1
- package/assets/plugin/live/stop-watcher.js +59 -2
- package/assets/plugin/onboarding/runtime.d.ts +13 -0
- package/assets/plugin/onboarding/runtime.js +22 -2
- package/assets/plugin/openclaw.plugin.json +1 -0
- package/assets/plugin/portfolio/wave9-admission.d.ts +67 -0
- package/assets/plugin/portfolio/wave9-admission.js +262 -0
- package/assets/plugin/portfolio/wave9-policy.d.ts +36 -0
- package/assets/plugin/portfolio/wave9-policy.js +183 -0
- package/assets/plugin/signals/conditions/registry.js +50 -0
- package/assets/plugin/simulator/exchange-simulator.js +5 -0
- package/assets/plugin/simulator/fill-engine.js +5 -1
- package/assets/plugin/simulator/types.d.ts +6 -1
- package/assets/plugin/strategy/evaluator.d.ts +3 -0
- package/assets/plugin/strategy/evaluator.js +5 -0
- package/assets/plugin/tools/assessment-validation.d.ts +2 -0
- package/assets/plugin/tools/attach-brackets.d.ts +7 -2
- package/assets/plugin/tools/attach-brackets.js +36 -0
- package/assets/plugin/tools/cancel-all-orders.d.ts +2 -0
- package/assets/plugin/tools/cancel-all-orders.js +4 -1
- package/assets/plugin/tools/cancel-order.d.ts +4 -0
- package/assets/plugin/tools/cancel-order.js +49 -3
- package/assets/plugin/tools/close-position.d.ts +23 -0
- package/assets/plugin/tools/close-position.js +286 -13
- package/assets/plugin/tools/create-order.d.ts +28 -0
- package/assets/plugin/tools/create-order.js +1364 -192
- package/assets/plugin/tools/get-analytics.js +2 -2
- package/assets/plugin/tools/get-basis.js +2 -2
- package/assets/plugin/tools/get-cascade-risk.js +2 -2
- package/assets/plugin/tools/get-crypto-metrics.js +14 -4
- package/assets/plugin/tools/get-cvd.js +2 -2
- package/assets/plugin/tools/get-divergences.js +2 -2
- package/assets/plugin/tools/get-funding-context.js +2 -2
- package/assets/plugin/tools/get-liquidation-levels.js +2 -2
- package/assets/plugin/tools/get-liquidation-pulse.js +2 -2
- package/assets/plugin/tools/get-pattern-scan.js +2 -2
- package/assets/plugin/tools/get-regime.js +2 -2
- package/assets/plugin/tools/get-resting-liquidity.js +2 -2
- package/assets/plugin/tools/get-risk-scenario.js +2 -2
- package/assets/plugin/tools/get-session-review.js +2 -2
- package/assets/plugin/tools/get-setup-detail.js +9 -1
- package/assets/plugin/tools/get-signals.js +2 -2
- package/assets/plugin/tools/get-sizing.js +2 -2
- package/assets/plugin/tools/get-trade-feedback.js +2 -2
- package/assets/plugin/tools/get-trade-flow.js +2 -2
- package/assets/plugin/tools/get-volume-profile.js +2 -2
- package/assets/plugin/tools/get-wave9-status.d.ts +127 -0
- package/assets/plugin/tools/get-wave9-status.js +796 -0
- package/assets/plugin/tools/intel-api.d.ts +20 -0
- package/assets/plugin/tools/intel-api.js +67 -0
- package/assets/plugin/tools/intel-cache.d.ts +1 -1
- package/assets/plugin/tools/intel-cache.js +20 -5
- package/assets/plugin/tools/list-strategies.d.ts +11 -1
- package/assets/plugin/tools/list-strategies.js +17 -0
- package/assets/plugin/tools/modify-stop.d.ts +4 -0
- package/assets/plugin/tools/modify-stop.js +63 -24
- package/assets/plugin/tools/modify-target.d.ts +4 -0
- package/assets/plugin/tools/modify-target.js +62 -23
- package/assets/plugin/tools/scan-pairs.js +19 -8
- package/assets/plugin/tools/toggle-strategy.js +7 -0
- package/assets/plugin/types.d.ts +5 -0
- package/assets/plugin/venues/hyperliquid/hl-balance.d.ts +116 -0
- package/assets/plugin/venues/hyperliquid/hl-balance.js +145 -0
- package/assets/plugin/venues/hyperliquid/hl-brackets.d.ts +102 -0
- package/assets/plugin/venues/hyperliquid/hl-brackets.js +172 -0
- package/assets/plugin/venues/hyperliquid/hl-cloid.d.ts +22 -0
- package/assets/plugin/venues/hyperliquid/hl-cloid.js +82 -0
- package/assets/plugin/venues/hyperliquid/hl-info-cache.d.ts +46 -0
- package/assets/plugin/venues/hyperliquid/hl-info-cache.js +125 -0
- package/assets/plugin/venues/hyperliquid/hl-live-adapter.d.ts +88 -0
- package/assets/plugin/venues/hyperliquid/hl-live-adapter.js +353 -0
- package/assets/plugin/venues/hyperliquid/hl-precision.d.ts +61 -0
- package/assets/plugin/venues/hyperliquid/hl-precision.js +176 -0
- package/assets/plugin/venues/hyperliquid/hl-private.d.ts +88 -0
- package/assets/plugin/venues/hyperliquid/hl-private.js +357 -0
- package/assets/plugin/venues/hyperliquid/hl-public.d.ts +31 -4
- package/assets/plugin/venues/hyperliquid/hl-public.js +155 -11
- package/assets/plugin/venues/hyperliquid/hl-rate-gate.d.ts +57 -0
- package/assets/plugin/venues/hyperliquid/hl-rate-gate.js +220 -0
- package/assets/plugin/venues/hyperliquid/hl-user-stream.d.ts +90 -0
- package/assets/plugin/venues/hyperliquid/hl-user-stream.js +220 -0
- package/assets/plugin/venues/registry.d.ts +23 -9
- package/assets/plugin/venues/registry.js +12 -13
- package/assets/plugin/venues/symbols.d.ts +43 -0
- package/assets/plugin/venues/symbols.js +107 -0
- package/assets/plugin/wave9/live-account-capture.d.ts +67 -0
- package/assets/plugin/wave9/live-account-capture.js +435 -0
- package/assets/plugin/wave9/live-autonomous-protection.d.ts +39 -0
- package/assets/plugin/wave9/live-autonomous-protection.js +112 -0
- package/assets/plugin/wave9/live-durable-reconciliation-scheduler.d.ts +33 -0
- package/assets/plugin/wave9/live-durable-reconciliation-scheduler.js +115 -0
- package/assets/plugin/wave9/live-execution-ledger.d.ts +107 -0
- package/assets/plugin/wave9/live-execution-ledger.js +498 -0
- package/assets/plugin/wave9/live-position-confirmation.d.ts +18 -0
- package/assets/plugin/wave9/live-position-confirmation.js +111 -0
- package/assets/plugin/wave9/live-residual-protection.d.ts +18 -0
- package/assets/plugin/wave9/live-residual-protection.js +250 -0
- package/assets/plugin/wave9/live-startup-reconciliation.d.ts +38 -0
- package/assets/plugin/wave9/live-startup-reconciliation.js +454 -0
- package/assets/plugin/wave9/live-symbol-ownership.d.ts +20 -0
- package/assets/plugin/wave9/live-symbol-ownership.js +132 -0
- package/assets/plugin/wave9/paper-admission-guard.d.ts +199 -0
- package/assets/plugin/wave9/paper-admission-guard.js +650 -0
- package/assets/plugin/wave9/usdm-evidence-provider.d.ts +42 -0
- package/assets/plugin/wave9/usdm-evidence-provider.js +133 -0
- package/assets/shared/portfolio/wave9-admission.d.ts +67 -0
- package/assets/shared/portfolio/wave9-admission.js +260 -0
- package/assets/shared/portfolio/wave9-policy.d.ts +36 -0
- package/assets/shared/portfolio/wave9-policy.js +176 -0
- package/assets/shared/signals/conditions/registry.js +50 -0
- package/assets/shared/signals/indicators-extended.d.ts +52 -0
- package/assets/shared/signals/indicators-extended.js +284 -0
- package/assets/shared/signals/indicators.d.ts +15 -0
- package/assets/shared/signals/indicators.js +107 -0
- package/dist/daemon.js +104 -0
- package/package.json +1 -1
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Shared indicator computation helpers.
|
|
2
|
+
// Used by both regime feature engineering and signal condition evaluation.
|
|
3
|
+
export function computeEMA(data, period) {
|
|
4
|
+
if (data.length < period)
|
|
5
|
+
return data[data.length - 1] ?? 0;
|
|
6
|
+
const k = 2 / (period + 1);
|
|
7
|
+
let ema = mean(data.slice(0, period));
|
|
8
|
+
for (let i = period; i < data.length; i++) {
|
|
9
|
+
ema = data[i] * k + ema * (1 - k);
|
|
10
|
+
}
|
|
11
|
+
return ema;
|
|
12
|
+
}
|
|
13
|
+
export function computeATR(highs, lows, closes, period) {
|
|
14
|
+
const series = computeATRSeries(highs, lows, closes, period);
|
|
15
|
+
return series[series.length - 1] ?? 0;
|
|
16
|
+
}
|
|
17
|
+
export function computeATRSeries(highs, lows, closes, period) {
|
|
18
|
+
if (highs.length < 2)
|
|
19
|
+
return [];
|
|
20
|
+
const tr = [];
|
|
21
|
+
for (let i = 1; i < highs.length; i++) {
|
|
22
|
+
tr.push(Math.max(highs[i] - lows[i], Math.abs(highs[i] - closes[i - 1]), Math.abs(lows[i] - closes[i - 1])));
|
|
23
|
+
}
|
|
24
|
+
const atr = [];
|
|
25
|
+
atr[0] = mean(tr.slice(0, period));
|
|
26
|
+
for (let i = 1; i < tr.length; i++) {
|
|
27
|
+
atr[i] = (atr[i - 1] * (period - 1) + tr[i]) / period;
|
|
28
|
+
}
|
|
29
|
+
return atr;
|
|
30
|
+
}
|
|
31
|
+
export function computeRSI(closes, period) {
|
|
32
|
+
if (closes.length < period + 1)
|
|
33
|
+
return 50;
|
|
34
|
+
const changes = [];
|
|
35
|
+
for (let i = 1; i < closes.length; i++) {
|
|
36
|
+
changes.push(closes[i] - closes[i - 1]);
|
|
37
|
+
}
|
|
38
|
+
let avgGain = 0;
|
|
39
|
+
let avgLoss = 0;
|
|
40
|
+
for (let i = 0; i < period; i++) {
|
|
41
|
+
if (changes[i] > 0)
|
|
42
|
+
avgGain += changes[i];
|
|
43
|
+
else
|
|
44
|
+
avgLoss -= changes[i];
|
|
45
|
+
}
|
|
46
|
+
avgGain /= period;
|
|
47
|
+
avgLoss /= period;
|
|
48
|
+
for (let i = period; i < changes.length; i++) {
|
|
49
|
+
const gain = changes[i] > 0 ? changes[i] : 0;
|
|
50
|
+
const loss = changes[i] < 0 ? -changes[i] : 0;
|
|
51
|
+
avgGain = (avgGain * (period - 1) + gain) / period;
|
|
52
|
+
avgLoss = (avgLoss * (period - 1) + loss) / period;
|
|
53
|
+
}
|
|
54
|
+
if (avgLoss === 0)
|
|
55
|
+
return 100;
|
|
56
|
+
const rs = avgGain / avgLoss;
|
|
57
|
+
return 100 - 100 / (1 + rs);
|
|
58
|
+
}
|
|
59
|
+
export function linearSlope(y, x) {
|
|
60
|
+
const n = y.length;
|
|
61
|
+
if (n < 2)
|
|
62
|
+
return 0;
|
|
63
|
+
const xs = x ?? Array.from({ length: n }, (_, i) => i);
|
|
64
|
+
const mx = mean(xs);
|
|
65
|
+
const my = mean(y);
|
|
66
|
+
let num = 0;
|
|
67
|
+
let den = 0;
|
|
68
|
+
for (let i = 0; i < n; i++) {
|
|
69
|
+
num += (xs[i] - mx) * (y[i] - my);
|
|
70
|
+
den += (xs[i] - mx) ** 2;
|
|
71
|
+
}
|
|
72
|
+
return den > 0 ? num / den : 0;
|
|
73
|
+
}
|
|
74
|
+
export function computeStd(data) {
|
|
75
|
+
if (data.length < 2)
|
|
76
|
+
return 0;
|
|
77
|
+
const avg = mean(data);
|
|
78
|
+
const variance = data.reduce((s, v) => s + (v - avg) ** 2, 0) / (data.length - 1);
|
|
79
|
+
return Math.sqrt(variance);
|
|
80
|
+
}
|
|
81
|
+
export function mean(data) {
|
|
82
|
+
if (data.length === 0)
|
|
83
|
+
return 0;
|
|
84
|
+
return data.reduce((s, v) => s + v, 0) / data.length;
|
|
85
|
+
}
|
|
86
|
+
/** Find swing highs and lows from OHLCV bars (simple pivot-point method). */
|
|
87
|
+
export function findSwingPoints(bars, lookback = 5) {
|
|
88
|
+
const highs = [];
|
|
89
|
+
const lows = [];
|
|
90
|
+
for (let i = lookback; i < bars.length - lookback; i++) {
|
|
91
|
+
let isHigh = true;
|
|
92
|
+
let isLow = true;
|
|
93
|
+
for (let j = i - lookback; j <= i + lookback; j++) {
|
|
94
|
+
if (j === i)
|
|
95
|
+
continue;
|
|
96
|
+
if (bars[j].high >= bars[i].high)
|
|
97
|
+
isHigh = false;
|
|
98
|
+
if (bars[j].low <= bars[i].low)
|
|
99
|
+
isLow = false;
|
|
100
|
+
}
|
|
101
|
+
if (isHigh)
|
|
102
|
+
highs.push(bars[i].high);
|
|
103
|
+
if (isLow)
|
|
104
|
+
lows.push(bars[i].low);
|
|
105
|
+
}
|
|
106
|
+
return { highs, lows };
|
|
107
|
+
}
|
package/dist/daemon.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// Keep the bridge running across reboots. Linux/systemd-user is implemented
|
|
2
|
+
// fully; macOS and Windows fall back to printing the manual run command (a
|
|
3
|
+
// launchd/Task-Scheduler unit is a follow-up). The bridge reads its config from
|
|
4
|
+
// ~/.openclaw/openclaw.json, so until the user pastes their connect message the
|
|
5
|
+
// service will start, find no token, and restart — harmless; it connects within
|
|
6
|
+
// seconds of the agent writing the config.
|
|
7
|
+
import { writeFileSync, mkdirSync } from 'node:fs';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import { homedir, userInfo } from 'node:os';
|
|
10
|
+
import { BRIDGE_DIR } from './paths.js';
|
|
11
|
+
import { run, which } from './exec.js';
|
|
12
|
+
import { step, ok, info, warn } from './ui.js';
|
|
13
|
+
const SERVICE_NAME = 'reefclaw-bridge';
|
|
14
|
+
const NODE = process.execPath; // absolute path to the node running the installer
|
|
15
|
+
/**
|
|
16
|
+
* Build the systemd user-unit text. Pure + exported so the path-quoting is
|
|
17
|
+
* unit-testable. Both `node` (process.execPath) and `bridgeDir` (under the
|
|
18
|
+
* user's home) can contain spaces. Quoting rules differ per directive:
|
|
19
|
+
* - ExecStart= is parsed with shell-like word splitting, so an unquoted
|
|
20
|
+
* `ExecStart=/home/a b/node …` reads the binary as `/home/a` — QUOTE both
|
|
21
|
+
* the binary and the script path.
|
|
22
|
+
* - WorkingDirectory= takes the raw value after `=` as a single path (no word
|
|
23
|
+
* splitting) — spaces are safe UNQUOTED, and quotes are treated as literal
|
|
24
|
+
* characters, failing the unit with "path is not absolute" (verified live
|
|
25
|
+
* on systemd 255 / Ubuntu 24.04). Do NOT quote it.
|
|
26
|
+
*/
|
|
27
|
+
export function buildSystemdUnit(node, bridgeDir) {
|
|
28
|
+
const indexJs = join(bridgeDir, 'index.js');
|
|
29
|
+
return `[Unit]
|
|
30
|
+
Description=ReefClaw connector - bridges OpenClaw to the ReefClaw dashboard
|
|
31
|
+
After=network-online.target
|
|
32
|
+
Wants=network-online.target
|
|
33
|
+
|
|
34
|
+
[Service]
|
|
35
|
+
Type=simple
|
|
36
|
+
WorkingDirectory=${bridgeDir}
|
|
37
|
+
ExecStart="${node}" "${indexJs}" --provider gateway --log-level info
|
|
38
|
+
Restart=always
|
|
39
|
+
RestartSec=5s
|
|
40
|
+
|
|
41
|
+
[Install]
|
|
42
|
+
WantedBy=default.target
|
|
43
|
+
`;
|
|
44
|
+
}
|
|
45
|
+
function manualHint() {
|
|
46
|
+
warn('Could not set up an auto-start service on this OS yet.');
|
|
47
|
+
info('Keep the connector running with this command (leave it open / use your own service manager):');
|
|
48
|
+
info(` "${NODE}" "${join(BRIDGE_DIR, 'index.js')}" --provider gateway`);
|
|
49
|
+
}
|
|
50
|
+
function installSystemd() {
|
|
51
|
+
if (!which('systemctl'))
|
|
52
|
+
return false;
|
|
53
|
+
const unitDir = join(homedir(), '.config', 'systemd', 'user');
|
|
54
|
+
mkdirSync(unitDir, { recursive: true });
|
|
55
|
+
const unit = buildSystemdUnit(NODE, BRIDGE_DIR);
|
|
56
|
+
writeFileSync(join(unitDir, `${SERVICE_NAME}.service`), unit, 'utf-8');
|
|
57
|
+
run('systemctl', ['--user', 'daemon-reload']);
|
|
58
|
+
const enabled = run('systemctl', ['--user', 'enable', '--now', `${SERVICE_NAME}.service`]);
|
|
59
|
+
if (!enabled.ok) {
|
|
60
|
+
warn('systemd --user enable/start did not succeed:');
|
|
61
|
+
if (enabled.stderr.trim())
|
|
62
|
+
info(enabled.stderr.trim().split('\n').slice(-2).join('\n'));
|
|
63
|
+
info(`Try: systemctl --user enable --now ${SERVICE_NAME}.service`);
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
// `enable --now` can exit 0 while the unit failed to load (e.g. a bad unit
|
|
67
|
+
// file setting) — verify the unit actually came up before claiming ✓.
|
|
68
|
+
// 'active' = running; 'activating' = the expected pre-token restart loop
|
|
69
|
+
// (the bridge exits until the user pastes their connect message, and
|
|
70
|
+
// Restart=always re-launches it). Anything else (inactive/failed) means the
|
|
71
|
+
// unit never loaded.
|
|
72
|
+
const active = run('systemctl', ['--user', 'is-active', `${SERVICE_NAME}.service`]);
|
|
73
|
+
const state = active.stdout.trim();
|
|
74
|
+
if (state !== 'active' && state !== 'activating') {
|
|
75
|
+
warn(`the service did not come up (state: ${state || 'unknown'}).`);
|
|
76
|
+
info(`Inspect: systemctl --user status ${SERVICE_NAME}.service`);
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
// Linger lets the user service run without an active login session (servers).
|
|
80
|
+
// Best-effort: needs privileges; non-fatal if it fails.
|
|
81
|
+
const linger = run('loginctl', ['enable-linger', userInfo().username]);
|
|
82
|
+
if (linger.ok) {
|
|
83
|
+
info('enabled linger (service survives logout / reboot)');
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
info('note: run `sudo loginctl enable-linger $USER` so the connector survives logout.');
|
|
87
|
+
}
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
export function installDaemon() {
|
|
91
|
+
step('Starting the connector as a background service');
|
|
92
|
+
if (process.platform === 'linux') {
|
|
93
|
+
if (installSystemd()) {
|
|
94
|
+
ok(`connector running as a systemd user service (${SERVICE_NAME})`);
|
|
95
|
+
info(`logs: journalctl --user -u ${SERVICE_NAME} -f`);
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
manualHint();
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
// macOS / Windows: manual for now (launchd / Task Scheduler unit is a follow-up).
|
|
102
|
+
manualHint();
|
|
103
|
+
return false;
|
|
104
|
+
}
|