@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 @@
|
|
|
1
|
+
export type { ConditionResult, ConditionContext, ConditionFn, ConditionConfig, EntryRuleConfig, StopRuleConfig, DirectionRule, PrimaryTimeframe, StrategyConfig, } from '@reefclaw/shared';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// ⚠️ GENERATED FILE — DO NOT EDIT.
|
|
2
|
+
// Canonical source of truth: shared/src/signals/direction-rules.ts
|
|
3
|
+
// Regenerate: node scripts/sync-shared-code.mjs (enforced by shared-code-sync.test.ts)
|
|
4
|
+
//
|
|
5
|
+
// This copy exists because this package builds with tsc and deploys as a
|
|
6
|
+
// self-contained tree that strips workspace deps, so it cannot import
|
|
7
|
+
// @reefclaw/shared runtime code across the deploy boundary.
|
|
8
|
+
export function resolveDirection(rule, ctx, condCtx) {
|
|
9
|
+
switch (rule) {
|
|
10
|
+
case 'from_regime':
|
|
11
|
+
return ctx.regime === 'TREND_UP' ? 'LONG' : ctx.regime === 'TREND_DOWN' ? 'SHORT' : null;
|
|
12
|
+
case 'from_sweep':
|
|
13
|
+
return condCtx.sweptDirection ?? null;
|
|
14
|
+
case 'from_funding':
|
|
15
|
+
// funding_extreme condition sets sweptDirection to the contra direction
|
|
16
|
+
return condCtx.sweptDirection ?? null;
|
|
17
|
+
case 'fixed_long':
|
|
18
|
+
return 'LONG';
|
|
19
|
+
case 'fixed_short':
|
|
20
|
+
return 'SHORT';
|
|
21
|
+
default:
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { MarketContext, Direction } from './types.js';
|
|
2
|
+
import type { EntryRuleConfig, ConditionContext } from './conditions/types.js';
|
|
3
|
+
export declare function computeEntry(rule: EntryRuleConfig, ctx: MarketContext, direction: Direction, condCtx: ConditionContext): {
|
|
4
|
+
low: number;
|
|
5
|
+
high: number;
|
|
6
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// ⚠️ GENERATED FILE — DO NOT EDIT.
|
|
2
|
+
// Canonical source of truth: shared/src/signals/entry-rules.ts
|
|
3
|
+
// Regenerate: node scripts/sync-shared-code.mjs (enforced by shared-code-sync.test.ts)
|
|
4
|
+
//
|
|
5
|
+
// This copy exists because this package builds with tsc and deploys as a
|
|
6
|
+
// self-contained tree that strips workspace deps, so it cannot import
|
|
7
|
+
// @reefclaw/shared runtime code across the deploy boundary.
|
|
8
|
+
// Entry zone calculation for declarative strategies.
|
|
9
|
+
import { computeEMA } from '../shared/indicators.js';
|
|
10
|
+
export function computeEntry(rule, ctx, direction, condCtx) {
|
|
11
|
+
switch (rule.type) {
|
|
12
|
+
case 'ema_offset': {
|
|
13
|
+
const period = rule.params.period ?? 21;
|
|
14
|
+
const atrFraction = (rule.params.atrFraction ?? 0.3) * ctx.atr14;
|
|
15
|
+
const ema = condCtx.ema21 && period === 21
|
|
16
|
+
? condCtx.ema21
|
|
17
|
+
: computeEMA(ctx.ohlcv1h.map(b => b.close), period);
|
|
18
|
+
return { low: ema - atrFraction, high: ema + atrFraction };
|
|
19
|
+
}
|
|
20
|
+
case 'sweep_range': {
|
|
21
|
+
const sweepLevel = condCtx.sweepLevel ?? ctx.currentPrice;
|
|
22
|
+
return direction === 'LONG'
|
|
23
|
+
? { low: sweepLevel, high: ctx.currentPrice }
|
|
24
|
+
: { low: ctx.currentPrice, high: sweepLevel };
|
|
25
|
+
}
|
|
26
|
+
case 'atr_offset': {
|
|
27
|
+
const atrFraction = (rule.params.atrFraction ?? 0.2) * ctx.atr14;
|
|
28
|
+
return { low: ctx.currentPrice - atrFraction, high: ctx.currentPrice + atrFraction };
|
|
29
|
+
}
|
|
30
|
+
default:
|
|
31
|
+
return { low: ctx.currentPrice - ctx.atr14 * 0.3, high: ctx.currentPrice + ctx.atr14 * 0.3 };
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { MarketContext } from './types.js';
|
|
2
|
+
export declare function serializeContext(ctx: MarketContext): string;
|
|
3
|
+
/** Parse a streamed context and rehydrate every Date field. Throws on bad JSON. */
|
|
4
|
+
export declare function deserializeContext(raw: string): MarketContext;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// ⚠️ GENERATED FILE — DO NOT EDIT.
|
|
2
|
+
// Canonical source of truth: shared/src/signals/serialize-context.ts
|
|
3
|
+
// Regenerate: node scripts/sync-shared-code.mjs (enforced by shared-code-sync.test.ts)
|
|
4
|
+
//
|
|
5
|
+
// This copy exists because this package builds with tsc and deploys as a
|
|
6
|
+
// self-contained tree that strips workspace deps, so it cannot import
|
|
7
|
+
// @reefclaw/shared runtime code across the deploy boundary.
|
|
8
|
+
export function serializeContext(ctx) {
|
|
9
|
+
return JSON.stringify(ctx);
|
|
10
|
+
}
|
|
11
|
+
function reviveBars(bars) {
|
|
12
|
+
if (!Array.isArray(bars))
|
|
13
|
+
return undefined;
|
|
14
|
+
return bars.map((b) => ({ ...b, time: new Date(b.time) }));
|
|
15
|
+
}
|
|
16
|
+
/** Parse a streamed context and rehydrate every Date field. Throws on bad JSON. */
|
|
17
|
+
export function deserializeContext(raw) {
|
|
18
|
+
const o = JSON.parse(raw);
|
|
19
|
+
o.timestamp = new Date(o.timestamp);
|
|
20
|
+
const oh1 = reviveBars(o.ohlcv1h);
|
|
21
|
+
if (oh1)
|
|
22
|
+
o.ohlcv1h = oh1;
|
|
23
|
+
const oh5 = reviveBars(o.ohlcv5m);
|
|
24
|
+
if (oh5)
|
|
25
|
+
o.ohlcv5m = oh5;
|
|
26
|
+
const oh4 = reviveBars(o.ohlcv4h);
|
|
27
|
+
if (oh4)
|
|
28
|
+
o.ohlcv4h = oh4;
|
|
29
|
+
const oh1d = reviveBars(o.ohlcv1d);
|
|
30
|
+
if (oh1d)
|
|
31
|
+
o.ohlcv1d = oh1d;
|
|
32
|
+
if (Array.isArray(o.tradeFlow)) {
|
|
33
|
+
o.tradeFlow = o.tradeFlow.map((t) => ({ ...t, bucket: new Date(t.bucket) }));
|
|
34
|
+
}
|
|
35
|
+
if (o.globalContext?.btcRsi14_1d_at) {
|
|
36
|
+
o.globalContext.btcRsi14_1d_at = new Date(o.globalContext.btcRsi14_1d_at);
|
|
37
|
+
}
|
|
38
|
+
return o;
|
|
39
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { MarketContext, Direction } from './types.js';
|
|
2
|
+
import type { StopRuleConfig, ConditionContext } from './conditions/types.js';
|
|
3
|
+
export declare function computeStop(rule: StopRuleConfig, ctx: MarketContext, direction: Direction, condCtx: ConditionContext): number;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// ⚠️ GENERATED FILE — DO NOT EDIT.
|
|
2
|
+
// Canonical source of truth: shared/src/signals/stop-rules.ts
|
|
3
|
+
// Regenerate: node scripts/sync-shared-code.mjs (enforced by shared-code-sync.test.ts)
|
|
4
|
+
//
|
|
5
|
+
// This copy exists because this package builds with tsc and deploys as a
|
|
6
|
+
// self-contained tree that strips workspace deps, so it cannot import
|
|
7
|
+
// @reefclaw/shared runtime code across the deploy boundary.
|
|
8
|
+
// Stop level calculation for declarative strategies.
|
|
9
|
+
import { findSwingPoints } from '../shared/indicators.js';
|
|
10
|
+
export function computeStop(rule, ctx, direction, condCtx) {
|
|
11
|
+
switch (rule.type) {
|
|
12
|
+
case 'swing_atr': {
|
|
13
|
+
const swingCount = rule.params.swingCount ?? 3;
|
|
14
|
+
const atrFraction = (rule.params.atrFraction ?? 0.3) * ctx.atr14;
|
|
15
|
+
const fallbackAtrMult = rule.params.fallbackAtrMultiple ?? 2;
|
|
16
|
+
const swings = findSwingPoints(ctx.ohlcv1h.slice(-48), 3);
|
|
17
|
+
if (direction === 'LONG') {
|
|
18
|
+
return swings.lows.length > 0
|
|
19
|
+
? Math.min(...swings.lows.slice(-swingCount)) - atrFraction
|
|
20
|
+
: ctx.currentPrice - ctx.atr14 * fallbackAtrMult;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
return swings.highs.length > 0
|
|
24
|
+
? Math.max(...swings.highs.slice(-swingCount)) + atrFraction
|
|
25
|
+
: ctx.currentPrice + ctx.atr14 * fallbackAtrMult;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
case 'recent_extreme_atr': {
|
|
29
|
+
const atrFraction = (rule.params.atrFraction ?? 0.5) * ctx.atr14;
|
|
30
|
+
if (direction === 'LONG') {
|
|
31
|
+
return (condCtx.recentLow ?? ctx.currentPrice - ctx.atr14) - atrFraction;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
return (condCtx.recentHigh ?? ctx.currentPrice + ctx.atr14) + atrFraction;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
case 'fixed_atr': {
|
|
38
|
+
const atrMultiple = rule.params.atrMultiple ?? 1.5;
|
|
39
|
+
return direction === 'LONG'
|
|
40
|
+
? ctx.currentPrice - ctx.atr14 * atrMultiple
|
|
41
|
+
: ctx.currentPrice + ctx.atr14 * atrMultiple;
|
|
42
|
+
}
|
|
43
|
+
default:
|
|
44
|
+
return direction === 'LONG'
|
|
45
|
+
? ctx.currentPrice - ctx.atr14 * 2
|
|
46
|
+
: ctx.currentPrice + ctx.atr14 * 2;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { StrategyDefinition } from './types.js';
|
|
2
|
+
import type { StrategyConfig } from './conditions/types.js';
|
|
3
|
+
export declare function clearStrategyGatingState(): void;
|
|
4
|
+
/**
|
|
5
|
+
* Convert a declarative StrategyConfig into a StrategyDefinition
|
|
6
|
+
* that the signal engine and backtest engine can evaluate.
|
|
7
|
+
*
|
|
8
|
+
* `gateNamespace` scopes the module-global HTF tick-gate to the calling tenant
|
|
9
|
+
* (pass the strategy-cache key — `global` for the background pass, the user key
|
|
10
|
+
* for a per-user pass). Omit it for single-tenant callers (backtests, the
|
|
11
|
+
* plugin's local evaluator) — they keep the original un-namespaced gate key,
|
|
12
|
+
* so their behaviour is byte-identical.
|
|
13
|
+
*/
|
|
14
|
+
export declare function adaptStrategy(config: StrategyConfig, gateNamespace?: string): StrategyDefinition;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// ⚠️ GENERATED FILE — DO NOT EDIT.
|
|
2
|
+
// Canonical source of truth: shared/src/signals/strategy-adapter.ts
|
|
3
|
+
// Regenerate: node scripts/sync-shared-code.mjs (enforced by shared-code-sync.test.ts)
|
|
4
|
+
//
|
|
5
|
+
// This copy exists because this package builds with tsc and deploys as a
|
|
6
|
+
// self-contained tree that strips workspace deps, so it cannot import
|
|
7
|
+
// @reefclaw/shared runtime code across the deploy boundary.
|
|
8
|
+
import { evaluateConditions } from './conditions/registry.js';
|
|
9
|
+
import { resolveDirection } from './direction-rules.js';
|
|
10
|
+
import { computeEntry } from './entry-rules.js';
|
|
11
|
+
import { computeStop } from './stop-rules.js';
|
|
12
|
+
/**
|
|
13
|
+
* Higher-timeframe tick gating state, keyed by
|
|
14
|
+
* `${gateNamespace}\x1f${strategyName}:${symbol}`.
|
|
15
|
+
*
|
|
16
|
+
* Lives at module scope because the strategy cache (strategy-store.ts) builds
|
|
17
|
+
* a fresh adapter every 60s, so closure-based state would reset constantly
|
|
18
|
+
* and 1d-primary strategies would re-evaluate on every tick instead of once
|
|
19
|
+
* per closed bar. Module-level state survives the cache refresh.
|
|
20
|
+
*
|
|
21
|
+
* ★ Multi-tenant: because the map is module-global, the key MUST carry a
|
|
22
|
+
* per-tenant `gateNamespace` (the caller's strategy-cache key — `global` vs a
|
|
23
|
+
* per-user key). Without it, two tenants running same-named strategies on the
|
|
24
|
+
* same symbol shared ONE gate: whichever evaluated first marked the bar
|
|
25
|
+
* consumed and the other tenant's strategy was silently SKIPPED until the next
|
|
26
|
+
* primary-timeframe bar closed (a full day for a 1d strategy). A `\x1f` (unit
|
|
27
|
+
* separator, never present in a UUID / strategy name / symbol) joins the
|
|
28
|
+
* namespace so distinct tenants can never collide.
|
|
29
|
+
*
|
|
30
|
+
* Backtests should call `clearStrategyGatingState()` between runs to avoid
|
|
31
|
+
* leakage across tests / sequential backtests.
|
|
32
|
+
*/
|
|
33
|
+
const lastEvaluatedBarTime = new Map();
|
|
34
|
+
export function clearStrategyGatingState() {
|
|
35
|
+
lastEvaluatedBarTime.clear();
|
|
36
|
+
}
|
|
37
|
+
function pickTimeframeBars(ctx, tf) {
|
|
38
|
+
if (tf === '1d')
|
|
39
|
+
return ctx.ohlcv1d ?? [];
|
|
40
|
+
if (tf === '4h')
|
|
41
|
+
return ctx.ohlcv4h ?? [];
|
|
42
|
+
return ctx.ohlcv1h;
|
|
43
|
+
}
|
|
44
|
+
/** Empty no-signal evaluation — used when gating skips a strategy. */
|
|
45
|
+
const SKIPPED = { direction: null, conditions: [], trade: undefined };
|
|
46
|
+
/**
|
|
47
|
+
* Convert a declarative StrategyConfig into a StrategyDefinition
|
|
48
|
+
* that the signal engine and backtest engine can evaluate.
|
|
49
|
+
*
|
|
50
|
+
* `gateNamespace` scopes the module-global HTF tick-gate to the calling tenant
|
|
51
|
+
* (pass the strategy-cache key — `global` for the background pass, the user key
|
|
52
|
+
* for a per-user pass). Omit it for single-tenant callers (backtests, the
|
|
53
|
+
* plugin's local evaluator) — they keep the original un-namespaced gate key,
|
|
54
|
+
* so their behaviour is byte-identical.
|
|
55
|
+
*/
|
|
56
|
+
export function adaptStrategy(config, gateNamespace) {
|
|
57
|
+
return {
|
|
58
|
+
name: config.name,
|
|
59
|
+
regimeWhitelist: config.regimeWhitelist,
|
|
60
|
+
minConfidence: config.minConfidence,
|
|
61
|
+
async evaluate(ctx) {
|
|
62
|
+
// ─── Tick gating ───────────────────────────────────────────────
|
|
63
|
+
// Only re-evaluate when a new bar of the strategy's primary
|
|
64
|
+
// timeframe has closed since the last evaluation for this
|
|
65
|
+
// strategy/symbol pair. Defaults to '1h' so existing strategies
|
|
66
|
+
// are unaffected.
|
|
67
|
+
const tf = config.primaryTimeframe ?? '1h';
|
|
68
|
+
const tfBars = pickTimeframeBars(ctx, tf);
|
|
69
|
+
if (tfBars.length === 0)
|
|
70
|
+
return SKIPPED;
|
|
71
|
+
const latestBarTime = tfBars[tfBars.length - 1].time.getTime();
|
|
72
|
+
// Namespaced per tenant (see lastEvaluatedBarTime doc) so same-named
|
|
73
|
+
// strategies across tenants never share a gate. Un-namespaced when
|
|
74
|
+
// gateNamespace is omitted — byte-identical to the original key.
|
|
75
|
+
const gateKey = gateNamespace
|
|
76
|
+
? `${gateNamespace}\x1f${config.name}:${ctx.symbol}`
|
|
77
|
+
: `${config.name}:${ctx.symbol}`;
|
|
78
|
+
const lastBarTime = lastEvaluatedBarTime.get(gateKey);
|
|
79
|
+
if (lastBarTime !== undefined && latestBarTime === lastBarTime) {
|
|
80
|
+
return SKIPPED;
|
|
81
|
+
}
|
|
82
|
+
lastEvaluatedBarTime.set(gateKey, latestBarTime);
|
|
83
|
+
// ─── SkipIf gates ──────────────────────────────────────────────
|
|
84
|
+
// Portfolio-wide / cross-symbol filters. If any are met the
|
|
85
|
+
// strategy is skipped this tick. Evaluated before main conditions
|
|
86
|
+
// so the bulk of the work is short-circuited.
|
|
87
|
+
if (config.skipIf && config.skipIf.length > 0) {
|
|
88
|
+
const { conditions: skipResults } = evaluateConditions(config.skipIf, ctx, null);
|
|
89
|
+
if (skipResults.some(c => c.met))
|
|
90
|
+
return SKIPPED;
|
|
91
|
+
}
|
|
92
|
+
// Pass 1: evaluate conditions with direction = null
|
|
93
|
+
const { conditions: pass1, condCtx } = evaluateConditions(config.conditions, ctx, null);
|
|
94
|
+
// Determine direction
|
|
95
|
+
const direction = resolveDirection(config.directionRule, ctx, condCtx);
|
|
96
|
+
// Pass 2: re-evaluate direction-sensitive conditions now that we know direction
|
|
97
|
+
// (orderbook_imbalance and funding_contrarian behave differently per direction)
|
|
98
|
+
const directionSensitive = new Set(['orderbook_imbalance', 'funding_contrarian', 'funding_extreme_skip', 'funding_position_ok', 'return_momentum']);
|
|
99
|
+
const hasDirSensitive = config.conditions.some(c => directionSensitive.has(c.type));
|
|
100
|
+
let finalConditions = pass1;
|
|
101
|
+
if (direction && hasDirSensitive) {
|
|
102
|
+
const { conditions: pass2 } = evaluateConditions(config.conditions, ctx, direction);
|
|
103
|
+
// Merge: use pass2 results for direction-sensitive, pass1 for others
|
|
104
|
+
finalConditions = pass1.map((c, i) => directionSensitive.has(config.conditions[i].type) ? pass2[i] : c);
|
|
105
|
+
}
|
|
106
|
+
const allMet = finalConditions.every(c => c.met);
|
|
107
|
+
let trade;
|
|
108
|
+
if (allMet && direction) {
|
|
109
|
+
const entryZone = computeEntry(config.entryRule, ctx, direction, condCtx);
|
|
110
|
+
const stopLevel = computeStop(config.stopRule, ctx, direction, condCtx);
|
|
111
|
+
const risk = direction === 'LONG'
|
|
112
|
+
? ctx.currentPrice - stopLevel
|
|
113
|
+
: stopLevel - ctx.currentPrice;
|
|
114
|
+
const targets = config.targetRMultiples.map(rm => direction === 'LONG'
|
|
115
|
+
? ctx.currentPrice + risk * rm
|
|
116
|
+
: ctx.currentPrice - risk * rm);
|
|
117
|
+
trade = { entryZone, stopLevel, targets };
|
|
118
|
+
}
|
|
119
|
+
return { direction, conditions: finalConditions, trade };
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { Direction, OhlcvBar, TradeFlowBucket, GlobalMarketContext, MarketContext, SignalCondition, StrategyEvaluation, StrategyDefinition, SignalEvent, StrategyState, SignalSnapshot, } from '@reefclaw/shared';
|
package/signals/types.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Re-export shim for the plugin-side strategy evaluator (facts-out).
|
|
2
|
+
//
|
|
3
|
+
// The generated eval-core copies (registry, strategy-adapter, direction/entry/
|
|
4
|
+
// stop-rules) import their types from `./types.js`. The canonical definitions
|
|
5
|
+
// live in @reefclaw/shared (type-only → erased at runtime), so this shim makes
|
|
6
|
+
// those relative imports resolve inside the plugin tree without pulling any
|
|
7
|
+
// runtime dependency into the emitted JS. See docs/FACTS_OUT_ARCHITECTURE.md.
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import type { SimulatorState, OrderBookDepth, SimulationConfig, ExecutionStats, PositionMetadata, CloseReason } from './types.js';
|
|
3
|
+
import type { CcxtOrder, CcxtBalance, CcxtPosition, CcxtTicker } from '../types.js';
|
|
4
|
+
export declare class ExchangeSimulator extends EventEmitter {
|
|
5
|
+
private state;
|
|
6
|
+
private lastTicker;
|
|
7
|
+
private lastOrderBook;
|
|
8
|
+
private simulationConfig;
|
|
9
|
+
/** Metadata for pending limit orders, keyed by order ID. Cleaned up on fill/cancel. */
|
|
10
|
+
private pendingOrderMetadata;
|
|
11
|
+
private cachedVolFactor;
|
|
12
|
+
private baselineAtr;
|
|
13
|
+
private atrSampleCount;
|
|
14
|
+
private readonly startupTime;
|
|
15
|
+
private readonly hadPositionsAtStartup;
|
|
16
|
+
private static readonly STARTUP_LOCKOUT_MS;
|
|
17
|
+
constructor(initialState: SimulatorState, config?: SimulationConfig);
|
|
18
|
+
getSimulationConfig(): SimulationConfig;
|
|
19
|
+
setVolFactor(factor: number): void;
|
|
20
|
+
getVolFactor(): number;
|
|
21
|
+
/** Update baseline ATR using exponential moving average of samples. */
|
|
22
|
+
updateBaselineAtr(atr14: number): void;
|
|
23
|
+
getBaselineAtr(): number;
|
|
24
|
+
/**
|
|
25
|
+
* Returns today's session-start NAV, lazily seeding it from current equity
|
|
26
|
+
* if unset or stale (different UTC day). This is the plugin-side anchor used
|
|
27
|
+
* by the pre-trade risk gate; a stale/missing anchor silently disables the
|
|
28
|
+
* drawdown zones, so callers must never see a zero.
|
|
29
|
+
*/
|
|
30
|
+
getSessionStartNav(): number;
|
|
31
|
+
setSessionStartNav(nav: number): void;
|
|
32
|
+
/** Seed sessionStartNav from current equity on the first check of each UTC day.
|
|
33
|
+
* Safe to call repeatedly — no-op once the anchor matches today's date. */
|
|
34
|
+
private ensureSessionAnchor;
|
|
35
|
+
/** Mark-to-market equity = walletTotal + for each open position, the
|
|
36
|
+
* collateral locked at entry + current unrealized P&L. Paper simulator is
|
|
37
|
+
* SPOT-collateral style: the full entry notional was deducted from wallet
|
|
38
|
+
* on open and is released on close, so we must add it back here. */
|
|
39
|
+
computeEquity(): number;
|
|
40
|
+
private getQuoteCurrency;
|
|
41
|
+
getBalance(): CcxtBalance;
|
|
42
|
+
getPositions(symbol?: string): CcxtPosition[];
|
|
43
|
+
getOpenOrders(symbol?: string): CcxtOrder[];
|
|
44
|
+
/** Get cumulative execution quality stats. */
|
|
45
|
+
getExecutionStats(): ExecutionStats | undefined;
|
|
46
|
+
/** Cache the latest order book snapshot for a symbol. */
|
|
47
|
+
updateOrderBook(symbol: string, orderbook: OrderBookDepth): void;
|
|
48
|
+
getLastOrderBook(symbol: string): OrderBookDepth | undefined;
|
|
49
|
+
createOrder(symbol: string, side: 'buy' | 'sell', type: 'market' | 'limit', amount: number, price?: number, metadata?: PositionMetadata): CcxtOrder;
|
|
50
|
+
cancelOrder(orderId: string): CcxtOrder;
|
|
51
|
+
cancelAllOrders(symbol?: string): CcxtOrder[];
|
|
52
|
+
closePosition(symbol: string, closeReason?: CloseReason): CcxtOrder;
|
|
53
|
+
/** Paper-only: move an open position's MUTABLE protective levels (stopPrice /
|
|
54
|
+
* targetPrice) in place and persist, WITHOUT the close+reopen round-trip
|
|
55
|
+
* (which pays an extra taker fee and resets the R/MFE denominators). The
|
|
56
|
+
* frozen originalStopPrice / originalEntryPrice are intentionally left
|
|
57
|
+
* untouched so R-multiples stay anchored at entry. The paper stop-watcher
|
|
58
|
+
* and getPositions both read metadata.stopPrice, so a moved stop takes
|
|
59
|
+
* effect on the next watcher tick. Throws if there is no open position. (M9) */
|
|
60
|
+
updatePositionMetadata(symbol: string, patch: {
|
|
61
|
+
stopPrice?: number;
|
|
62
|
+
targetPrice?: number;
|
|
63
|
+
}): void;
|
|
64
|
+
updateTicker(ticker: CcxtTicker): void;
|
|
65
|
+
getLastTicker(symbol: string): CcxtTicker | undefined;
|
|
66
|
+
/** Walk every position for `symbol` and refresh MFE / give-back from the
|
|
67
|
+
* latest mark. Idempotent — pure update of `metadata.mfePeakPrice` (only
|
|
68
|
+
* ratchets favourably) plus derived `mfeR` and `giveBackRatio`. Safe to
|
|
69
|
+
* call before any positions exist (no-op). */
|
|
70
|
+
private refreshMfeForSymbol;
|
|
71
|
+
/** Replace internal state with a fresh copy from disk.
|
|
72
|
+
* Used by the gateway process to pick up state saved by the agent process.
|
|
73
|
+
*
|
|
74
|
+
* Non-destructive for the MFE ratchet (M3): the disk copy can lag the live
|
|
75
|
+
* peak (refreshMfeForSymbol ratchets every tick; persistence coalesces), so
|
|
76
|
+
* a wholesale swap would discard it. For each position present in BOTH
|
|
77
|
+
* snapshots (same symbol+side+openedAt) we carry over the MORE-favourable
|
|
78
|
+
* monotone peak and recompute mfeR/giveBackRatio from the current mark, so a
|
|
79
|
+
* reload never regresses the agent's give-back signal. */
|
|
80
|
+
replaceState(newState: SimulatorState): void;
|
|
81
|
+
getState(): SimulatorState;
|
|
82
|
+
private shouldFillLimit;
|
|
83
|
+
private executeMarketFill;
|
|
84
|
+
private executeLimitFill;
|
|
85
|
+
/** Apply a fill result: update positions, record trade, track stats, emit state change. */
|
|
86
|
+
private applyFillResult;
|
|
87
|
+
private updatePosition;
|
|
88
|
+
private addTrade;
|
|
89
|
+
/** Update cumulative execution stats from a fill's execution quality. */
|
|
90
|
+
private updateExecutionStats;
|
|
91
|
+
private emitStateChanged;
|
|
92
|
+
private toCcxtOrder;
|
|
93
|
+
}
|