From b40f4ceafce19ee34e51ef98a1d4bff2820d9e84 Mon Sep 17 00:00:00 2001 From: Porter Date: Sat, 27 Sep 2025 17:43:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A8=AA=E7=89=88=E6=9B=B4=E5=A5=BD=E4=B8=80?= =?UTF-8?q?=E4=BA=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- EMA52横线版.pine | 213 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 147 insertions(+), 66 deletions(-) diff --git a/EMA52横线版.pine b/EMA52横线版.pine index 8b6985d..bad4e67 100644 --- a/EMA52横线版.pine +++ b/EMA52横线版.pine @@ -14,78 +14,78 @@ padPercent = input.float(2.0, "可视边界留白(%)", minval=0.0, maxval labelBgAlpha = input.int(85, "标签背景透明(0-100)", minval=0, maxval=100, group="标注") labelSize = input.string("tiny", "标签字号", options=["tiny","small","normal","large","huge"], group="标注") labelOffsetBars = input.int(2, "标签右移K线的距离(根数)", minval=0, maxval=50, group="标注") +showLegend = input.bool(true, "显示右侧图例(周期映射)", group="标注") // ============ 按线控制(可见性/颜色/宽度/样式) ============ -// 为满足 Pine 对常量标题的要求,逐一声明。 -// 长级别 +// 固定时框命名,满足“用 1m/3m/… 显示”的需求 groupHTF = "按线控制 - 长级别" -hShow1 = input.bool(true, "显示 HTF1", group=groupHTF) -hColor1 = input.color(color.new(color.teal, 0), "颜色 HTF1", group=groupHTF) -hWidth1 = input.int(1, "线宽 HTF1", minval=1, maxval=4, group=groupHTF) -hStyle1 = input.string("dotted", "样式 HTF1", options=["solid","dashed","dotted"], group=groupHTF) -hShow2 = input.bool(true, "显示 HTF2", group=groupHTF) -hColor2 = input.color(color.new(color.orange, 0), "颜色 HTF2", group=groupHTF) -hWidth2 = input.int(1, "线宽 HTF2", minval=1, maxval=4, group=groupHTF) -hStyle2 = input.string("dotted", "样式 HTF2", options=["solid","dashed","dotted"], group=groupHTF) -hShow3 = input.bool(true, "显示 HTF3", group=groupHTF) -hColor3 = input.color(color.new(color.fuchsia,0), "颜色 HTF3", group=groupHTF) -hWidth3 = input.int(1, "线宽 HTF3", minval=1, maxval=4, group=groupHTF) -hStyle3 = input.string("dotted", "样式 HTF3", options=["solid","dashed","dotted"], group=groupHTF) -hShow4 = input.bool(true, "显示 HTF4", group=groupHTF) -hColor4 = input.color(color.new(color.aqua, 0), "颜色 HTF4", group=groupHTF) -hWidth4 = input.int(1, "线宽 HTF4", minval=1, maxval=4, group=groupHTF) -hStyle4 = input.string("dotted", "样式 HTF4", options=["solid","dashed","dotted"], group=groupHTF) -hShow5 = input.bool(true, "显示 HTF5", group=groupHTF) -hColor5 = input.color(color.new(color.yellow, 0), "颜色 HTF5", group=groupHTF) -hWidth5 = input.int(1, "线宽 HTF5", minval=1, maxval=4, group=groupHTF) -hStyle5 = input.string("dotted", "样式 HTF5", options=["solid","dashed","dotted"], group=groupHTF) -hShow6 = input.bool(true, "显示 HTF6", group=groupHTF) -hColor6 = input.color(color.new(color.purple, 0), "颜色 HTF6", group=groupHTF) -hWidth6 = input.int(1, "线宽 HTF6", minval=1, maxval=4, group=groupHTF) -hStyle6 = input.string("dotted", "样式 HTF6", options=["solid","dashed","dotted"], group=groupHTF) -hShow7 = input.bool(true, "显示 HTF7", group=groupHTF) -hColor7 = input.color(color.new(color.lime, 0), "颜色 HTF7", group=groupHTF) -hWidth7 = input.int(1, "线宽 HTF7", minval=1, maxval=4, group=groupHTF) -hStyle7 = input.string("dotted", "样式 HTF7", options=["solid","dashed","dotted"], group=groupHTF) -hShow8 = input.bool(true, "显示 HTF8", group=groupHTF) -hColor8 = input.color(color.new(color.red, 0), "颜色 HTF8", group=groupHTF) -hWidth8 = input.int(1, "线宽 HTF8", minval=1, maxval=4, group=groupHTF) -hStyle8 = input.string("dotted", "样式 HTF8", options=["solid","dashed","dotted"], group=groupHTF) -hShow9 = input.bool(true, "显示 HTF9", group=groupHTF) -hColor9 = input.color(color.new(color.blue, 0), "颜色 HTF9", group=groupHTF) -hWidth9 = input.int(1, "线宽 HTF9", minval=1, maxval=4, group=groupHTF) -hStyle9 = input.string("dotted", "样式 HTF9", options=["solid","dashed","dotted"], group=groupHTF) -hShow10 = input.bool(true, "显示 HTF10", group=groupHTF) -hColor10 = input.color(color.new(color.navy, 0), "颜色 HTF10", group=groupHTF) -hWidth10 = input.int(1, "线宽 HTF10", minval=1, maxval=4, group=groupHTF) -hStyle10 = input.string("dotted", "样式 HTF10", options=["solid","dashed","dotted"], group=groupHTF) -hShow11 = input.bool(true, "显示 HTF11", group=groupHTF) -hColor11 = input.color(color.new(color.maroon, 0), "颜色 HTF11", group=groupHTF) -hWidth11 = input.int(1, "线宽 HTF11", minval=1, maxval=4, group=groupHTF) -hStyle11 = input.string("dotted", "样式 HTF11", options=["solid","dashed","dotted"], group=groupHTF) -hShow12 = input.bool(true, "显示 HTF12", group=groupHTF) -hColor12 = input.color(color.new(color.silver, 0), "颜色 HTF12", group=groupHTF) -hWidth12 = input.int(1, "线宽 HTF12", minval=1, maxval=4, group=groupHTF) -hStyle12 = input.string("dotted", "样式 HTF12", options=["solid","dashed","dotted"], group=groupHTF) +hShow1 = input.bool(true, "显示 30m", group=groupHTF) +hColor1 = input.color(color.new(color.teal, 0), "颜色 30m", group=groupHTF) +hWidth1 = input.int(1, "线宽 30m", minval=1, maxval=4, group=groupHTF) +hStyle1 = input.string("dotted", "样式 30m", options=["solid","dashed","dotted"], group=groupHTF) +hShow2 = input.bool(true, "显示 45m", group=groupHTF) +hColor2 = input.color(color.new(color.orange, 0), "颜色 45m", group=groupHTF) +hWidth2 = input.int(1, "线宽 45m", minval=1, maxval=4, group=groupHTF) +hStyle2 = input.string("dotted", "样式 45m", options=["solid","dashed","dotted"], group=groupHTF) +hShow3 = input.bool(true, "显示 1h", group=groupHTF) +hColor3 = input.color(color.new(color.fuchsia,0), "颜色 1h", group=groupHTF) +hWidth3 = input.int(1, "线宽 1h", minval=1, maxval=4, group=groupHTF) +hStyle3 = input.string("dotted", "样式 1h", options=["solid","dashed","dotted"], group=groupHTF) +hShow4 = input.bool(true, "显示 2h", group=groupHTF) +hColor4 = input.color(color.new(color.aqua, 0), "颜色 2h", group=groupHTF) +hWidth4 = input.int(1, "线宽 2h", minval=1, maxval=4, group=groupHTF) +hStyle4 = input.string("dotted", "样式 2h", options=["solid","dashed","dotted"], group=groupHTF) +hShow5 = input.bool(true, "显示 4h", group=groupHTF) +hColor5 = input.color(color.new(color.yellow, 0), "颜色 4h", group=groupHTF) +hWidth5 = input.int(1, "线宽 4h", minval=1, maxval=4, group=groupHTF) +hStyle5 = input.string("dotted", "样式 4h", options=["solid","dashed","dotted"], group=groupHTF) +hShow6 = input.bool(true, "显示 6h", group=groupHTF) +hColor6 = input.color(color.new(color.purple, 0), "颜色 6h", group=groupHTF) +hWidth6 = input.int(1, "线宽 6h", minval=1, maxval=4, group=groupHTF) +hStyle6 = input.string("dotted", "样式 6h", options=["solid","dashed","dotted"], group=groupHTF) +hShow7 = input.bool(true, "显示 8h", group=groupHTF) +hColor7 = input.color(color.new(color.lime, 0), "颜色 8h", group=groupHTF) +hWidth7 = input.int(1, "线宽 8h", minval=1, maxval=4, group=groupHTF) +hStyle7 = input.string("dotted", "样式 8h", options=["solid","dashed","dotted"], group=groupHTF) +hShow8 = input.bool(true, "显示 12h", group=groupHTF) +hColor8 = input.color(color.new(color.red, 0), "颜色 12h", group=groupHTF) +hWidth8 = input.int(1, "线宽 12h", minval=1, maxval=4, group=groupHTF) +hStyle8 = input.string("dotted", "样式 12h", options=["solid","dashed","dotted"], group=groupHTF) +hShow9 = input.bool(true, "显示 1D", group=groupHTF) +hColor9 = input.color(color.new(color.blue, 0), "颜色 1D", group=groupHTF) +hWidth9 = input.int(1, "线宽 1D", minval=1, maxval=4, group=groupHTF) +hStyle9 = input.string("dotted", "样式 1D", options=["solid","dashed","dotted"], group=groupHTF) +hShow10 = input.bool(true, "显示 2D", group=groupHTF) +hColor10 = input.color(color.new(color.navy, 0), "颜色 2D", group=groupHTF) +hWidth10 = input.int(1, "线宽 2D", minval=1, maxval=4, group=groupHTF) +hStyle10 = input.string("dotted", "样式 2D", options=["solid","dashed","dotted"], group=groupHTF) +hShow11 = input.bool(true, "显示 1W", group=groupHTF) +hColor11 = input.color(color.new(color.maroon, 0), "颜色 1W", group=groupHTF) +hWidth11 = input.int(1, "线宽 1W", minval=1, maxval=4, group=groupHTF) +hStyle11 = input.string("dotted", "样式 1W", options=["solid","dashed","dotted"], group=groupHTF) +hShow12 = input.bool(true, "显示 1M", group=groupHTF) +hColor12 = input.color(color.new(color.silver, 0), "颜色 1M", group=groupHTF) +hWidth12 = input.int(1, "线宽 1M", minval=1, maxval=4, group=groupHTF) +hStyle12 = input.string("dotted", "样式 1M", options=["solid","dashed","dotted"], group=groupHTF) // 次级别 groupLTF = "按线控制 - 次级别" -lShow1 = input.bool(true, "显示 LTF1", group=groupLTF) -lColor1 = input.color(color.new(color.teal, 30), "颜色 LTF1", group=groupLTF) -lWidth1 = input.int(1, "线宽 LTF1", minval=1, maxval=4, group=groupLTF) -lStyle1 = input.string("dotted", "样式 LTF1", options=["solid","dashed","dotted"], group=groupLTF) -lShow2 = input.bool(true, "显示 LTF2", group=groupLTF) -lColor2 = input.color(color.new(color.orange, 30),"颜色 LTF2", group=groupLTF) -lWidth2 = input.int(1, "线宽 LTF2", minval=1, maxval=4, group=groupLTF) -lStyle2 = input.string("dotted", "样式 LTF2", options=["solid","dashed","dotted"], group=groupLTF) -lShow3 = input.bool(true, "显示 LTF3", group=groupLTF) -lColor3 = input.color(color.new(color.fuchsia,30),"颜色 LTF3", group=groupLTF) -lWidth3 = input.int(1, "线宽 LTF3", minval=1, maxval=4, group=groupLTF) -lStyle3 = input.string("dotted", "样式 LTF3", options=["solid","dashed","dotted"], group=groupLTF) -lShow4 = input.bool(true, "显示 LTF4", group=groupLTF) -lColor4 = input.color(color.new(color.aqua, 30),"颜色 LTF4", group=groupLTF) -lWidth4 = input.int(1, "线宽 LTF4", minval=1, maxval=4, group=groupLTF) -lStyle4 = input.string("dotted", "样式 LTF4", options=["solid","dashed","dotted"], group=groupLTF) +lShow1 = input.bool(true, "显示 1m", group=groupLTF) +lColor1 = input.color(color.new(color.teal, 30), "颜色 1m", group=groupLTF) +lWidth1 = input.int(1, "线宽 1m", minval=1, maxval=4, group=groupLTF) +lStyle1 = input.string("dotted", "样式 1m", options=["solid","dashed","dotted"], group=groupLTF) +lShow2 = input.bool(true, "显示 3m", group=groupLTF) +lColor2 = input.color(color.new(color.orange, 30),"颜色 3m", group=groupLTF) +lWidth2 = input.int(1, "线宽 3m", minval=1, maxval=4, group=groupLTF) +lStyle2 = input.string("dotted", "样式 3m", options=["solid","dashed","dotted"], group=groupLTF) +lShow3 = input.bool(true, "显示 5m", group=groupLTF) +lColor3 = input.color(color.new(color.fuchsia,30),"颜色 5m", group=groupLTF) +lWidth3 = input.int(1, "线宽 5m", minval=1, maxval=4, group=groupLTF) +lStyle3 = input.string("dotted", "样式 5m", options=["solid","dashed","dotted"], group=groupLTF) +lShow4 = input.bool(true, "显示 15m", group=groupLTF) +lColor4 = input.color(color.new(color.aqua, 30),"颜色 15m", group=groupLTF) +lWidth4 = input.int(1, "线宽 15m", minval=1, maxval=4, group=groupLTF) +lStyle4 = input.string("dotted", "样式 15m", options=["solid","dashed","dotted"], group=groupLTF) // 样式字符串到 line.style 的映射 f_lineStyle(string s) => s == "solid" ? line.style_solid : s == "dashed" ? line.style_dashed : line.style_dotted @@ -101,6 +101,27 @@ f_ltfColor(int i) => i == 0 ? lColor1 : i == 1 ? lColor2 : i == 2 ? lColor3 : lC f_ltfWidth(int i) => i == 0 ? lWidth1 : i == 1 ? lWidth2 : i == 2 ? lWidth3 : lWidth4 f_ltfStyle(int i) => f_lineStyle(i == 0 ? lStyle1 : i == 1 ? lStyle2 : i == 2 ? lStyle3 : lStyle4) +// 固定时框键列表(与上面输入顺序一致) +var string[] HTF_KEYS = array.new_string() +var string[] LTF_KEYS = array.new_string() +if barstate.isfirst and array.size(HTF_KEYS) == 0 + array.push(HTF_KEYS, "30") + array.push(HTF_KEYS, "45") + array.push(HTF_KEYS, "60") + array.push(HTF_KEYS, "120") + array.push(HTF_KEYS, "240") + array.push(HTF_KEYS, "360") + array.push(HTF_KEYS, "480") + array.push(HTF_KEYS, "720") + array.push(HTF_KEYS, "D") + array.push(HTF_KEYS, "2D") + array.push(HTF_KEYS, "W") + array.push(HTF_KEYS, "M") + array.push(LTF_KEYS, "1") + array.push(LTF_KEYS, "3") + array.push(LTF_KEYS, "5") + array.push(LTF_KEYS, "15") + // ============ 工具 ============ f_strToSize(string s) => switch s "tiny" => size.tiny @@ -200,6 +221,38 @@ for i = 0 to array.size(ALL_RES) - 1 else if rsec < curResSec array.push(ltfRes, res) +// 重新按预设优先级对选中的 HTF/LTF 排序以匹配输入面板顺序(Pine 不支持自定义比较器,用手动重排) +f_contains(string[] arr, string key) => + found = false + for ii = 0 to array.size(arr) - 1 + if array.get(arr, ii) == key + found := true + break + found + +// 长级别重排 +var string[] _htfOrdered = array.new_string() +array.clear(_htfOrdered) +for ii = 0 to array.size(HTF_KEYS) - 1 + key = array.get(HTF_KEYS, ii) + if f_contains(htfRes, key) + array.push(_htfOrdered, key) +// 用重排后的覆盖原数组 +array.clear(htfRes) +for ii = 0 to array.size(_htfOrdered) - 1 + array.push(htfRes, array.get(_htfOrdered, ii)) + +// 次级别重排 +var string[] _ltfOrdered = array.new_string() +array.clear(_ltfOrdered) +for ii = 0 to array.size(LTF_KEYS) - 1 + key = array.get(LTF_KEYS, ii) + if f_contains(ltfRes, key) + array.push(_ltfOrdered, key) +array.clear(ltfRes) +for ii = 0 to array.size(_ltfOrdered) - 1 + array.push(ltfRes, array.get(_ltfOrdered, ii)) + var string[] ltfSel = array.new_string() array.clear(ltfSel) ltfsz = array.size(ltfRes) @@ -251,6 +304,7 @@ var label[] htfLabels = array.new_label() var label[] ltfLabels = array.new_label() var string lastTicker = na var string lastTf = na +var table legendTbl = na if barstate.isfirst for _i = 0 to 11 array.push(htfLines, na) @@ -260,6 +314,8 @@ if barstate.isfirst array.push(ltfLabels, na) lastTicker := syminfo.tickerid lastTf := timeframe.period + // 预建图例表(固定行列),右上角显示 + legendTbl := table.new(position.top_right, 2, 20, frame_color=color.new(color.black, 100), frame_width=1) // 清理:品种或周期变化 symbolChanged = lastTicker != syminfo.tickerid @@ -288,6 +344,31 @@ if symbolChanged or tfChanged // 更新:在最后一根柱上画从最左端到最右端的水平线(仅一段),并在右侧放标签 if barstate.islast + // 更新图例 + if showLegend and not na(legendTbl) + // 先清空 + for r = 0 to 19 + table.cell(legendTbl, 0, r, "", text_color=color.new(color.white, 0), text_halign=text.align_left, bgcolor=color.new(color.black, 100)) + table.cell(legendTbl, 1, r, "", text_color=color.new(color.white, 0), text_halign=text.align_right, bgcolor=color.new(color.black, 100)) + row = 0 + // 长级别 + for i = 0 to 11 + v = array.get(htfVals, i) + if enableHTF and i < htfCountSelected and f_htfShow(i) and not na(v) and f_inRange(v) + tfStr = array.get(htfRes, i) + col = f_htfColor(i) + table.cell(legendTbl, 0, row, f_prettyTf(tfStr), text_color=col, text_halign=text.align_left) + table.cell(legendTbl, 1, row, str.tostring(v, format.mintick), text_color=col, text_halign=text.align_right) + row += 1 + // 次级别 + for i = 0 to 3 + v = array.get(ltfVals, i) + if enableLTF and i < ltfCountSelected and f_ltfShow(i) and not na(v) and f_inRange(v) + tfStr = array.get(ltfSel, i) + col = f_ltfColor(i) + table.cell(legendTbl, 0, row, f_prettyTf(tfStr), text_color=col, text_halign=text.align_left) + table.cell(legendTbl, 1, row, str.tostring(v, format.mintick), text_color=col, text_halign=text.align_right) + row += 1 // 长级别 for i = 0 to 11 // 颜色/线宽/样式来自按线控制面板