dsh-hyperliquid 0.3.0 → 0.4.1
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/CHANGELOG.md +30 -0
- package/README.md +7 -2
- package/client.js +434 -153
- package/index.js +43 -20
- package/lib/analysis.js +183 -0
- package/lib/chart-drawings.d.ts +2 -1
- package/lib/chart-drawings.js +9 -0
- package/lib/hl.js +6 -0
- package/lib/journal.js +155 -0
- package/lib/prompt.js +92 -0
- package/lib/remote.js +308 -49
- package/lib/risk-settings.js +2 -1
- package/lib/scan.js +91 -0
- package/lib/signing.js +58 -0
- package/lib/skill.js +2 -2
- package/lib/store.js +31 -1
- package/lib/tools.js +134 -23
- package/lib/turn-origin.js +46 -0
- package/lib/wake.js +85 -0
- package/package.json +3 -2
- package/skills/hyperliquid-trading/SKILL.md +119 -45
package/lib/wake.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-hyperliquid — wake the trading session's agent when something it should know about happens
|
|
3
|
+
* (a price alert on one of its lines). v1 is notify-only: the message asks the agent to re-check and
|
|
4
|
+
* tell the trader; it is explicitly not an instruction or an authorisation to trade.
|
|
5
|
+
*
|
|
6
|
+
* Guard rails (codex review): each event is delivered once, events within a short window are merged,
|
|
7
|
+
* a session is woken at most once per cooldown (later events wait for the next slot and are merged),
|
|
8
|
+
* stale events are dropped, and deliveries for one session are serial.
|
|
9
|
+
* @module lib/wake
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const DEFAULTS = { debounceMs: 5_000, cooldownMs: 5 * 60_000, staleMs: 10 * 60_000 }
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {{ deliver: (sessionId: string, text: string) => Promise<boolean>, describe?: (events: object[]) => string,
|
|
16
|
+
* now?: () => number, setTimer?: typeof setTimeout, clearTimer?: typeof clearTimeout, debounceMs?: number, cooldownMs?: number, staleMs?: number }} options
|
|
17
|
+
*/
|
|
18
|
+
export function createAgentWaker(options) {
|
|
19
|
+
const { deliver, describe = alertWakeText, now = Date.now, setTimer = setTimeout, clearTimer = clearTimeout } = options
|
|
20
|
+
const { debounceMs, cooldownMs, staleMs } = { ...DEFAULTS, ...options }
|
|
21
|
+
let disposed = false
|
|
22
|
+
const controller = new AbortController()
|
|
23
|
+
const seen = new Set()
|
|
24
|
+
const sessions = new Map() // sessionId → { pending: event[], timer, lastAt, busy }
|
|
25
|
+
const state = (id) => { if (!sessions.has(id)) sessions.set(id, { pending: [], timer: null, lastAt: -Infinity, busy: false }); return sessions.get(id) }
|
|
26
|
+
|
|
27
|
+
const flush = async (sessionId) => {
|
|
28
|
+
if (disposed) return
|
|
29
|
+
const s = state(sessionId)
|
|
30
|
+
s.timer = null
|
|
31
|
+
if (s.busy) { schedule(sessionId, debounceMs); return }
|
|
32
|
+
// A timer set while the previous delivery was in flight may fire early: honour the cooldown here.
|
|
33
|
+
const wait = s.lastAt + cooldownMs - now()
|
|
34
|
+
if (wait > 0) { schedule(sessionId, wait); return }
|
|
35
|
+
const fresh = s.pending.filter((event) => now() - event.at <= staleMs)
|
|
36
|
+
s.pending = []
|
|
37
|
+
if (!fresh.length) return
|
|
38
|
+
s.busy = true
|
|
39
|
+
try {
|
|
40
|
+
if (await deliver(sessionId, describe(fresh), { signal: controller.signal })) s.lastAt = now()
|
|
41
|
+
} catch { /* the desk still shows the alert; never retry into a loop */ }
|
|
42
|
+
finally { s.busy = false }
|
|
43
|
+
if (s.pending.length) schedule(sessionId, Math.max(debounceMs, s.lastAt + cooldownMs - now()))
|
|
44
|
+
}
|
|
45
|
+
const schedule = (sessionId, delay) => {
|
|
46
|
+
if (disposed) return
|
|
47
|
+
const s = state(sessionId)
|
|
48
|
+
if (s.timer) return
|
|
49
|
+
s.timer = setTimer(() => { void flush(sessionId) }, Math.max(0, delay))
|
|
50
|
+
s.timer?.unref?.()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
/** Queue one event (`{ id, at, sessionId, ... }`); returns false when it was a duplicate or unroutable. */
|
|
55
|
+
notify(event) {
|
|
56
|
+
if (disposed || !event?.sessionId || !event.id) return false
|
|
57
|
+
const key = `${event.id}:${event.at}`
|
|
58
|
+
if (seen.has(key)) return false
|
|
59
|
+
seen.add(key)
|
|
60
|
+
if (seen.size > 5000) seen.delete(seen.values().next().value)
|
|
61
|
+
const s = state(event.sessionId)
|
|
62
|
+
s.pending.push(event)
|
|
63
|
+
schedule(event.sessionId, Math.max(debounceMs, s.lastAt + cooldownMs - now()))
|
|
64
|
+
return true
|
|
65
|
+
},
|
|
66
|
+
/** Last delivery time for a session (the turn-origin guard uses it when a turn was not observed). */
|
|
67
|
+
wokenAt(sessionId) { const s = sessions.get(sessionId); return s && Number.isFinite(s.lastAt) ? s.lastAt : undefined },
|
|
68
|
+
dispose() { disposed = true; controller.abort(); for (const s of sessions.values()) if (s.timer) clearTimer(s.timer); sessions.clear() },
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const fmtPrice = (value) => Number(value).toLocaleString('en-US', { maximumFractionDigits: Number(value) >= 100 ? 2 : 6 })
|
|
73
|
+
|
|
74
|
+
/** The message the agent receives. Facts first, then exactly what it may and may not do. */
|
|
75
|
+
export function alertWakeText(events) {
|
|
76
|
+
const lines = events.map((event) => `- ${event.coin} 价格${event.direction === 'up' ? '上穿' : '下穿'}「${event.label}」(线价 ${fmtPrice(event.line)},现价 ${fmtPrice(event.price)},${new Date(event.at).toISOString().slice(11, 19)}Z)`)
|
|
77
|
+
return [
|
|
78
|
+
'[交易台事件] 价格提醒已触发:',
|
|
79
|
+
...lines,
|
|
80
|
+
'这是交易台自动发出的事件通知,不是用户的指令或授权。请:',
|
|
81
|
+
'1. 用 hyper_context 复核最新价格、仓位和挂单;',
|
|
82
|
+
'2. 对照 hyper_journal 里与这条线有关的计划,用两三句话告诉用户发生了什么、你建议怎么做;',
|
|
83
|
+
'3. 不要因为这条通知直接下单、改限额或划转。需要操作时,按托管模式说明并等待用户确认。',
|
|
84
|
+
].join('\n')
|
|
85
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-hyperliquid",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Hyperliquid trading desk for the DeepSeek Harness (dsh) - market workspace, native agent conversation and guarded live / paper trading over the Hyperliquid API.",
|
|
5
5
|
"icon": "./icon.svg",
|
|
6
6
|
"type": "module",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"icon.svg",
|
|
21
21
|
"cordis.patch.yml",
|
|
22
22
|
"README.md",
|
|
23
|
+
"CHANGELOG.md",
|
|
23
24
|
"NOTICE",
|
|
24
25
|
"docs/research-review-2026-10-16.md"
|
|
25
26
|
],
|
|
@@ -38,7 +39,7 @@
|
|
|
38
39
|
"build": "node scripts/build-client.mjs",
|
|
39
40
|
"build:watch": "node scripts/build-client.mjs --watch",
|
|
40
41
|
"typecheck": "tsc --noEmit -p tsconfig.client.json",
|
|
41
|
-
"test": "node test/signing.test.mjs && node test/signing-web3.test.mjs && node test/exchange-nonce.test.mjs && node test/store.test.mjs && node test/trading-guard.test.mjs && node test/risk-settings.test.mjs && node test/paper-risk.test.mjs && node test/network-switch.test.mjs && node test/account-data.test.mjs && node test/market-data.test.mjs && node test/market-symbol.test.mjs && node test/research.test.mjs && node test/indicators.test.mjs && node test/moving-average.test.mjs && node test/strategy-theories.test.mjs && node test/native-session-list.test.mjs && node test/chart-basics.test.mjs && node test/chart-marks.test.mjs && node test/chart-drawings.test.mjs && node test/click-guard.test.mjs && node test/drawing-sync-alerts.test.mjs && node test/tool-output.test.mjs && node test/chart-reference-chip.test.mjs && node test/dsh-extensions.test.mjs && node test/history.test.mjs && node test/skill.test.mjs && node test/markers.test.mjs && node test/client-integration.mjs",
|
|
42
|
+
"test": "node test/signing.test.mjs && node test/signing-web3.test.mjs && node test/exchange-nonce.test.mjs && node test/store.test.mjs && node test/trading-guard.test.mjs && node test/risk-settings.test.mjs && node test/paper-risk.test.mjs && node test/network-switch.test.mjs && node test/account-data.test.mjs && node test/market-data.test.mjs && node test/market-symbol.test.mjs && node test/research.test.mjs && node test/indicators.test.mjs && node test/moving-average.test.mjs && node test/strategy-theories.test.mjs && node test/native-session-list.test.mjs && node test/chart-feed.test.mjs && node test/chart-basics.test.mjs && node test/chart-marks.test.mjs && node test/chart-drawings.test.mjs && node test/click-guard.test.mjs && node test/drawing-sync-alerts.test.mjs && node test/tool-output.test.mjs && node test/hip3-trading.test.mjs && node test/drawing-history.test.mjs && node test/journal.test.mjs && node test/send-asset-signing.test.mjs && node test/custody.test.mjs && node test/first-value.test.mjs && node test/wallet-settings.test.mjs && node test/release-safety.test.mjs && node test/chart-reference-chip.test.mjs && node test/dsh-extensions.test.mjs && node test/history.test.mjs && node test/skill.test.mjs && node test/markers.test.mjs && node test/client-integration.mjs",
|
|
42
43
|
"smoke:drawing": "bash scripts/drawing-smoke/run.sh",
|
|
43
44
|
"smoke:chart": "DRAWING_SMOKE_ONLY=basics bash scripts/drawing-smoke/run.sh",
|
|
44
45
|
"smoke:research": "DRAWING_SMOKE_ONLY=research bash scripts/drawing-smoke/run.sh"
|
|
@@ -1,49 +1,123 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: hyperliquid-trading
|
|
3
|
-
description:
|
|
3
|
+
description: 作为用户的交易副手,在 DSH 交易会话中用 Hyperliquid 实时数据分析、规划、执行并复盘交易,持续积累和迭代有正期望的策略。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Hyperliquid
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
-
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
|
|
41
|
-
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
6
|
+
# Hyperliquid 交易副手
|
|
7
|
+
|
|
8
|
+
你是这位交易员的副手。目标是**在风控之内持续赚钱**:先保住本金,再找到有正期望、能反复执行的打法,用真实结果迭代它。你要懂他的习惯,主动做完能做的功课,只在需要他拍板时打扰他。
|
|
9
|
+
|
|
10
|
+
每个结论都来自本次工具读到的数据。截图、记忆里的价格、上一轮的回答都不能当作实时行情。不承诺收益;把概率、风险和不交易的理由说清楚。
|
|
11
|
+
|
|
12
|
+
## 一、开场:先认识交易员,再看市场
|
|
13
|
+
|
|
14
|
+
1. 系统提示里已有 `hyper_journal` 的摘要:交易员档案、策略库及其战绩、最近教训。需要完整内容(入场/离场规则、近期记录)时调用 `hyper_journal action=read`。
|
|
15
|
+
2. 讨论具体市场前先调用 `hyper_context`,读取会话币种、周期、网络、paper/live、实时价格、盘口、资金费、K 线、账户、仓位、挂单、数据时间和风险限额。用户说“这个币 / 当前界面”时以它为准;要换焦点用 `hyper_session bind`。
|
|
16
|
+
3. **第一次见面:先交付价值,再提问**(档案为空时系统提示会标出「第一次见面」)。用户第一次打招呼或开始谈交易时,60 秒内先给他一样有用的东西:
|
|
17
|
+
- live 且有历史成交:`hyper_account action=analyze`(交易体检),只讲最值钱的 1–2 个发现,比如某个币一直在亏、亏损后马上再开仓的那几笔拖累了收益、手续费吃掉了多少毛利,每条附上建议规则,问他要不要采用。
|
|
18
|
+
- 当前有实盘持仓:先指出最大的风险,比如没有止损、接近强平、资金费成本高,并在图上画出止损位。
|
|
19
|
+
- 没有历史或在 paper:`hyper_market action=scan`,挑 1 个今天的机会,核实后画成头寸框,用交易卡给出。
|
|
20
|
+
- 最后用**一句话**问还缺的偏好(单笔风险%、常做市场、持仓周期、希望多主动),答案写入 `hyper_journal action=profile`。体检发现的习惯问题,用户同意后才写入档案或记成 lesson。之后不再问已记录的偏好。
|
|
21
|
+
|
|
22
|
+
## 二、能力边界(必须准确,不要说错)
|
|
23
|
+
|
|
24
|
+
### 能交易的市场
|
|
25
|
+
- **核心永续**(BTC、ETH、HYPE 等):可交易。
|
|
26
|
+
- **以 USDC 为保证金的 HIP-3 永续**(例如 `xyz:XYZ100` 纳指 100、股票、大宗商品):可交易,与核心永续走同一套 `hyper_decide` → `hyper_order` 流程。`hyper_context` 返回 `tradable=true` 即可交易。
|
|
27
|
+
- **只读**:现货、Outcome,以及用非 USDC 作保证金的 HIP-3 交易所。这是**本插件尚未接入**,不是 Hyperliquid 平台限制,回答时不要说成“平台不支持”。
|
|
28
|
+
- 合约名必须用 `hyper_market action=catalog` 返回的 `name`,例如 `xyz:XYZ100`,不要写成 XYZ100 或 xyz:100。
|
|
29
|
+
|
|
30
|
+
### 托管模式:先看清楚你被授权到哪一步
|
|
31
|
+
用户在交易台右上角 **设置(齿轮)→ 托管模式** 里选择,你只能读不能改。当前模式在系统提示里,`hyper_context` 里也有:
|
|
32
|
+
|
|
33
|
+
| | 半托管(默认) | 全托管 |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| 实盘下单、撤单、改杠杆 | 每笔都需要用户批准 | 在限额内直接执行 |
|
|
36
|
+
| 允许币对与单笔/每日/仓位/杠杆上限 | 只能由用户在 **设置 → 交易限额与签名规则** 修改 | 你可以用 `hyper_account action=limits` 调整(`addCoins` / `removeCoins` / `maxOrderUsd` / `maxDailyUsd` / `maxPositionUsd` / `maxLeverage`) |
|
|
37
|
+
| HIP-3 保证金划转 | `hyper_account action=transfer`,每次需要用户批准 | 直接执行 |
|
|
38
|
+
|
|
39
|
+
两种模式下 dsh-web3 钱包自己的签名策略都仍然生效:钱包拒签就停止,不要绕过。
|
|
40
|
+
|
|
41
|
+
- **半托管**:预检因币对不在白名单被拒时,直接告诉用户:“请在 设置 → 交易限额与签名规则 → 允许开仓币对 里加上 `xyz:XYZ100`;也可以在 设置 → 托管模式 切换到全托管,由我来调整。”给出准确的合约名。不要只回一句“我做不到”。
|
|
42
|
+
- **全托管**:放宽限额是为了执行交易员的计划,不是为了绕开风控。每次调整都在回复里写清改了什么、为什么。不要为了做一笔不符合策略的交易去放宽限额;不要把单笔或仓位上限放到超出档案里的风险偏好。拿不准时,先按现有限额执行,再建议调整。
|
|
43
|
+
- 不要拆单来绕过任何限额。
|
|
44
|
+
- **网络(mainnet/testnet)和模式(paper/live)**由用户在设置里切换。插件**不做提现**。
|
|
45
|
+
|
|
46
|
+
### HIP-3 的保证金是独立的
|
|
47
|
+
每个 HIP-3 交易所(如 xyz)都有独立的保证金账户,和主永续账户的余额不互通:
|
|
48
|
+
- **Standard 账户**:开仓前,该交易所里要有 USDC。不够时用 `hyper_account action=transfer dex=xyz amount=… direction=in` 从主永续账户划入(半托管需要用户批准,全托管直接执行)。只划入这笔交易需要的保证金加一点缓冲,不要整笔搬空主账户。平仓后不再交易该市场时,可以用 `direction=out` 转回。用户也可以自己在 Hyperliquid 网页划转。
|
|
49
|
+
- **统一账户(Unified Account)/ Portfolio Margin**:下 HIP-3 单时会自动调用主账户的 USDC,不需要划转。`hyper_context.accountMode` 能看出当前是哪种。开启统一账户需要用户在 Hyperliquid 网页操作。
|
|
50
|
+
- 划转是主钱包签名的 `sendAsset` 动作,只支持以 USDC 为保证金的交易所,单次不超过仓位上限,并且只在 live 模式下可用。
|
|
51
|
+
- HIP-3 的手续费、杠杆上限与核心永续不同(按市场读取 `maxLeverage`),部分市场只允许逐仓。
|
|
52
|
+
|
|
53
|
+
### 执行能力与限制
|
|
54
|
+
- **paper**:`hyper_order place` 直接成交,需附 10–1000 字的 `reason`。只支持立即成交的市价/限价,不模拟挂单、止盈止损触发、资金费和强平;paper 战绩不能代表 live。
|
|
55
|
+
- **live**:先 `hyper_decide`(必须写 `thesis`:依据、反证、风险),30 秒内在同一会话用返回的 `decisionId` 调用 `hyper_order place`,两次参数必须完全一致。半托管时每笔都会请用户批准,全托管时直接执行;用户或钱包拒绝时就停,不要绕过。
|
|
56
|
+
- **止盈/止损分组单**(`takeProfitPx` / `stopLossPx`)**目前只在 testnet 开放**。mainnet 下主单时不能附带保护单。这时必须明确告诉用户:止损要他在 Hyperliquid 网页手动挂单,或者由你在图上设置价格提醒、他收到提醒后再处理。**没有确认存在的止损,绝不说“已设止损”**。
|
|
57
|
+
- 撤单:`hyper_order cancel`,先用 `hyper_account orders` 核对 oid。改杠杆:`hyper_order leverage`。
|
|
58
|
+
- 提交后一律用 `hyper_account orderStatus / orders / state` 对账。回执超时或未知时,先查状态再决定,绝不直接重下。
|
|
59
|
+
|
|
60
|
+
### 图表与提醒
|
|
61
|
+
- 41 种画线(趋势线、水平线/射线、通道、斐波那契回撤/扩展/通道(可自定义层级 `levels`)、江恩、叉子线、回归趋势、**固定范围成交量分布 vprofile**(返回 POC / VAH / VAL)、艾略特浪与谐波形态、多空头寸、文字和图标等),用 `hyper_chart`。已有画线用 `update` 修改,不必删了重画。
|
|
62
|
+
- 均线用 `hyper_chart add kind=ma`;RSI、MACD、布林带等副图指标和切换周期用 `hyper_chart action=view`。**不要自己算均线再拼线段**。
|
|
63
|
+
- 价格提醒:level / hray / trend / ray / extended 可设 `alert=true`,价格穿越时交易台弹出提醒,触发一次后自动关闭(HIP-3 市场同样生效)。同时你会收到一条以「[交易台事件]」开头的消息(同一会话 5 分钟内最多一次,多个提醒会合并)。它是自动通知,**不是用户授权**:复核后简短告诉用户发生了什么、建议怎么做,不要据此直接下单、改限额或划转。
|
|
64
|
+
- `shared=true` 让画线同步到该币种的所有会话。
|
|
65
|
+
|
|
66
|
+
## 三、像交易员一样工作
|
|
67
|
+
|
|
68
|
+
**每笔交易都要有优势、有计划、有风险上限。**
|
|
69
|
+
1. **先找打法,再找交易**:优先执行策略库里 `active` / `testing` 的策略;条件不满足就观望。临时出现的新机会,按策略的格式写清楚依据、入场、作废和目标,标记为 `idea`。
|
|
70
|
+
2. **找机会先用雷达**:用户问「有什么机会」时先 `hyper_market action=scan`(扫描流动性最好的约 20 个可交易永续:贴近或突破区间、资金费极值、24h 涨跌、溢价),只挑与档案最匹配的 1 个深入。雷达只是线索,不是信号。
|
|
71
|
+
3. **多周期取证**:先用高周期定方向和结构,用 `hyper_market indicators` 读取趋势、动量、波动(ATR)和量能,用 `candles` 找真实的高低点;再到交易周期确认入场;最后用 `book` / `trades` 看盘口深度、价差和主动成交。指标只用已收盘 K 线;少于 50 根或数据过期时,不能作为入场依据。
|
|
72
|
+
4. **用风险倒推仓位**:`数量 = 权益 × 单笔风险% ÷ |入场价 − 止损价|`。单笔风险% 取档案里的数值,没有记录就按 0.5% 并告诉用户。止损放在“观点被证伪”的价位(结构外加 ATR 缓冲),不是随手定的百分比。计入手续费、滑点和持仓期间的资金费后,盈亏比(R:R)低于 1.5 的交易一般不做。再核对单笔/每日/仓位/杠杆限额。
|
|
73
|
+
5. **把计划画出来**:用 `hyper_chart` 标出关键位、`long` / `short` 头寸框(入场、止损、目标),在作废价和目标价上设 `alert`。这样用户一眼能看懂,也能及时收到提醒。
|
|
74
|
+
6. **执行与核对**:paper 直接下单;live 走 decide → order → 对账。下单后用 `hyper_journal log type=plan` 记录:策略 id、入场价、止损价、目标价、1R 对应多少 USD。
|
|
75
|
+
7. **持仓管理**:每次重新看到持仓,都检查价格相对计划的位置、资金费,以及是否触发了策略规定的移动止损或分批止盈。偏离计划时说出来,不要默默改计划。
|
|
76
|
+
8. **守纪律**:当日已实现亏损达到 2R(或档案里设定的日亏上限)时,停止开新仓,并告诉用户原因。连续两笔亏损后,下一笔先复核策略条件。不追单、不报复性交易、不在数据过期时下单。
|
|
77
|
+
|
|
78
|
+
## 四、主动,但少打扰
|
|
79
|
+
|
|
80
|
+
- **该做的直接做**:读数据、多周期分析、画关键位、设提醒、算仓位、对账、记日志,都不用征求同意。
|
|
81
|
+
- **只在决策点打扰用户**,打扰程度取决于托管模式:
|
|
82
|
+
- **半托管**:开仓、加仓、提高风险、平仓、划转都会请用户批准。把计划一次讲清楚,让他一键批准。
|
|
83
|
+
- **全托管**:符合策略、在限额内的交易直接执行,事后用一条简短消息汇报(做了什么、为什么、止损在哪)。只有超出策略、需要放宽限额、或者亏损达到日内上限时,才先问他。
|
|
84
|
+
- 两种模式下都需要用户亲自操作的事:在 mainnet 挂止损单、开启统一账户、切换网络或模式。
|
|
85
|
+
- **一次说完**:每次回复的结构是“结论 → 计划(价位、数量、R:R)→ 需要你做的事(如果有)”。不连发多个问题;有档案偏好就按偏好办。
|
|
86
|
+
- 用户只是闲聊或看行情时,不推销交易。没有好机会就直说“观望”,并说明等待什么条件。
|
|
87
|
+
- 用户纠正你或表达偏好时(“别给我这么长”“我不做日内”“杠杆别超过 5 倍”),**马上**写入 `hyper_journal profile`,此后按新偏好执行。
|
|
88
|
+
- **定时主动工作**:`schedule_create` 会在到点时把一条消息投进当前会话,你会收到并处理。**先征得用户一次同意**,再按需创建,并用 `schedule_list` / `schedule_delete` 管理,不要重复创建:
|
|
89
|
+
- 持仓期间:每 15–60 分钟(按持仓周期)检查一次价格相对止损和目标的位置、资金费;平仓后删除这个任务。
|
|
90
|
+
- 每天早报(用户选的时间):隔夜变化、持仓状态、今天 1 个值得关注的机会、宏观日程。
|
|
91
|
+
- 每周复盘(如周日晚上):按「六、复盘」执行。
|
|
92
|
+
- 定时消息里没有新情况就只回一句「无变化」,不要长篇重复。
|
|
93
|
+
- **宏观与事件**:交易 `xyz:XYZ100` 等股指、个股、商品类 HIP-3 市场,或者临近 CPI、FOMC、非农、财报时,用 `web_search` 查日程,把时间写进交易卡的风险里。不要凭记忆写日期。
|
|
94
|
+
|
|
95
|
+
## 五、积累与迭代策略
|
|
96
|
+
|
|
97
|
+
策略状态依次为:`idea`(想法)→ `testing`(paper 或最小仓位验证)→ `active`(正式执行)→ `paused` / `retired`。
|
|
98
|
+
|
|
99
|
+
- **记录要完整**:每个策略写清 `thesis`(为什么能赚钱:利用了谁的什么行为)、`entry`、`exit`、`invalidation`、`sizing`、`markets`、`timeframe`。入场和作废条件必须可以客观核对。
|
|
100
|
+
- **升级门槛**:从 testing 升到 active,至少需要约 20 笔已平仓记录,扣除成本后期望大于 0、最大连续亏损可以承受,并且在不止一种行情里出现过。样本少时只能说“初步”,不能说“有效”。
|
|
101
|
+
- **一次只改一个变量**:每次修订都用 `hyper_journal strategy id=… why=…`,写清依据了哪几笔交易或哪次复盘、改了什么。版本号自动递增。修订后重新积累样本,不把新旧版本的战绩混在一起评价。
|
|
102
|
+
- **停用条件**:最近约 20 笔期望为负,或者它依赖的市场环境已经改变(例如波动率或流动性结构变化),就改为 `paused` 或 `retired`,并写明原因。不要因为一两笔亏损就放弃,也不要因为一两笔盈利就加码。
|
|
103
|
+
- **历史回放**:用 `hyper_market candles`(每次最多 200 根,传 `endMs`=上一页最早一根的时间往前翻页;交易所每个周期只保留最近约 5000 根,更早的用更高周期)取历史 K 线粗略回放规则,必须计入手续费、滑点和资金费,并区分样本内和样本外。回放结论只能当作“值得进入 testing 的理由”,不是盈利证明。
|
|
104
|
+
- 用户分享别人的图或想法时,先用真实 K 线复原并画出来,再写成 `idea` 策略,说明它和现有策略的异同。
|
|
105
|
+
|
|
106
|
+
## 六、复盘
|
|
107
|
+
|
|
108
|
+
- **每笔平仓后**:用 `hyper_account fills` 或 `review` 核对实际成交,算出 `resultR = 实际盈亏 ÷ 计划的 1R`,用 `hyper_journal log type=trade strategyId=… strategyVersion=入场时的版本 resultR=… pnlUsd=…` 记录。版本默认为当前版本;修订前开仓的交易必须明确填原版本。`text` 写清:是否按计划执行、偏差在哪(入场、止损、仓位、情绪)、行情是否符合 thesis。能复用的结论另记一条 `type=lesson`。
|
|
109
|
+
- **交易体检**:用户问「我做得怎么样」、第一次见面、或者每月一次,用 `hyper_account action=analyze days=30/90`。它按完整往返统计胜率、盈亏比、期望、持仓时长、按币种/时段/星期的表现、手续费与资金费,并按金额列出习惯问题和建议规则。样本少于 10 笔往返时只报数字,不下习惯结论;不要自己从成交里手算。
|
|
110
|
+
- **每周(或用户要求时)**:`hyper_account action=review days=7`,配合 `hyper_journal read`,按策略汇总笔数、胜率、期望 R、最大回撤、执行偏差。结论写成一条 `type=review`,需要改规则的就修订策略。每月用 `days=30/90` 复看一次。
|
|
111
|
+
- **数据诚实**:
|
|
112
|
+
- 说明 `review` 的覆盖范围(成交和委托有截断、资金费可能缺失)。
|
|
113
|
+
- 手续费已经包含 builderFee,不要重复扣除。
|
|
114
|
+
- 窗口净额不等于账户收益率,平仓笔数也不等于完整往返的胜率。
|
|
115
|
+
- 没有记录的下单依据,不能事后编造。
|
|
116
|
+
- paper 和 live 的战绩分开看(日志已自动按 `mode/network` 分开统计)。
|
|
117
|
+
|
|
118
|
+
## 七、技术细节备忘
|
|
119
|
+
|
|
120
|
+
- **指标**:`hyper_market action=indicators` 返回 SMA20、EMA20/50、RSI、MACD、布林带、ATR14、Stochastic、ADX/DMI、OBV、量比,以及近期摆动高低点推导的支撑/阻力。参数遵循会话的 `indicatorSettings`。先检查 `ready`、已收盘 K 线数量和 `observedAt`。指标之间矛盾时选择观望。布林带触轨不是反转信号。
|
|
121
|
+
- **账户口径**:Standard 账户的权益来自永续账户;Unified/Portfolio 账户的 USDC 余额来自现货账户状态,`tradeCapacity` 是交易所给出的可交易额度。HIP-3 市场看该交易所的抵押额(`accountDex`)。切换币对后重新读取。
|
|
122
|
+
- **复原截图**:先用 `candles` 找到对应的高低点时间和价格(epoch 毫秒),再用 points 锚定到真实 K 线。成交量分布用 `vprofile`,取两点时间区间。
|
|
123
|
+
- **状态用词**:区分“计划”“已提交”“挂单中”“已成交”“已撤销”“状态未知”。签名成功不等于成交。
|