@reefclaw/openclaw-plugin 0.1.0
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/.gitignore +8 -0
- package/audit/mode-transition-audit.d.ts +11 -0
- package/audit/mode-transition-audit.js +29 -0
- package/balance-utils.d.ts +36 -0
- package/balance-utils.js +98 -0
- package/bridge/bridge.d.ts +109 -0
- package/bridge/bridge.js +1036 -0
- package/bridge/config.d.ts +43 -0
- package/bridge/config.js +176 -0
- package/bridge/connector.d.ts +52 -0
- package/bridge/connector.js +293 -0
- package/bridge/event-replay-buffer.d.ts +43 -0
- package/bridge/event-replay-buffer.js +109 -0
- package/bridge/gateway/event-parser.d.ts +209 -0
- package/bridge/gateway/event-parser.js +793 -0
- package/bridge/gateway/gateway-config.d.ts +39 -0
- package/bridge/gateway/gateway-config.js +86 -0
- package/bridge/gateway/gateway-http-client.d.ts +50 -0
- package/bridge/gateway/gateway-http-client.js +165 -0
- package/bridge/gateway/gateway-ws-client.d.ts +116 -0
- package/bridge/gateway/gateway-ws-client.js +417 -0
- package/bridge/gateway/poller.d.ts +146 -0
- package/bridge/gateway/poller.js +505 -0
- package/bridge/gateway/tool-discovery.d.ts +25 -0
- package/bridge/gateway/tool-discovery.js +198 -0
- package/bridge/index.d.ts +2 -0
- package/bridge/index.js +253 -0
- package/bridge/logger.d.ts +2 -0
- package/bridge/logger.js +2 -0
- package/bridge/provider.d.ts +156 -0
- package/bridge/provider.js +2 -0
- package/bridge/providers/emergency-commands.d.ts +54 -0
- package/bridge/providers/emergency-commands.js +235 -0
- package/bridge/providers/gateway.d.ts +322 -0
- package/bridge/providers/gateway.js +2302 -0
- package/bridge/providers/mock.d.ts +37 -0
- package/bridge/providers/mock.js +385 -0
- package/bridge/providers/onboarding-commands.d.ts +83 -0
- package/bridge/providers/onboarding-commands.js +213 -0
- package/bridge/providers/risk-calculator.d.ts +96 -0
- package/bridge/providers/risk-calculator.js +369 -0
- package/bridge/setup.d.ts +32 -0
- package/bridge/setup.js +226 -0
- package/bridge/types.d.ts +584 -0
- package/bridge/types.js +50 -0
- package/bridge/utils/reconnect.d.ts +6 -0
- package/bridge/utils/reconnect.js +6 -0
- package/bridge/utils/skill-signing.d.ts +51 -0
- package/bridge/utils/skill-signing.js +138 -0
- package/bridge/utils/skill-version.d.ts +17 -0
- package/bridge/utils/skill-version.js +74 -0
- package/ccxt/binance-ban-gate.d.ts +47 -0
- package/ccxt/binance-ban-gate.js +409 -0
- package/ccxt/binance-private.d.ts +325 -0
- package/ccxt/binance-private.js +1415 -0
- package/ccxt/binance-public.d.ts +18 -0
- package/ccxt/binance-public.js +147 -0
- package/config/agent-config-client.d.ts +55 -0
- package/config/agent-config-client.js +145 -0
- package/config/agent-config-poller.d.ts +25 -0
- package/config/agent-config-poller.js +100 -0
- package/config/brackets-config.d.ts +22 -0
- package/config/brackets-config.js +58 -0
- package/config/gate-store.d.ts +18 -0
- package/config/gate-store.js +61 -0
- package/config/plugin-config-io.d.ts +181 -0
- package/config/plugin-config-io.js +84 -0
- package/config/position-review-config.d.ts +35 -0
- package/config/position-review-config.js +105 -0
- package/config/tool-gate.d.ts +53 -0
- package/config/tool-gate.js +125 -0
- package/config/user-data-stream-config.d.ts +85 -0
- package/config/user-data-stream-config.js +224 -0
- package/connector-supervisor.d.ts +36 -0
- package/connector-supervisor.js +149 -0
- package/exchange-adapter.d.ts +49 -0
- package/exchange-adapter.js +4 -0
- package/index.d.ts +30 -0
- package/index.js +2030 -0
- package/ingest/pending-entry-metadata.d.ts +52 -0
- package/ingest/pending-entry-metadata.js +182 -0
- package/ingest/position-auto-capture.d.ts +98 -0
- package/ingest/position-auto-capture.js +394 -0
- package/ingest/position-decisions-client.d.ts +318 -0
- package/ingest/position-decisions-client.js +296 -0
- package/ingest/reconcile-db-vs-exchange.d.ts +13 -0
- package/ingest/reconcile-db-vs-exchange.js +114 -0
- package/ingest/reconciler-cleanup.d.ts +37 -0
- package/ingest/reconciler-cleanup.js +147 -0
- package/ingest/rest-gap-filler.d.ts +191 -0
- package/ingest/rest-gap-filler.js +565 -0
- package/ingest/touched-symbols-store.d.ts +25 -0
- package/ingest/touched-symbols-store.js +96 -0
- package/ingest/trade-store-client.d.ts +40 -0
- package/ingest/trade-store-client.js +125 -0
- package/ingest/ws-ingest.d.ts +43 -0
- package/ingest/ws-ingest.js +126 -0
- package/learning/setup-family.d.ts +21 -0
- package/learning/setup-family.js +103 -0
- package/lifecycle/install-signal-handlers.d.ts +33 -0
- package/lifecycle/install-signal-handlers.js +112 -0
- package/lifecycle/shutdown-coordinator.d.ts +43 -0
- package/lifecycle/shutdown-coordinator.js +131 -0
- package/live/bracket-id.d.ts +18 -0
- package/live/bracket-id.js +81 -0
- package/live/bracket-ledger.d.ts +54 -0
- package/live/bracket-ledger.js +267 -0
- package/live/bracket-manager.d.ts +82 -0
- package/live/bracket-manager.js +478 -0
- package/live/bracket-params.d.ts +22 -0
- package/live/bracket-params.js +124 -0
- package/live/bracket-reconciler.d.ts +95 -0
- package/live/bracket-reconciler.js +573 -0
- package/live/bracket-types.d.ts +102 -0
- package/live/bracket-types.js +8 -0
- package/live/deposit-tracker.d.ts +62 -0
- package/live/deposit-tracker.js +97 -0
- package/live/emergency-controls.d.ts +32 -0
- package/live/emergency-controls.js +226 -0
- package/live/exchange-errors.d.ts +12 -0
- package/live/exchange-errors.js +130 -0
- package/live/exchange-info-cache.d.ts +35 -0
- package/live/exchange-info-cache.js +119 -0
- package/live/fact-subscriber.d.ts +78 -0
- package/live/fact-subscriber.js +182 -0
- package/live/intent-journal.d.ts +42 -0
- package/live/intent-journal.js +122 -0
- package/live/listen-key-manager.d.ts +70 -0
- package/live/listen-key-manager.js +169 -0
- package/live/live-adapter.d.ts +264 -0
- package/live/live-adapter.js +1665 -0
- package/live/live-balance-enricher.d.ts +32 -0
- package/live/live-balance-enricher.js +104 -0
- package/live/live-bracket-api.d.ts +13 -0
- package/live/live-bracket-api.js +20 -0
- package/live/live-state-store.d.ts +194 -0
- package/live/live-state-store.js +450 -0
- package/live/local-signal-service.d.ts +57 -0
- package/live/local-signal-service.js +146 -0
- package/live/local-strategy-evaluator.d.ts +62 -0
- package/live/local-strategy-evaluator.js +127 -0
- package/live/microstructure-assembler.d.ts +54 -0
- package/live/microstructure-assembler.js +148 -0
- package/live/order-poller.d.ts +29 -0
- package/live/order-poller.js +125 -0
- package/live/position-state-store.d.ts +83 -0
- package/live/position-state-store.js +237 -0
- package/live/proposal-decision-listener.d.ts +64 -0
- package/live/proposal-decision-listener.js +288 -0
- package/live/proposal-manager.d.ts +76 -0
- package/live/proposal-manager.js +140 -0
- package/live/rate-limiter.d.ts +47 -0
- package/live/rate-limiter.js +159 -0
- package/live/reconciler.d.ts +39 -0
- package/live/reconciler.js +175 -0
- package/live/setup-buckets.d.ts +7 -0
- package/live/setup-buckets.js +33 -0
- package/live/slippage-tracker.d.ts +45 -0
- package/live/slippage-tracker.js +78 -0
- package/live/stop-watcher.d.ts +34 -0
- package/live/stop-watcher.js +158 -0
- package/live/user-data-active-probe.d.ts +54 -0
- package/live/user-data-active-probe.js +180 -0
- package/live/user-data-stream-controller.d.ts +200 -0
- package/live/user-data-stream-controller.js +579 -0
- package/live/user-data-stream-ws.d.ts +22 -0
- package/live/user-data-stream-ws.js +63 -0
- package/live/user-data-stream.d.ts +243 -0
- package/live/user-data-stream.js +704 -0
- package/logger.d.ts +2 -0
- package/logger.js +2 -0
- package/mfe.d.ts +21 -0
- package/mfe.js +68 -0
- package/onboarding/mode-ladder.d.ts +1 -0
- package/onboarding/mode-ladder.js +3 -0
- package/onboarding/runtime.d.ts +71 -0
- package/onboarding/runtime.js +153 -0
- package/openclaw.plugin.json +94 -0
- package/package.json +27 -0
- package/paper-adapter.d.ts +24 -0
- package/paper-adapter.js +91 -0
- package/persistence/state-manager.d.ts +42 -0
- package/persistence/state-manager.js +164 -0
- package/pinned-plan.d.ts +9 -0
- package/pinned-plan.js +23 -0
- package/risk/pre-trade-check.d.ts +38 -0
- package/risk/pre-trade-check.js +345 -0
- package/risk/pre-trade-types.d.ts +60 -0
- package/risk/pre-trade-types.js +3 -0
- package/scripts/assemble.mjs +114 -0
- package/shadow/shadow-tracker.d.ts +36 -0
- package/shadow/shadow-tracker.js +151 -0
- package/shadow/types.d.ts +42 -0
- package/shadow/types.js +20 -0
- package/shared/indicators-extended.d.ts +52 -0
- package/shared/indicators-extended.js +291 -0
- package/shared/indicators.d.ts +15 -0
- package/shared/indicators.js +114 -0
- package/signals/conditions/registry.d.ts +16 -0
- package/signals/conditions/registry.js +1274 -0
- package/signals/conditions/types.d.ts +1 -0
- package/signals/conditions/types.js +4 -0
- package/signals/direction-rules.d.ts +3 -0
- package/signals/direction-rules.js +24 -0
- package/signals/entry-rules.d.ts +6 -0
- package/signals/entry-rules.js +33 -0
- package/signals/serialize-context.d.ts +4 -0
- package/signals/serialize-context.js +39 -0
- package/signals/stop-rules.d.ts +3 -0
- package/signals/stop-rules.js +48 -0
- package/signals/strategy-adapter.d.ts +14 -0
- package/signals/strategy-adapter.js +122 -0
- package/signals/types.d.ts +1 -0
- package/signals/types.js +8 -0
- package/simulator/exchange-simulator.d.ts +93 -0
- package/simulator/exchange-simulator.js +684 -0
- package/simulator/fill-engine.d.ts +53 -0
- package/simulator/fill-engine.js +276 -0
- package/simulator/paper-market-feed.d.ts +26 -0
- package/simulator/paper-market-feed.js +104 -0
- package/simulator/realistic-fills.d.ts +59 -0
- package/simulator/realistic-fills.js +175 -0
- package/simulator/types.d.ts +219 -0
- package/simulator/types.js +43 -0
- package/skills/reefclaw/SKILL.md +97 -0
- package/strategy/builtin-strategies.d.ts +2 -0
- package/strategy/builtin-strategies.js +109 -0
- package/strategy/condition-registry.d.ts +3 -0
- package/strategy/condition-registry.js +153 -0
- package/strategy/evaluator.d.ts +67 -0
- package/strategy/evaluator.js +93 -0
- package/tools/assessment-validation.d.ts +118 -0
- package/tools/assessment-validation.js +415 -0
- package/tools/attach-brackets.d.ts +34 -0
- package/tools/attach-brackets.js +363 -0
- package/tools/audit-bracket-protection.d.ts +49 -0
- package/tools/audit-bracket-protection.js +527 -0
- package/tools/cancel-all-orders.d.ts +7 -0
- package/tools/cancel-all-orders.js +5 -0
- package/tools/cancel-order.d.ts +10 -0
- package/tools/cancel-order.js +14 -0
- package/tools/check-position-health.d.ts +46 -0
- package/tools/check-position-health.js +194 -0
- package/tools/clear-exchange-credentials.d.ts +24 -0
- package/tools/clear-exchange-credentials.js +70 -0
- package/tools/close-position.d.ts +22 -0
- package/tools/close-position.js +449 -0
- package/tools/create-order.d.ts +54 -0
- package/tools/create-order.js +338 -0
- package/tools/exit-gate.d.ts +58 -0
- package/tools/exit-gate.js +162 -0
- package/tools/fetch-balance.d.ts +5 -0
- package/tools/fetch-balance.js +4 -0
- package/tools/fetch-ohlcv.d.ts +11 -0
- package/tools/fetch-ohlcv.js +8 -0
- package/tools/fetch-open-orders.d.ts +7 -0
- package/tools/fetch-open-orders.js +4 -0
- package/tools/fetch-positions.d.ts +7 -0
- package/tools/fetch-positions.js +4 -0
- package/tools/fetch-ticker.d.ts +11 -0
- package/tools/fetch-ticker.js +5 -0
- package/tools/get-agent-profile.d.ts +4 -0
- package/tools/get-agent-profile.js +6 -0
- package/tools/get-analytics.d.ts +6 -0
- package/tools/get-analytics.js +7 -0
- package/tools/get-backtest.d.ts +12 -0
- package/tools/get-backtest.js +91 -0
- package/tools/get-basis.d.ts +7 -0
- package/tools/get-basis.js +7 -0
- package/tools/get-bracket-config.d.ts +11 -0
- package/tools/get-bracket-config.js +24 -0
- package/tools/get-cascade-risk.d.ts +7 -0
- package/tools/get-cascade-risk.js +8 -0
- package/tools/get-crypto-metrics.d.ts +18 -0
- package/tools/get-crypto-metrics.js +45 -0
- package/tools/get-cvd.d.ts +6 -0
- package/tools/get-cvd.js +6 -0
- package/tools/get-divergences.d.ts +6 -0
- package/tools/get-divergences.js +6 -0
- package/tools/get-funding-context.d.ts +6 -0
- package/tools/get-funding-context.js +16 -0
- package/tools/get-liquidation-levels.d.ts +7 -0
- package/tools/get-liquidation-levels.js +7 -0
- package/tools/get-liquidation-pulse.d.ts +9 -0
- package/tools/get-liquidation-pulse.js +22 -0
- package/tools/get-market-breadth.d.ts +6 -0
- package/tools/get-market-breadth.js +8 -0
- package/tools/get-market-intel.d.ts +19 -0
- package/tools/get-market-intel.js +116 -0
- package/tools/get-market-structure.d.ts +47 -0
- package/tools/get-market-structure.js +198 -0
- package/tools/get-my-mined-patterns.d.ts +20 -0
- package/tools/get-my-mined-patterns.js +61 -0
- package/tools/get-my-proposed-learnings.d.ts +20 -0
- package/tools/get-my-proposed-learnings.js +55 -0
- package/tools/get-my-recent-reviews.d.ts +22 -0
- package/tools/get-my-recent-reviews.js +66 -0
- package/tools/get-orderbook.d.ts +21 -0
- package/tools/get-orderbook.js +32 -0
- package/tools/get-pattern-scan.d.ts +7 -0
- package/tools/get-pattern-scan.js +8 -0
- package/tools/get-regime.d.ts +6 -0
- package/tools/get-regime.js +7 -0
- package/tools/get-relevant-learnings.d.ts +21 -0
- package/tools/get-relevant-learnings.js +65 -0
- package/tools/get-resting-liquidity.d.ts +6 -0
- package/tools/get-resting-liquidity.js +11 -0
- package/tools/get-risk-scenario.d.ts +29 -0
- package/tools/get-risk-scenario.js +47 -0
- package/tools/get-risk-summary.d.ts +51 -0
- package/tools/get-risk-summary.js +118 -0
- package/tools/get-sentiment.d.ts +4 -0
- package/tools/get-sentiment.js +6 -0
- package/tools/get-session-review.d.ts +7 -0
- package/tools/get-session-review.js +8 -0
- package/tools/get-setup-detail.d.ts +7 -0
- package/tools/get-setup-detail.js +303 -0
- package/tools/get-signals.d.ts +15 -0
- package/tools/get-signals.js +54 -0
- package/tools/get-sizing.d.ts +6 -0
- package/tools/get-sizing.js +6 -0
- package/tools/get-trade-feedback.d.ts +7 -0
- package/tools/get-trade-feedback.js +8 -0
- package/tools/get-trade-flow.d.ts +7 -0
- package/tools/get-trade-flow.js +7 -0
- package/tools/get-volume-analysis.d.ts +21 -0
- package/tools/get-volume-analysis.js +74 -0
- package/tools/get-volume-profile.d.ts +7 -0
- package/tools/get-volume-profile.js +7 -0
- package/tools/helpers.d.ts +25 -0
- package/tools/helpers.js +38 -0
- package/tools/intel-api.d.ts +14 -0
- package/tools/intel-api.js +52 -0
- package/tools/intel-cache.d.ts +25 -0
- package/tools/intel-cache.js +133 -0
- package/tools/list-strategies.d.ts +7 -0
- package/tools/list-strategies.js +6 -0
- package/tools/modify-stop.d.ts +17 -0
- package/tools/modify-stop.js +81 -0
- package/tools/modify-target.d.ts +17 -0
- package/tools/modify-target.js +71 -0
- package/tools/propose-learning.d.ts +22 -0
- package/tools/propose-learning.js +65 -0
- package/tools/query-review-outcomes.d.ts +30 -0
- package/tools/query-review-outcomes.js +64 -0
- package/tools/query-trades.d.ts +21 -0
- package/tools/query-trades.js +37 -0
- package/tools/record-position-reviews.d.ts +38 -0
- package/tools/record-position-reviews.js +147 -0
- package/tools/save-strategy.d.ts +16 -0
- package/tools/save-strategy.js +46 -0
- package/tools/scan-pairs.d.ts +18 -0
- package/tools/scan-pairs.js +220 -0
- package/tools/score-setup.d.ts +31 -0
- package/tools/score-setup.js +268 -0
- package/tools/set-bracket-requirement.d.ts +18 -0
- package/tools/set-bracket-requirement.js +81 -0
- package/tools/set-exchange-credentials.d.ts +25 -0
- package/tools/set-exchange-credentials.js +80 -0
- package/tools/set-trading-mode.d.ts +26 -0
- package/tools/set-trading-mode.js +135 -0
- package/tools/test-exchange-credentials.d.ts +16 -0
- package/tools/test-exchange-credentials.js +100 -0
- package/tools/toggle-strategy.d.ts +8 -0
- package/tools/toggle-strategy.js +8 -0
- package/trading-params-cache.d.ts +26 -0
- package/trading-params-cache.js +52 -0
- package/types.d.ts +110 -0
- package/types.js +7 -0
- package/util/plugin-paths.d.ts +3 -0
- package/util/plugin-paths.js +15 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import type { BinancePrivateApi } from '../ccxt/binance-private.js';
|
|
3
|
+
import { UserDataStream } from './user-data-stream.js';
|
|
4
|
+
import type { ParsedAlgoUpdate } from './user-data-stream.js';
|
|
5
|
+
import { LiveStateStore } from './live-state-store.js';
|
|
6
|
+
import type { RestSnapshot, StateDrift } from './live-state-store.js';
|
|
7
|
+
import type { UserDataStreamMode, UserDataStreamTunables } from '../config/user-data-stream-config.js';
|
|
8
|
+
import type { CcxtBalance } from '../types.js';
|
|
9
|
+
import type { TradeStoreClient } from '../ingest/trade-store-client.js';
|
|
10
|
+
import type { TouchedSymbolsStore } from '../ingest/touched-symbols-store.js';
|
|
11
|
+
import type { AutoCaptureContext } from '../ingest/position-auto-capture.js';
|
|
12
|
+
/**
|
|
13
|
+
* Rewrite `balance.total[asset]` from CCXT's marginBalance-equivalent (wallet
|
|
14
|
+
* + unrealizedProfit for Binance Futures) to raw walletBalance only, so the
|
|
15
|
+
* REST snapshot aligns with what the WS ACCOUNT_UPDATE frames deliver. The
|
|
16
|
+
* raw walletBalance field lives under `balance.info.assets[i].walletBalance`
|
|
17
|
+
* — an array of per-asset records Binance Futures always returns alongside
|
|
18
|
+
* the top-level totals. Exported for unit testing.
|
|
19
|
+
*
|
|
20
|
+
* Falls back to the unmodified balance if `info.assets` is missing or
|
|
21
|
+
* malformed (e.g. mock responses in unit tests without the info envelope).
|
|
22
|
+
* Only `total` is rewritten; `free` and `used` are left untouched because
|
|
23
|
+
* the WS store computes them separately from position-lock state.
|
|
24
|
+
*/
|
|
25
|
+
export declare function normalizeBinanceFuturesBalance(balance: CcxtBalance): CcxtBalance;
|
|
26
|
+
/**
|
|
27
|
+
* Thrown by `buildSnapshot` when ANY of the three REST fetches returned
|
|
28
|
+
* `null` — i.e. the fetch FAILED (Binance 429 / weight-paced / transient
|
|
29
|
+
* network), state is UNKNOWN. It does NOT mean "the account is flat / has no
|
|
30
|
+
* orders". `LiveStateStore.applySnapshot` replaces positions + orders +
|
|
31
|
+
* balances WHOLESALE, so applying a snapshot built from a failed fetch would
|
|
32
|
+
* wipe still-live positions and bracket SL/TP from the store — which is the
|
|
33
|
+
* AUTHORITATIVE read path in observe/enforce mode — blinding the agent into
|
|
34
|
+
* the documented phantom-naked spiral.
|
|
35
|
+
*
|
|
36
|
+
* Subclass of `Error` so the existing `.catch()` sites absorb it unchanged;
|
|
37
|
+
* callers detect the type to skip the apply, leave the store intact, and let
|
|
38
|
+
* WS deltas + the next reconnect/resync repair state. Same null≠empty rule as
|
|
39
|
+
* `getOpenOrders` / `getPositions` / `closePosition` / the bracket reconciler.
|
|
40
|
+
*/
|
|
41
|
+
export declare class UntrustedSnapshotError extends Error {
|
|
42
|
+
constructor(message: string);
|
|
43
|
+
}
|
|
44
|
+
export interface ControllerTimerDeps {
|
|
45
|
+
setInterval: (fn: () => void, ms: number) => ReturnType<typeof setInterval>;
|
|
46
|
+
clearInterval: (handle: ReturnType<typeof setInterval>) => void;
|
|
47
|
+
now: () => number;
|
|
48
|
+
}
|
|
49
|
+
export interface UserDataStreamControllerOptions {
|
|
50
|
+
mode: UserDataStreamMode;
|
|
51
|
+
testnet: boolean;
|
|
52
|
+
tunables: UserDataStreamTunables;
|
|
53
|
+
/** If absent, a real WS stream is built from `defaultWebSocketFactory`.
|
|
54
|
+
* Tests inject a prebuilt stream to avoid touching the network. */
|
|
55
|
+
stream?: UserDataStream;
|
|
56
|
+
/** If absent, a fresh LiveStateStore is constructed. */
|
|
57
|
+
store?: LiveStateStore;
|
|
58
|
+
/** 60_000 by default. Shorter values allowed for post-drift tightening. */
|
|
59
|
+
truthCheckIntervalMs?: number;
|
|
60
|
+
/** Timer injection for unit tests. */
|
|
61
|
+
timers?: Partial<ControllerTimerDeps>;
|
|
62
|
+
/** Audit-trail ingest path (TRADE_AUDIT_TRAIL_PLAN Phase 1). When present
|
|
63
|
+
* AND mode≠'off', the controller starts a WsIngest alongside the stream
|
|
64
|
+
* that POSTs every TRADE event to the webapp's /api/internal/trades.
|
|
65
|
+
* Caller decides whether to pass this in based on userDataStream.dbWrite. */
|
|
66
|
+
tradeIngest?: {
|
|
67
|
+
client: TradeStoreClient;
|
|
68
|
+
userId: string;
|
|
69
|
+
exchange?: string;
|
|
70
|
+
/** Optional override for the gap-filler's persistent touched-symbols
|
|
71
|
+
* store. Pass `null` to disable cross-restart persistence (tests).
|
|
72
|
+
* Production callers leave this undefined to get the file-backed
|
|
73
|
+
* default under ~/.reefclaw/touched-symbols-<userId>.json. */
|
|
74
|
+
touchedSymbolsStore?: TouchedSymbolsStore | null;
|
|
75
|
+
};
|
|
76
|
+
/** Position-decision auto-capture context. When provided alongside
|
|
77
|
+
* tradeIngest, the controller passes it to WsIngest so every TRADE event
|
|
78
|
+
* is also routed through `onWsFillObserved` (limit-order entries +
|
|
79
|
+
* scale-ins). When omitted, ws-ingest only records to the audit trail
|
|
80
|
+
* (the legacy PR1 behaviour). */
|
|
81
|
+
autoCapture?: AutoCaptureContext;
|
|
82
|
+
}
|
|
83
|
+
export type ControllerEvents = {
|
|
84
|
+
/** Emitted after every REST snapshot has been applied. */
|
|
85
|
+
snapshotApplied: (snap: RestSnapshot) => void;
|
|
86
|
+
/** Emitted when the 60s drift check finds anything (minor or major). */
|
|
87
|
+
drift: (drift: StateDrift) => void;
|
|
88
|
+
/** Emitted when a major drift triggered a forced resync. */
|
|
89
|
+
forcedResync: (cause: string) => void;
|
|
90
|
+
/** Emitted when the stream reports a reconnect — observability. */
|
|
91
|
+
reconnecting: (attempt: number, delayMs: number) => void;
|
|
92
|
+
/** Pass-through of advisory events from the stream. */
|
|
93
|
+
marginCall: (ev: unknown) => void;
|
|
94
|
+
/** Pass-through of ALGO_UPDATE (conditional/bracket order lifecycle).
|
|
95
|
+
* LiveAdapter consumes this as the AUTHORITATIVE bracket-state signal —
|
|
96
|
+
* Binance pushes EXPIRED when it auto-cancels a sibling on position
|
|
97
|
+
* close, CANCELED only on an explicit cancel, TRIGGERED/FINISHED on
|
|
98
|
+
* fire. Replaces REST-audit guessing. */
|
|
99
|
+
algoUpdate: (ev: ParsedAlgoUpdate) => void;
|
|
100
|
+
};
|
|
101
|
+
export declare class UserDataStreamController extends EventEmitter {
|
|
102
|
+
readonly mode: UserDataStreamMode;
|
|
103
|
+
private readonly api;
|
|
104
|
+
private readonly stream;
|
|
105
|
+
private readonly store;
|
|
106
|
+
private readonly truthCheckIntervalMs;
|
|
107
|
+
private readonly staleStoreThresholdMs;
|
|
108
|
+
private readonly timers;
|
|
109
|
+
private truthCheckTimer;
|
|
110
|
+
private algoRefreshTimer;
|
|
111
|
+
private reconnectRateTimer;
|
|
112
|
+
private readonly algoRefreshMs;
|
|
113
|
+
private readonly wsIngest;
|
|
114
|
+
private readonly restGapFiller;
|
|
115
|
+
private readonly activeProbe;
|
|
116
|
+
/** Count of stale-forced + other reconnects in the current hourly window.
|
|
117
|
+
* Checked every hour; a spike above RECONNECT_RATE_ALERT_THRESHOLD logs
|
|
118
|
+
* a WARN so operator can spot Binance-side trouble or network flaps. */
|
|
119
|
+
private reconnectCountThisHour;
|
|
120
|
+
private running;
|
|
121
|
+
private snapshotInFlight;
|
|
122
|
+
/** Serialises snapshot applies so WS events don't race with a snapshot
|
|
123
|
+
* we're in the middle of fetching. WS events that arrive during a
|
|
124
|
+
* snapshot are buffered here and drained after apply. */
|
|
125
|
+
private bufferedDuringSnapshot;
|
|
126
|
+
private consecutiveMajorDrifts;
|
|
127
|
+
constructor(api: BinancePrivateApi, options: UserDataStreamControllerOptions);
|
|
128
|
+
getStore(): LiveStateStore;
|
|
129
|
+
getStream(): UserDataStream;
|
|
130
|
+
/** True when the in-memory store is safe to serve as the authoritative
|
|
131
|
+
* source for positions/orders reads. Two independent conditions, BOTH
|
|
132
|
+
* required — each guards a distinct failure in the null≠empty class
|
|
133
|
+
* (same class as the getOpenOrders / getPositions / closePosition /
|
|
134
|
+
* bracket-reconciler / UntrustedSnapshotError rules):
|
|
135
|
+
*
|
|
136
|
+
* (1) **Seeded.** A trusted REST snapshot has run at least once
|
|
137
|
+
* (`lastSnapshotAt !== null`). False during startup before the
|
|
138
|
+
* `connected` handler's initial snapshot lands and the gap after
|
|
139
|
+
* `reset()`. An unseeded `[]` is indistinguishable from "no
|
|
140
|
+
* positions/orders" and would trip naked-bracket / orphan-cancel
|
|
141
|
+
* paths against real exchange state.
|
|
142
|
+
*
|
|
143
|
+
* (2) **Fresh.** We've received SOME incoming frame within
|
|
144
|
+
* `staleStoreThresholdMs` — the SAME calibrated threshold
|
|
145
|
+
* (`staleEventWatchdogMs`, default 6 min) and the SAME signal
|
|
146
|
+
* (`lastFrameAt`, any frame incl. Binance's 3-min server pings) the
|
|
147
|
+
* dead-socket watchdog itself uses to declare the socket dead.
|
|
148
|
+
* Beyond it the watchdog is already forcing a reconnect; serving a
|
|
149
|
+
* seeded-but-stale store as authoritative there would present stale
|
|
150
|
+
* state as truth on a destructive-action-gating read — the residual
|
|
151
|
+
* a reviewer flagged. Deliberately NOT a bare `isConnected()` check:
|
|
152
|
+
* a brief reconnect (listenKey rotation ~25 min, 1 s→60 s backoff)
|
|
153
|
+
* keeps `lastFrameAt` recent, so the common case is NOT pushed onto
|
|
154
|
+
* the weight-heavy / rate-limit-poisoned REST path — that would just
|
|
155
|
+
* trade one failure in this class for another. When the reconnect +
|
|
156
|
+
* resync completes, `lastFrameAt` refreshes and the store is trusted
|
|
157
|
+
* again. `lastFrameAt === null` (seeded but never a frame — an odd
|
|
158
|
+
* state) is conservatively treated as untrusted. */
|
|
159
|
+
isStoreTrusted(): boolean;
|
|
160
|
+
/** Start the stream + run the initial REST snapshot + seed the store.
|
|
161
|
+
* No-op if mode is 'off'. Throws if already running. */
|
|
162
|
+
start(): Promise<void>;
|
|
163
|
+
/** Graceful shutdown. */
|
|
164
|
+
stop(): Promise<void>;
|
|
165
|
+
/** Force a full snapshot + re-seed. Used by operator tools for manual resync. */
|
|
166
|
+
forceResync(cause: string): Promise<void>;
|
|
167
|
+
private buildStreamOptions;
|
|
168
|
+
private attachStreamHandlers;
|
|
169
|
+
/** Fetch REST positions/balance/orders and normalise symbols so the store
|
|
170
|
+
* keys match WS events regardless of which write path landed first.
|
|
171
|
+
* CCXT returns `BTC/USDT:USDT`; our WS parser produces `BTC/USDT`. */
|
|
172
|
+
private buildSnapshot;
|
|
173
|
+
private takeAndApplySnapshot;
|
|
174
|
+
private startTruthCheckLoop;
|
|
175
|
+
private stopTruthCheckLoop;
|
|
176
|
+
/** Start the algo-order refresh loop — REST-polls open orders and replaces
|
|
177
|
+
* the algo (bracket SL/TP) subset in the store. Fills the gap left by
|
|
178
|
+
* Binance's WS not emitting ORDER_TRADE_UPDATE for algo orders until they
|
|
179
|
+
* trigger. Disabled when algoRefreshMs === 0. */
|
|
180
|
+
private startAlgoRefreshLoop;
|
|
181
|
+
private stopAlgoRefreshLoop;
|
|
182
|
+
/** Alert threshold — hourly reconnect count that logs a WARN. Set at
|
|
183
|
+
* 10/hour because the natural baseline on a quiet account (listenKey
|
|
184
|
+
* rotation every 25 min + occasional stale-watchdog firing) is
|
|
185
|
+
* 3-4/hour; anything consistently above that is unexpected. Does NOT
|
|
186
|
+
* auto-pause or take action — operator investigates when they see
|
|
187
|
+
* the log line land. */
|
|
188
|
+
private static readonly RECONNECT_RATE_ALERT_THRESHOLD;
|
|
189
|
+
private static readonly RECONNECT_RATE_WINDOW_MS;
|
|
190
|
+
/** Start the reconnect-rate monitor. Runs hourly; resets the counter
|
|
191
|
+
* after each check whether or not it alerted. */
|
|
192
|
+
private startReconnectRateMonitor;
|
|
193
|
+
private stopReconnectRateMonitor;
|
|
194
|
+
/** One pass of algo-order refresh: fetch open orders (merges regular + algo
|
|
195
|
+
* via BinancePrivateApi), filter to algo-bracket cids, and hand them to the
|
|
196
|
+
* store's replaceAlgoOrders. No mutation if WS isn't connected (we'd be
|
|
197
|
+
* polluting state the reconnect snapshot is about to replace anyway). */
|
|
198
|
+
private runAlgoRefresh;
|
|
199
|
+
private runTruthCheck;
|
|
200
|
+
}
|