@senpi/runtime 2.0.2-dev.openclaw-upgrade-mai.20260622175851 → 3.0.0-dev.runtime-phase-2.20260623210537
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/README.md +9 -10
- package/dist/actions/decision-engine.d.ts.map +1 -1
- package/dist/actions/decision-engine.js +0 -3
- package/dist/actions/decision-engine.js.map +1 -1
- package/dist/actions/open-position/open-position.action.d.ts.map +1 -1
- package/dist/actions/open-position/open-position.action.js +2 -6
- package/dist/actions/open-position/open-position.action.js.map +1 -1
- package/dist/cli/guide-commands.d.ts.map +1 -1
- package/dist/cli/guide-commands.js +56 -43
- package/dist/cli/guide-commands.js.map +1 -1
- package/dist/cli/senpi-commands.d.ts.map +1 -1
- package/dist/cli/senpi-commands.js +108 -0
- package/dist/cli/senpi-commands.js.map +1 -1
- package/dist/constants/dsl/index.d.ts +0 -2
- package/dist/constants/dsl/index.d.ts.map +1 -1
- package/dist/constants/dsl/index.js +0 -2
- package/dist/constants/dsl/index.js.map +1 -1
- package/dist/dsl/engine-client/config-mapping.d.ts +0 -7
- package/dist/dsl/engine-client/config-mapping.d.ts.map +1 -1
- package/dist/dsl/engine-client/config-mapping.js +2 -16
- package/dist/dsl/engine-client/config-mapping.js.map +1 -1
- package/dist/dsl/events/handlers.d.ts +2 -18
- package/dist/dsl/events/handlers.d.ts.map +1 -1
- package/dist/dsl/events/handlers.js +213 -302
- package/dist/dsl/events/handlers.js.map +1 -1
- package/dist/dsl/monitor/create-monitor.d.ts +0 -15
- package/dist/dsl/monitor/create-monitor.d.ts.map +1 -1
- package/dist/dsl/monitor/create-monitor.js +9 -44
- package/dist/dsl/monitor/create-monitor.js.map +1 -1
- package/dist/dsl/monitor/process-one-position.d.ts.map +1 -1
- package/dist/dsl/monitor/process-one-position.js +1 -24
- package/dist/dsl/monitor/process-one-position.js.map +1 -1
- package/dist/dsl/plugin/index.d.ts +1 -16
- package/dist/dsl/plugin/index.d.ts.map +1 -1
- package/dist/dsl/plugin/index.js +4 -35
- package/dist/dsl/plugin/index.js.map +1 -1
- package/dist/dsl/plugin/options.d.ts +0 -18
- package/dist/dsl/plugin/options.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/runtime/create-scanner-module.d.ts +3 -4
- package/dist/runtime/create-scanner-module.d.ts.map +1 -1
- package/dist/runtime/create-scanner-module.js +5 -14
- package/dist/runtime/create-scanner-module.js.map +1 -1
- package/dist/runtime/create-scanner-providers-for-run.d.ts.map +1 -1
- package/dist/runtime/create-scanner-providers-for-run.js +1 -12
- package/dist/runtime/create-scanner-providers-for-run.js.map +1 -1
- package/dist/runtime/load-runtime-config.js +1 -1
- package/dist/runtime/load-runtime-config.js.map +1 -1
- package/dist/runtime/map-strategies-registration.js +8 -7
- package/dist/runtime/map-strategies-registration.js.map +1 -1
- package/dist/runtime/map-strategies.d.ts.map +1 -1
- package/dist/runtime/map-strategies.js +3 -12
- package/dist/runtime/map-strategies.js.map +1 -1
- package/dist/runtime/reconcile-state.d.ts +0 -44
- package/dist/runtime/reconcile-state.d.ts.map +1 -1
- package/dist/runtime/reconcile-state.js +44 -80
- package/dist/runtime/reconcile-state.js.map +1 -1
- package/dist/runtime/risk-guard.d.ts.map +1 -1
- package/dist/runtime/risk-guard.js +12 -17
- package/dist/runtime/risk-guard.js.map +1 -1
- package/dist/runtime/runtime-schema.d.ts +995 -2855
- package/dist/runtime/runtime-schema.d.ts.map +1 -1
- package/dist/runtime/runtime-schema.js +40 -133
- package/dist/runtime/runtime-schema.js.map +1 -1
- package/dist/runtime/runtime.d.ts +0 -26
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +5 -233
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/scanner-registry.d.ts +1 -1
- package/dist/runtime/scanner-registry.d.ts.map +1 -1
- package/dist/runtime/scanner-registry.js +12 -3
- package/dist/runtime/scanner-registry.js.map +1 -1
- package/dist/runtime/supervisor/long-running-supervisor.d.ts.map +1 -1
- package/dist/runtime/supervisor/long-running-supervisor.js +1 -1
- package/dist/runtime/supervisor/long-running-supervisor.js.map +1 -1
- package/dist/runtime/supervisor/orphan-sweep.js +1 -1
- package/dist/runtime/supervisor/orphan-sweep.js.map +1 -1
- package/dist/runtime/supervisor/supervisor-utils.d.ts +3 -3
- package/dist/runtime/supervisor/supervisor-utils.d.ts.map +1 -1
- package/dist/runtime/supervisor/supervisor-utils.js +3 -3
- package/dist/runtime/supervisor/supervisor-utils.js.map +1 -1
- package/dist/runtime-api/intake/intake-mount.d.ts +3 -3
- package/dist/runtime-api/intake/intake-mount.d.ts.map +1 -1
- package/dist/runtime-api/intake/intake-mount.js +36 -28
- package/dist/runtime-api/intake/intake-mount.js.map +1 -1
- package/dist/runtime-api/intake/liveness-store.d.ts +6 -2
- package/dist/runtime-api/intake/liveness-store.d.ts.map +1 -1
- package/dist/runtime-api/intake/liveness-store.js +6 -2
- package/dist/runtime-api/intake/liveness-store.js.map +1 -1
- package/dist/runtime-api/intake/process-signal-post.d.ts.map +1 -1
- package/dist/runtime-api/intake/process-signal-post.js +0 -0
- package/dist/runtime-api/intake/process-signal-post.js.map +1 -1
- package/dist/runtime-api/intake/scanner-launcher.d.ts +29 -24
- package/dist/runtime-api/intake/scanner-launcher.d.ts.map +1 -1
- package/dist/runtime-api/intake/scanner-launcher.js +3 -24
- package/dist/runtime-api/intake/scanner-launcher.js.map +1 -1
- package/dist/runtime-api/intake/types.d.ts +0 -6
- package/dist/runtime-api/intake/types.d.ts.map +1 -1
- package/dist/runtime-api/routes/signals.d.ts +6 -0
- package/dist/runtime-api/routes/signals.d.ts.map +1 -1
- package/dist/runtime-api/routes/signals.js +14 -0
- package/dist/runtime-api/routes/signals.js.map +1 -1
- package/dist/runtime-api/routes/signals.schema.d.ts +0 -1
- package/dist/runtime-api/routes/signals.schema.d.ts.map +1 -1
- package/dist/runtime-api/routes/signals.schema.js +0 -5
- package/dist/runtime-api/routes/signals.schema.js.map +1 -1
- package/dist/runtime-api/server.d.ts.map +1 -1
- package/dist/runtime-api/server.js +1 -0
- package/dist/runtime-api/server.js.map +1 -1
- package/dist/scanners/external/liquidation-watchdog/README.md +107 -0
- package/dist/scanners/external/liquidation-watchdog/liquidation-watchdog.yaml +48 -0
- package/dist/scanners/external/liquidation-watchdog/producer.mjs +336 -0
- package/dist/scanners/external/momentum/README.md +148 -0
- package/dist/scanners/external/momentum/momentum.yaml +116 -0
- package/dist/scanners/external/momentum/producer.mjs +251 -0
- package/dist/scanners/external/scaffold/__main__.py +24 -65
- package/dist/scanners/external/scaffold/delivery.py +22 -56
- package/dist/scanners/external/scaffold/entrypoint_loader.py +48 -42
- package/dist/scanners/external/scaffold/journal.py +22 -15
- package/dist/scanners/external/scaffold/scaffold.py +128 -159
- package/dist/scanners/external/scaffold/signal_envelope.py +34 -177
- package/dist/scanners/external/shared/ingest.mjs +112 -0
- package/dist/scanners/external-scanner-receiver.d.ts +0 -6
- package/dist/scanners/external-scanner-receiver.d.ts.map +1 -1
- package/dist/scanners/external-scanner-receiver.js +1 -14
- package/dist/scanners/external-scanner-receiver.js.map +1 -1
- package/dist/scripts/run-dsl-standalone-live.d.ts +1 -1
- package/dist/scripts/run-dsl-standalone-live.js +3 -5
- package/dist/scripts/run-dsl-standalone-live.js.map +1 -1
- package/dist/senpi/client.d.ts +0 -12
- package/dist/senpi/client.d.ts.map +1 -1
- package/dist/senpi/client.js +2 -31
- package/dist/senpi/client.js.map +1 -1
- package/dist/state/state-manager.d.ts +0 -17
- package/dist/state/state-manager.d.ts.map +1 -1
- package/dist/state/state-manager.js +0 -28
- package/dist/state/state-manager.js.map +1 -1
- package/dist/strategy/strategy-state.d.ts.map +1 -1
- package/dist/strategy/strategy-state.js +1 -7
- package/dist/strategy/strategy-state.js.map +1 -1
- package/dist/tracking/constants.d.ts.map +1 -1
- package/dist/tracking/constants.js +0 -2
- package/dist/tracking/constants.js.map +1 -1
- package/dist/types/dsl/index.d.ts +1 -1
- package/dist/types/dsl/index.d.ts.map +1 -1
- package/dist/types/scanner.d.ts +0 -7
- package/dist/types/scanner.d.ts.map +1 -1
- package/examples/README.md +89 -0
- package/examples/scanners-consumer-quickstart.mjs +134 -0
- package/examples/scanners-emerging-movers-v4.mjs +287 -0
- package/examples/scanners-liquidation-watchdog.mjs +341 -0
- package/examples/scanners-live-mcp.mjs +208 -0
- package/examples/scanners-multi-strategy.mjs +165 -0
- package/examples/scanners-position-tracker-e2e.mjs +225 -0
- package/examples/scanners-scheduled-events.mjs +96 -0
- package/examples/scanners-senpi-provider-client.mjs +182 -0
- package/examples/scanners-single-strategy.mjs +198 -0
- package/examples/strategies/README.md +12 -17
- package/examples/strategies/dsl-showcase.yaml +68 -0
- package/examples/strategies/dsl.yaml +51 -0
- package/examples/strategies/fox-minimal-loosened.yaml +240 -0
- package/examples/strategies/fox-minimal.yaml +242 -0
- package/examples/strategies/minimal.yaml +46 -0
- package/examples/strategies/momentum/how-it-works.md +48 -0
- package/examples/strategies/momentum/momentum-guarded.yaml +161 -0
- package/examples/strategies/risk-showcase.yaml +93 -0
- package/examples/strategies/viper.yaml +67 -0
- package/examples/strategies/wolf.yaml +72 -0
- package/examples/yamls/sample-with-dsl-and-emerging-movers.yaml +123 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/dist/runtime/reconcile-decide.d.ts +0 -73
- package/dist/runtime/reconcile-decide.d.ts.map +0 -1
- package/dist/runtime/reconcile-decide.js +0 -166
- package/dist/runtime/reconcile-decide.js.map +0 -1
- package/dist/runtime/reconcile-run.d.ts +0 -62
- package/dist/runtime/reconcile-run.d.ts.map +0 -1
- package/dist/runtime/reconcile-run.js +0 -173
- package/dist/runtime/reconcile-run.js.map +0 -1
- package/dist/scanners/external/scaffold/ctx.py +0 -78
- package/dist/scanners/external/scaffold/requirements.txt +0 -11
- package/dist/scanners/external/scaffold/senpi_mcp.py +0 -250
- package/dist/scanners/external/scaffold/state_manager.py +0 -175
- package/dist/utils/keyed-mutex.d.ts +0 -37
- package/dist/utils/keyed-mutex.d.ts.map +0 -1
- package/dist/utils/keyed-mutex.js +0 -77
- package/dist/utils/keyed-mutex.js.map +0 -1
- package/examples/strategies/iguana/README.md +0 -135
- package/examples/strategies/iguana/recipe.yaml +0 -137
- package/examples/strategies/iguana/scanners/scan.py +0 -243
- package/examples/strategies/iguana/scanners/scoring.py +0 -152
- package/examples/strategies/raptor/README.md +0 -156
- package/examples/strategies/raptor/recipe.yaml +0 -154
- package/examples/strategies/raptor/scanners/scan.py +0 -349
- package/examples/strategies/raptor/scanners/scoring.py +0 -452
- package/examples/strategies/spider/README.md +0 -97
- package/examples/strategies/spider/scalp/recipe.yaml +0 -129
- package/examples/strategies/spider/scalp/scanners/scan.py +0 -219
- package/examples/strategies/spider/scalp/scanners/scoring.py +0 -179
- package/examples/strategies/spider/swing/recipe.yaml +0 -141
- package/examples/strategies/spider/swing/scanners/scan.py +0 -334
- package/examples/strategies/spider/swing/scanners/scoring.py +0 -184
- package/examples/strategies/turbine/README.md +0 -167
- package/examples/strategies/turbine/recipe-runners.yaml +0 -123
- package/examples/strategies/turbine/recipe-volume.yaml +0 -129
- package/examples/strategies/turbine/scanners/scan.py +0 -283
- package/examples/strategies/turbine/scanners/scoring.py +0 -190
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
name: fox-minimal
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
description: >
|
|
4
|
+
FOX v1.6 — autonomous momentum trading via @senpi-ai/runtime.
|
|
5
|
+
Emerging movers detect first jumps, LLM entry filter applies the five-layer
|
|
6
|
+
gauntlet, DSL v5.3.1 manages trailing exits, watchdog guards margin health,
|
|
7
|
+
market-regime provides macro context, sm-flip detects conviction reversals.
|
|
8
|
+
|
|
9
|
+
strategy:
|
|
10
|
+
wallet: "${FOX_WALLET}"
|
|
11
|
+
slots: 1
|
|
12
|
+
margin_per_slot: 100
|
|
13
|
+
trading_risk: aggressive
|
|
14
|
+
enabled: true
|
|
15
|
+
|
|
16
|
+
scanners:
|
|
17
|
+
# References in depends_on/actions use these scanner names, not the built-in types.
|
|
18
|
+
# ── Primary signal: emerging movers (every 90s, matching Fox 3-min cron) ──
|
|
19
|
+
- name: emerging_movers
|
|
20
|
+
type: emerging_movers
|
|
21
|
+
interval: 90s
|
|
22
|
+
depends_on:
|
|
23
|
+
- scanner: market_regime
|
|
24
|
+
required: false
|
|
25
|
+
max_age: 2h
|
|
26
|
+
on_missing: degrade
|
|
27
|
+
on_stale: degrade
|
|
28
|
+
blocked_assets: []
|
|
29
|
+
config:
|
|
30
|
+
topN: 50
|
|
31
|
+
minRankJump: 5
|
|
32
|
+
minTopTradersGain: 0.1
|
|
33
|
+
minScansBeforeSignals: 2
|
|
34
|
+
historyLimit: 60
|
|
35
|
+
immediateJumpThreshold: 10
|
|
36
|
+
deepClimbRankThreshold: 25
|
|
37
|
+
contribExplosionMultiplier: 3
|
|
38
|
+
contribAccelThreshold: 0.003
|
|
39
|
+
minVelocityForDeepClimber: 0.0003
|
|
40
|
+
erraticReversalThreshold: 5
|
|
41
|
+
climbStreakScans: 3
|
|
42
|
+
rankClimbThreshold: 3
|
|
43
|
+
firstJumpMinPrevRank: 30
|
|
44
|
+
minLeverage: 7
|
|
45
|
+
blacklist: ["XPL", "kPEPE"]
|
|
46
|
+
|
|
47
|
+
# ── Macro context: BTC+ETH regime classification (every 4h) ──
|
|
48
|
+
- name: market_regime
|
|
49
|
+
type: market_regime
|
|
50
|
+
interval: 14400s
|
|
51
|
+
config:
|
|
52
|
+
btcWeight: 0.6
|
|
53
|
+
ethWeight: 0.4
|
|
54
|
+
emaFast: 9
|
|
55
|
+
emaSlow: 21
|
|
56
|
+
neutralThreshold: 0.3
|
|
57
|
+
|
|
58
|
+
# ── SM conviction reversal detection (every 5 min) ──
|
|
59
|
+
- name: sm_flip
|
|
60
|
+
type: sm_flip
|
|
61
|
+
interval: 300s
|
|
62
|
+
config:
|
|
63
|
+
minConviction: 4
|
|
64
|
+
|
|
65
|
+
# ── Margin safety net (every 5 min) ──
|
|
66
|
+
- name: watchdog
|
|
67
|
+
type: liquidation_watchdog
|
|
68
|
+
interval: 300s
|
|
69
|
+
config:
|
|
70
|
+
bufferWarningPct: 50
|
|
71
|
+
bufferCriticalPct: 30
|
|
72
|
+
liqDistanceWarningPct: 30
|
|
73
|
+
roeDangerPct: -15
|
|
74
|
+
|
|
75
|
+
# ── Infrastructure: prescreener for opportunity scanner (every 60s) ──
|
|
76
|
+
- name: prescreener
|
|
77
|
+
type: prescreener
|
|
78
|
+
interval: 60s
|
|
79
|
+
config:
|
|
80
|
+
topN: 30
|
|
81
|
+
minDayVolume: 500000
|
|
82
|
+
minLeverage: 2
|
|
83
|
+
minOpenInterest: 0
|
|
84
|
+
|
|
85
|
+
# ── Secondary deep scan: 4-pillar opportunity scoring (every 15 min) ──
|
|
86
|
+
- name: opportunity
|
|
87
|
+
type: opportunity
|
|
88
|
+
interval: 900s
|
|
89
|
+
depends_on:
|
|
90
|
+
- scanner: prescreener
|
|
91
|
+
required: true
|
|
92
|
+
max_age: 5m
|
|
93
|
+
- scanner: market_regime
|
|
94
|
+
required: false
|
|
95
|
+
max_age: 4h
|
|
96
|
+
on_missing: degrade
|
|
97
|
+
on_stale: degrade
|
|
98
|
+
config:
|
|
99
|
+
minCompositeScore: 60
|
|
100
|
+
maxCandidates: 15
|
|
101
|
+
minDayVolume: 500000
|
|
102
|
+
|
|
103
|
+
actions:
|
|
104
|
+
# ── Entry: LLM five-layer gauntlet on emerging mover signals ──
|
|
105
|
+
- name: fox_entry
|
|
106
|
+
action_type: OPEN_POSITION
|
|
107
|
+
decision_mode: llm
|
|
108
|
+
decision_model: claude-sonnet-4-6
|
|
109
|
+
scanners: [emerging_movers]
|
|
110
|
+
min_confidence: 7
|
|
111
|
+
params:
|
|
112
|
+
order_type: FEE_OPTIMIZED_LIMIT
|
|
113
|
+
fee_optimized_limit_options:
|
|
114
|
+
ensure_execution_as_taker: true
|
|
115
|
+
execution_timeout_seconds: 15
|
|
116
|
+
context:
|
|
117
|
+
- type: signal
|
|
118
|
+
scanner: emerging_movers
|
|
119
|
+
- type: context
|
|
120
|
+
scanner: market_regime
|
|
121
|
+
decision_prompt: |
|
|
122
|
+
You are the FOX v1.6 entry filter. Evaluate emerging mover signals through
|
|
123
|
+
a strict five-layer gauntlet. Speed is edge — enter on FIRST signal or skip.
|
|
124
|
+
|
|
125
|
+
SIGNAL DATA:
|
|
126
|
+
{{emerging_movers}}
|
|
127
|
+
|
|
128
|
+
MARKET REGIME:
|
|
129
|
+
{{regime}}
|
|
130
|
+
|
|
131
|
+
═══ LAYER 1: FIRST JUMP DETECTION (mandatory) ═══
|
|
132
|
+
- Must have FIRST_JUMP reason (jumped 10+ ranks from #25+ in one scan)
|
|
133
|
+
- Previous rank must be ≥ 20 (outside top 20)
|
|
134
|
+
- rankJumpThisScan ≥ 15 OR contribVelocity > 15 (small jumps eliminated)
|
|
135
|
+
- Asset already at #1-10 for 2+ scans → SKIP (move is over)
|
|
136
|
+
|
|
137
|
+
═══ LAYER 2: SCORING (minimum 7 points, 8 for NEUTRAL regime) ═══
|
|
138
|
+
FIRST_JUMP: +3 (mandatory)
|
|
139
|
+
IMMEDIATE_MOVER: +2
|
|
140
|
+
contribVelocity > 10: +2
|
|
141
|
+
CONTRIB_EXPLOSION: +2
|
|
142
|
+
DEEP_CLIMBER: +1
|
|
143
|
+
RANK_UP: +1
|
|
144
|
+
CLIMBING: +1
|
|
145
|
+
ACCEL: +1
|
|
146
|
+
STREAK: +1
|
|
147
|
+
BTC 1h bias aligned: +1
|
|
148
|
+
UTC 04:00-13:59: +1 (time-of-day bonus)
|
|
149
|
+
UTC 18:00-02:00: -2 (evening penalty — needs score 9+ effective)
|
|
150
|
+
|
|
151
|
+
Minimum requirements: score ≥ 7, reasons ≥ 3, contribVelocity > 7 (hard gate)
|
|
152
|
+
|
|
153
|
+
═══ LAYER 3: VELOCITY & PRICE ACTION ═══
|
|
154
|
+
- Negative velocity without big jump → SKIP
|
|
155
|
+
- IMMEDIATE_MOVER/FIRST_JUMP: vel > 0 sufficient
|
|
156
|
+
- DEEP_CLIMBER: vel ≥ 0.03% (0.0003 decimal)
|
|
157
|
+
- Erratic rank history (zigzag) → SKIP unless CONTRIB_EXPLOSION
|
|
158
|
+
|
|
159
|
+
═══ LAYER 4: LEVERAGE & ASSET CHECKS ═══
|
|
160
|
+
- Max leverage for asset must be ≥ 7x — skip if capped at 3-5x
|
|
161
|
+
- XYZ equities: ignore trader count, require score ≥ 10,
|
|
162
|
+
use leverageType "ISOLATED" and dex "xyz"
|
|
163
|
+
- ≥ 10 SM traders required (crypto only, waived for XYZ)
|
|
164
|
+
|
|
165
|
+
═══ LAYER 5: MARKET REGIME ═══
|
|
166
|
+
- BEARISH (bear ≥ 60, conf ≥ 50): SHORT only
|
|
167
|
+
- BULLISH (bull ≥ 60, conf ≥ 50): LONG only
|
|
168
|
+
- NEUTRAL or stale (> 1h): both directions if score ≥ 8
|
|
169
|
+
|
|
170
|
+
═══ ROTATION (slots full + explosive FIRST_JUMP) ═══
|
|
171
|
+
- Weakest position has negative ROE → CUT and ENTER new
|
|
172
|
+
- Weakest has positive ROE or SM conviction 3+ → HOLD
|
|
173
|
+
- Never rotate positions younger than 10 minutes
|
|
174
|
+
|
|
175
|
+
═══ ANTI-PATTERNS (hard blocks) ═══
|
|
176
|
+
- Rank #1-10 for 2+ scans → move is over
|
|
177
|
+
- 4+ reasons at rank #5 → already peaked
|
|
178
|
+
- Counter to BTC hourly trend → hard block
|
|
179
|
+
- Burned/blacklisted asset → SKIP
|
|
180
|
+
|
|
181
|
+
Respond:
|
|
182
|
+
{
|
|
183
|
+
"execute": true/false,
|
|
184
|
+
"actionType": "OPEN_POSITION",
|
|
185
|
+
"confidence": 1-10,
|
|
186
|
+
"reasoning": "one sentence",
|
|
187
|
+
"payload": {
|
|
188
|
+
"signals": [
|
|
189
|
+
{
|
|
190
|
+
"asset": "<ticker>",
|
|
191
|
+
"direction": "LONG" or "SHORT",
|
|
192
|
+
"reason": "one sentence",
|
|
193
|
+
"rotate_out": "<asset_to_cut>",
|
|
194
|
+
"leverage": <number, optional — your recommended leverage>,
|
|
195
|
+
"margin": <number, optional — $ margin amount>
|
|
196
|
+
}
|
|
197
|
+
]
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
# ── SM flip: immediate close on conviction reversal ──
|
|
202
|
+
- name: sm_flip_close
|
|
203
|
+
action_type: CLOSE_POSITION
|
|
204
|
+
decision_mode: rule
|
|
205
|
+
scanners: [sm_flip]
|
|
206
|
+
min_confidence: 1
|
|
207
|
+
params:
|
|
208
|
+
order_type: FEE_OPTIMIZED_LIMIT
|
|
209
|
+
fee_optimized_limit_options:
|
|
210
|
+
ensure_execution_as_taker: true
|
|
211
|
+
execution_timeout_seconds: 10
|
|
212
|
+
|
|
213
|
+
# ── Watchdog: emergency close on margin danger ──
|
|
214
|
+
- name: watchdog_close
|
|
215
|
+
action_type: CLOSE_POSITION
|
|
216
|
+
decision_mode: rule
|
|
217
|
+
scanners: [watchdog]
|
|
218
|
+
min_confidence: 1
|
|
219
|
+
params:
|
|
220
|
+
order_type: MARKET
|
|
221
|
+
|
|
222
|
+
# ── DSL — trailing exit
|
|
223
|
+
exit:
|
|
224
|
+
engine: dsl
|
|
225
|
+
interval_seconds: 30
|
|
226
|
+
order_type: FEE_OPTIMIZED_LIMIT
|
|
227
|
+
fee_optimized_limit_options:
|
|
228
|
+
ensure_execution_as_taker: true
|
|
229
|
+
execution_timeout_seconds: 15
|
|
230
|
+
dsl_preset:
|
|
231
|
+
phase1:
|
|
232
|
+
enabled: true
|
|
233
|
+
max_loss_pct: 2.0
|
|
234
|
+
retrace_threshold: 7
|
|
235
|
+
consecutive_breaches_required: 3
|
|
236
|
+
phase2:
|
|
237
|
+
enabled: true
|
|
238
|
+
tiers:
|
|
239
|
+
- { trigger_pct: 7, lock_hw_pct: 40 }
|
|
240
|
+
- { trigger_pct: 12, lock_hw_pct: 55 }
|
|
241
|
+
- { trigger_pct: 15, lock_hw_pct: 75 }
|
|
242
|
+
- { trigger_pct: 20, lock_hw_pct: 85 }
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: minimal
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
description: Watch-only strategy — logs signals, opens no positions.
|
|
4
|
+
|
|
5
|
+
strategy:
|
|
6
|
+
wallet: "${WALLET_ADDRESS}"
|
|
7
|
+
slots: 1
|
|
8
|
+
trading_risk: conservative
|
|
9
|
+
enabled: true
|
|
10
|
+
|
|
11
|
+
scanners:
|
|
12
|
+
- name: emerging_movers
|
|
13
|
+
type: emerging_movers
|
|
14
|
+
interval: 60s
|
|
15
|
+
config:
|
|
16
|
+
topN: 20
|
|
17
|
+
minRankJump: 5
|
|
18
|
+
minScansBeforeSignals: 2
|
|
19
|
+
|
|
20
|
+
actions:
|
|
21
|
+
- name: log_signals
|
|
22
|
+
action_type: OPEN_POSITION
|
|
23
|
+
decision_mode: no_decision
|
|
24
|
+
scanners: [emerging_movers]
|
|
25
|
+
min_confidence: 0
|
|
26
|
+
|
|
27
|
+
exit:
|
|
28
|
+
engine: dsl
|
|
29
|
+
interval_seconds: 60
|
|
30
|
+
order_type: FEE_OPTIMIZED_LIMIT
|
|
31
|
+
fee_optimized_limit_options:
|
|
32
|
+
ensure_execution_as_taker: true
|
|
33
|
+
execution_timeout_seconds: 30
|
|
34
|
+
dsl_preset:
|
|
35
|
+
phase1:
|
|
36
|
+
enabled: true
|
|
37
|
+
max_loss_pct: 5.0
|
|
38
|
+
retrace_threshold: 7
|
|
39
|
+
consecutive_breaches_required: 1
|
|
40
|
+
phase2:
|
|
41
|
+
enabled: true
|
|
42
|
+
tiers:
|
|
43
|
+
- { trigger_pct: 7, lock_hw_pct: 40 }
|
|
44
|
+
- { trigger_pct: 12, lock_hw_pct: 55 }
|
|
45
|
+
- { trigger_pct: 15, lock_hw_pct: 75 }
|
|
46
|
+
- { trigger_pct: 20, lock_hw_pct: 85 }
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# `momentum-guarded` — How it works
|
|
2
|
+
|
|
3
|
+
Companion notes for [`examples/strategies/momentum-guarded.yaml`](../momentum-guarded.yaml).
|
|
4
|
+
|
|
5
|
+
## The trading thesis
|
|
6
|
+
|
|
7
|
+
Catch **short-horizon directional breakouts** on liquid Hyperliquid perps the moment a 1h candle prints an outsized move vs. the prior close — but only when the move passes both an LLM sanity check and a real-time risk gauntlet, and only with a trailing-exit playbook strict enough to survive momentum reversals.
|
|
8
|
+
|
|
9
|
+
## Signal flow (entry side)
|
|
10
|
+
|
|
11
|
+
1. **External producer** ([`src/scanners/external/momentum/producer.mjs`](../../../src/scanners/external/momentum/producer.mjs)) runs out-of-process — pulls instruments + 1h candles from Senpi MCP, computes last-vs-prev close % move, and ingests `MOMENTUM_BREAKOUT` signals via `senpi.ingestExternalScannerData`. Re-run on a cron / `watch`.
|
|
12
|
+
2. The runtime's `external_momentum` scanner of type `external_scanner` accepts the push, validates the payload schema (`sourceMeta`, `sourceFactors`, …), and emits a `scanner:run:complete` event carrying the signals.
|
|
13
|
+
3. `momentum_entry` (an `OPEN_POSITION` action with `decision_mode: llm`) consumes the signals, runs each through a 6-step gauntlet (move magnitude ≥1.5%, direction matches sign, day notional ≥1M, max leverage ≥5, producer score ≥0.4, pick highest-score), and returns at most one trade. `min_confidence: 7` blocks lukewarm LLM verdicts.
|
|
14
|
+
4. **Risk gates** fire before the position opens. With `slots: 3` and `margin_per_slot: 300` (~$900 deployed of a $5k budget), the gauntlet of guardrails is:
|
|
15
|
+
- `daily_loss_limit_pct: 4` — closes the gate if today's PnL drops 4% of day-open account value.
|
|
16
|
+
- `drawdown_halt_pct: 20` — closes the gate at 20% PnL drawdown from peak (peak carries ~24h, not reset at midnight).
|
|
17
|
+
- `max_entries_per_day: 6` — caps churn on noisy breakout days.
|
|
18
|
+
- `bypass_max_entries_per_day_on_profit` (here `false`) — when `true`, at that daily cap the max-entries gate stays OPEN if intraday `today_snapshot.pnl.delta_since_open > 0` (reuses the same PnL snapshot as daily loss in this recipe).
|
|
19
|
+
- `max_consecutive_losses: 3` + `cooldown_minutes: 90` — three losers in a row pauses entries for 90 min so the strategy doesn't tilt.
|
|
20
|
+
- `per_asset_cooldown_minutes: 45` — no re-entry on the same ticker for 45 min after a close (avoids whipsaw fills).
|
|
21
|
+
|
|
22
|
+
Order matters: **CLOSED beats COOLDOWN beats OPEN**; the first non-OPEN gate short-circuits.
|
|
23
|
+
5. If everything passes, `FEE_OPTIMIZED_LIMIT` posts the order with a 15s execution timeout (taker fallback guaranteed).
|
|
24
|
+
|
|
25
|
+
## Position management (exit side)
|
|
26
|
+
|
|
27
|
+
Once filled, the **DSL exit engine** owns the position (`position_tracker` keeps it in sync even for manually-opened positions on the same wallet):
|
|
28
|
+
|
|
29
|
+
- **Phase 1** — fixed stop at `-2.5%` plus a `7%` retrace floor; needs `3` consecutive breaches before firing (debounce against single-tick spikes).
|
|
30
|
+
- **Phase 2** — once price advances, trailing floors lock in profit on a four-tier ladder:
|
|
31
|
+
- +6% → lock 35% of high-water
|
|
32
|
+
- +10% → lock 55%
|
|
33
|
+
- +15% → lock 70%
|
|
34
|
+
- +20% → lock 85%
|
|
35
|
+
- **Time-based cuts** — momentum that fails to develop is the silent killer:
|
|
36
|
+
- `dead_weight_cut` after 30 min flat → close.
|
|
37
|
+
- `weak_peak_cut` after 45 min if peak < +2% → close.
|
|
38
|
+
- `hard_timeout` at 2 hours → close regardless.
|
|
39
|
+
|
|
40
|
+
## What this looks like in practice
|
|
41
|
+
|
|
42
|
+
- A trader runs the producer every minute via cron.
|
|
43
|
+
- 90% of producer ticks emit zero signals; the runtime stays idle.
|
|
44
|
+
- When BTC prints a +2% 1h candle on healthy volume, the LLM accepts, the risk gauntlet checks daily PnL/drawdown/entries/cooldowns, and one slot fires a long.
|
|
45
|
+
- DSL trails the move. If BTC stalls, time-cuts close it within ~30–45 min instead of bleeding margin. If BTC runs to +12%, the +10% tier locks in 55% of the high-water, so a retrace to +5% still books profit.
|
|
46
|
+
- A bad day (3 stop-outs) trips the consecutive-loss cooldown — the runtime stops trying for 90 min and resumes fresh.
|
|
47
|
+
|
|
48
|
+
Net effect: **a small, slot-bounded, risk-gated breakout sniper** with strict trailing protection — appropriate for a $5k moderate-risk wallet that wants asymmetric upside without unsupervised drawdown.
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
name: momentum-guarded
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
description: >
|
|
4
|
+
Risk-managed external momentum strategy. An out-of-process producer
|
|
5
|
+
(src/scanners/external/momentum/producer.mjs) pushes MOMENTUM_BREAKOUT
|
|
6
|
+
signals into the runtime; an LLM gauntlet decides which breakouts deserve
|
|
7
|
+
capital; the risk component gates every entry against daily loss, drawdown,
|
|
8
|
+
per-day entry count, consecutive-loss cooldown, and per-asset cooldown;
|
|
9
|
+
the DSL exit engine manages trailing exits on accepted fills.
|
|
10
|
+
|
|
11
|
+
notifications:
|
|
12
|
+
telegram_chat_id: "${TELEGRAM_CHAT_ID}"
|
|
13
|
+
|
|
14
|
+
strategy:
|
|
15
|
+
wallet: "${WALLET_ADDRESS}"
|
|
16
|
+
slots: 3
|
|
17
|
+
margin_per_slot: 300
|
|
18
|
+
trading_risk: moderate
|
|
19
|
+
enabled: true
|
|
20
|
+
|
|
21
|
+
# ── RISK ──
|
|
22
|
+
# Real-time gates enforced on every OPEN_POSITION attempt. Any non-OPEN gate
|
|
23
|
+
# short-circuits and skips the entry. See docs/risk-component.md.
|
|
24
|
+
risk:
|
|
25
|
+
data_retention_hours: 72
|
|
26
|
+
|
|
27
|
+
guard_rails:
|
|
28
|
+
# Daily loss halt — stop trading if daily PnL drops > 4% of day-open account value.
|
|
29
|
+
daily_loss_limit_pct: 4
|
|
30
|
+
|
|
31
|
+
# Cap entries per UTC day so a noisy producer day can't churn the wallet.
|
|
32
|
+
max_entries_per_day: 6
|
|
33
|
+
# At cap: if true, gate stays OPEN when today_snapshot.pnl.delta_since_open > 0 (see docs/risk-component.md).
|
|
34
|
+
bypass_max_entries_per_day_on_profit: false
|
|
35
|
+
|
|
36
|
+
# Consecutive-loss cooldown — three losers in a row pauses entries for 90 min.
|
|
37
|
+
max_consecutive_losses: 3
|
|
38
|
+
cooldown_minutes: 90
|
|
39
|
+
|
|
40
|
+
# Drawdown halt — 20% PnL drawdown from peak halts entries; peak carries ~24h.
|
|
41
|
+
drawdown_halt_pct: 20
|
|
42
|
+
drawdown_reset_on_day_rollover: false
|
|
43
|
+
|
|
44
|
+
# Per-asset cooldown — no re-entry on the same asset for 45 min after a close.
|
|
45
|
+
per_asset_cooldown_minutes: 45
|
|
46
|
+
|
|
47
|
+
# ── SCANNERS ──
|
|
48
|
+
scanners:
|
|
49
|
+
# Onchain position tracker — emits position lifecycle events into the DSL exit engine.
|
|
50
|
+
- name: position_tracker
|
|
51
|
+
type: position_tracker
|
|
52
|
+
interval: 10s
|
|
53
|
+
|
|
54
|
+
# External producer feed — schema for inbound MOMENTUM_BREAKOUT signals
|
|
55
|
+
# delivered via senpi.ingestExternalScannerData.
|
|
56
|
+
- name: external_momentum
|
|
57
|
+
type: external_scanner
|
|
58
|
+
outputs:
|
|
59
|
+
signals: true
|
|
60
|
+
context: false
|
|
61
|
+
config:
|
|
62
|
+
fields:
|
|
63
|
+
sourceScannerId: { type: string, required: true }
|
|
64
|
+
sourceSignalType: { type: string, required: true }
|
|
65
|
+
sourceTimestamp: { type: number, required: true }
|
|
66
|
+
sourceFactors: { type: object, required: true }
|
|
67
|
+
sourceMeta: { type: object, required: true }
|
|
68
|
+
|
|
69
|
+
# ── ACTIONS ──
|
|
70
|
+
actions:
|
|
71
|
+
# Position lifecycle tracking — feeds the DSL exit engine.
|
|
72
|
+
- name: position_tracker_action
|
|
73
|
+
action_type: POSITION_TRACKER
|
|
74
|
+
decision_mode: rule
|
|
75
|
+
scanners: [position_tracker]
|
|
76
|
+
|
|
77
|
+
# Entry: LLM gauntlet on momentum breakout signals.
|
|
78
|
+
- name: momentum_entry
|
|
79
|
+
action_type: OPEN_POSITION
|
|
80
|
+
decision_mode: llm
|
|
81
|
+
decision_model: claude-sonnet-4-20250514
|
|
82
|
+
scanners: [external_momentum]
|
|
83
|
+
min_confidence: 7
|
|
84
|
+
params:
|
|
85
|
+
order_type: FEE_OPTIMIZED_LIMIT
|
|
86
|
+
fee_optimized_limit_options:
|
|
87
|
+
ensure_execution_as_taker: true
|
|
88
|
+
execution_timeout_seconds: 15
|
|
89
|
+
context:
|
|
90
|
+
- type: signal
|
|
91
|
+
scanner: external_momentum
|
|
92
|
+
decision_prompt: |
|
|
93
|
+
You are a trade-decisioning evaluator. Given a MOMENTUM_BREAKOUT
|
|
94
|
+
signal pushed by the external momentum producer, decide whether to
|
|
95
|
+
open a position on it or skip.
|
|
96
|
+
|
|
97
|
+
A MOMENTUM_BREAKOUT fires when an asset's latest closed candle moves
|
|
98
|
+
by at least the producer's threshold vs. the previous close on the
|
|
99
|
+
signal's timeframe — i.e. a short-term directional breakout in price.
|
|
100
|
+
`meta.movePct` carries the signed % change (positive = LONG bias,
|
|
101
|
+
negative = SHORT bias); `score` (0..1) scales with the move's
|
|
102
|
+
magnitude; `meta.dayNtlVlm` and `meta.maxLeverage` describe the
|
|
103
|
+
instrument's liquidity and leverage headroom.
|
|
104
|
+
|
|
105
|
+
SIGNAL DATA:
|
|
106
|
+
{{signal_external_momentum}}
|
|
107
|
+
|
|
108
|
+
═══ GAUNTLET ═══
|
|
109
|
+
1. movePct magnitude — require |movePct| >= 1.5; reject sub-threshold noise.
|
|
110
|
+
2. Direction sanity — LONG only if movePct > 0, SHORT only if movePct < 0.
|
|
111
|
+
3. Liquidity — meta.dayNtlVlm must be >= 1_000_000.
|
|
112
|
+
4. Leverage — meta.maxLeverage must be >= 5; skip otherwise.
|
|
113
|
+
5. Score — use the producer score (0..1) as a proxy for strength; require >= 0.4.
|
|
114
|
+
6. One signal at a time — pick the highest-score eligible signal; skip the rest.
|
|
115
|
+
|
|
116
|
+
Respond with a single JSON object:
|
|
117
|
+
{
|
|
118
|
+
"execute": true|false,
|
|
119
|
+
"actionType": "OPEN_POSITION",
|
|
120
|
+
"confidence": 1-10,
|
|
121
|
+
"reasoning": "one sentence",
|
|
122
|
+
"payload": {
|
|
123
|
+
"signals": [
|
|
124
|
+
{ "asset": "<ticker>", "direction": "LONG"|"SHORT", "reason": "one sentence" }
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
# ── EXIT (DSL) ──
|
|
130
|
+
# Trailing stop-loss tuned for short-horizon momentum entries.
|
|
131
|
+
# Time-based cuts catch stalled trades that never deliver follow-through.
|
|
132
|
+
exit:
|
|
133
|
+
engine: dsl
|
|
134
|
+
interval_seconds: 30
|
|
135
|
+
order_type: FEE_OPTIMIZED_LIMIT
|
|
136
|
+
fee_optimized_limit_options:
|
|
137
|
+
ensure_execution_as_taker: true
|
|
138
|
+
execution_timeout_seconds: 15
|
|
139
|
+
dsl_preset:
|
|
140
|
+
hard_timeout:
|
|
141
|
+
enabled: true
|
|
142
|
+
interval_in_minutes: 120
|
|
143
|
+
weak_peak_cut:
|
|
144
|
+
enabled: true
|
|
145
|
+
interval_in_minutes: 45
|
|
146
|
+
min_value: 2
|
|
147
|
+
dead_weight_cut:
|
|
148
|
+
enabled: true
|
|
149
|
+
interval_in_minutes: 30
|
|
150
|
+
phase1:
|
|
151
|
+
enabled: true
|
|
152
|
+
max_loss_pct: 2.5
|
|
153
|
+
retrace_threshold: 7
|
|
154
|
+
consecutive_breaches_required: 3
|
|
155
|
+
phase2:
|
|
156
|
+
enabled: true
|
|
157
|
+
tiers:
|
|
158
|
+
- { trigger_pct: 6, lock_hw_pct: 35 }
|
|
159
|
+
- { trigger_pct: 10, lock_hw_pct: 55 }
|
|
160
|
+
- { trigger_pct: 15, lock_hw_pct: 70 }
|
|
161
|
+
- { trigger_pct: 20, lock_hw_pct: 85 }
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Risk showcase — every risk guardrail field annotated for reference.
|
|
2
|
+
# Use as a copy-paste reference when configuring risk management.
|
|
3
|
+
name: risk-showcase
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
description: >
|
|
6
|
+
Annotated risk guardrails config reference.
|
|
7
|
+
Uses position_tracker scanner with DSL exit engine.
|
|
8
|
+
Lists explicit example values for each field (not implicit runtime defaults).
|
|
9
|
+
|
|
10
|
+
notifications:
|
|
11
|
+
telegram_chat_id: "${TELEGRAM_CHAT_ID}"
|
|
12
|
+
|
|
13
|
+
strategy:
|
|
14
|
+
wallet: "${WALLET_ADDRESS}"
|
|
15
|
+
budget: 10000
|
|
16
|
+
slots: 3
|
|
17
|
+
margin_per_slot: 250
|
|
18
|
+
trading_risk: moderate
|
|
19
|
+
enabled: true
|
|
20
|
+
|
|
21
|
+
# ── RISK ──
|
|
22
|
+
# Optional. Without this block, all gates are OPEN (no risk management).
|
|
23
|
+
risk:
|
|
24
|
+
# How long to keep audit log files (JSONL + daily snapshots), in hours.
|
|
25
|
+
# Range: 1–168 (1 hour to 7 days). Default: 48.
|
|
26
|
+
data_retention_hours: 48
|
|
27
|
+
|
|
28
|
+
guard_rails:
|
|
29
|
+
# ── Daily Loss Halt ──
|
|
30
|
+
# Gate CLOSED when daily trading PnL drop exceeds this % of account value at day open.
|
|
31
|
+
# Uses Hyperliquid portfolio PnL (realized + unrealized + funding, excludes deposits/withdrawals).
|
|
32
|
+
# Resets at UTC midnight.
|
|
33
|
+
daily_loss_limit_pct: 5 # 5% of account value at day open
|
|
34
|
+
|
|
35
|
+
# ── Max Entries Per Day ──
|
|
36
|
+
# Gate CLOSED when position entries today >= max_entries_per_day.
|
|
37
|
+
# Counts open positions opened today (startTime) + closed trades opened today (openTime).
|
|
38
|
+
# Resets at UTC midnight.
|
|
39
|
+
max_entries_per_day: 8
|
|
40
|
+
# When true, at the entry cap gate 5 stays OPEN if today_snapshot.pnl.delta_since_open > 0
|
|
41
|
+
# (intraday PnL delta vs UTC day open; same MCP snapshot as daily loss when gates 1–2 run).
|
|
42
|
+
# Default: false.
|
|
43
|
+
bypass_max_entries_per_day_on_profit: false
|
|
44
|
+
|
|
45
|
+
# ── Consecutive Loss Cooldown ──
|
|
46
|
+
# Gate COOLDOWN when the last N closed trades all have negative realizedPnl.
|
|
47
|
+
# Stateless: derived from trade history API on every tick, no persisted streak.
|
|
48
|
+
# Streak carries across days. Cooldown window starts from the most recent
|
|
49
|
+
# loss's close time and expires cooldown_minutes later.
|
|
50
|
+
max_consecutive_losses: 3
|
|
51
|
+
cooldown_minutes: 60
|
|
52
|
+
|
|
53
|
+
# ── Drawdown Halt ──
|
|
54
|
+
# Gate CLOSED when PnL drawdown from peak >= drawdown_halt_pct %.
|
|
55
|
+
# PnL-based: immune to deposits and withdrawals.
|
|
56
|
+
# Drawdown = (peak_pnl - current_pnl) / account_value_at_day_open * 100.
|
|
57
|
+
drawdown_halt_pct: 30 # 30% PnL drawdown from peak triggers halt
|
|
58
|
+
# When true, PnL peak resets at UTC midnight (intraday drawdown only).
|
|
59
|
+
# When false (default), PnL peak carries from prior ~24h (perpDay window).
|
|
60
|
+
drawdown_reset_on_day_rollover: false
|
|
61
|
+
|
|
62
|
+
# ── Per-Asset Cooldown ──
|
|
63
|
+
# Gate COOLDOWN for a specific asset when it was closed within the last N minutes.
|
|
64
|
+
# Checked on each entry attempt. Only evaluated when all other gates are OPEN.
|
|
65
|
+
# Minimum: 5 minutes (backend latency floor).
|
|
66
|
+
per_asset_cooldown_minutes: 30 # 30 min cooldown after closing any asset
|
|
67
|
+
|
|
68
|
+
# ── SCANNERS ──
|
|
69
|
+
scanners:
|
|
70
|
+
- name: position_tracker
|
|
71
|
+
type: position_tracker
|
|
72
|
+
interval: 10s
|
|
73
|
+
|
|
74
|
+
# ── ACTIONS ──
|
|
75
|
+
actions:
|
|
76
|
+
- name: position_tracker_action
|
|
77
|
+
action_type: POSITION_TRACKER
|
|
78
|
+
decision_mode: rule
|
|
79
|
+
scanners: [position_tracker]
|
|
80
|
+
|
|
81
|
+
# ── EXIT ──
|
|
82
|
+
exit:
|
|
83
|
+
engine: dsl
|
|
84
|
+
interval_seconds: 30
|
|
85
|
+
dsl_preset:
|
|
86
|
+
phase1:
|
|
87
|
+
max_loss_pct: 5.0
|
|
88
|
+
retrace_threshold: 10
|
|
89
|
+
consecutive_breaches_required: 2
|
|
90
|
+
phase2:
|
|
91
|
+
tiers:
|
|
92
|
+
- { trigger_pct: 10, lock_hw_pct: 50 }
|
|
93
|
+
- { trigger_pct: 20, lock_hw_pct: 70 }
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
name: viper
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
description: Moderate — candle-based breakouts via prescreener + momentum.
|
|
4
|
+
|
|
5
|
+
strategy:
|
|
6
|
+
wallet: "${WALLET_ADDRESS}"
|
|
7
|
+
slots: 4
|
|
8
|
+
margin_pct: 10
|
|
9
|
+
trading_risk: moderate
|
|
10
|
+
enabled: true
|
|
11
|
+
|
|
12
|
+
scanners:
|
|
13
|
+
- name: prescreener
|
|
14
|
+
type: prescreener
|
|
15
|
+
interval: 5m
|
|
16
|
+
config:
|
|
17
|
+
topN: 30
|
|
18
|
+
minDayVolume: 1000000
|
|
19
|
+
minLeverage: 2
|
|
20
|
+
minOpenInterest: 0
|
|
21
|
+
- name: momentum
|
|
22
|
+
type: momentum
|
|
23
|
+
interval: 1m
|
|
24
|
+
config:
|
|
25
|
+
timeframe: "1h"
|
|
26
|
+
minMovePct: 1.5
|
|
27
|
+
maxCandidates: 20
|
|
28
|
+
minDayVolume: 1000000
|
|
29
|
+
minSignalScore: 0.2
|
|
30
|
+
requirePrescreened: true
|
|
31
|
+
|
|
32
|
+
actions:
|
|
33
|
+
- name: open_breakout
|
|
34
|
+
action_type: OPEN_POSITION
|
|
35
|
+
decision_mode: llm
|
|
36
|
+
decision_model: claude-sonnet-4-20250514
|
|
37
|
+
scanners: [momentum]
|
|
38
|
+
min_confidence: 6
|
|
39
|
+
params:
|
|
40
|
+
order_type: FEE_OPTIMIZED_LIMIT
|
|
41
|
+
fee_optimized_limit_options:
|
|
42
|
+
ensure_execution_as_taker: true
|
|
43
|
+
execution_timeout_seconds: 15
|
|
44
|
+
context: [signal]
|
|
45
|
+
decision_prompt: |
|
|
46
|
+
Evaluate the momentum breakout signal. Reply with JSON: {"execute": true|false, "actionType": "OPEN_POSITION", "confidence": 1-10, "reasoning": "...", "payload": {"signals": [{"asset": "SYMBOL", "direction": "LONG"|"SHORT", "reason": "...", "leverage": <optional number>, "margin": <optional $ amount>}]}}.
|
|
47
|
+
|
|
48
|
+
exit:
|
|
49
|
+
engine: dsl
|
|
50
|
+
interval_seconds: 30
|
|
51
|
+
order_type: FEE_OPTIMIZED_LIMIT
|
|
52
|
+
fee_optimized_limit_options:
|
|
53
|
+
ensure_execution_as_taker: true
|
|
54
|
+
execution_timeout_seconds: 15
|
|
55
|
+
dsl_preset:
|
|
56
|
+
phase1:
|
|
57
|
+
enabled: true
|
|
58
|
+
max_loss_pct: 4.0
|
|
59
|
+
retrace_threshold: 10
|
|
60
|
+
consecutive_breaches_required: 3
|
|
61
|
+
phase2:
|
|
62
|
+
enabled: true
|
|
63
|
+
tiers:
|
|
64
|
+
- { trigger_pct: 10, lock_hw_pct: 50 }
|
|
65
|
+
- { trigger_pct: 20, lock_hw_pct: 60 }
|
|
66
|
+
- { trigger_pct: 35, lock_hw_pct: 63 }
|
|
67
|
+
- { trigger_pct: 50, lock_hw_pct: 70 }
|