dsh-hyperliquid 0.4.2 → 0.4.3
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 +5 -0
- package/client.js +20 -10
- package/lib/chart-drawings.d.ts +1 -1
- package/lib/chart-drawings.js +8 -1
- package/lib/remote.js +1 -1
- package/lib/tools.js +2 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.3 — 2026-10-17
|
|
4
|
+
|
|
5
|
+
- 趋势线可分别向左、向右延长(浮动工具条两个开关,agent 工具 `extendLeft` / `extendRight`);价格提醒按延长后的线判断,延长的线不参与屏幕外剔除。
|
|
6
|
+
- 「点击没反应」根因补充验证:0.1.0 两次点击间隔 300ms、450ms 同样漏画 20/20,550ms 0/20,分界与图表库 500ms 双击窗口一致;当前版本同样间隔 0 漏画。
|
|
7
|
+
|
|
3
8
|
## 0.4.2 — 2026-10-17
|
|
4
9
|
|
|
5
10
|
- 画线对象属性对齐 TradingView:按周期显示(仅本周期,水平线的轴价格标签同样隐藏)、文本与标注气泡字号(10–32px)与粗体 / 斜体、矩形 / 圆 / 三角 / 通道 / 斐波那契 / 区间等的背景填充浓淡;浮动工具条、agent 工具参数、撤销与复制都支持。限定周期的画线在其他周期不绘制但保留在画线列表。
|
package/client.js
CHANGED
|
@@ -17908,9 +17908,9 @@ function drawingLabel(kind, points2, price) {
|
|
|
17908
17908
|
const when = new Date(first.time).toLocaleString(tr("zh-CN", "en-US"), { month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", hour12: false });
|
|
17909
17909
|
return `${name} ${when}`;
|
|
17910
17910
|
}
|
|
17911
|
-
function clipLine(a, b, w, h, from) {
|
|
17911
|
+
function clipLine(a, b, w, h, from, to = Infinity) {
|
|
17912
17912
|
const dx = b.x - a.x, dy = b.y - a.y;
|
|
17913
|
-
let t0 = from, t1 =
|
|
17913
|
+
let t0 = from, t1 = to;
|
|
17914
17914
|
for (const [p, q] of [[-dx, a.x], [dx, w - a.x], [-dy, a.y], [dy, h - a.y]]) {
|
|
17915
17915
|
if (p === 0) {
|
|
17916
17916
|
if (q < 0) return null;
|
|
@@ -17992,7 +17992,7 @@ function guide(a, b, value, key3, text) {
|
|
|
17992
17992
|
}
|
|
17993
17993
|
var BADGE_PATHS = { alert: "M6 16V11a6 6 0 0 1 12 0v5l2 2H4zM10 20a2 2 0 0 0 4 0", shared: "M4 9h13l-3-3M20 15H7l3 3" };
|
|
17994
17994
|
var DASH = { solid: void 0, dashed: "7 5", dotted: "1.5 4" };
|
|
17995
|
-
var DrawingShape = React7.memo(function DrawingShape2({ kind, points: points2, label, text: textValue, className, view, anchors = false, interactive = false, color, lineWidth, lineStyle, id, alert, shared, rows, valueArea, levels, fontSize, bold, italic, fillOpacity }) {
|
|
17995
|
+
var DrawingShape = React7.memo(function DrawingShape2({ kind, points: points2, label, text: textValue, className, view, anchors = false, interactive = false, color, lineWidth, lineStyle, id, alert, shared, rows, valueArea, levels, fontSize, bold, italic, fillOpacity, extendLeft, extendRight }) {
|
|
17996
17996
|
const k = (fontSize ?? 12) / 12;
|
|
17997
17997
|
const badges = [...alert ? ["alert"] : [], ...shared ? ["shared"] : []];
|
|
17998
17998
|
const { width: w, height: h } = view;
|
|
@@ -18014,9 +18014,17 @@ var DrawingShape = React7.memo(function DrawingShape2({ kind, points: points2, l
|
|
|
18014
18014
|
body = /* @__PURE__ */ React7.createElement("line", { x1: p[0].x, x2: p[0].x, y1: "0", y2: h });
|
|
18015
18015
|
handles = [{ x: p[0].x, y: Math.min(h - 12, Math.max(12, p[0].y)) }];
|
|
18016
18016
|
break;
|
|
18017
|
-
case "trend":
|
|
18018
|
-
|
|
18017
|
+
case "trend": {
|
|
18018
|
+
if (!p[1]) break;
|
|
18019
|
+
if (!extendLeft && !extendRight) {
|
|
18020
|
+
body = /* @__PURE__ */ React7.createElement("line", { x1: p[0].x, y1: p[0].y, x2: p[1].x, y2: p[1].y });
|
|
18021
|
+
break;
|
|
18022
|
+
}
|
|
18023
|
+
const [l, r] = p[0].x <= p[1].x ? [p[0], p[1]] : [p[1], p[0]];
|
|
18024
|
+
const seg = clipLine(l, r, w, h, extendLeft ? -Infinity : 0, extendRight ? Infinity : 1);
|
|
18025
|
+
body = seg ? /* @__PURE__ */ React7.createElement("line", { x1: seg[0].x, y1: seg[0].y, x2: seg[1].x, y2: seg[1].y }) : null;
|
|
18019
18026
|
break;
|
|
18027
|
+
}
|
|
18020
18028
|
case "ray":
|
|
18021
18029
|
case "extended": {
|
|
18022
18030
|
if (!p[1]) break;
|
|
@@ -18435,7 +18443,7 @@ function DrawToolbar({ mark, globallyLocked, onEdit, onRemove, onClose, onClone,
|
|
|
18435
18443
|
onClick: () => onEdit({ lineStyle: value })
|
|
18436
18444
|
},
|
|
18437
18445
|
/* @__PURE__ */ React8.createElement("svg", { viewBox: "0 0 18 18", width: "16", height: "16", "aria-hidden": "true" }, /* @__PURE__ */ React8.createElement("line", { x1: "2", x2: "16", y1: "9", y2: "9", stroke: "currentColor", strokeWidth: "2", strokeDasharray: value === "dashed" ? "4 3" : value === "dotted" ? "1 3" : void 0, strokeLinecap: "round" }))
|
|
18438
|
-
))) : null, FONT_KINDS.includes(mark.kind) || FILL_KINDS.includes(mark.kind) ? /* @__PURE__ */ React8.createElement("span", { className: "dhl-draw-toolbar-group", role: "group", "aria-label": tr("\u6587\u5B57\u4E0E\u586B\u5145", "Text and fill") }, FONT_KINDS.includes(mark.kind) ? /* @__PURE__ */ React8.createElement(Select, { "aria-label": tr("\u5B57\u53F7", "Font size"), title: tr("\u5B57\u53F7", "Font size"), value: String(mark.fontSize ?? 12), disabled: locked, onChange: (event) => onEdit({ fontSize: Number(event.target.value) }) }, [10, 12, 14, 18, 24, 32].map((size3) => /* @__PURE__ */ React8.createElement("option", { key: size3, value: size3 }, `${size3}px`))) : null, FONT_KINDS.includes(mark.kind) ? /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement("button", { type: "button", className: mark.bold ? "on" : "", "aria-pressed": Boolean(mark.bold), disabled: locked, "aria-label": tr("\u7C97\u4F53", "Bold"), title: tr("\u7C97\u4F53", "Bold"), onClick: () => onEdit({ bold: !mark.bold }) }, /* @__PURE__ */ React8.createElement("b", null, "B")), /* @__PURE__ */ React8.createElement("button", { type: "button", className: mark.italic ? "on" : "", "aria-pressed": Boolean(mark.italic), disabled: locked, "aria-label": tr("\u659C\u4F53", "Italic"), title: tr("\u659C\u4F53", "Italic"), onClick: () => onEdit({ italic: !mark.italic }) }, /* @__PURE__ */ React8.createElement("i", null, "I"))) : null, FILL_KINDS.includes(mark.kind) ? /* @__PURE__ */ React8.createElement(Select, { "aria-label": tr("\u80CC\u666F\u586B\u5145", "Background fill"), title: tr("\u80CC\u666F\u586B\u5145", "Background fill"), value: String(mark.fillOpacity ?? (mark.kind === "fib" ? 0.07 : 0.08)), disabled: locked, onChange: (event) => onEdit({ fillOpacity: Number(event.target.value) }) }, [[0, "\u65E0\u586B\u5145", "No fill"], [mark.kind === "fib" ? 0.07 : 0.08, "\u6DE1", "Light"], [0.18, "\u4E2D", "Medium"], [0.32, "\u6D53", "Strong"]].map(([value, zh, en]) => /* @__PURE__ */ React8.createElement("option", { key: String(value), value: String(value) }, tr(String(zh), String(en))))) : null) : null, FIB_LEVEL_KINDS.includes(mark.kind) ? /* @__PURE__ */ React8.createElement("span", { className: "dhl-draw-toolbar-group", role: "group", "aria-label": tr("\u6590\u6CE2\u90A3\u5951\u5C42\u7EA7", "Fibonacci levels") }, /* @__PURE__ */ React8.createElement(
|
|
18446
|
+
))) : null, mark.kind === "trend" ? /* @__PURE__ */ React8.createElement("span", { className: "dhl-draw-toolbar-group", role: "group", "aria-label": tr("\u5EF6\u957F", "Extend") }, /* @__PURE__ */ React8.createElement("button", { type: "button", className: mark.extendLeft ? "on" : "", "aria-pressed": Boolean(mark.extendLeft), disabled: locked, "aria-label": tr("\u5411\u5DE6\u5EF6\u957F", "Extend left"), title: tr("\u5411\u5DE6\u5EF6\u957F", "Extend left"), onClick: () => onEdit({ extendLeft: !mark.extendLeft }) }, /* @__PURE__ */ React8.createElement("svg", { viewBox: "0 0 24 24", width: "15", height: "15", fill: "none", stroke: "currentColor", strokeWidth: "1.8", "aria-hidden": "true" }, /* @__PURE__ */ React8.createElement("path", { d: "M3 12h13", strokeDasharray: "2 2.5" }), /* @__PURE__ */ React8.createElement("path", { d: "M14 12h7" }), /* @__PURE__ */ React8.createElement("circle", { cx: "14", cy: "12", r: "1.8" }), /* @__PURE__ */ React8.createElement("path", { d: "M6 9l-3 3 3 3" }))), /* @__PURE__ */ React8.createElement("button", { type: "button", className: mark.extendRight ? "on" : "", "aria-pressed": Boolean(mark.extendRight), disabled: locked, "aria-label": tr("\u5411\u53F3\u5EF6\u957F", "Extend right"), title: tr("\u5411\u53F3\u5EF6\u957F", "Extend right"), onClick: () => onEdit({ extendRight: !mark.extendRight }) }, /* @__PURE__ */ React8.createElement("svg", { viewBox: "0 0 24 24", width: "15", height: "15", fill: "none", stroke: "currentColor", strokeWidth: "1.8", "aria-hidden": "true" }, /* @__PURE__ */ React8.createElement("path", { d: "M3 12h7" }), /* @__PURE__ */ React8.createElement("path", { d: "M10 12h11", strokeDasharray: "2 2.5" }), /* @__PURE__ */ React8.createElement("circle", { cx: "10", cy: "12", r: "1.8" }), /* @__PURE__ */ React8.createElement("path", { d: "M18 9l3 3-3 3" })))) : null, FONT_KINDS.includes(mark.kind) || FILL_KINDS.includes(mark.kind) ? /* @__PURE__ */ React8.createElement("span", { className: "dhl-draw-toolbar-group", role: "group", "aria-label": tr("\u6587\u5B57\u4E0E\u586B\u5145", "Text and fill") }, FONT_KINDS.includes(mark.kind) ? /* @__PURE__ */ React8.createElement(Select, { "aria-label": tr("\u5B57\u53F7", "Font size"), title: tr("\u5B57\u53F7", "Font size"), value: String(mark.fontSize ?? 12), disabled: locked, onChange: (event) => onEdit({ fontSize: Number(event.target.value) }) }, [10, 12, 14, 18, 24, 32].map((size3) => /* @__PURE__ */ React8.createElement("option", { key: size3, value: size3 }, `${size3}px`))) : null, FONT_KINDS.includes(mark.kind) ? /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement("button", { type: "button", className: mark.bold ? "on" : "", "aria-pressed": Boolean(mark.bold), disabled: locked, "aria-label": tr("\u7C97\u4F53", "Bold"), title: tr("\u7C97\u4F53", "Bold"), onClick: () => onEdit({ bold: !mark.bold }) }, /* @__PURE__ */ React8.createElement("b", null, "B")), /* @__PURE__ */ React8.createElement("button", { type: "button", className: mark.italic ? "on" : "", "aria-pressed": Boolean(mark.italic), disabled: locked, "aria-label": tr("\u659C\u4F53", "Italic"), title: tr("\u659C\u4F53", "Italic"), onClick: () => onEdit({ italic: !mark.italic }) }, /* @__PURE__ */ React8.createElement("i", null, "I"))) : null, FILL_KINDS.includes(mark.kind) ? /* @__PURE__ */ React8.createElement(Select, { "aria-label": tr("\u80CC\u666F\u586B\u5145", "Background fill"), title: tr("\u80CC\u666F\u586B\u5145", "Background fill"), value: String(mark.fillOpacity ?? (mark.kind === "fib" ? 0.07 : 0.08)), disabled: locked, onChange: (event) => onEdit({ fillOpacity: Number(event.target.value) }) }, [[0, "\u65E0\u586B\u5145", "No fill"], [mark.kind === "fib" ? 0.07 : 0.08, "\u6DE1", "Light"], [0.18, "\u4E2D", "Medium"], [0.32, "\u6D53", "Strong"]].map(([value, zh, en]) => /* @__PURE__ */ React8.createElement("option", { key: String(value), value: String(value) }, tr(String(zh), String(en))))) : null) : null, FIB_LEVEL_KINDS.includes(mark.kind) ? /* @__PURE__ */ React8.createElement("span", { className: "dhl-draw-toolbar-group", role: "group", "aria-label": tr("\u6590\u6CE2\u90A3\u5951\u5C42\u7EA7", "Fibonacci levels") }, /* @__PURE__ */ React8.createElement(
|
|
18439
18447
|
"input",
|
|
18440
18448
|
{
|
|
18441
18449
|
className: "dhl-draw-toolbar-text dhl-fib-levels",
|
|
@@ -19666,7 +19674,7 @@ function CandleChart({ candles, marks, indicators, expanded, resetToken, drawMod
|
|
|
19666
19674
|
const cloneOf = React10.useCallback((mark) => {
|
|
19667
19675
|
const line = timelineRef.current;
|
|
19668
19676
|
const shifted = markPoints(mark).map((point) => ({ time: line.toTime(line.toLogical(point.time) + 5), price: point.price }));
|
|
19669
|
-
const style = Object.fromEntries(Object.entries({ color: mark.color, lineWidth: mark.lineWidth, lineStyle: mark.lineStyle, levels: mark.levels, rows: mark.rows, valueArea: mark.valueArea, fontSize: mark.fontSize, bold: mark.bold, italic: mark.italic, fillOpacity: mark.fillOpacity, visibleIntervals: mark.visibleIntervals }).filter(([, value]) => value != null));
|
|
19677
|
+
const style = Object.fromEntries(Object.entries({ color: mark.color, lineWidth: mark.lineWidth, lineStyle: mark.lineStyle, levels: mark.levels, rows: mark.rows, valueArea: mark.valueArea, fontSize: mark.fontSize, bold: mark.bold, italic: mark.italic, extendLeft: mark.extendLeft, extendRight: mark.extendRight, fillOpacity: mark.fillOpacity, visibleIntervals: mark.visibleIntervals }).filter(([, value]) => value != null));
|
|
19670
19678
|
return { kind: mark.kind, geometry: geometryPatch(mark.kind, shifted), style, label: mark.label };
|
|
19671
19679
|
}, []);
|
|
19672
19680
|
const clipboard = React10.useRef(null);
|
|
@@ -19915,7 +19923,7 @@ function CandleChart({ candles, marks, indicators, expanded, resetToken, drawMod
|
|
|
19915
19923
|
const selected = selectedId === mark.id || group.includes(mark.id);
|
|
19916
19924
|
if (interval && mark.visibleIntervals?.length && !mark.visibleIntervals.includes(interval)) return null;
|
|
19917
19925
|
const clampedDecoration = !(mark.source === "user" || mark.kind === "level") || Boolean(mark.alert) || Boolean(mark.shared);
|
|
19918
|
-
if (!selected && !clampedDecoration && FINITE_KINDS.has(mark.kind) && offscreen(shown, view)) return null;
|
|
19926
|
+
if (!selected && !clampedDecoration && !mark.extendLeft && !mark.extendRight && FINITE_KINDS.has(mark.kind) && offscreen(shown, view)) return null;
|
|
19919
19927
|
return /* @__PURE__ */ React10.createElement(
|
|
19920
19928
|
DrawingShape,
|
|
19921
19929
|
{
|
|
@@ -19941,7 +19949,9 @@ function CandleChart({ candles, marks, indicators, expanded, resetToken, drawMod
|
|
|
19941
19949
|
fontSize: mark.fontSize,
|
|
19942
19950
|
bold: mark.bold,
|
|
19943
19951
|
italic: mark.italic,
|
|
19944
|
-
fillOpacity: mark.fillOpacity
|
|
19952
|
+
fillOpacity: mark.fillOpacity,
|
|
19953
|
+
extendLeft: mark.extendLeft,
|
|
19954
|
+
extendRight: mark.extendRight
|
|
19945
19955
|
}
|
|
19946
19956
|
);
|
|
19947
19957
|
}), /* @__PURE__ */ React10.createElement("g", { className: "dhl-fills" }, fills.map((event) => {
|
|
@@ -20017,7 +20027,7 @@ function CandleChart({ candles, marks, indicators, expanded, resetToken, drawMod
|
|
|
20017
20027
|
var React11 = __toESM(require("react"), 1);
|
|
20018
20028
|
var HISTORY_LIMIT = 100;
|
|
20019
20029
|
var GEOMETRY = ["price", "fromTime", "fromPrice", "toTime", "toPrice", "points"];
|
|
20020
|
-
var STYLE = ["color", "lineWidth", "lineStyle", "locked", "hidden", "shared", "alert", "rows", "valueArea", "levels", "visibleIntervals", "fontSize", "fillOpacity", "bold", "italic"];
|
|
20030
|
+
var STYLE = ["color", "lineWidth", "lineStyle", "locked", "hidden", "shared", "alert", "rows", "valueArea", "levels", "visibleIntervals", "fontSize", "fillOpacity", "bold", "italic", "extendLeft", "extendRight"];
|
|
20021
20031
|
var FLAGS = /* @__PURE__ */ new Set(["locked", "hidden", "shared", "alert"]);
|
|
20022
20032
|
function recreateRequest(mark) {
|
|
20023
20033
|
const out = { kind: mark.kind, label: mark.label, role: mark.role, coin: mark.coin, interval: mark.interval };
|
package/lib/chart-drawings.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type DrawingKind = 'level' | 'hray' | 'vline' | 'text' | 'trend' | 'ray' | 'extended' | 'fib' | 'rect' | 'measure' | 'channel' | 'long' | 'short' | 'fibext' | 'fibchannel' | 'fibtime' | 'gannfan' | 'pitchfork' | 'regression' | 'vprofile' | 'arrow' | 'callout' | 'circle' | 'triangle' | 'brush' | 'crossline' | 'pricelabel' | 'infoline' | 'trendangle' | 'pricerange' | 'daterange' | 'elliott' | 'elliottabc' | 'xabcd' | 'abcd' | 'headshoulders' | 'gannbox' | 'gannsquare' | 'schiff' | 'modschiff' | 'icon'
|
|
2
2
|
export type LineStyleName = 'solid' | 'dashed' | 'dotted'
|
|
3
|
-
export interface DrawingStyle { visibleIntervals?: string[]; fontSize?: number; bold?: boolean; italic?: boolean; fillOpacity?: number; levels?: number[]; rows?: number; valueArea?: number; color?: string; lineWidth?: number; lineStyle?: LineStyleName; locked?: boolean; hidden?: boolean; shared?: boolean; alert?: boolean }
|
|
3
|
+
export interface DrawingStyle { visibleIntervals?: string[]; fontSize?: number; bold?: boolean; italic?: boolean; extendLeft?: boolean; extendRight?: boolean; fillOpacity?: number; levels?: number[]; rows?: number; valueArea?: number; color?: string; lineWidth?: number; lineStyle?: LineStyleName; locked?: boolean; hidden?: boolean; shared?: boolean; alert?: boolean }
|
|
4
4
|
export declare const DRAWING_POINTS: Record<DrawingKind, number>
|
|
5
5
|
export declare const DRAWING_KINDS: DrawingKind[]
|
|
6
6
|
export declare const DRAWING_CLICKS: Record<DrawingKind, number>
|
package/lib/chart-drawings.js
CHANGED
|
@@ -106,7 +106,8 @@ export function linePriceAt(mark, time) {
|
|
|
106
106
|
if (!a) return null
|
|
107
107
|
if (mark.kind === 'hray') return time >= a.time ? a.price : null
|
|
108
108
|
if (!b || b.time === a.time) return null
|
|
109
|
-
|
|
109
|
+
// A trend line can be extended left and/or right (TradingView's per-line extend option).
|
|
110
|
+
if (mark.kind === 'trend' && ((!mark.extendLeft && time < Math.min(a.time, b.time)) || (!mark.extendRight && time > Math.max(a.time, b.time)))) return null
|
|
110
111
|
if (mark.kind === 'ray' && (time - a.time) * (b.time - a.time) < 0) return null
|
|
111
112
|
return a.price + (b.price - a.price) * (time - a.time) / (b.time - a.time)
|
|
112
113
|
}
|
|
@@ -206,6 +207,12 @@ export function drawingStyle(request) {
|
|
|
206
207
|
if (!Number.isInteger(size) || size < 10 || size > 32) throw new Error('字号必须为 10-32 的整数')
|
|
207
208
|
style.fontSize = size
|
|
208
209
|
}
|
|
210
|
+
for (const flag of ['extendLeft', 'extendRight']) {
|
|
211
|
+
if (request?.[flag] == null) continue
|
|
212
|
+
if (request?.kind != null && request.kind !== 'trend') throw new Error(`${flag} 只适用于 trend`)
|
|
213
|
+
if (typeof request[flag] !== 'boolean') throw new Error(`${flag} 必须为布尔值`)
|
|
214
|
+
style[flag] = request[flag]
|
|
215
|
+
}
|
|
209
216
|
for (const flag of ['bold', 'italic']) {
|
|
210
217
|
if (request?.[flag] == null) continue
|
|
211
218
|
if (request?.kind != null && !FONT_KINDS.includes(request.kind)) throw new Error(`${flag} 只适用于 ${FONT_KINDS.join('/')}`)
|
package/lib/remote.js
CHANGED
|
@@ -575,7 +575,7 @@ export class HyperRemote extends TypertRemoteService {
|
|
|
575
575
|
const fields = { ...drawingStyle({ ...patch, kind: current.kind }) }
|
|
576
576
|
if (patch?.alert === true) fields.alertTriggeredAt = undefined
|
|
577
577
|
// null clears a style back to its default (undo of a first restyle relies on this).
|
|
578
|
-
for (const key of ['color', 'lineWidth', 'lineStyle', 'rows', 'valueArea', 'levels', 'visibleIntervals', 'fontSize', 'fillOpacity', 'bold', 'italic']) if (key in patch && patch[key] === null) fields[key] = undefined
|
|
578
|
+
for (const key of ['color', 'lineWidth', 'lineStyle', 'rows', 'valueArea', 'levels', 'visibleIntervals', 'fontSize', 'fillOpacity', 'bold', 'italic', 'extendLeft', 'extendRight']) if (key in patch && patch[key] === null) fields[key] = undefined
|
|
579
579
|
if (geometryKeys.some((key) => key in patch)) Object.assign(fields, drawingGeometry(current.kind, merged))
|
|
580
580
|
if ('label' in patch) {
|
|
581
581
|
const label = String(patch.label ?? '').trim()
|
package/lib/tools.js
CHANGED
|
@@ -254,6 +254,7 @@ function buildTools(remote) {
|
|
|
254
254
|
lineWidth: { type: 'number', description: '画线线宽 1-4' },
|
|
255
255
|
visibleIntervals: { type: 'array', items: { type: 'string' }, description: '只在这些周期显示(如 ["4h","1d"]);省略=所有周期' },
|
|
256
256
|
fontSize: { type: 'number', description: 'kind=text/callout:字号 10-32' },
|
|
257
|
+
extendLeft: { type: 'boolean', description: 'kind=trend:向左延长' }, extendRight: { type: 'boolean', description: 'kind=trend:向右延长' },
|
|
257
258
|
bold: { type: 'boolean', description: 'kind=text/callout:粗体' }, italic: { type: 'boolean', description: 'kind=text/callout:斜体' },
|
|
258
259
|
fillOpacity: { type: 'number', description: '矩形/圆/三角形/通道/斐波那契/区间等的背景填充透明度 0-0.6(0=无填充)' },
|
|
259
260
|
levels: { type: 'array', items: { type: 'number' }, description: 'kind=fib/fibext/fibchannel:自定义斐波那契层级,如 [0,0.382,0.5,0.618,1,1.618]' },
|
|
@@ -310,7 +311,7 @@ function buildTools(remote) {
|
|
|
310
311
|
return { text: `已移除均线:${maLabel(removed)}(${removed.id})`, line: removed }
|
|
311
312
|
}
|
|
312
313
|
if (args?.action === 'update') {
|
|
313
|
-
const patch = Object.fromEntries(['points', 'price', 'fromTime', 'fromPrice', 'toTime', 'toPrice', 'label', 'color', 'lineWidth', 'lineStyle', 'locked', 'hidden', 'shared', 'alert', 'rows', 'valueArea', 'levels', 'visibleIntervals', 'fontSize', 'fillOpacity', 'bold', 'italic'].filter((key) => args?.[key] != null).map((key) => [key, args[key]]))
|
|
314
|
+
const patch = Object.fromEntries(['points', 'price', 'fromTime', 'fromPrice', 'toTime', 'toPrice', 'label', 'color', 'lineWidth', 'lineStyle', 'locked', 'hidden', 'shared', 'alert', 'rows', 'valueArea', 'levels', 'visibleIntervals', 'fontSize', 'fillOpacity', 'bold', 'italic', 'extendLeft', 'extendRight'].filter((key) => args?.[key] != null).map((key) => [key, args[key]]))
|
|
314
315
|
const mark = remote.editChartMark(args?.id, patch, sessionId)
|
|
315
316
|
return { text: `已更新${DRAWING_NAMES[mark.kind] ?? mark.kind}:${mark.label}(${mark.id})`, mark }
|
|
316
317
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-hyperliquid",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
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",
|