@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,37 @@
|
|
|
1
|
+
import type { OpenClawProvider, ProviderEvents, ProviderEventName } from '../provider.js';
|
|
2
|
+
import type { EmergencyAction, ReconciliationSnapshot } from '../types.js';
|
|
3
|
+
export declare class MockProvider implements OpenClawProvider {
|
|
4
|
+
private btcPrice;
|
|
5
|
+
private position;
|
|
6
|
+
private orderSeq;
|
|
7
|
+
private riskCycle;
|
|
8
|
+
private agentMode;
|
|
9
|
+
private startTime;
|
|
10
|
+
private marketInterval;
|
|
11
|
+
private agentInterval;
|
|
12
|
+
private readonly listeners;
|
|
13
|
+
private readonly RISK_LIMITS;
|
|
14
|
+
start(): void;
|
|
15
|
+
stop(): void;
|
|
16
|
+
executeEmergency(action: EmergencyAction): Promise<{
|
|
17
|
+
action: string;
|
|
18
|
+
executed: boolean;
|
|
19
|
+
timestamp: string;
|
|
20
|
+
}>;
|
|
21
|
+
handleChat(content: string): Promise<{
|
|
22
|
+
received: boolean;
|
|
23
|
+
}>;
|
|
24
|
+
closePosition(symbol: string): Promise<{
|
|
25
|
+
closed: boolean;
|
|
26
|
+
symbol: string;
|
|
27
|
+
error?: string;
|
|
28
|
+
}>;
|
|
29
|
+
getSnapshot(): Promise<ReconciliationSnapshot>;
|
|
30
|
+
on<E extends ProviderEventName>(event: E, listener: ProviderEvents[E]): void;
|
|
31
|
+
off<E extends ProviderEventName>(event: E, listener: ProviderEvents[E]): void;
|
|
32
|
+
private fire;
|
|
33
|
+
private simulateMarketTick;
|
|
34
|
+
private simulateRandomTrade;
|
|
35
|
+
private emitAgentState;
|
|
36
|
+
private emitRiskUpdate;
|
|
37
|
+
}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
// MockProvider — simulates an OpenClaw agent for standalone testing.
|
|
2
|
+
// Extracted from relay/scripts/mock-skill.ts into the provider interface.
|
|
3
|
+
import { logger } from '../logger.js';
|
|
4
|
+
import { redactTokens } from '@reefclaw/shared';
|
|
5
|
+
const TAG = 'mock';
|
|
6
|
+
export class MockProvider {
|
|
7
|
+
// ---- Simulated market state ----
|
|
8
|
+
btcPrice = 65_000;
|
|
9
|
+
position = null;
|
|
10
|
+
orderSeq = 0;
|
|
11
|
+
riskCycle = 0;
|
|
12
|
+
agentMode = 'ACTIVE';
|
|
13
|
+
startTime = Date.now();
|
|
14
|
+
// ---- Timers ----
|
|
15
|
+
marketInterval = null;
|
|
16
|
+
agentInterval = null;
|
|
17
|
+
// ---- Event listeners ----
|
|
18
|
+
listeners = {
|
|
19
|
+
ticker: new Set(),
|
|
20
|
+
candle: new Set(),
|
|
21
|
+
orderUpdate: new Set(),
|
|
22
|
+
agentState: new Set(),
|
|
23
|
+
riskUpdate: new Set(),
|
|
24
|
+
chatMessage: new Set(),
|
|
25
|
+
chatMessageStart: new Set(),
|
|
26
|
+
chatMessageChunk: new Set(),
|
|
27
|
+
chatMessageEnd: new Set(),
|
|
28
|
+
chatStreamingKeepAlive: new Set(),
|
|
29
|
+
marketStructure: new Set(),
|
|
30
|
+
cryptoMetrics: new Set(),
|
|
31
|
+
volumeAnalysis: new Set(),
|
|
32
|
+
tradeJournal: new Set(),
|
|
33
|
+
regimeUpdate: new Set(),
|
|
34
|
+
signalUpdate: new Set(),
|
|
35
|
+
missionUpdate: new Set(),
|
|
36
|
+
analyticsUpdate: new Set(),
|
|
37
|
+
fillError: new Set(),
|
|
38
|
+
shadowComparison: new Set(),
|
|
39
|
+
tradingModeUpdate: new Set(),
|
|
40
|
+
decisionTraceUpdate: new Set(),
|
|
41
|
+
};
|
|
42
|
+
// ---- Risk limits ----
|
|
43
|
+
RISK_LIMITS = {
|
|
44
|
+
position: {
|
|
45
|
+
maxPositionSize: 10_000,
|
|
46
|
+
maxOpenPositions: 5,
|
|
47
|
+
maxGrossExposure: 1.5,
|
|
48
|
+
maxNetExposure: 1.5,
|
|
49
|
+
},
|
|
50
|
+
loss: {
|
|
51
|
+
maxDailyDrawdown: -0.03,
|
|
52
|
+
maxPerTradeLoss: -500,
|
|
53
|
+
maxDailyLoss: -2000,
|
|
54
|
+
},
|
|
55
|
+
rate: { maxOrdersPerMinute: 60, maxCancelsPerMinute: 30 },
|
|
56
|
+
};
|
|
57
|
+
// ---- Provider interface ----
|
|
58
|
+
start() {
|
|
59
|
+
logger.info(TAG, 'Starting mock provider');
|
|
60
|
+
this.startTime = Date.now();
|
|
61
|
+
// Emit initial state immediately
|
|
62
|
+
this.emitAgentState();
|
|
63
|
+
this.emitRiskUpdate();
|
|
64
|
+
// Market data every 500ms
|
|
65
|
+
this.marketInterval = setInterval(() => {
|
|
66
|
+
this.simulateMarketTick();
|
|
67
|
+
this.simulateRandomTrade();
|
|
68
|
+
}, 500);
|
|
69
|
+
// Agent state + risk every 5s
|
|
70
|
+
this.agentInterval = setInterval(() => {
|
|
71
|
+
this.emitAgentState();
|
|
72
|
+
this.emitRiskUpdate();
|
|
73
|
+
}, 5_000);
|
|
74
|
+
}
|
|
75
|
+
stop() {
|
|
76
|
+
logger.info(TAG, 'Stopping mock provider');
|
|
77
|
+
if (this.marketInterval)
|
|
78
|
+
clearInterval(this.marketInterval);
|
|
79
|
+
if (this.agentInterval)
|
|
80
|
+
clearInterval(this.agentInterval);
|
|
81
|
+
this.marketInterval = null;
|
|
82
|
+
this.agentInterval = null;
|
|
83
|
+
}
|
|
84
|
+
async executeEmergency(action) {
|
|
85
|
+
logger.info(TAG, `Emergency ${action} executed`);
|
|
86
|
+
switch (action) {
|
|
87
|
+
case 'kill':
|
|
88
|
+
this.agentMode = 'STOPPED';
|
|
89
|
+
this.position = null;
|
|
90
|
+
break;
|
|
91
|
+
case 'flatten':
|
|
92
|
+
this.position = null;
|
|
93
|
+
break;
|
|
94
|
+
case 'pause':
|
|
95
|
+
this.agentMode = 'PAUSED';
|
|
96
|
+
break;
|
|
97
|
+
case 'resume':
|
|
98
|
+
this.agentMode = 'ACTIVE';
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
// Emit updated state immediately
|
|
102
|
+
this.emitAgentState();
|
|
103
|
+
return {
|
|
104
|
+
action,
|
|
105
|
+
executed: true,
|
|
106
|
+
timestamp: new Date().toISOString(),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
async handleChat(content) {
|
|
110
|
+
// Mirror the bridge's redaction: never log a raw rc_* token, even in mock
|
|
111
|
+
// mode. If the redactor changed the string, surface that — mock mode is
|
|
112
|
+
// sometimes used for end-to-end QA where a real token might land here.
|
|
113
|
+
const safeForLog = redactTokens(content);
|
|
114
|
+
if (safeForLog !== content) {
|
|
115
|
+
logger.warn(TAG, 'Chat contained a connection token — mock provider does not auto-revoke.');
|
|
116
|
+
}
|
|
117
|
+
logger.info(TAG, `Chat: "${safeForLog}"`);
|
|
118
|
+
// Echo back a mock response after a short delay. Use the redacted form so
|
|
119
|
+
// the synthesized agent reply doesn't contain a raw token either.
|
|
120
|
+
setTimeout(() => {
|
|
121
|
+
const responses = [
|
|
122
|
+
`Understood. Monitoring market conditions for "${safeForLog}".`,
|
|
123
|
+
`Acknowledged. Current BTC price is ${this.btcPrice.toFixed(2)}.`,
|
|
124
|
+
`Roger that. Strategy MockScalper v1.0.0 is active.`,
|
|
125
|
+
`Processing your instruction. All systems nominal.`,
|
|
126
|
+
];
|
|
127
|
+
this.fire('chatMessage', {
|
|
128
|
+
message: {
|
|
129
|
+
id: `agent-msg-${Date.now()}`,
|
|
130
|
+
role: 'agent',
|
|
131
|
+
content: responses[Math.floor(Math.random() * responses.length)],
|
|
132
|
+
timestamp: new Date().toISOString(),
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
}, 500 + Math.random() * 1000);
|
|
136
|
+
return { received: true };
|
|
137
|
+
}
|
|
138
|
+
async closePosition(symbol) {
|
|
139
|
+
logger.info(TAG, `Close position: ${symbol}`);
|
|
140
|
+
if (this.position) {
|
|
141
|
+
this.position = null;
|
|
142
|
+
return { closed: true, symbol };
|
|
143
|
+
}
|
|
144
|
+
return { closed: false, symbol, error: 'No position to close' };
|
|
145
|
+
}
|
|
146
|
+
async getSnapshot() {
|
|
147
|
+
logger.info(TAG, 'Reconciliation snapshot requested');
|
|
148
|
+
const posSize = this.position ? this.position.qty * this.btcPrice : 0;
|
|
149
|
+
return {
|
|
150
|
+
positions: this.position
|
|
151
|
+
? [
|
|
152
|
+
{
|
|
153
|
+
symbol: 'BTC/USDT',
|
|
154
|
+
side: this.position.side,
|
|
155
|
+
quantity: this.position.qty,
|
|
156
|
+
entryPrice: this.position.entry,
|
|
157
|
+
currentPrice: this.btcPrice,
|
|
158
|
+
unrealizedPnl: 0,
|
|
159
|
+
unrealizedPnlPercent: 0,
|
|
160
|
+
portfolioPercent: 100,
|
|
161
|
+
},
|
|
162
|
+
]
|
|
163
|
+
: [],
|
|
164
|
+
balance: {
|
|
165
|
+
currency: 'USDT',
|
|
166
|
+
total: 10_000,
|
|
167
|
+
available: 8_000,
|
|
168
|
+
locked: 2_000,
|
|
169
|
+
},
|
|
170
|
+
openOrders: [],
|
|
171
|
+
agentState: {
|
|
172
|
+
mode: this.agentMode,
|
|
173
|
+
strategy: { name: 'MockScalper', version: '1.0.0' },
|
|
174
|
+
health: {
|
|
175
|
+
uptime: Math.floor((Date.now() - this.startTime) / 1000),
|
|
176
|
+
lastDecision: new Date().toISOString(),
|
|
177
|
+
lastTrade: null,
|
|
178
|
+
errorRate: 0,
|
|
179
|
+
thinkingInterval: 30,
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
riskMetrics: {
|
|
183
|
+
limits: this.RISK_LIMITS,
|
|
184
|
+
utilization: {
|
|
185
|
+
currentPositionSize: posSize > 0 ? { 'BTC/USDT': +posSize.toFixed(2) } : {},
|
|
186
|
+
openPositionCount: this.position ? 1 : 0,
|
|
187
|
+
grossExposure: 0,
|
|
188
|
+
netExposure: 0,
|
|
189
|
+
dailyDrawdown: 0,
|
|
190
|
+
dailyLoss: 0,
|
|
191
|
+
ordersPerMinute: 0,
|
|
192
|
+
cancelsPerMinute: 0,
|
|
193
|
+
},
|
|
194
|
+
activeBreaches: [],
|
|
195
|
+
},
|
|
196
|
+
gapFill: [],
|
|
197
|
+
sessionStartNav: 10_000,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
on(event, listener) {
|
|
201
|
+
this.listeners[event].add(listener);
|
|
202
|
+
}
|
|
203
|
+
off(event, listener) {
|
|
204
|
+
this.listeners[event].delete(listener);
|
|
205
|
+
}
|
|
206
|
+
// ---- Simulation logic ----
|
|
207
|
+
fire(event, ...args) {
|
|
208
|
+
for (const listener of this.listeners[event]) {
|
|
209
|
+
listener(...args);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
simulateMarketTick() {
|
|
213
|
+
// Random walk
|
|
214
|
+
this.btcPrice += (Math.random() - 0.5) * 50;
|
|
215
|
+
this.btcPrice = Math.max(60_000, Math.min(70_000, this.btcPrice));
|
|
216
|
+
// Ticker
|
|
217
|
+
this.fire('ticker', {
|
|
218
|
+
symbol: 'BTC/USDT',
|
|
219
|
+
lastPrice: +this.btcPrice.toFixed(2),
|
|
220
|
+
bidPrice: +(this.btcPrice - 0.5).toFixed(2),
|
|
221
|
+
askPrice: +(this.btcPrice + 0.5).toFixed(2),
|
|
222
|
+
volume24h: 12345.67,
|
|
223
|
+
change24h: +(this.btcPrice - 65_000).toFixed(2),
|
|
224
|
+
change24hPercent: +(((this.btcPrice - 65_000) / 65_000) * 100).toFixed(4),
|
|
225
|
+
timestamp: new Date().toISOString(),
|
|
226
|
+
});
|
|
227
|
+
// Candle (1s candles for demo)
|
|
228
|
+
const now = Math.floor(Date.now() / 1000);
|
|
229
|
+
this.fire('candle', {
|
|
230
|
+
symbol: 'BTC/USDT',
|
|
231
|
+
candle: {
|
|
232
|
+
time: now,
|
|
233
|
+
open: +(this.btcPrice - 5).toFixed(2),
|
|
234
|
+
high: +(this.btcPrice + 10).toFixed(2),
|
|
235
|
+
low: +(this.btcPrice - 10).toFixed(2),
|
|
236
|
+
close: +this.btcPrice.toFixed(2),
|
|
237
|
+
volume: +(Math.random() * 10).toFixed(4),
|
|
238
|
+
},
|
|
239
|
+
timestamp: new Date().toISOString(),
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
simulateRandomTrade() {
|
|
243
|
+
if (this.agentMode !== 'ACTIVE')
|
|
244
|
+
return;
|
|
245
|
+
if (Math.random() > 0.05)
|
|
246
|
+
return; // ~5% chance per tick
|
|
247
|
+
const orderId = `mock-order-${++this.orderSeq}`;
|
|
248
|
+
if (!this.position) {
|
|
249
|
+
// Open a position
|
|
250
|
+
const side = Math.random() > 0.5 ? 'BUY' : 'SELL';
|
|
251
|
+
const qty = +(Math.random() * 0.1 + 0.01).toFixed(4);
|
|
252
|
+
this.fire('orderUpdate', {
|
|
253
|
+
orderId,
|
|
254
|
+
status: 'FILLED',
|
|
255
|
+
order: {
|
|
256
|
+
id: orderId,
|
|
257
|
+
symbol: 'BTC/USDT',
|
|
258
|
+
side,
|
|
259
|
+
type: 'MARKET',
|
|
260
|
+
status: 'FILLED',
|
|
261
|
+
quantity: qty,
|
|
262
|
+
filledQuantity: qty,
|
|
263
|
+
averageFillPrice: this.btcPrice,
|
|
264
|
+
timeInForce: 'IOC',
|
|
265
|
+
createdAt: new Date().toISOString(),
|
|
266
|
+
updatedAt: new Date().toISOString(),
|
|
267
|
+
},
|
|
268
|
+
fill: {
|
|
269
|
+
id: `fill-${this.orderSeq}`,
|
|
270
|
+
orderId,
|
|
271
|
+
symbol: 'BTC/USDT',
|
|
272
|
+
side,
|
|
273
|
+
quantity: qty,
|
|
274
|
+
price: this.btcPrice,
|
|
275
|
+
expectedPrice: this.btcPrice,
|
|
276
|
+
slippage: 0,
|
|
277
|
+
slippageBps: 0,
|
|
278
|
+
fee: +(qty * this.btcPrice * 0.001).toFixed(4),
|
|
279
|
+
feeCurrency: 'USDT',
|
|
280
|
+
timestamp: new Date().toISOString(),
|
|
281
|
+
},
|
|
282
|
+
timestamp: new Date().toISOString(),
|
|
283
|
+
});
|
|
284
|
+
this.position = {
|
|
285
|
+
side: side === 'BUY' ? 'LONG' : 'SHORT',
|
|
286
|
+
qty,
|
|
287
|
+
entry: this.btcPrice,
|
|
288
|
+
};
|
|
289
|
+
logger.info(TAG, `Opened ${this.position.side} ${qty} BTC @ ${this.btcPrice.toFixed(2)}`);
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
// Close the position
|
|
293
|
+
const closeSide = this.position.side === 'LONG' ? 'SELL' : 'BUY';
|
|
294
|
+
const slippage = +(Math.random() * 2 - 1).toFixed(2);
|
|
295
|
+
this.fire('orderUpdate', {
|
|
296
|
+
orderId,
|
|
297
|
+
status: 'FILLED',
|
|
298
|
+
order: {
|
|
299
|
+
id: orderId,
|
|
300
|
+
symbol: 'BTC/USDT',
|
|
301
|
+
side: closeSide,
|
|
302
|
+
type: 'MARKET',
|
|
303
|
+
status: 'FILLED',
|
|
304
|
+
quantity: this.position.qty,
|
|
305
|
+
filledQuantity: this.position.qty,
|
|
306
|
+
averageFillPrice: this.btcPrice + slippage,
|
|
307
|
+
timeInForce: 'IOC',
|
|
308
|
+
createdAt: new Date().toISOString(),
|
|
309
|
+
updatedAt: new Date().toISOString(),
|
|
310
|
+
},
|
|
311
|
+
fill: {
|
|
312
|
+
id: `fill-${this.orderSeq}`,
|
|
313
|
+
orderId,
|
|
314
|
+
symbol: 'BTC/USDT',
|
|
315
|
+
side: closeSide,
|
|
316
|
+
quantity: this.position.qty,
|
|
317
|
+
price: this.btcPrice + slippage,
|
|
318
|
+
expectedPrice: this.btcPrice,
|
|
319
|
+
slippage,
|
|
320
|
+
slippageBps: +((slippage / this.btcPrice) * 10000).toFixed(2),
|
|
321
|
+
fee: +(this.position.qty * this.btcPrice * 0.001).toFixed(4),
|
|
322
|
+
feeCurrency: 'USDT',
|
|
323
|
+
timestamp: new Date().toISOString(),
|
|
324
|
+
},
|
|
325
|
+
timestamp: new Date().toISOString(),
|
|
326
|
+
});
|
|
327
|
+
const pnl = this.position.side === 'LONG'
|
|
328
|
+
? (this.btcPrice - this.position.entry) * this.position.qty
|
|
329
|
+
: (this.position.entry - this.btcPrice) * this.position.qty;
|
|
330
|
+
logger.info(TAG, `Closed ${this.position.side} ${this.position.qty} BTC @ ${this.btcPrice.toFixed(2)} (PnL: ${pnl.toFixed(2)})`);
|
|
331
|
+
this.position = null;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
emitAgentState() {
|
|
335
|
+
this.fire('agentState', {
|
|
336
|
+
state: {
|
|
337
|
+
mode: this.agentMode,
|
|
338
|
+
strategy: { name: 'MockScalper', version: '1.0.0' },
|
|
339
|
+
health: {
|
|
340
|
+
uptime: Math.floor((Date.now() - this.startTime) / 1000),
|
|
341
|
+
lastDecision: new Date().toISOString(),
|
|
342
|
+
lastTrade: new Date().toISOString(),
|
|
343
|
+
errorRate: 0,
|
|
344
|
+
thinkingInterval: 30,
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
timestamp: new Date().toISOString(),
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
emitRiskUpdate() {
|
|
351
|
+
const phase = this.riskCycle % 12;
|
|
352
|
+
const t = phase < 8 ? phase / 8 : 1 - (phase - 8) / 4;
|
|
353
|
+
this.riskCycle++;
|
|
354
|
+
const posSize = this.position ? this.position.qty * this.btcPrice : 0;
|
|
355
|
+
const activeBreaches = [];
|
|
356
|
+
if (phase === 7) {
|
|
357
|
+
activeBreaches.push({
|
|
358
|
+
metric: 'dailyDrawdown',
|
|
359
|
+
limit: -0.03,
|
|
360
|
+
current: -(t * 0.035),
|
|
361
|
+
level: 'CRITICAL',
|
|
362
|
+
action: 'AUTO_PAUSE',
|
|
363
|
+
timestamp: new Date().toISOString(),
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
this.fire('riskUpdate', {
|
|
367
|
+
event: 'risk_update',
|
|
368
|
+
metrics: {
|
|
369
|
+
limits: this.RISK_LIMITS,
|
|
370
|
+
utilization: {
|
|
371
|
+
currentPositionSize: posSize > 0 ? { 'BTC/USDT': +posSize.toFixed(2) } : {},
|
|
372
|
+
openPositionCount: this.position ? 1 : 0,
|
|
373
|
+
grossExposure: +(t * 1.2).toFixed(3),
|
|
374
|
+
netExposure: +(t * 0.35).toFixed(3),
|
|
375
|
+
dailyDrawdown: -(t * 0.025),
|
|
376
|
+
dailyLoss: -(t * 1500),
|
|
377
|
+
ordersPerMinute: Math.round(t * 45),
|
|
378
|
+
cancelsPerMinute: Math.round(t * 20),
|
|
379
|
+
},
|
|
380
|
+
activeBreaches,
|
|
381
|
+
},
|
|
382
|
+
timestamp: new Date().toISOString(),
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { GatewayHttpClient } from '../gateway/gateway-http-client.js';
|
|
2
|
+
import type { ToolMap } from '../gateway/tool-discovery.js';
|
|
3
|
+
import type { TradingMode } from '@reefclaw/shared';
|
|
4
|
+
export interface SetTradingModeOutcome {
|
|
5
|
+
ok: boolean;
|
|
6
|
+
message: string;
|
|
7
|
+
previousMode: TradingMode;
|
|
8
|
+
mode: TradingMode;
|
|
9
|
+
readiness: string;
|
|
10
|
+
reason?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface SetExchangeCredentialsOutcome {
|
|
13
|
+
ok: boolean;
|
|
14
|
+
message: string;
|
|
15
|
+
fingerprint: string;
|
|
16
|
+
reconnected: boolean;
|
|
17
|
+
mode: TradingMode;
|
|
18
|
+
readiness: string;
|
|
19
|
+
}
|
|
20
|
+
export interface TestExchangeCredentialsOutcome {
|
|
21
|
+
ok: boolean;
|
|
22
|
+
message: string;
|
|
23
|
+
fingerprint: string;
|
|
24
|
+
canReadBalance: boolean;
|
|
25
|
+
canReadPositions: boolean;
|
|
26
|
+
balanceUSDT: number | null;
|
|
27
|
+
testnet: boolean;
|
|
28
|
+
errors: string[];
|
|
29
|
+
}
|
|
30
|
+
export interface ClearExchangeCredentialsOutcome {
|
|
31
|
+
ok: boolean;
|
|
32
|
+
message: string;
|
|
33
|
+
modeBefore: TradingMode;
|
|
34
|
+
mode: TradingMode;
|
|
35
|
+
rolledBackToPaper: boolean;
|
|
36
|
+
readiness: string;
|
|
37
|
+
}
|
|
38
|
+
export interface OnboardingContext {
|
|
39
|
+
http: GatewayHttpClient | null;
|
|
40
|
+
toolMap: ToolMap;
|
|
41
|
+
}
|
|
42
|
+
export type BracketMode = 'off' | 'observe' | 'enforce';
|
|
43
|
+
export type BracketRequirementFlag = 'requireStopLoss' | 'requireTakeProfit';
|
|
44
|
+
export interface GetBracketConfigOutcome {
|
|
45
|
+
ok: boolean;
|
|
46
|
+
message?: string;
|
|
47
|
+
mode: BracketMode;
|
|
48
|
+
requireStopLoss: boolean;
|
|
49
|
+
requireTakeProfit: boolean;
|
|
50
|
+
}
|
|
51
|
+
export interface SetBracketRequirementOutcome {
|
|
52
|
+
ok: boolean;
|
|
53
|
+
flag: BracketRequirementFlag;
|
|
54
|
+
previousValue: boolean;
|
|
55
|
+
value: boolean;
|
|
56
|
+
warning?: string;
|
|
57
|
+
error?: string;
|
|
58
|
+
message?: string;
|
|
59
|
+
}
|
|
60
|
+
/** Forward a set_trading_mode invocation to the plugin via HTTP. */
|
|
61
|
+
export declare function executeSetTradingMode(ctx: OnboardingContext, mode: TradingMode, acknowledged: boolean | undefined): Promise<SetTradingModeOutcome>;
|
|
62
|
+
/** Forward a test_exchange_credentials invocation to the plugin. The plugin
|
|
63
|
+
* does a throwaway read-only call to verify permissions without persisting
|
|
64
|
+
* the keys. Error messages are scrubbed of the raw secret before logging
|
|
65
|
+
* (same approach as the set path). */
|
|
66
|
+
export declare function executeTestExchangeCredentials(ctx: OnboardingContext, apiKey: string, secret: string, testnet: boolean | undefined): Promise<TestExchangeCredentialsOutcome>;
|
|
67
|
+
/** Forward a clear_exchange_credentials invocation to the plugin. Sends
|
|
68
|
+
* `confirm: true` unconditionally — the skill RPC only accepts the call
|
|
69
|
+
* at all when the bridge has decided it's legitimate, so the plugin-side
|
|
70
|
+
* safety gate is always satisfied when we reach this function. */
|
|
71
|
+
export declare function executeClearExchangeCredentials(ctx: OnboardingContext): Promise<ClearExchangeCredentialsOutcome>;
|
|
72
|
+
/** Forward a get_bracket_config invocation to the plugin. Returns safe
|
|
73
|
+
* defaults if the tool isn't available (bracket feature not enabled or
|
|
74
|
+
* plugin is older than v2.7) so the dashboard can still render. */
|
|
75
|
+
export declare function executeGetBracketConfig(ctx: OnboardingContext): Promise<GetBracketConfigOutcome>;
|
|
76
|
+
/** Forward a set_bracket_requirement invocation to the plugin. The plugin
|
|
77
|
+
* side enforces flag + boolean validation; the skill layer just forwards. */
|
|
78
|
+
export declare function executeSetBracketRequirement(ctx: OnboardingContext, flag: BracketRequirementFlag, value: boolean): Promise<SetBracketRequirementOutcome>;
|
|
79
|
+
/** Forward a set_exchange_credentials invocation to the plugin via HTTP.
|
|
80
|
+
* The raw secret is sent once over TLS and never retained here — no
|
|
81
|
+
* caching, no log lines with the raw value. Errors are scrubbed of the
|
|
82
|
+
* secret before logging in case it ever appears in an error chain. */
|
|
83
|
+
export declare function executeSetExchangeCredentials(ctx: OnboardingContext, apiKey: string, secret: string, testnet: boolean | undefined): Promise<SetExchangeCredentialsOutcome>;
|