@reefclaw/connect 0.1.12 → 0.1.13
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/audit/mode-transition-audit.d.ts +11 -0
- package/assets/plugin/audit/mode-transition-audit.js +29 -0
- package/assets/plugin/balance-utils.d.ts +36 -0
- package/assets/plugin/balance-utils.js +98 -0
- package/assets/plugin/ccxt/binance-ban-gate.d.ts +47 -0
- package/assets/plugin/ccxt/binance-ban-gate.js +420 -0
- package/assets/plugin/ccxt/binance-private.d.ts +346 -0
- package/assets/plugin/ccxt/binance-private.js +1525 -0
- package/assets/plugin/ccxt/binance-public.d.ts +34 -0
- package/assets/plugin/ccxt/binance-public.js +180 -0
- package/assets/plugin/ccxt/intel-public.d.ts +25 -0
- package/assets/plugin/ccxt/intel-public.js +80 -0
- package/assets/plugin/ccxt/public-market-data-api.d.ts +26 -0
- package/assets/plugin/ccxt/public-market-data-api.js +23 -0
- package/assets/plugin/config/agent-config-client.d.ts +77 -0
- package/assets/plugin/config/agent-config-client.js +188 -0
- package/assets/plugin/config/agent-config-poller.d.ts +32 -0
- package/assets/plugin/config/agent-config-poller.js +101 -0
- package/assets/plugin/config/brackets-config.d.ts +22 -0
- package/assets/plugin/config/brackets-config.js +58 -0
- package/assets/plugin/config/entitlement-gate.d.ts +51 -0
- package/assets/plugin/config/entitlement-gate.js +137 -0
- package/assets/plugin/config/gate-store.d.ts +18 -0
- package/assets/plugin/config/gate-store.js +61 -0
- package/assets/plugin/config/plugin-config-io.d.ts +222 -0
- package/assets/plugin/config/plugin-config-io.js +126 -0
- package/assets/plugin/config/position-review-config.d.ts +35 -0
- package/assets/plugin/config/position-review-config.js +105 -0
- package/assets/plugin/config/tool-gate.d.ts +53 -0
- package/assets/plugin/config/tool-gate.js +128 -0
- package/assets/plugin/config/user-data-stream-config.d.ts +89 -0
- package/assets/plugin/config/user-data-stream-config.js +239 -0
- package/assets/plugin/connector-supervisor.d.ts +36 -0
- package/assets/plugin/connector-supervisor.js +149 -0
- package/assets/plugin/exchange-adapter.d.ts +65 -0
- package/assets/plugin/exchange-adapter.js +4 -0
- package/assets/plugin/index.d.ts +30 -0
- package/assets/plugin/index.js +2763 -0
- package/assets/plugin/ingest/pending-entry-metadata.d.ts +74 -0
- package/assets/plugin/ingest/pending-entry-metadata.js +236 -0
- package/assets/plugin/ingest/position-auto-capture.d.ts +171 -0
- package/assets/plugin/ingest/position-auto-capture.js +709 -0
- package/assets/plugin/ingest/position-decisions-client.d.ts +327 -0
- package/assets/plugin/ingest/position-decisions-client.js +306 -0
- package/assets/plugin/ingest/readiness-reporter.d.ts +42 -0
- package/assets/plugin/ingest/readiness-reporter.js +163 -0
- package/assets/plugin/ingest/reconcile-db-vs-exchange.d.ts +51 -0
- package/assets/plugin/ingest/reconcile-db-vs-exchange.js +170 -0
- package/assets/plugin/ingest/reconciler-cleanup.d.ts +37 -0
- package/assets/plugin/ingest/reconciler-cleanup.js +147 -0
- package/assets/plugin/ingest/rest-gap-filler.d.ts +191 -0
- package/assets/plugin/ingest/rest-gap-filler.js +565 -0
- package/assets/plugin/ingest/touched-symbols-store.d.ts +25 -0
- package/assets/plugin/ingest/touched-symbols-store.js +96 -0
- package/assets/plugin/ingest/trade-store-client.d.ts +40 -0
- package/assets/plugin/ingest/trade-store-client.js +125 -0
- package/assets/plugin/ingest/ws-ingest.d.ts +43 -0
- package/assets/plugin/ingest/ws-ingest.js +126 -0
- package/assets/plugin/learning/setup-family.d.ts +21 -0
- package/assets/plugin/learning/setup-family.js +103 -0
- package/assets/plugin/lifecycle/install-signal-handlers.d.ts +33 -0
- package/assets/plugin/lifecycle/install-signal-handlers.js +112 -0
- package/assets/plugin/lifecycle/shutdown-coordinator.d.ts +43 -0
- package/assets/plugin/lifecycle/shutdown-coordinator.js +131 -0
- 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 +26 -0
- package/assets/plugin/live/bracket-id.js +112 -0
- package/assets/plugin/live/bracket-ledger.d.ts +54 -0
- package/assets/plugin/live/bracket-ledger.js +267 -0
- package/assets/plugin/live/bracket-manager.d.ts +82 -0
- package/assets/plugin/live/bracket-manager.js +478 -0
- package/assets/plugin/live/bracket-params.d.ts +22 -0
- package/assets/plugin/live/bracket-params.js +124 -0
- package/assets/plugin/live/bracket-reconciler.d.ts +95 -0
- package/assets/plugin/live/bracket-reconciler.js +573 -0
- package/assets/plugin/live/bracket-types.d.ts +102 -0
- package/assets/plugin/live/bracket-types.js +8 -0
- package/assets/plugin/live/deposit-tracker.d.ts +62 -0
- package/assets/plugin/live/deposit-tracker.js +97 -0
- package/assets/plugin/live/emergency-controls.d.ts +32 -0
- package/assets/plugin/live/emergency-controls.js +226 -0
- package/assets/plugin/live/exchange-errors.d.ts +12 -0
- package/assets/plugin/live/exchange-errors.js +130 -0
- package/assets/plugin/live/exchange-info-cache.d.ts +37 -0
- package/assets/plugin/live/exchange-info-cache.js +134 -0
- package/assets/plugin/live/fact-subscriber.d.ts +78 -0
- package/assets/plugin/live/fact-subscriber.js +182 -0
- package/assets/plugin/live/fill-price.d.ts +13 -0
- package/assets/plugin/live/fill-price.js +37 -0
- package/assets/plugin/live/intent-journal.d.ts +42 -0
- package/assets/plugin/live/intent-journal.js +122 -0
- package/assets/plugin/live/listen-key-manager.d.ts +70 -0
- package/assets/plugin/live/listen-key-manager.js +169 -0
- package/assets/plugin/live/live-adapter.d.ts +319 -0
- package/assets/plugin/live/live-adapter.js +1906 -0
- package/assets/plugin/live/live-balance-enricher.d.ts +32 -0
- package/assets/plugin/live/live-balance-enricher.js +104 -0
- package/assets/plugin/live/live-bracket-api.d.ts +13 -0
- package/assets/plugin/live/live-bracket-api.js +20 -0
- package/assets/plugin/live/live-state-store.d.ts +194 -0
- package/assets/plugin/live/live-state-store.js +450 -0
- package/assets/plugin/live/local-signal-service.d.ts +57 -0
- package/assets/plugin/live/local-signal-service.js +151 -0
- package/assets/plugin/live/local-strategy-evaluator.d.ts +62 -0
- package/assets/plugin/live/local-strategy-evaluator.js +131 -0
- package/assets/plugin/live/microstructure-assembler.d.ts +54 -0
- package/assets/plugin/live/microstructure-assembler.js +148 -0
- package/assets/plugin/live/order-poller.d.ts +29 -0
- package/assets/plugin/live/order-poller.js +125 -0
- package/assets/plugin/live/position-state-store.d.ts +87 -0
- package/assets/plugin/live/position-state-store.js +237 -0
- package/assets/plugin/live/proposal-decision-listener.d.ts +70 -0
- package/assets/plugin/live/proposal-decision-listener.js +292 -0
- package/assets/plugin/live/proposal-manager.d.ts +76 -0
- package/assets/plugin/live/proposal-manager.js +140 -0
- package/assets/plugin/live/rate-limiter.d.ts +47 -0
- package/assets/plugin/live/rate-limiter.js +159 -0
- package/assets/plugin/live/reconciler.d.ts +39 -0
- package/assets/plugin/live/reconciler.js +175 -0
- package/assets/plugin/live/setup-buckets.d.ts +7 -0
- package/assets/plugin/live/setup-buckets.js +33 -0
- package/assets/plugin/live/slippage-tracker.d.ts +45 -0
- package/assets/plugin/live/slippage-tracker.js +78 -0
- package/assets/plugin/live/stop-watcher.d.ts +67 -0
- package/assets/plugin/live/stop-watcher.js +218 -0
- package/assets/plugin/live/user-data-active-probe.d.ts +54 -0
- package/assets/plugin/live/user-data-active-probe.js +180 -0
- package/assets/plugin/live/user-data-stream-controller.d.ts +200 -0
- package/assets/plugin/live/user-data-stream-controller.js +579 -0
- package/assets/plugin/live/user-data-stream-ws.d.ts +22 -0
- package/assets/plugin/live/user-data-stream-ws.js +63 -0
- package/assets/plugin/live/user-data-stream.d.ts +243 -0
- package/assets/plugin/live/user-data-stream.js +704 -0
- package/assets/plugin/logger.d.ts +2 -0
- package/assets/plugin/logger.js +2 -0
- package/assets/plugin/mfe.d.ts +21 -0
- package/assets/plugin/mfe.js +68 -0
- package/assets/plugin/onboarding/mode-ladder.d.ts +1 -0
- package/assets/plugin/onboarding/mode-ladder.js +3 -0
- package/assets/plugin/onboarding/runtime.d.ts +102 -0
- package/assets/plugin/onboarding/runtime.js +215 -0
- package/assets/plugin/openclaw.plugin.json +92 -0
- package/assets/plugin/paper-adapter.d.ts +24 -0
- package/assets/plugin/paper-adapter.js +91 -0
- package/assets/plugin/persistence/state-manager.d.ts +66 -0
- package/assets/plugin/persistence/state-manager.js +222 -0
- package/assets/plugin/pinned-plan.d.ts +9 -0
- package/assets/plugin/pinned-plan.js +23 -0
- package/assets/plugin/portfolio/reentry-tracker.d.ts +36 -0
- package/assets/plugin/portfolio/reentry-tracker.js +127 -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/risk/pre-trade-check.d.ts +38 -0
- package/assets/plugin/risk/pre-trade-check.js +345 -0
- package/assets/plugin/risk/pre-trade-types.d.ts +60 -0
- package/assets/plugin/risk/pre-trade-types.js +3 -0
- package/assets/plugin/shadow/shadow-tracker.d.ts +36 -0
- package/assets/plugin/shadow/shadow-tracker.js +151 -0
- package/assets/plugin/shadow/types.d.ts +42 -0
- package/assets/plugin/shadow/types.js +20 -0
- package/assets/plugin/shared/indicators-extended.d.ts +52 -0
- package/assets/plugin/shared/indicators-extended.js +291 -0
- package/assets/plugin/shared/indicators.d.ts +15 -0
- package/assets/plugin/shared/indicators.js +114 -0
- package/assets/plugin/signals/conditions/registry.d.ts +16 -0
- package/assets/plugin/signals/conditions/registry.js +1333 -0
- package/assets/plugin/signals/conditions/types.d.ts +1 -0
- package/assets/plugin/signals/conditions/types.js +4 -0
- package/assets/plugin/signals/direction-rules.d.ts +3 -0
- package/assets/plugin/signals/direction-rules.js +24 -0
- package/assets/plugin/signals/entry-rules.d.ts +6 -0
- package/assets/plugin/signals/entry-rules.js +33 -0
- package/assets/plugin/signals/serialize-context.d.ts +4 -0
- package/assets/plugin/signals/serialize-context.js +39 -0
- package/assets/plugin/signals/stop-rules.d.ts +3 -0
- package/assets/plugin/signals/stop-rules.js +48 -0
- package/assets/plugin/signals/strategy-adapter.d.ts +47 -0
- package/assets/plugin/signals/strategy-adapter.js +209 -0
- package/assets/plugin/signals/types.d.ts +1 -0
- package/assets/plugin/signals/types.js +8 -0
- package/assets/plugin/simulator/exchange-simulator.d.ts +105 -0
- package/assets/plugin/simulator/exchange-simulator.js +759 -0
- package/assets/plugin/simulator/fill-engine.d.ts +53 -0
- package/assets/plugin/simulator/fill-engine.js +280 -0
- package/assets/plugin/simulator/paper-market-feed.d.ts +26 -0
- package/assets/plugin/simulator/paper-market-feed.js +104 -0
- package/assets/plugin/simulator/realistic-fills.d.ts +59 -0
- package/assets/plugin/simulator/realistic-fills.js +175 -0
- package/assets/plugin/simulator/types.d.ts +228 -0
- package/assets/plugin/simulator/types.js +43 -0
- package/assets/plugin/strategy/builtin-strategies.d.ts +2 -0
- package/assets/plugin/strategy/builtin-strategies.js +113 -0
- package/assets/plugin/strategy/condition-registry.d.ts +3 -0
- package/assets/plugin/strategy/condition-registry.js +153 -0
- package/assets/plugin/strategy/evaluator.d.ts +70 -0
- package/assets/plugin/strategy/evaluator.js +98 -0
- package/assets/plugin/tools/assessment-validation.d.ts +141 -0
- package/assets/plugin/tools/assessment-validation.js +473 -0
- package/assets/plugin/tools/attach-brackets.d.ts +39 -0
- package/assets/plugin/tools/attach-brackets.js +564 -0
- package/assets/plugin/tools/audit-bracket-protection.d.ts +49 -0
- package/assets/plugin/tools/audit-bracket-protection.js +683 -0
- package/assets/plugin/tools/bracket-control.d.ts +12 -0
- package/assets/plugin/tools/bracket-control.js +35 -0
- package/assets/plugin/tools/cancel-all-orders.d.ts +9 -0
- package/assets/plugin/tools/cancel-all-orders.js +8 -0
- package/assets/plugin/tools/cancel-order.d.ts +14 -0
- package/assets/plugin/tools/cancel-order.js +60 -0
- package/assets/plugin/tools/check-position-health.d.ts +46 -0
- package/assets/plugin/tools/check-position-health.js +194 -0
- package/assets/plugin/tools/clear-exchange-credentials.d.ts +24 -0
- package/assets/plugin/tools/clear-exchange-credentials.js +70 -0
- package/assets/plugin/tools/close-position.d.ts +45 -0
- package/assets/plugin/tools/close-position.js +722 -0
- package/assets/plugin/tools/create-order.d.ts +89 -0
- package/assets/plugin/tools/create-order.js +1555 -0
- package/assets/plugin/tools/exit-gate.d.ts +58 -0
- package/assets/plugin/tools/exit-gate.js +162 -0
- package/assets/plugin/tools/fetch-balance.d.ts +5 -0
- package/assets/plugin/tools/fetch-balance.js +4 -0
- package/assets/plugin/tools/fetch-ohlcv.d.ts +11 -0
- package/assets/plugin/tools/fetch-ohlcv.js +8 -0
- package/assets/plugin/tools/fetch-open-orders.d.ts +7 -0
- package/assets/plugin/tools/fetch-open-orders.js +4 -0
- package/assets/plugin/tools/fetch-positions.d.ts +7 -0
- package/assets/plugin/tools/fetch-positions.js +4 -0
- package/assets/plugin/tools/fetch-ticker.d.ts +11 -0
- package/assets/plugin/tools/fetch-ticker.js +5 -0
- package/assets/plugin/tools/get-agent-profile.d.ts +4 -0
- package/assets/plugin/tools/get-agent-profile.js +6 -0
- package/assets/plugin/tools/get-analytics.d.ts +6 -0
- package/assets/plugin/tools/get-analytics.js +7 -0
- package/assets/plugin/tools/get-backtest.d.ts +12 -0
- package/assets/plugin/tools/get-backtest.js +91 -0
- package/assets/plugin/tools/get-basis.d.ts +7 -0
- package/assets/plugin/tools/get-basis.js +7 -0
- package/assets/plugin/tools/get-bracket-config.d.ts +11 -0
- package/assets/plugin/tools/get-bracket-config.js +24 -0
- package/assets/plugin/tools/get-cascade-risk.d.ts +7 -0
- package/assets/plugin/tools/get-cascade-risk.js +8 -0
- package/assets/plugin/tools/get-crypto-metrics.d.ts +18 -0
- package/assets/plugin/tools/get-crypto-metrics.js +62 -0
- package/assets/plugin/tools/get-cvd.d.ts +6 -0
- package/assets/plugin/tools/get-cvd.js +6 -0
- package/assets/plugin/tools/get-divergences.d.ts +6 -0
- package/assets/plugin/tools/get-divergences.js +6 -0
- package/assets/plugin/tools/get-funding-context.d.ts +6 -0
- package/assets/plugin/tools/get-funding-context.js +16 -0
- package/assets/plugin/tools/get-liquidation-levels.d.ts +7 -0
- package/assets/plugin/tools/get-liquidation-levels.js +7 -0
- package/assets/plugin/tools/get-liquidation-pulse.d.ts +9 -0
- package/assets/plugin/tools/get-liquidation-pulse.js +22 -0
- package/assets/plugin/tools/get-market-breadth.d.ts +6 -0
- package/assets/plugin/tools/get-market-breadth.js +8 -0
- package/assets/plugin/tools/get-market-intel.d.ts +19 -0
- package/assets/plugin/tools/get-market-intel.js +116 -0
- package/assets/plugin/tools/get-market-structure.d.ts +47 -0
- package/assets/plugin/tools/get-market-structure.js +198 -0
- package/assets/plugin/tools/get-my-mined-patterns.d.ts +20 -0
- package/assets/plugin/tools/get-my-mined-patterns.js +61 -0
- package/assets/plugin/tools/get-my-proposed-learnings.d.ts +20 -0
- package/assets/plugin/tools/get-my-proposed-learnings.js +55 -0
- package/assets/plugin/tools/get-my-recent-reviews.d.ts +22 -0
- package/assets/plugin/tools/get-my-recent-reviews.js +66 -0
- package/assets/plugin/tools/get-orderbook.d.ts +21 -0
- package/assets/plugin/tools/get-orderbook.js +32 -0
- package/assets/plugin/tools/get-pattern-scan.d.ts +7 -0
- package/assets/plugin/tools/get-pattern-scan.js +8 -0
- package/assets/plugin/tools/get-regime.d.ts +6 -0
- package/assets/plugin/tools/get-regime.js +7 -0
- package/assets/plugin/tools/get-relevant-learnings.d.ts +21 -0
- package/assets/plugin/tools/get-relevant-learnings.js +65 -0
- package/assets/plugin/tools/get-resting-liquidity.d.ts +6 -0
- package/assets/plugin/tools/get-resting-liquidity.js +11 -0
- package/assets/plugin/tools/get-risk-scenario.d.ts +29 -0
- package/assets/plugin/tools/get-risk-scenario.js +47 -0
- package/assets/plugin/tools/get-risk-summary.d.ts +51 -0
- package/assets/plugin/tools/get-risk-summary.js +118 -0
- package/assets/plugin/tools/get-sentiment.d.ts +4 -0
- package/assets/plugin/tools/get-sentiment.js +6 -0
- package/assets/plugin/tools/get-session-review.d.ts +7 -0
- package/assets/plugin/tools/get-session-review.js +8 -0
- package/assets/plugin/tools/get-setup-detail.d.ts +7 -0
- package/assets/plugin/tools/get-setup-detail.js +322 -0
- package/assets/plugin/tools/get-signals.d.ts +15 -0
- package/assets/plugin/tools/get-signals.js +54 -0
- package/assets/plugin/tools/get-sizing.d.ts +6 -0
- package/assets/plugin/tools/get-sizing.js +6 -0
- package/assets/plugin/tools/get-trade-feedback.d.ts +7 -0
- package/assets/plugin/tools/get-trade-feedback.js +8 -0
- package/assets/plugin/tools/get-trade-flow.d.ts +7 -0
- package/assets/plugin/tools/get-trade-flow.js +7 -0
- package/assets/plugin/tools/get-volume-analysis.d.ts +21 -0
- package/assets/plugin/tools/get-volume-analysis.js +74 -0
- package/assets/plugin/tools/get-volume-profile.d.ts +7 -0
- package/assets/plugin/tools/get-volume-profile.js +7 -0
- 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/helpers.d.ts +26 -0
- package/assets/plugin/tools/helpers.js +39 -0
- package/assets/plugin/tools/intel-api.d.ts +34 -0
- package/assets/plugin/tools/intel-api.js +119 -0
- package/assets/plugin/tools/intel-cache.d.ts +25 -0
- package/assets/plugin/tools/intel-cache.js +148 -0
- package/assets/plugin/tools/list-strategies.d.ts +17 -0
- package/assets/plugin/tools/list-strategies.js +23 -0
- package/assets/plugin/tools/modify-stop.d.ts +21 -0
- package/assets/plugin/tools/modify-stop.js +120 -0
- package/assets/plugin/tools/modify-target.d.ts +21 -0
- package/assets/plugin/tools/modify-target.js +110 -0
- package/assets/plugin/tools/propose-learning.d.ts +22 -0
- package/assets/plugin/tools/propose-learning.js +65 -0
- package/assets/plugin/tools/query-review-outcomes.d.ts +30 -0
- package/assets/plugin/tools/query-review-outcomes.js +64 -0
- package/assets/plugin/tools/query-trades.d.ts +21 -0
- package/assets/plugin/tools/query-trades.js +37 -0
- package/assets/plugin/tools/record-position-reviews.d.ts +38 -0
- package/assets/plugin/tools/record-position-reviews.js +147 -0
- package/assets/plugin/tools/save-strategy.d.ts +16 -0
- package/assets/plugin/tools/save-strategy.js +46 -0
- package/assets/plugin/tools/scan-pairs.d.ts +22 -0
- package/assets/plugin/tools/scan-pairs.js +234 -0
- package/assets/plugin/tools/score-setup.d.ts +31 -0
- package/assets/plugin/tools/score-setup.js +268 -0
- package/assets/plugin/tools/set-bracket-requirement.d.ts +18 -0
- package/assets/plugin/tools/set-bracket-requirement.js +81 -0
- package/assets/plugin/tools/set-exchange-credentials.d.ts +25 -0
- package/assets/plugin/tools/set-exchange-credentials.js +80 -0
- package/assets/plugin/tools/set-trading-mode.d.ts +26 -0
- package/assets/plugin/tools/set-trading-mode.js +152 -0
- package/assets/plugin/tools/test-exchange-credentials.d.ts +16 -0
- package/assets/plugin/tools/test-exchange-credentials.js +100 -0
- package/assets/plugin/tools/toggle-strategy.d.ts +8 -0
- package/assets/plugin/tools/toggle-strategy.js +15 -0
- package/assets/plugin/trading-params-cache.d.ts +26 -0
- package/assets/plugin/trading-params-cache.js +52 -0
- package/assets/plugin/types.d.ts +134 -0
- package/assets/plugin/types.js +7 -0
- package/assets/plugin/util/plugin-paths.d.ts +3 -0
- package/assets/plugin/util/plugin-paths.js +15 -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-bracket-coordinator.d.ts +123 -0
- package/assets/plugin/venues/hyperliquid/hl-bracket-coordinator.js +533 -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 +146 -0
- package/assets/plugin/venues/hyperliquid/hl-live-adapter.js +728 -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 +79 -0
- package/assets/plugin/venues/hyperliquid/hl-public.js +436 -0
- 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 +38 -0
- package/assets/plugin/venues/registry.js +46 -0
- 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/package.json +1 -1
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
export interface PositionDecisionsClientOptions {
|
|
2
|
+
baseUrl: string;
|
|
3
|
+
ingestToken: string;
|
|
4
|
+
fetchImpl?: typeof fetch;
|
|
5
|
+
requestTimeoutMs?: number;
|
|
6
|
+
maxAttempts?: number;
|
|
7
|
+
baseBackoffMs?: number;
|
|
8
|
+
backoffCapMs?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface PositionUpsertPayload {
|
|
11
|
+
symbol: string;
|
|
12
|
+
positionOpenAt: number;
|
|
13
|
+
side: 'long' | 'short';
|
|
14
|
+
currentSize: number;
|
|
15
|
+
avgEntryPrice: number;
|
|
16
|
+
/** Trading mode the position was opened in ('paper' | 'live'). Tags the
|
|
17
|
+
* journal row so paper and live positions can be segregated. Omitted only
|
|
18
|
+
* if the active adapter can't be resolved (treated as legacy/NULL). */
|
|
19
|
+
mode?: 'paper' | 'live';
|
|
20
|
+
/** Venue the position was opened on ('binance' | 'hyperliquid') — journal /
|
|
21
|
+
* analytics segmentation (fees + funding cadence differ per venue).
|
|
22
|
+
* Absent → NULL (legacy binance), mirroring `mode`. Migration 0058. */
|
|
23
|
+
exchange?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface PositionEntryPayload {
|
|
26
|
+
positionId: string;
|
|
27
|
+
entryAt: number;
|
|
28
|
+
isScaleIn?: boolean;
|
|
29
|
+
thesis: string;
|
|
30
|
+
setupType: string;
|
|
31
|
+
regime: string;
|
|
32
|
+
regimeConfidence: number;
|
|
33
|
+
scorecardVerdict: string;
|
|
34
|
+
confluenceScore: number;
|
|
35
|
+
confluenceComponents?: Record<string, unknown>;
|
|
36
|
+
fillPrice: number;
|
|
37
|
+
fillSize: number;
|
|
38
|
+
exchangeTradeId?: string;
|
|
39
|
+
metadata?: Record<string, unknown>;
|
|
40
|
+
}
|
|
41
|
+
export interface PositionReviewPayload {
|
|
42
|
+
positionId: string;
|
|
43
|
+
reviewAt?: number;
|
|
44
|
+
verdict: 'hold' | 'add_on' | 'close_recommended';
|
|
45
|
+
thesisStatus: 'intact' | 'weakening' | 'invalidated' | 'evolving';
|
|
46
|
+
entryScore: number;
|
|
47
|
+
currentScore: number;
|
|
48
|
+
scoreDelta: number;
|
|
49
|
+
confluenceComponents: Record<string, unknown>;
|
|
50
|
+
regimeEntry: string;
|
|
51
|
+
regimeCurrent: string;
|
|
52
|
+
regimeConfidence: number;
|
|
53
|
+
rMultiple: number;
|
|
54
|
+
distanceToStopBps: number;
|
|
55
|
+
distanceToTargetBps?: number | null;
|
|
56
|
+
timeInPositionMinutes: number;
|
|
57
|
+
mfeR: number;
|
|
58
|
+
giveBackPct: number;
|
|
59
|
+
whatChanged: string;
|
|
60
|
+
invalidationTrigger: string;
|
|
61
|
+
restingBandImbalance05?: number | null;
|
|
62
|
+
cascadePulseAtReview?: 'quiet' | 'elevated' | 'active_cascade' | null;
|
|
63
|
+
coveragePctAtReview?: number | null;
|
|
64
|
+
imbalanceDeltaSinceEntry?: number | null;
|
|
65
|
+
metadata?: Record<string, unknown>;
|
|
66
|
+
}
|
|
67
|
+
export interface PositionClosePayload {
|
|
68
|
+
positionId: string;
|
|
69
|
+
closeAt: number;
|
|
70
|
+
closeReason: string;
|
|
71
|
+
closeAssessment: Record<string, unknown>;
|
|
72
|
+
scorecardVerdict: string;
|
|
73
|
+
confluenceScore: number;
|
|
74
|
+
regime: string;
|
|
75
|
+
regimeConfidence: number;
|
|
76
|
+
fillPrice: number;
|
|
77
|
+
fillSize: number;
|
|
78
|
+
realizedPnl: number;
|
|
79
|
+
realizedR: number;
|
|
80
|
+
mfeRAtClose: number;
|
|
81
|
+
giveBackPctAtClose: number;
|
|
82
|
+
exchangeTradeId?: string;
|
|
83
|
+
metadata?: Record<string, unknown>;
|
|
84
|
+
}
|
|
85
|
+
/** Row shape from GET /api/internal/positions?status=open (DB-vs-exchange
|
|
86
|
+
* reconcile). Keyed off the DB row id so a wiped state-store can't hide it. */
|
|
87
|
+
export interface OpenPositionRow {
|
|
88
|
+
id: string;
|
|
89
|
+
symbol: string;
|
|
90
|
+
side: 'long' | 'short';
|
|
91
|
+
remainingSize: number;
|
|
92
|
+
entryPrice: number;
|
|
93
|
+
openedAt: number;
|
|
94
|
+
}
|
|
95
|
+
export interface OpenPositionsResponse {
|
|
96
|
+
positions: OpenPositionRow[];
|
|
97
|
+
}
|
|
98
|
+
export interface PositionDecisionsClientHealth {
|
|
99
|
+
inFlight: number;
|
|
100
|
+
totalPosted: number;
|
|
101
|
+
totalSucceeded: number;
|
|
102
|
+
totalDroppedTerminal: number;
|
|
103
|
+
totalDroppedRetriesExhausted: number;
|
|
104
|
+
}
|
|
105
|
+
export interface PriorReview {
|
|
106
|
+
reviewAt: number;
|
|
107
|
+
verdict: 'hold' | 'add_on' | 'close_recommended';
|
|
108
|
+
thesisStatus: 'intact' | 'weakening' | 'invalidated' | 'evolving';
|
|
109
|
+
scoreDelta: number;
|
|
110
|
+
currentScore: number;
|
|
111
|
+
rMultiple: number;
|
|
112
|
+
regimeCurrent: string;
|
|
113
|
+
whatChanged: string;
|
|
114
|
+
}
|
|
115
|
+
export interface VerdictStreak {
|
|
116
|
+
verdict: 'hold' | 'add_on' | 'close_recommended';
|
|
117
|
+
consecutiveCount: number;
|
|
118
|
+
thesisProgression: ('intact' | 'weakening' | 'invalidated' | 'evolving')[];
|
|
119
|
+
truncated: boolean;
|
|
120
|
+
}
|
|
121
|
+
export interface ReentryContext {
|
|
122
|
+
recentOpenedCount: number;
|
|
123
|
+
recentClosedCount: number;
|
|
124
|
+
recentClosedRealizedR: number[];
|
|
125
|
+
minutesSinceLastClose: number | null;
|
|
126
|
+
}
|
|
127
|
+
export interface PositionReviewContext {
|
|
128
|
+
positionId: string;
|
|
129
|
+
symbol: string;
|
|
130
|
+
side: 'long' | 'short';
|
|
131
|
+
openedAt: number;
|
|
132
|
+
reviews: PriorReview[];
|
|
133
|
+
verdictStreak: VerdictStreak | null;
|
|
134
|
+
reentryContext: ReentryContext | null;
|
|
135
|
+
}
|
|
136
|
+
export interface RecentReviewsResponse {
|
|
137
|
+
positions: PositionReviewContext[];
|
|
138
|
+
}
|
|
139
|
+
export interface ReviewOutcomesFilters {
|
|
140
|
+
verdict?: 'hold' | 'add_on' | 'close_recommended';
|
|
141
|
+
thesisStatus?: 'intact' | 'weakening' | 'invalidated' | 'evolving';
|
|
142
|
+
regimeCurrent?: string;
|
|
143
|
+
symbol?: string;
|
|
144
|
+
side?: 'long' | 'short';
|
|
145
|
+
setupType?: string;
|
|
146
|
+
daysBack?: number;
|
|
147
|
+
minScoreDelta?: number;
|
|
148
|
+
maxScoreDelta?: number;
|
|
149
|
+
closedOnly?: boolean;
|
|
150
|
+
sampleLimit?: number;
|
|
151
|
+
}
|
|
152
|
+
export interface ReviewOutcomesStats {
|
|
153
|
+
nTotal: number;
|
|
154
|
+
nClosed: number;
|
|
155
|
+
winRate: number | null;
|
|
156
|
+
medianR: number | null;
|
|
157
|
+
meanR: number | null;
|
|
158
|
+
medianGiveBack: number | null;
|
|
159
|
+
p25R: number | null;
|
|
160
|
+
p75R: number | null;
|
|
161
|
+
outcomeCounts: Record<string, number>;
|
|
162
|
+
}
|
|
163
|
+
export interface ReviewOutcomeSample {
|
|
164
|
+
reviewId: string;
|
|
165
|
+
positionId: string;
|
|
166
|
+
reviewAt: string;
|
|
167
|
+
symbol: string;
|
|
168
|
+
side: 'long' | 'short';
|
|
169
|
+
verdict: string;
|
|
170
|
+
thesisStatus: string;
|
|
171
|
+
regimeCurrent: string;
|
|
172
|
+
setupType: string | null;
|
|
173
|
+
scoreDelta: number;
|
|
174
|
+
rAtReview: number;
|
|
175
|
+
mfeAtReview: number;
|
|
176
|
+
whatChanged: string;
|
|
177
|
+
positionStatus: 'open' | 'closed';
|
|
178
|
+
closeAt: string | null;
|
|
179
|
+
finalRealizedR: number | null;
|
|
180
|
+
finalCloseReason: string | null;
|
|
181
|
+
minutesReviewToClose: number | null;
|
|
182
|
+
}
|
|
183
|
+
export interface ReviewOutcomesResponse {
|
|
184
|
+
filters: Record<string, unknown>;
|
|
185
|
+
stats: ReviewOutcomesStats;
|
|
186
|
+
sample: ReviewOutcomeSample[];
|
|
187
|
+
}
|
|
188
|
+
export interface RelevantLearning {
|
|
189
|
+
id: string;
|
|
190
|
+
title: string;
|
|
191
|
+
directive: string;
|
|
192
|
+
triggerCondition: Record<string, unknown> | null;
|
|
193
|
+
evidence: Record<string, unknown> | null;
|
|
194
|
+
lastValidatedAt: string | null;
|
|
195
|
+
updatedAt: string;
|
|
196
|
+
}
|
|
197
|
+
export interface RelevantLearningsResponse {
|
|
198
|
+
learnings: RelevantLearning[];
|
|
199
|
+
appliesAt: 'entry' | 'heartbeat' | 'close';
|
|
200
|
+
totalCandidates: number;
|
|
201
|
+
returnedCount: number;
|
|
202
|
+
}
|
|
203
|
+
export interface RelevantLearningsFilters {
|
|
204
|
+
appliesAt: 'entry' | 'heartbeat' | 'close';
|
|
205
|
+
setupType?: string;
|
|
206
|
+
regime?: string;
|
|
207
|
+
verdict?: 'hold' | 'add_on' | 'close_recommended';
|
|
208
|
+
}
|
|
209
|
+
export interface MyMinedPattern {
|
|
210
|
+
id: string;
|
|
211
|
+
patternType: string;
|
|
212
|
+
matchConditions: Record<string, unknown>;
|
|
213
|
+
sampleSize: number;
|
|
214
|
+
baselineValue: number | null;
|
|
215
|
+
observedValue: number | null;
|
|
216
|
+
effectSize: number;
|
|
217
|
+
pValue: number;
|
|
218
|
+
humanSummary: string;
|
|
219
|
+
minedAt: string;
|
|
220
|
+
dateRangeEnd: string | null;
|
|
221
|
+
promotedToLearningId: string | null;
|
|
222
|
+
}
|
|
223
|
+
export interface MyMinedPatternsResponse {
|
|
224
|
+
patterns: MyMinedPattern[];
|
|
225
|
+
totalReturned: number;
|
|
226
|
+
}
|
|
227
|
+
export interface MyMinedPatternsFilters {
|
|
228
|
+
withinDays?: number;
|
|
229
|
+
minSampleSize?: number;
|
|
230
|
+
maxPValue?: number;
|
|
231
|
+
includePromoted?: boolean;
|
|
232
|
+
}
|
|
233
|
+
export interface MyProposedLearning {
|
|
234
|
+
id: string;
|
|
235
|
+
confidence: 'hypothesis' | 'confirmed' | 'retired';
|
|
236
|
+
appliesAt: 'entry' | 'heartbeat' | 'close';
|
|
237
|
+
title: string;
|
|
238
|
+
directive: string;
|
|
239
|
+
triggerCondition: Record<string, unknown> | null;
|
|
240
|
+
evidence: Record<string, unknown> | null;
|
|
241
|
+
sourceMinedPatternId: string | null;
|
|
242
|
+
proposedBy: 'operator' | 'agent';
|
|
243
|
+
autoConfirmed: boolean;
|
|
244
|
+
createdAt: string;
|
|
245
|
+
updatedAt: string;
|
|
246
|
+
}
|
|
247
|
+
export interface MyProposedLearningsResponse {
|
|
248
|
+
learnings: MyProposedLearning[];
|
|
249
|
+
totalReturned: number;
|
|
250
|
+
}
|
|
251
|
+
export interface MyProposedLearningsFilters {
|
|
252
|
+
includeHypothesis?: boolean;
|
|
253
|
+
includeConfirmed?: boolean;
|
|
254
|
+
includeRetired?: boolean;
|
|
255
|
+
proposedBy?: 'agent' | 'operator';
|
|
256
|
+
}
|
|
257
|
+
export interface ProposeLearningPayload {
|
|
258
|
+
appliesAt: 'entry' | 'heartbeat' | 'close';
|
|
259
|
+
title: string;
|
|
260
|
+
directive: string;
|
|
261
|
+
sourceMinedPatternId?: string;
|
|
262
|
+
triggerCondition?: Record<string, unknown>;
|
|
263
|
+
evidence?: Record<string, unknown>;
|
|
264
|
+
}
|
|
265
|
+
export interface ProposeLearningResponse {
|
|
266
|
+
id: string;
|
|
267
|
+
confidence: 'hypothesis' | 'confirmed';
|
|
268
|
+
autoConfirmed: boolean;
|
|
269
|
+
trustMode: 'manual' | 'auto';
|
|
270
|
+
proposalsUsed: number;
|
|
271
|
+
proposalsLimit: number;
|
|
272
|
+
}
|
|
273
|
+
export declare class PositionDecisionsClient {
|
|
274
|
+
private readonly opts;
|
|
275
|
+
private inFlight;
|
|
276
|
+
private totalPosted;
|
|
277
|
+
private totalSucceeded;
|
|
278
|
+
private totalDroppedTerminal;
|
|
279
|
+
private totalDroppedRetriesExhausted;
|
|
280
|
+
constructor(options: PositionDecisionsClientOptions);
|
|
281
|
+
/** Awaited — the auto-capture pipeline needs the returned positionId before
|
|
282
|
+
* posting children. Returns null on terminal failure (caller logs + drops). */
|
|
283
|
+
postPosition(userId: string, payload: PositionUpsertPayload): Promise<string | null>;
|
|
284
|
+
/** Fire-and-forget. */
|
|
285
|
+
postEntry(userId: string, payload: PositionEntryPayload): void;
|
|
286
|
+
/** Fire-and-forget. */
|
|
287
|
+
postReview(userId: string, payload: PositionReviewPayload): void;
|
|
288
|
+
/** Fire-and-forget. */
|
|
289
|
+
postClose(userId: string, payload: PositionClosePayload): void;
|
|
290
|
+
/** DB-vs-exchange reconcile read: this tenant's open positions. Awaited.
|
|
291
|
+
* Returns null on terminal/retry-exhausted failure — the caller MUST treat
|
|
292
|
+
* null as UNKNOWN (never as "no open rows"), else a failed fetch would
|
|
293
|
+
* false-close the whole book. Pass `mode` to scope the read to the ACTIVE
|
|
294
|
+
* book (paper strict / live incl. legacy NULL rows) and `exchange` to scope
|
|
295
|
+
* it to the ACTIVE venue (hyperliquid strict / binance incl. legacy NULL
|
|
296
|
+
* rows) — the sweep diffs against one adapter's snapshot, so an unscoped
|
|
297
|
+
* read misreads the inactive book's/venue's rows as orphans (issue #209
|
|
298
|
+
* item 5: the same corruption class on the venue axis). */
|
|
299
|
+
getOpenPositions(userId: string, mode?: 'paper' | 'live', exchange?: 'binance' | 'hyperliquid'): Promise<OpenPositionsResponse | null>;
|
|
300
|
+
/** Read endpoint for the Phase 1 self-reflection feature. Awaited.
|
|
301
|
+
* Returns null on terminal/retry-exhausted failure (caller logs + degrades). */
|
|
302
|
+
getRecentReviews(userId: string, positionIds: string[], reviewLimit?: number): Promise<RecentReviewsResponse | null>;
|
|
303
|
+
/** Phase 2 outcome-attribution read. Aggregate stats + sample over the
|
|
304
|
+
* position_review_outcomes view filtered by the provided criteria. */
|
|
305
|
+
queryReviewOutcomes(userId: string, filters: ReviewOutcomesFilters): Promise<ReviewOutcomesResponse | null>;
|
|
306
|
+
/** Phase 4 — curated learnings read. The agent calls this at decision
|
|
307
|
+
* time (entry/heartbeat/close) to fetch confirmed learnings whose
|
|
308
|
+
* trigger_condition matches the current decision context. Returns null
|
|
309
|
+
* on terminal/retry-exhausted failure (caller logs + degrades to empty). */
|
|
310
|
+
getRelevantLearnings(userId: string, filters: RelevantLearningsFilters): Promise<RelevantLearningsResponse | null>;
|
|
311
|
+
/** Phase 4.5 — agent self-assessment: read this user's own unpromoted
|
|
312
|
+
* mined_patterns so the agent can pick candidates to propose. */
|
|
313
|
+
getMyMinedPatterns(userId: string, filters: MyMinedPatternsFilters): Promise<MyMinedPatternsResponse | null>;
|
|
314
|
+
/** Phase 4.5 — read this user's own learnings across confidence states, so
|
|
315
|
+
* the agent can dedup before proposing a fresh hypothesis. */
|
|
316
|
+
getMyProposedLearnings(userId: string, filters: MyProposedLearningsFilters): Promise<MyProposedLearningsResponse | null>;
|
|
317
|
+
/** Phase 4.5 — POST a new hypothesis (or auto-confirmed) learning. Confidence
|
|
318
|
+
* is server-determined by user trust mode; we cannot set it from here. */
|
|
319
|
+
proposeLearning(userId: string, payload: ProposeLearningPayload): Promise<ProposeLearningResponse | null>;
|
|
320
|
+
drain(): Promise<void>;
|
|
321
|
+
getHealth(): PositionDecisionsClientHealth;
|
|
322
|
+
private fireAndForget;
|
|
323
|
+
private run;
|
|
324
|
+
private runReturning;
|
|
325
|
+
private runGetReturning;
|
|
326
|
+
private sleepBackoff;
|
|
327
|
+
}
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
// HTTP client for the webapp's /api/internal/position-{positions,entries,reviews,closes}
|
|
2
|
+
// ingest endpoints.
|
|
3
|
+
//
|
|
4
|
+
// Mirrors trade-store-client.ts retry semantics:
|
|
5
|
+
// - 2xx : success.
|
|
6
|
+
// - 4xx : terminal — drop + log loudly (caller bug or duplicate).
|
|
7
|
+
// - 5xx / network : retry with exponential backoff up to maxAttempts.
|
|
8
|
+
//
|
|
9
|
+
// Two callable surfaces:
|
|
10
|
+
// - postPosition() is awaited (returns the parent UUID); the auto-capture
|
|
11
|
+
// pipeline needs the id before posting children.
|
|
12
|
+
// - postEntry/Review/Close are fire-and-forget (don't block the WS hot path).
|
|
13
|
+
//
|
|
14
|
+
// All four routes accept the same auth: Bearer + X-User-Id headers.
|
|
15
|
+
import { logger, formatError } from '../logger.js';
|
|
16
|
+
const TAG = 'position-decisions-client';
|
|
17
|
+
export class PositionDecisionsClient {
|
|
18
|
+
opts;
|
|
19
|
+
inFlight = new Set();
|
|
20
|
+
totalPosted = 0;
|
|
21
|
+
totalSucceeded = 0;
|
|
22
|
+
totalDroppedTerminal = 0;
|
|
23
|
+
totalDroppedRetriesExhausted = 0;
|
|
24
|
+
constructor(options) {
|
|
25
|
+
this.opts = {
|
|
26
|
+
baseUrl: options.baseUrl.replace(/\/+$/, ''),
|
|
27
|
+
ingestToken: options.ingestToken,
|
|
28
|
+
fetchImpl: options.fetchImpl ?? fetch,
|
|
29
|
+
requestTimeoutMs: options.requestTimeoutMs ?? 10_000,
|
|
30
|
+
maxAttempts: options.maxAttempts ?? 4,
|
|
31
|
+
baseBackoffMs: options.baseBackoffMs ?? 250,
|
|
32
|
+
backoffCapMs: options.backoffCapMs ?? 5_000,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** Awaited — the auto-capture pipeline needs the returned positionId before
|
|
36
|
+
* posting children. Returns null on terminal failure (caller logs + drops). */
|
|
37
|
+
async postPosition(userId, payload) {
|
|
38
|
+
const result = await this.runReturning(userId, '/api/internal/positions', payload);
|
|
39
|
+
return result?.positionId ?? null;
|
|
40
|
+
}
|
|
41
|
+
/** Fire-and-forget. */
|
|
42
|
+
postEntry(userId, payload) {
|
|
43
|
+
this.fireAndForget(userId, '/api/internal/position-entries', payload);
|
|
44
|
+
}
|
|
45
|
+
/** Fire-and-forget. */
|
|
46
|
+
postReview(userId, payload) {
|
|
47
|
+
this.fireAndForget(userId, '/api/internal/position-reviews', payload);
|
|
48
|
+
}
|
|
49
|
+
/** Fire-and-forget. */
|
|
50
|
+
postClose(userId, payload) {
|
|
51
|
+
this.fireAndForget(userId, '/api/internal/position-closes', payload);
|
|
52
|
+
}
|
|
53
|
+
/** DB-vs-exchange reconcile read: this tenant's open positions. Awaited.
|
|
54
|
+
* Returns null on terminal/retry-exhausted failure — the caller MUST treat
|
|
55
|
+
* null as UNKNOWN (never as "no open rows"), else a failed fetch would
|
|
56
|
+
* false-close the whole book. Pass `mode` to scope the read to the ACTIVE
|
|
57
|
+
* book (paper strict / live incl. legacy NULL rows) and `exchange` to scope
|
|
58
|
+
* it to the ACTIVE venue (hyperliquid strict / binance incl. legacy NULL
|
|
59
|
+
* rows) — the sweep diffs against one adapter's snapshot, so an unscoped
|
|
60
|
+
* read misreads the inactive book's/venue's rows as orphans (issue #209
|
|
61
|
+
* item 5: the same corruption class on the venue axis). */
|
|
62
|
+
async getOpenPositions(userId, mode, exchange) {
|
|
63
|
+
const qs = new URLSearchParams({ status: 'open' });
|
|
64
|
+
if (mode)
|
|
65
|
+
qs.set('mode', mode);
|
|
66
|
+
if (exchange)
|
|
67
|
+
qs.set('exchange', exchange);
|
|
68
|
+
return this.runGetReturning(userId, `/api/internal/positions?${qs.toString()}`);
|
|
69
|
+
}
|
|
70
|
+
/** Read endpoint for the Phase 1 self-reflection feature. Awaited.
|
|
71
|
+
* Returns null on terminal/retry-exhausted failure (caller logs + degrades). */
|
|
72
|
+
async getRecentReviews(userId, positionIds, reviewLimit) {
|
|
73
|
+
if (positionIds.length === 0)
|
|
74
|
+
return { positions: [] };
|
|
75
|
+
const qs = new URLSearchParams();
|
|
76
|
+
qs.set('positionIds', positionIds.join(','));
|
|
77
|
+
if (reviewLimit && reviewLimit > 0)
|
|
78
|
+
qs.set('reviewLimit', String(reviewLimit));
|
|
79
|
+
const path = `/api/internal/position-reviews/recent?${qs.toString()}`;
|
|
80
|
+
return this.runGetReturning(userId, path);
|
|
81
|
+
}
|
|
82
|
+
/** Phase 2 outcome-attribution read. Aggregate stats + sample over the
|
|
83
|
+
* position_review_outcomes view filtered by the provided criteria. */
|
|
84
|
+
async queryReviewOutcomes(userId, filters) {
|
|
85
|
+
const qs = new URLSearchParams();
|
|
86
|
+
if (filters.verdict)
|
|
87
|
+
qs.set('verdict', filters.verdict);
|
|
88
|
+
if (filters.thesisStatus)
|
|
89
|
+
qs.set('thesis_status', filters.thesisStatus);
|
|
90
|
+
if (filters.regimeCurrent)
|
|
91
|
+
qs.set('regime_current', filters.regimeCurrent);
|
|
92
|
+
if (filters.symbol)
|
|
93
|
+
qs.set('symbol', filters.symbol);
|
|
94
|
+
if (filters.side)
|
|
95
|
+
qs.set('side', filters.side);
|
|
96
|
+
if (filters.setupType)
|
|
97
|
+
qs.set('setup_type', filters.setupType);
|
|
98
|
+
if (filters.daysBack !== undefined)
|
|
99
|
+
qs.set('days_back', String(filters.daysBack));
|
|
100
|
+
if (filters.minScoreDelta !== undefined) {
|
|
101
|
+
qs.set('min_score_delta', String(filters.minScoreDelta));
|
|
102
|
+
}
|
|
103
|
+
if (filters.maxScoreDelta !== undefined) {
|
|
104
|
+
qs.set('max_score_delta', String(filters.maxScoreDelta));
|
|
105
|
+
}
|
|
106
|
+
if (filters.closedOnly)
|
|
107
|
+
qs.set('closed_only', '1');
|
|
108
|
+
if (filters.sampleLimit !== undefined)
|
|
109
|
+
qs.set('sample_limit', String(filters.sampleLimit));
|
|
110
|
+
const path = `/api/internal/positions/reviews/with-outcomes${qs.toString() ? `?${qs.toString()}` : ''}`;
|
|
111
|
+
return this.runGetReturning(userId, path);
|
|
112
|
+
}
|
|
113
|
+
/** Phase 4 — curated learnings read. The agent calls this at decision
|
|
114
|
+
* time (entry/heartbeat/close) to fetch confirmed learnings whose
|
|
115
|
+
* trigger_condition matches the current decision context. Returns null
|
|
116
|
+
* on terminal/retry-exhausted failure (caller logs + degrades to empty). */
|
|
117
|
+
async getRelevantLearnings(userId, filters) {
|
|
118
|
+
const qs = new URLSearchParams();
|
|
119
|
+
qs.set('applies_at', filters.appliesAt);
|
|
120
|
+
if (filters.setupType)
|
|
121
|
+
qs.set('setup_type', filters.setupType);
|
|
122
|
+
if (filters.regime)
|
|
123
|
+
qs.set('regime', filters.regime);
|
|
124
|
+
if (filters.verdict)
|
|
125
|
+
qs.set('verdict', filters.verdict);
|
|
126
|
+
const path = `/api/internal/learnings?${qs.toString()}`;
|
|
127
|
+
return this.runGetReturning(userId, path);
|
|
128
|
+
}
|
|
129
|
+
/** Phase 4.5 — agent self-assessment: read this user's own unpromoted
|
|
130
|
+
* mined_patterns so the agent can pick candidates to propose. */
|
|
131
|
+
async getMyMinedPatterns(userId, filters) {
|
|
132
|
+
const qs = new URLSearchParams();
|
|
133
|
+
if (filters.withinDays !== undefined)
|
|
134
|
+
qs.set('within_days', String(filters.withinDays));
|
|
135
|
+
if (filters.minSampleSize !== undefined)
|
|
136
|
+
qs.set('min_sample_size', String(filters.minSampleSize));
|
|
137
|
+
if (filters.maxPValue !== undefined)
|
|
138
|
+
qs.set('max_p_value', String(filters.maxPValue));
|
|
139
|
+
if (filters.includePromoted)
|
|
140
|
+
qs.set('include_promoted', '1');
|
|
141
|
+
const q = qs.toString();
|
|
142
|
+
const path = `/api/internal/learnings/my-patterns${q ? `?${q}` : ''}`;
|
|
143
|
+
return this.runGetReturning(userId, path);
|
|
144
|
+
}
|
|
145
|
+
/** Phase 4.5 — read this user's own learnings across confidence states, so
|
|
146
|
+
* the agent can dedup before proposing a fresh hypothesis. */
|
|
147
|
+
async getMyProposedLearnings(userId, filters) {
|
|
148
|
+
const qs = new URLSearchParams();
|
|
149
|
+
if (filters.includeHypothesis === false)
|
|
150
|
+
qs.set('include_hypothesis', '0');
|
|
151
|
+
if (filters.includeConfirmed === false)
|
|
152
|
+
qs.set('include_confirmed', '0');
|
|
153
|
+
if (filters.includeRetired)
|
|
154
|
+
qs.set('include_retired', '1');
|
|
155
|
+
if (filters.proposedBy)
|
|
156
|
+
qs.set('proposed_by', filters.proposedBy);
|
|
157
|
+
const q = qs.toString();
|
|
158
|
+
const path = `/api/internal/learnings/my-proposals${q ? `?${q}` : ''}`;
|
|
159
|
+
return this.runGetReturning(userId, path);
|
|
160
|
+
}
|
|
161
|
+
/** Phase 4.5 — POST a new hypothesis (or auto-confirmed) learning. Confidence
|
|
162
|
+
* is server-determined by user trust mode; we cannot set it from here. */
|
|
163
|
+
async proposeLearning(userId, payload) {
|
|
164
|
+
return this.runReturning(userId, '/api/internal/learnings/propose', payload);
|
|
165
|
+
}
|
|
166
|
+
async drain() {
|
|
167
|
+
if (this.inFlight.size === 0)
|
|
168
|
+
return;
|
|
169
|
+
logger.info(TAG, `Draining ${this.inFlight.size} in-flight decision post(s)...`);
|
|
170
|
+
await Promise.allSettled(Array.from(this.inFlight));
|
|
171
|
+
}
|
|
172
|
+
getHealth() {
|
|
173
|
+
return {
|
|
174
|
+
inFlight: this.inFlight.size,
|
|
175
|
+
totalPosted: this.totalPosted,
|
|
176
|
+
totalSucceeded: this.totalSucceeded,
|
|
177
|
+
totalDroppedTerminal: this.totalDroppedTerminal,
|
|
178
|
+
totalDroppedRetriesExhausted: this.totalDroppedRetriesExhausted,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
// ---- Internals ----
|
|
182
|
+
fireAndForget(userId, path, body) {
|
|
183
|
+
this.totalPosted++;
|
|
184
|
+
const promise = this.run(userId, path, body).finally(() => {
|
|
185
|
+
this.inFlight.delete(promise);
|
|
186
|
+
});
|
|
187
|
+
this.inFlight.add(promise);
|
|
188
|
+
}
|
|
189
|
+
async run(userId, path, body) {
|
|
190
|
+
await this.runReturning(userId, path, body);
|
|
191
|
+
}
|
|
192
|
+
async runReturning(userId, path, body) {
|
|
193
|
+
const url = `${this.opts.baseUrl}${path}`;
|
|
194
|
+
const json = JSON.stringify(body);
|
|
195
|
+
for (let attempt = 1; attempt <= this.opts.maxAttempts; attempt++) {
|
|
196
|
+
try {
|
|
197
|
+
const ac = new AbortController();
|
|
198
|
+
const tid = setTimeout(() => ac.abort(), this.opts.requestTimeoutMs);
|
|
199
|
+
let res;
|
|
200
|
+
try {
|
|
201
|
+
res = await this.opts.fetchImpl(url, {
|
|
202
|
+
method: 'POST',
|
|
203
|
+
headers: {
|
|
204
|
+
'content-type': 'application/json',
|
|
205
|
+
authorization: `Bearer ${this.opts.ingestToken}`,
|
|
206
|
+
'x-user-id': userId,
|
|
207
|
+
},
|
|
208
|
+
body: json,
|
|
209
|
+
signal: ac.signal,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
finally {
|
|
213
|
+
clearTimeout(tid);
|
|
214
|
+
}
|
|
215
|
+
if (res.status >= 200 && res.status < 300) {
|
|
216
|
+
this.totalSucceeded++;
|
|
217
|
+
try {
|
|
218
|
+
return (await res.json());
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (res.status >= 400 && res.status < 500) {
|
|
225
|
+
this.totalDroppedTerminal++;
|
|
226
|
+
let errBody = '';
|
|
227
|
+
try {
|
|
228
|
+
errBody = await res.text();
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
// ignore
|
|
232
|
+
}
|
|
233
|
+
logger.warn(TAG, `POST ${url} → ${res.status} (terminal, dropped). userId=${userId} body=${errBody.slice(0, 200)}`);
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
logger.warn(TAG, `POST ${url} → ${res.status} (attempt ${attempt}/${this.opts.maxAttempts}).`);
|
|
237
|
+
}
|
|
238
|
+
catch (err) {
|
|
239
|
+
logger.warn(TAG, `POST ${url} threw (attempt ${attempt}/${this.opts.maxAttempts}): ${formatError(err)}`);
|
|
240
|
+
}
|
|
241
|
+
if (attempt < this.opts.maxAttempts) {
|
|
242
|
+
await this.sleepBackoff(attempt);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
this.totalDroppedRetriesExhausted++;
|
|
246
|
+
logger.error(TAG, `POST ${url} dropped after ${this.opts.maxAttempts} attempts. userId=${userId}.`);
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
async runGetReturning(userId, path) {
|
|
250
|
+
const url = `${this.opts.baseUrl}${path}`;
|
|
251
|
+
for (let attempt = 1; attempt <= this.opts.maxAttempts; attempt++) {
|
|
252
|
+
try {
|
|
253
|
+
const ac = new AbortController();
|
|
254
|
+
const tid = setTimeout(() => ac.abort(), this.opts.requestTimeoutMs);
|
|
255
|
+
let res;
|
|
256
|
+
try {
|
|
257
|
+
res = await this.opts.fetchImpl(url, {
|
|
258
|
+
method: 'GET',
|
|
259
|
+
headers: {
|
|
260
|
+
authorization: `Bearer ${this.opts.ingestToken}`,
|
|
261
|
+
'x-user-id': userId,
|
|
262
|
+
},
|
|
263
|
+
signal: ac.signal,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
finally {
|
|
267
|
+
clearTimeout(tid);
|
|
268
|
+
}
|
|
269
|
+
if (res.status >= 200 && res.status < 300) {
|
|
270
|
+
try {
|
|
271
|
+
return (await res.json());
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (res.status >= 400 && res.status < 500) {
|
|
278
|
+
let errBody = '';
|
|
279
|
+
try {
|
|
280
|
+
errBody = await res.text();
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
// ignore
|
|
284
|
+
}
|
|
285
|
+
logger.warn(TAG, `GET ${url} → ${res.status} (terminal, dropped). userId=${userId} body=${errBody.slice(0, 200)}`);
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
logger.warn(TAG, `GET ${url} → ${res.status} (attempt ${attempt}/${this.opts.maxAttempts}).`);
|
|
289
|
+
}
|
|
290
|
+
catch (err) {
|
|
291
|
+
logger.warn(TAG, `GET ${url} threw (attempt ${attempt}/${this.opts.maxAttempts}): ${formatError(err)}`);
|
|
292
|
+
}
|
|
293
|
+
if (attempt < this.opts.maxAttempts) {
|
|
294
|
+
await this.sleepBackoff(attempt);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
logger.error(TAG, `GET ${url} failed after ${this.opts.maxAttempts} attempts. userId=${userId}.`);
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
async sleepBackoff(attempt) {
|
|
301
|
+
const exp = Math.min(this.opts.baseBackoffMs * 2 ** (attempt - 1), this.opts.backoffCapMs);
|
|
302
|
+
const jitter = exp * 0.2 * (Math.random() * 2 - 1);
|
|
303
|
+
const delay = Math.max(0, Math.round(exp + jitter));
|
|
304
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
305
|
+
}
|
|
306
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type ReadinessReport, type VenueId } from '@reefclaw/shared';
|
|
2
|
+
/** Venue-agnostic reachability probe — BinancePublicApi.probeReachability and
|
|
3
|
+
* HyperliquidPublicApi.probeReachability both return exactly this shape. */
|
|
4
|
+
export interface VenueReachabilityProbe {
|
|
5
|
+
probeReachability(): Promise<{
|
|
6
|
+
outcome: 'reachable' | 'geo_blocked' | 'unreachable' | 'unknown';
|
|
7
|
+
driftMs: number | null;
|
|
8
|
+
}>;
|
|
9
|
+
}
|
|
10
|
+
export interface ReadinessReporterOptions {
|
|
11
|
+
apiBaseUrl: string;
|
|
12
|
+
token: string;
|
|
13
|
+
/** Which venue this agent trades — decides the reachability check id
|
|
14
|
+
* (binance_reachable vs hyperliquid_reachable) and which host `publicApi`
|
|
15
|
+
* probes. The reporter probes ONLY the configured venue: on a
|
|
16
|
+
* Binance-451-blocked host trading Hyperliquid, a Binance probe would be
|
|
17
|
+
* a permanent false alarm (plan §5.11). */
|
|
18
|
+
venue: VenueId;
|
|
19
|
+
/** Public API of the CONFIGURED venue (probe only). */
|
|
20
|
+
publicApi: VenueReachabilityProbe;
|
|
21
|
+
/** Number of trading tools registered (a health signal). */
|
|
22
|
+
toolCount: number;
|
|
23
|
+
fetchImpl?: typeof fetch;
|
|
24
|
+
intervalMs?: number;
|
|
25
|
+
requestTimeoutMs?: number;
|
|
26
|
+
}
|
|
27
|
+
/** Run every connect-phase check once and assemble the report. Exported for
|
|
28
|
+
* unit tests.
|
|
29
|
+
*
|
|
30
|
+
* `bootWarmup` marks the FIRST cycle, which fires during gateway boot while
|
|
31
|
+
* the event loop is congested (WS start, snapshot, seed all racing). That
|
|
32
|
+
* delay between the probe's server-time response and the local `Date.now()`
|
|
33
|
+
* read inflates the apparent clock drift — observed −4112ms at boot
|
|
34
|
+
* self-correcting to −108ms on the next 5-min cycle. During warm-up a
|
|
35
|
+
* warn/fail drift is reported 'unknown' (not amber/red) so the readiness
|
|
36
|
+
* banner doesn't cry-wolf for ~5 min after every restart; a genuinely
|
|
37
|
+
* skewed clock still surfaces on cycle 2. */
|
|
38
|
+
export declare function collectReadiness(opts: Pick<ReadinessReporterOptions, 'venue' | 'publicApi' | 'toolCount'>, bootWarmup?: boolean): Promise<ReadinessReport>;
|
|
39
|
+
/** Test-only — reset the singleton guard between unit tests. */
|
|
40
|
+
export declare function __resetReadinessReporterForTests(): void;
|
|
41
|
+
/** Fire the readiness report once at boot then on an unref'd interval. */
|
|
42
|
+
export declare function startReadinessReporter(opts: ReadinessReporterOptions): void;
|