dsl-dynamic-stop-loss
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDynamic Stop Loss (DSL) v4
动态止损(DSL)v4
Automated trailing stop loss for leveraged perp positions on Hyperliquid. Monitors price via cron, ratchets profit floors upward through configurable tiers, and auto-closes positions on breach — no agent intervention required for the critical path.
面向Hyperliquid上杠杆永续合约仓位的自动追踪止损工具。通过cron监控价格,通过可配置的层级逐步上调利润下限,触发止损线时自动平仓——核心路径无需Agent介入。
Self-Contained Design
独立设计
Script handles: Agent handles:
✅ Price monitoring 📢 Telegram alerts
✅ High water tracking 🧹 Cron cleanup (disable after close)
✅ Tier upgrades 📊 Portfolio reporting
✅ Breach detection 🔄 Retry awareness (pendingClose alerts)
✅ Position closing (via mcporter, with retry)
✅ State deactivation
✅ Error handling (fetch failures)The script closes positions directly via . If the agent is slow, busy, or restarting, the position still gets closed on the next cron tick.
mcporterScript handles: Agent handles:
✅ Price monitoring 📢 Telegram alerts
✅ High water tracking 🧹 Cron cleanup (disable after close)
✅ Tier upgrades 📊 Portfolio reporting
✅ Breach detection 🔄 Retry awareness (pendingClose alerts)
✅ Position closing (via mcporter, with retry)
✅ State deactivation
✅ Error handling (fetch failures)脚本直接通过平仓。如果Agent响应慢、繁忙或重启,仓位仍会在下一个cron执行周期完成平仓。
mcporterHow It Works
工作原理
Phase 1: "Let It Breathe" (uPnL < first tier)
阶段1:“预留波动空间”(uPnL < 第一层级阈值)
- Wide retrace: 3% from high water mark
- Patient: requires 3 consecutive breach checks below floor
- Absolute floor: hard price floor to cap max loss
- Goal: Don't get shaken out before the trade develops
- 宽幅回撤容忍: 距离最高水位价3%
- 延迟判定: 需要连续3次检测到价格低于止损线才会触发平仓
- 绝对止损线: 硬价格下限,限制最大亏损
- 目标: 交易走势成型前避免被小幅震荡洗出
Phase 2: "Lock the Bag" (uPnL ≥ first tier)
阶段2:“锁定收益”(uPnL ≥ 第一层级阈值)
- Tight retrace: 1.5% from high water mark (or per-tier retrace)
- Quick exit: 1–2 consecutive breaches to close
- Tier floors: ratchet up as profit grows — never go back down
- Effective floor: best of tier floor and trailing floor
- 窄幅回撤容忍: 距离最高水位价1.5%(或各层级自定义回撤阈值)
- 快速平仓: 连续1-2次触发止损即平仓
- 层级止损线: 随利润增长逐步上调——永不下调
- 有效止损线: 取层级止损线和追踪止损线的最优值
ROE-Based Tier Ratcheting
基于ROE的层级递进机制
All tier triggers use ROE (Return on Equity): . This means a fires at 10% return on margin, not 10% price move. Leverage is accounted for automatically.
PnL / margin × 100triggerPct: 10Tiers are defined as pairs. Each tier can optionally specify its own value to tighten stops as profit grows:
{triggerPct, lockPct}retracejson
"tiers": [
{"triggerPct": 10, "lockPct": 5},
{"triggerPct": 20, "lockPct": 14},
{"triggerPct": 30, "lockPct": 22, "retrace": 0.012},
{"triggerPct": 50, "lockPct": 40, "retrace": 0.010},
{"triggerPct": 75, "lockPct": 60, "retrace": 0.008},
{"triggerPct": 100, "lockPct": 80, "retrace": 0.006}
]The gap between trigger and lock (e.g., 10% trigger → 5% lock) gives breathing room so a minor pullback after hitting a tier doesn't immediately close. Ratchets never go down — once you hit Tier 2, Tier 1's floor is permanently superseded.
See references/tier-examples.md for LONG and SHORT worked examples with exact price calculations.
所有层级触发条件都使用ROE(净资产收益率)计算:。这意味着会在保证金回报率达到10%时触发,而非价格波动10%,杠杆倍数会被自动纳入计算。
PnL / margin × 100triggerPct: 10层级通过键值对定义。每个层级可选择性指定专属的值,随利润增长收紧止损阈值:
{triggerPct, lockPct}retracejson
"tiers": [
{"triggerPct": 10, "lockPct": 5},
{"triggerPct": 20, "lockPct": 14},
{"triggerPct": 30, "lockPct": 22, "retrace": 0.012},
{"triggerPct": 50, "lockPct": 40, "retrace": 0.010},
{"triggerPct": 75, "lockPct": 60, "retrace": 0.008},
{"triggerPct": 100, "lockPct": 80, "retrace": 0.006}
]触发阈值和锁定阈值的差值(例如10%触发→5%锁定)预留了波动空间,避免触达层级后的小幅回调立即触发平仓。层级永不回退——一旦达到第2层级,第1层级的止损线将永久失效。
查看 references/tier-examples.md 可获取LONG和SHORT仓位的完整示例,包含精确的价格计算逻辑。
Direction Matters
方向敏感逻辑
⚠️ CRITICAL — Getting direction backwards causes immediate false breaches or no protection at all. The script handles this automatically via thefield, but double-check when initializing state files manually.direction
| LONG | SHORT | |
|---|---|---|
| Tier floor | | |
| Absolute floor | Below entry (e.g., entry × 0.97) | Above entry (e.g., entry × 1.03) |
| High water | Highest price seen | Lowest price seen |
| Trailing floor | | |
| Breach | | |
| uPnL | | |
⚠️ 重要提示——方向设置错误会导致立即误触发平仓或完全失去保护。脚本会通过字段自动处理方向逻辑,但手动初始化状态文件时请务必双重校验。direction
| LONG | SHORT | |
|---|---|---|
| 层级止损线 | | |
| 绝对止损线 | 低于入场价(例如入场价 × 0.97) | 高于入场价(例如入场价 × 1.03) |
| 最高水位价 | 观测到的最高价格 | 观测到的最低价格 |
| 追踪止损线 | | |
| 触发止损 | | |
| 未实现盈利 | | |
Breach Decay
止损触发计数衰减机制
When price recovers above the floor:
- (default): breach count resets to 0
"hard" - : breach count decays by 1 per check
"soft"
Soft mode is useful for volatile assets where price rapidly oscillates around the floor.
当价格回升到止损线以上时:
- (默认模式): 触发计数重置为0
"hard" - : 每次检测触发计数减1
"soft"
软模式适合价格在止损线附近快速震荡的高波动资产。
Floor Resolution
止损线判定逻辑
At each check, the effective floor is the best of:
- Tier floor — locked profit level (Phase 2 only)
- Trailing floor — from high water mark and retrace %
- Absolute floor — hard minimum (Phase 1 only)
For LONGs, "best" = maximum. For SHORTs, "best" = minimum.
每次检测时,有效止损线取以下三者的最优值:
- 层级止损线 —— 锁定的利润水平(仅阶段2生效)
- 追踪止损线 —— 基于最高水位价和回撤比例计算
- 绝对止损线 —— 硬下限(仅阶段1生效)
对于LONG仓位,“最优值”=最大值。对于SHORT仓位,“最优值”=最小值。
Architecture
架构
┌──────────────────────────────────────────┐
│ Cron: every 3-5 min (per position) │
├──────────────────────────────────────────┤
│ scripts/dsl-v4.py │
│ • Reads state from JSON file │
│ • Fetches price from allMids API │
│ • Direction-aware (LONG + SHORT) │
│ • Updates high water mark │
│ • Checks tier upgrades (ROE-based) │
│ • Per-tier retrace override │
│ • Calculates effective floor │
│ • Detects breaches (with decay modes) │
│ • ON BREACH: closes via mcporter w/retry │
│ • pendingClose if close fails │
│ • Outputs enriched JSON status │
├──────────────────────────────────────────┤
│ Agent reads JSON output: │
│ • closed=true → alert user, disable cron │
│ • pending_close=true → alert, will retry │
│ • tier_changed=true → notify user │
│ • status=error → log, check failures │
│ • Otherwise → silent │
└──────────────────────────────────────────┘┌──────────────────────────────────────────┐
│ Cron: every 3-5 min (per position) │
├──────────────────────────────────────────┤
│ scripts/dsl-v4.py │
│ • Reads state from JSON file │
│ • Fetches price from allMids API │
│ • Direction-aware (LONG + SHORT) │
│ • Updates high water mark │
│ • Checks tier upgrades (ROE-based) │
│ • Per-tier retrace override │
│ • Calculates effective floor │
│ • Detects breaches (with decay modes) │
│ • ON BREACH: closes via mcporter w/retry │
│ • pendingClose if close fails │
│ • Outputs enriched JSON status │
├──────────────────────────────────────────┤
│ Agent reads JSON output: │
│ • closed=true → alert user, disable cron │
│ • pending_close=true → alert, will retry │
│ • tier_changed=true → notify user │
│ • status=error → log, check failures │
│ • Otherwise → silent │
└──────────────────────────────────────────┘Files
文件说明
| File | Purpose |
|---|---|
| Core DSL engine — monitors, closes, outputs JSON |
| State file (JSON) | Per-position config + runtime state |
Multiple positions: Set to run separate instances per position. Each gets its own state file and cron job.
DSL_STATE_FILE=/path/to/state.json| 文件 | 用途 |
|---|---|
| DSL核心引擎——监控、平仓、输出JSON |
| 状态文件(JSON) | 每个仓位独立的配置+运行时状态 |
多仓位支持:设置即可为每个仓位运行独立实例,每个实例对应独立的状态文件和cron任务。
DSL_STATE_FILE=/path/to/state.jsonState File Schema
状态文件 Schema
See references/state-schema.md for the complete schema with all fields documented.
Minimal required fields to create a new state file:
json
{
"active": true,
"asset": "HYPE",
"direction": "LONG",
"leverage": 10,
"entryPrice": 28.87,
"size": 1890.28,
"wallet": "0xYourStrategyWalletAddress",
"strategyId": "uuid-of-strategy",
"phase": 1,
"phase1": {
"retraceThreshold": 0.03,
"consecutiveBreachesRequired": 3,
"absoluteFloor": 28.00
},
"phase2TriggerTier": 1,
"phase2": {
"retraceThreshold": 0.015,
"consecutiveBreachesRequired": 2
},
"tiers": [
{"triggerPct": 10, "lockPct": 5},
{"triggerPct": 20, "lockPct": 14},
{"triggerPct": 30, "lockPct": 22, "retrace": 0.012},
{"triggerPct": 50, "lockPct": 40, "retrace": 0.010},
{"triggerPct": 75, "lockPct": 60, "retrace": 0.008},
{"triggerPct": 100, "lockPct": 80, "retrace": 0.006}
],
"currentTierIndex": -1,
"tierFloorPrice": null,
"highWaterPrice": 28.87,
"floorPrice": 28.00,
"currentBreachCount": 0,
"createdAt": "2026-02-20T15:22:00.000Z"
}walletclose_position查看 references/state-schema.md 获取完整的字段说明Schema。
创建新状态文件所需的最少必填字段:
json
{
"active": true,
"asset": "HYPE",
"direction": "LONG",
"leverage": 10,
"entryPrice": 28.87,
"size": 1890.28,
"wallet": "0xYourStrategyWalletAddress",
"strategyId": "uuid-of-strategy",
"phase": 1,
"phase1": {
"retraceThreshold": 0.03,
"consecutiveBreachesRequired": 3,
"absoluteFloor": 28.00
},
"phase2TriggerTier": 1,
"phase2": {
"retraceThreshold": 0.015,
"consecutiveBreachesRequired": 2
},
"tiers": [
{"triggerPct": 10, "lockPct": 5},
{"triggerPct": 20, "lockPct": 14},
{"triggerPct": 30, "lockPct": 22, "retrace": 0.012},
{"triggerPct": 50, "lockPct": 40, "retrace": 0.010},
{"triggerPct": 75, "lockPct": 60, "retrace": 0.008},
{"triggerPct": 100, "lockPct": 80, "retrace": 0.006}
],
"currentTierIndex": -1,
"tierFloorPrice": null,
"highWaterPrice": 28.87,
"floorPrice": 28.00,
"currentBreachCount": 0,
"createdAt": "2026-02-20T15:22:00.000Z"
}walletclose_positionAbsolute Floor Calculation
绝对止损线计算
- LONG: — e.g., 10x with 3% →
entry × (1 - maxLoss% / leverage)= $28.7828.87 × (1 - 0.03/10) - SHORT: — e.g., 7x with 3% →
entry × (1 + maxLoss% / leverage)= $1,963.381955 × (1 + 0.03/7)
- LONG仓位:—— 例如10倍杠杆、3%最大亏损 →
入场价 × (1 - 最大亏损% / 杠杆倍数)= $28.7828.87 × (1 - 0.03/10) - SHORT仓位:—— 例如7倍杠杆、3%最大亏损 →
入场价 × (1 + 最大亏损% / 杠杆倍数)= $1,963.381955 × (1 + 0.03/7)
Output JSON
输出JSON
The script prints a single JSON line per run. See references/output-schema.md for the complete schema.
Key fields for agent decision-making:
| Field | Agent action |
|---|---|
| Alert user, disable cron |
| Alert — close failed, retrying next tick |
| Notify user with tier details |
| Log; alert if |
| Alert "⚠️ BREACH X/X" |
| Optionally notify approaching next tier |
脚本每次运行会打印一行JSON。查看 references/output-schema.md 获取完整Schema。
Agent决策所需的关键字段:
| 字段 | Agent执行动作 |
|---|---|
| 通知用户,禁用cron |
| 告警——平仓失败,下一个执行周期重试 |
| 告知用户层级升级详情 |
| 日志记录;如果 |
| 告警 "⚠️ 已触发X/X次止损校验" |
| 可选通知用户即将触达下一层级 |
Cron Setup
Cron 配置
Per-position cron (every 3-5 min):
DSL_STATE_FILE=/data/workspace/dsl-state-BTC.json python3 scripts/dsl-v4.pyStagger multiple positions by offsetting start times (:00, :01, :02).
每个仓位独立配置cron(每3-5分钟执行一次):
DSL_STATE_FILE=/data/workspace/dsl-state-BTC.json python3 scripts/dsl-v4.py多个仓位可错开启动时间(:00, :01, :02)避免并发压力。
How to Set Up a New Position
新仓位设置流程
- Open position via Senpi API ()
create_position - Create a state file with position details (see schema above)
- Double-check — controls all LONG/SHORT math
direction - Calculate correctly for the direction
absoluteFloor
- Double-check
- Create a cron job (every 3-5 min)
- DSL handles everything from there
- 通过Senpi API开仓()
create_position - 创建包含仓位详情的状态文件(参考上述Schema)
- 双重校验字段——控制所有LONG/SHORT计算逻辑
direction - 根据持仓方向正确计算
absoluteFloor
- 双重校验
- 创建cron任务(每3-5分钟执行一次)
- 后续流程全部由DSL自动处理
When a Position Closes
仓位平仓流程
- ✅ Script closes position via (with retry)
mcporter call senpi close_position - ✅ Script sets (or
active: falseif close fails)pendingClose: true - 🤖 Agent disables the cron (reads )
closed=true - 🤖 Agent sends alert to user
If close fails, script sets and retries next cron tick.
pendingClose: true- ✅ 脚本通过平仓(支持重试)
mcporter call senpi close_position - ✅ 脚本设置(如果平仓失败则设置
active: false)pendingClose: true - 🤖 Agent禁用cron(读取到)
closed=true - 🤖 Agent向用户发送告警
如果平仓失败,脚本会设置,并在下一个cron周期重试。
pendingClose: trueCustomization
自定义配置
See references/customization.md for conservative/moderate/aggressive presets and per-tier retrace tuning guidelines.
查看 references/customization.md 获取保守/适中/激进配置预设,以及各层级回撤阈值调优指南。
API Dependencies
API 依赖
- Price: Hyperliquid API (direct HTTP, no auth)
allMids - Close position: Senpi via mcporter
close_position
⚠️ Do NOT useto close individual positions. That closes the entire strategy (irreversible). Usestrategy_close_strategy.close_position
- 价格数据: Hyperliquid API(直接HTTP请求,无需鉴权)
allMids - 平仓接口: 通过mcporter调用Senpi 接口
close_position
⚠️ 不要使用关闭单个仓位。该接口会关闭整个策略(不可逆)。请使用strategy_close_strategy。close_position
Setup Checklist
配置检查清单
- Extract and
scripts/dsl-v4.pychmod +x - Ensure is configured with Senpi auth
mcporter - Create state file(s) per position
- Set up cron:
DSL_STATE_FILE=/path/to/state.json python3 scripts/dsl-v4.py - Agent reads output for alerts and cron cleanup
- If , script auto-retries on next tick
pending_close=true
- 提取并执行
scripts/dsl-v4.py赋予执行权限chmod +x - 确保已配置Senpi鉴权信息
mcporter - 为每个仓位创建独立的状态文件
- 配置cron:
DSL_STATE_FILE=/path/to/state.json python3 scripts/dsl-v4.py - Agent读取输出用于告警和cron清理
- 如果,脚本会在下一个执行周期自动重试
pending_close=true