移植合并K、分型、笔、线段、中枢和买卖点,并加上均线与 ChanMACD 的 SD/CD 标记。 Co-authored-by: Cursor <cursoragent@cursor.com>
1090 lines
47 KiB
Plaintext
1090 lines
47 KiB
Plaintext
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
|
||
// 缠论画法 — 移植自 chan 引擎(chanlun/pipeline/builders)
|
||
// K线包含 → 分型 → 笔 → 线段 → 中枢 → 买卖点
|
||
// 画法颜色与 chan/web 主周期叠层一致
|
||
|
||
//@version=6
|
||
indicator("缠论画法(chan引擎)", shorttitle="缠论chan", overlay=true, max_lines_count=500, max_labels_count=500, max_boxes_count=500, max_bars_back=5000)
|
||
|
||
// ============================================================================
|
||
// 参数
|
||
// ============================================================================
|
||
show_merged_k = input.bool(false, "显示合并K线", group="显示")
|
||
show_fenxing = input.bool(true, "显示分型", group="显示")
|
||
show_fx_box = input.bool(true, "显示分型框", group="显示")
|
||
show_bi = input.bool(true, "显示笔", group="显示")
|
||
show_bi_pending = input.bool(true, "显示未完成笔", group="显示")
|
||
show_xianduan = input.bool(true, "显示线段", group="显示")
|
||
show_xd_pending = input.bool(true, "显示未完成线段", group="显示")
|
||
show_bi_zs = input.bool(true, "显示笔中枢", group="显示")
|
||
show_xd_zs = input.bool(true, "显示线段中枢", group="显示")
|
||
show_bsp = input.bool(true, "显示买卖点", group="显示")
|
||
show_info = input.bool(true, "显示结构计数", group="显示")
|
||
show_ema26 = input.bool(true, "显示EMA26", group="均线")
|
||
show_ema52 = input.bool(true, "显示EMA52", group="均线")
|
||
show_ema104 = input.bool(true, "显示EMA104", group="均线")
|
||
show_ema158 = input.bool(true, "显示EMA158", group="均线")
|
||
show_ma30 = input.bool(true, "显示MA30", group="均线")
|
||
show_ma250 = input.bool(true, "显示MA250", group="均线")
|
||
show_macd_div = input.bool(true, "显示MACD背离SD/CD", group="MACD背离")
|
||
|
||
bi_klc_min = input.int(4, "笔最小合并K线数", group="缠论参数", tooltip="结合律:相邻分型间隔,对应 chan 的 bi_klc_min=4")
|
||
|
||
color_bi_up = input.color(#dc3545, "上升笔", group="颜色")
|
||
color_bi_down = input.color(#28a745, "下降笔", group="颜色")
|
||
color_bi_pending = input.color(#FF0000, "未完成笔", group="颜色")
|
||
color_xd_up = input.color(#FF6B6B, "上升线段", group="颜色")
|
||
color_xd_down = input.color(#4CAF50, "下降线段", group="颜色")
|
||
color_xd_pending = input.color(#FF0000, "未完成线段", group="颜色")
|
||
color_bi_zs = input.color(#9C27B0, "笔中枢", group="颜色")
|
||
color_xd_zs = input.color(#FF9800, "线段中枢", group="颜色")
|
||
color_fx_top = input.color(#dc3545, "顶分型", group="颜色")
|
||
color_fx_bot = input.color(#28a745, "底分型", group="颜色")
|
||
color_ema26 = input.color(color.yellow, "EMA26", group="均线颜色")
|
||
color_ema52 = input.color(color.orange, "EMA52", group="均线颜色")
|
||
color_ema104 = input.color(color.blue, "EMA104", group="均线颜色")
|
||
color_ema158 = input.color(color.purple, "EMA158", group="均线颜色")
|
||
color_ma30 = input.color(color.gray, "MA30", group="均线颜色")
|
||
color_ma250 = input.color(color.fuchsia, "MA250", group="均线颜色")
|
||
|
||
[macd_line, signal_line, macd_hist] = ta.macd(close, 12, 26, 9)
|
||
|
||
ema26 = ta.ema(close, 26)
|
||
ema52 = ta.ema(close, 52)
|
||
ema104 = ta.ema(close, 104)
|
||
ema158 = ta.ema(close, 158)
|
||
ma30 = ta.sma(close, 30)
|
||
ma250 = ta.sma(close, 250)
|
||
|
||
plot(show_ema26 ? ema26 : na, "EMA26", color=color_ema26, linewidth=1)
|
||
plot(show_ema52 ? ema52 : na, "EMA52", color=color_ema52, linewidth=2)
|
||
plot(show_ema104 ? ema104 : na, "EMA104", color=color_ema104, linewidth=2)
|
||
plot(show_ema158 ? ema158 : na, "EMA158", color=color_ema158, linewidth=2)
|
||
plot(show_ma30 ? ma30 : na, "MA30", color=color_ma30, linewidth=1)
|
||
plot(show_ma250 ? ma250 : na, "MA250", color=color_ma250, linewidth=2)
|
||
|
||
// ChanMACD:CD=同柱波内 continue_div;SD=同向柱波之间 separate_div
|
||
var int wave_dir = 0
|
||
var int wave_len = 0
|
||
var float wave_peak = na
|
||
var int unit_dir = 0
|
||
var float unit_peak = na
|
||
var int unit_sd_n = 0
|
||
sd_n = 0
|
||
cd_hit = false
|
||
if macd_line != 0 or signal_line != 0 or macd_hist != 0
|
||
cur_dir = macd_hist > 0 ? 1 : -1
|
||
if wave_dir == 0
|
||
wave_dir := cur_dir
|
||
wave_len := 1
|
||
wave_peak := na
|
||
else if cur_dir == wave_dir
|
||
wave_len += 1
|
||
if wave_len >= 3 and math.abs(macd_hist[1]) > math.abs(macd_hist[2]) and math.abs(macd_hist[1]) > math.abs(macd_hist)
|
||
if na(wave_peak) or math.abs(macd_hist[1]) > math.abs(wave_peak)
|
||
wave_peak := macd_hist[1]
|
||
if unit_dir == wave_dir and not na(unit_peak) and math.abs(wave_peak) < math.abs(unit_peak)
|
||
if macd_line[1] * macd_hist[1] > 0
|
||
unit_sd_n += 1
|
||
sd_n := unit_sd_n
|
||
else if macd_line[1] * macd_hist[1] > 0 and signal_line[1] * macd_hist[1] > 0
|
||
cd_hit := true
|
||
else
|
||
if wave_dir == unit_dir and not na(wave_peak)
|
||
if na(unit_peak) or math.abs(wave_peak) >= math.abs(unit_peak)
|
||
unit_peak := wave_peak
|
||
wave_dir := cur_dir
|
||
wave_len := 1
|
||
wave_peak := na
|
||
if signal_line[1] >= 0 and signal_line < 0
|
||
unit_dir := -1
|
||
unit_peak := wave_dir == -1 ? wave_peak : na
|
||
unit_sd_n := 0
|
||
else if signal_line[1] <= 0 and signal_line > 0
|
||
unit_dir := 1
|
||
unit_peak := wave_dir == 1 ? wave_peak : na
|
||
unit_sd_n := 0
|
||
|
||
plotshape(show_macd_div and sd_n == 1 and macd_line[1] > 0, title="SD1上", style=shape.triangleup, location=location.abovebar, color=#03a9f4, offset=-1, text="SD1", textcolor=#03a9f4, size=size.tiny)
|
||
plotshape(show_macd_div and sd_n == 1 and macd_line[1] < 0, title="SD1下", style=shape.triangleup, location=location.belowbar, color=#03a9f4, offset=-1, text="SD1", textcolor=#03a9f4, size=size.tiny)
|
||
plotshape(show_macd_div and sd_n == 2 and macd_line[1] > 0, title="SD2上", style=shape.triangleup, location=location.abovebar, color=#03a9f4, offset=-1, text="SD2", textcolor=#03a9f4, size=size.tiny)
|
||
plotshape(show_macd_div and sd_n == 2 and macd_line[1] < 0, title="SD2下", style=shape.triangleup, location=location.belowbar, color=#03a9f4, offset=-1, text="SD2", textcolor=#03a9f4, size=size.tiny)
|
||
plotshape(show_macd_div and sd_n >= 3 and macd_line[1] > 0, title="SD上", style=shape.triangleup, location=location.abovebar, color=#03a9f4, offset=-1, text="SD", textcolor=#03a9f4, size=size.tiny)
|
||
plotshape(show_macd_div and sd_n >= 3 and macd_line[1] < 0, title="SD下", style=shape.triangleup, location=location.belowbar, color=#03a9f4, offset=-1, text="SD", textcolor=#03a9f4, size=size.tiny)
|
||
plotshape(show_macd_div and cd_hit and macd_line[1] > 0, title="CD上", style=shape.triangledown, location=location.abovebar, color=#ff9800, offset=-1, text="CD", textcolor=#ff9800, size=size.tiny)
|
||
plotshape(show_macd_div and cd_hit and macd_line[1] < 0, title="CD下", style=shape.triangledown, location=location.belowbar, color=#ff9800, offset=-1, text="CD", textcolor=#ff9800, size=size.tiny)
|
||
|
||
// ============================================================================
|
||
// 合并K线状态
|
||
// ============================================================================
|
||
var float[] kh = array.new<float>()
|
||
var float[] kl = array.new<float>()
|
||
var float[] ko = array.new<float>()
|
||
var float[] kc = array.new<float>()
|
||
var float[] km = array.new<float>()
|
||
var int[] ks = array.new<int>()
|
||
var int[] ke = array.new<int>()
|
||
var int[] kd = array.new<int>()
|
||
|
||
// 结构缓存(仅在最后一根重建)
|
||
var int[] fx_idx = array.new<int>()
|
||
var int[] fx_typ = array.new<int>()
|
||
var float[] fx_px = array.new<float>()
|
||
var int[] fx_bar = array.new<int>()
|
||
|
||
var int[] bi_s = array.new<int>()
|
||
var int[] bi_e = array.new<int>()
|
||
var int[] bi_d = array.new<int>()
|
||
var int[] bi_sure = array.new<int>()
|
||
var float[] bi_h = array.new<float>()
|
||
var float[] bi_l = array.new<float>()
|
||
var float[] bi_macd = array.new<float>()
|
||
|
||
var int[] xd_s = array.new<int>()
|
||
var int[] xd_e = array.new<int>()
|
||
var int[] xd_d = array.new<int>()
|
||
var int[] xd_sure = array.new<int>()
|
||
var float[] xd_h = array.new<float>()
|
||
var float[] xd_l = array.new<float>()
|
||
|
||
var float[] feat_hh = array.new<float>()
|
||
var float[] feat_ll = array.new<float>()
|
||
var int[] feat_bi = array.new<int>()
|
||
var float[] us_hh = array.new<float>()
|
||
var float[] us_ll = array.new<float>()
|
||
var int[] us_bi = array.new<int>()
|
||
|
||
var int[] zs_s = array.new<int>()
|
||
var int[] zs_e = array.new<int>()
|
||
var float[] zs_zg = array.new<float>()
|
||
var float[] zs_zd = array.new<float>()
|
||
var float[] zs_gg = array.new<float>()
|
||
var float[] zs_dd = array.new<float>()
|
||
var int[] zs_sure = array.new<int>()
|
||
var int[] zs_dir = array.new<int>()
|
||
|
||
var int[] xzs_s = array.new<int>()
|
||
var int[] xzs_e = array.new<int>()
|
||
var float[] xzs_zg = array.new<float>()
|
||
var float[] xzs_zd = array.new<float>()
|
||
var int[] xzs_sure = array.new<int>()
|
||
var int[] xzs_dir = array.new<int>()
|
||
|
||
var int[] bsp_bar = array.new<int>()
|
||
var float[] bsp_px = array.new<float>()
|
||
var int[] bsp_kind = array.new<int>()
|
||
var string[] bsp_txt = array.new<string>()
|
||
|
||
var table info_tbl = table.new(position.top_right, 2, 7, bgcolor=color.new(color.black, 70), border_width=1)
|
||
|
||
var int last_top = -1
|
||
var int last_bot = -1
|
||
var line pending_bi_ln = na
|
||
var line pending_xd_ln = na
|
||
var box[] zs_boxes = array.new<box>()
|
||
var line[] zs_gg_lns = array.new<line>()
|
||
var line[] zs_dd_lns = array.new<line>()
|
||
var box[] xzs_boxes = array.new<box>()
|
||
|
||
|
||
// ============================================================================
|
||
// 工具函数(必须在全局)
|
||
// ============================================================================
|
||
klc_included(ph, pl, ch, cl) =>
|
||
bool inc = false
|
||
int mode = 0
|
||
if ph >= ch
|
||
if pl <= cl
|
||
inc := true
|
||
mode := 1
|
||
else if ph == ch
|
||
inc := true
|
||
mode := 2
|
||
else if pl >= cl
|
||
inc := true
|
||
mode := 3
|
||
[inc, mode]
|
||
|
||
is_top_fx(h1, l1, h2, l2, h3, l3) =>
|
||
h2 > h1 and h2 > h3 and l2 > l1 and l2 > l3
|
||
|
||
is_bot_fx(h1, l1, h2, l2, h3, l3) =>
|
||
l2 < l1 and l2 < l3 and h2 < h1 and h2 < h3
|
||
|
||
sbi_included(sh, sl, bh, bl) =>
|
||
sh > bh and sl < bl
|
||
|
||
in_xwin(x) =>
|
||
not na(x) and bar_index - x < 5000
|
||
|
||
push_fx(ki, typ) =>
|
||
array.push(fx_idx, ki)
|
||
array.push(fx_typ, typ)
|
||
array.push(fx_px, typ == 1 ? array.get(kh, ki) : array.get(kl, ki))
|
||
array.push(fx_bar, array.get(ke, ki))
|
||
0
|
||
|
||
fx_has(ki) =>
|
||
found = false
|
||
n = array.size(fx_idx)
|
||
if n > 0
|
||
for j = 0 to n - 1
|
||
if array.get(fx_idx, j) == ki
|
||
found := true
|
||
found
|
||
|
||
sync_xd_hl(idx) =>
|
||
// 对齐 ChanSEG:涨段 high=终点笔高 low=起点笔低;跌段 high=起点笔高 low=终点笔低
|
||
s = array.get(xd_s, idx)
|
||
e = array.get(xd_e, idx)
|
||
d = array.get(xd_d, idx)
|
||
if d == 1
|
||
array.set(xd_h, idx, array.get(bi_h, e))
|
||
array.set(xd_l, idx, array.get(bi_l, s))
|
||
else
|
||
array.set(xd_h, idx, array.get(bi_h, s))
|
||
array.set(xd_l, idx, array.get(bi_l, e))
|
||
0
|
||
|
||
push_xd(s, e, d, sure) =>
|
||
array.push(xd_s, s)
|
||
array.push(xd_e, e)
|
||
array.push(xd_d, d)
|
||
array.push(xd_sure, sure)
|
||
if d == 1
|
||
array.push(xd_h, array.get(bi_h, e))
|
||
array.push(xd_l, array.get(bi_l, s))
|
||
else
|
||
array.push(xd_h, array.get(bi_h, s))
|
||
array.push(xd_l, array.get(bi_l, e))
|
||
0
|
||
|
||
finish_xd(end_i, sure) =>
|
||
xn = array.size(xd_s)
|
||
if xn > 0 and end_i >= array.get(xd_s, xn - 1)
|
||
array.set(xd_e, xn - 1, end_i)
|
||
array.set(xd_sure, xn - 1, sure)
|
||
sync_xd_hl(xn - 1)
|
||
0
|
||
|
||
sbi_try_include(hs, ls, bh, bl, dir) =>
|
||
inc = false
|
||
n = array.size(hs)
|
||
if n > 0
|
||
if array.get(hs, n - 1) > bh and array.get(ls, n - 1) < bl
|
||
if dir == -1
|
||
array.set(ls, n - 1, bl)
|
||
else
|
||
array.set(hs, n - 1, bh)
|
||
inc := true
|
||
inc
|
||
|
||
sbi_push(hs, ls, bs, bh, bl, bi) =>
|
||
array.push(hs, bh)
|
||
array.push(ls, bl)
|
||
array.push(bs, bi)
|
||
0
|
||
|
||
sbi_seed(hs, ls, bs, bi) =>
|
||
array.clear(hs)
|
||
array.clear(ls)
|
||
array.clear(bs)
|
||
if bi >= 0
|
||
array.push(hs, array.get(bi_h, bi))
|
||
array.push(ls, array.get(bi_l, bi))
|
||
array.push(bs, bi)
|
||
0
|
||
|
||
sbi_fx(hs, ls) =>
|
||
int fx = 0
|
||
int gap = 0
|
||
n = array.size(hs)
|
||
if n >= 3
|
||
h1 = array.get(hs, n - 3)
|
||
l1 = array.get(ls, n - 3)
|
||
h2 = array.get(hs, n - 2)
|
||
l2 = array.get(ls, n - 2)
|
||
h3 = array.get(hs, n - 1)
|
||
l3 = array.get(ls, n - 1)
|
||
if h2 > h1 and h2 > h3
|
||
fx := 1
|
||
if l2 > h1
|
||
gap := 1
|
||
else if l2 < l1 and l2 < l3
|
||
fx := -1
|
||
if h2 < l1
|
||
gap := 1
|
||
[fx, gap]
|
||
|
||
trim_klc() =>
|
||
if array.size(kh) > 4000
|
||
array.shift(kh)
|
||
array.shift(kl)
|
||
array.shift(ko)
|
||
array.shift(kc)
|
||
array.shift(km)
|
||
array.shift(ks)
|
||
array.shift(ke)
|
||
array.shift(kd)
|
||
0
|
||
|
||
add_klc_to_last(ci) =>
|
||
// 对齐 ChanBI.add_klc:只推进终点,不改 high/low
|
||
bn = array.size(bi_s)
|
||
if bn > 0
|
||
array.set(bi_e, bn - 1, ci)
|
||
acc = array.get(bi_macd, bn - 1)
|
||
hv = array.get(km, ci)
|
||
if array.get(bi_d, bn - 1) == 1
|
||
if hv > 0
|
||
acc += hv
|
||
else if hv < 0
|
||
acc -= hv
|
||
array.set(bi_macd, bn - 1, acc)
|
||
0
|
||
|
||
confirm_bi(end_i) =>
|
||
// 对齐 ChanBI.set_end_klc:按方向用终点分型延伸 high/low
|
||
bn = array.size(bi_s)
|
||
if bn > 0 and array.get(bi_sure, bn - 1) == 0
|
||
array.set(bi_e, bn - 1, end_i)
|
||
array.set(bi_sure, bn - 1, 1)
|
||
d = array.get(bi_d, bn - 1)
|
||
if d == 1
|
||
eh = array.get(kh, end_i)
|
||
if eh > array.get(bi_h, bn - 1)
|
||
array.set(bi_h, bn - 1, eh)
|
||
else
|
||
el = array.get(kl, end_i)
|
||
if el < array.get(bi_l, bn - 1)
|
||
array.set(bi_l, bn - 1, el)
|
||
0
|
||
|
||
new_bi(start_i, dir) =>
|
||
array.push(bi_s, start_i)
|
||
array.push(bi_e, start_i)
|
||
array.push(bi_d, dir)
|
||
array.push(bi_sure, 0)
|
||
array.push(bi_h, array.get(kh, start_i))
|
||
array.push(bi_l, array.get(kl, start_i))
|
||
array.push(bi_macd, 0.0)
|
||
0
|
||
|
||
reset_struct() =>
|
||
array.clear(fx_idx)
|
||
array.clear(fx_typ)
|
||
array.clear(fx_px)
|
||
array.clear(fx_bar)
|
||
array.clear(bi_s)
|
||
array.clear(bi_e)
|
||
array.clear(bi_d)
|
||
array.clear(bi_sure)
|
||
array.clear(bi_h)
|
||
array.clear(bi_l)
|
||
array.clear(bi_macd)
|
||
array.clear(xd_s)
|
||
array.clear(xd_e)
|
||
array.clear(xd_d)
|
||
array.clear(xd_sure)
|
||
array.clear(xd_h)
|
||
array.clear(xd_l)
|
||
array.clear(feat_hh)
|
||
array.clear(feat_ll)
|
||
array.clear(feat_bi)
|
||
array.clear(us_hh)
|
||
array.clear(us_ll)
|
||
array.clear(us_bi)
|
||
array.clear(zs_s)
|
||
array.clear(zs_e)
|
||
array.clear(zs_zg)
|
||
array.clear(zs_zd)
|
||
array.clear(zs_gg)
|
||
array.clear(zs_dd)
|
||
array.clear(zs_sure)
|
||
array.clear(zs_dir)
|
||
array.clear(xzs_s)
|
||
array.clear(xzs_e)
|
||
array.clear(xzs_zg)
|
||
array.clear(xzs_zd)
|
||
array.clear(xzs_sure)
|
||
array.clear(xzs_dir)
|
||
array.clear(bsp_bar)
|
||
array.clear(bsp_px)
|
||
array.clear(bsp_kind)
|
||
array.clear(bsp_txt)
|
||
0
|
||
|
||
bi_overlap(i) =>
|
||
ok = false
|
||
bn = array.size(bi_s)
|
||
if i + 2 < bn
|
||
if array.get(bi_sure, i + 2) == 1
|
||
if array.get(bi_d, i) == 1
|
||
ok := array.get(bi_h, i) > array.get(bi_l, i + 1) and array.get(bi_h, i) < array.get(bi_h, i + 2)
|
||
else
|
||
ok := array.get(bi_h, i) > array.get(bi_h, i + 1) and array.get(bi_l, i) > array.get(bi_l, i + 2)
|
||
ok
|
||
|
||
// ============================================================================
|
||
// 逐K合并
|
||
// ============================================================================
|
||
nklc = array.size(kh)
|
||
|
||
if nklc == 0
|
||
array.push(kh, high)
|
||
array.push(kl, low)
|
||
array.push(ko, open)
|
||
array.push(kc, close)
|
||
array.push(km, macd_hist)
|
||
array.push(ks, bar_index)
|
||
array.push(ke, bar_index)
|
||
array.push(kd, close >= open ? 1 : -1)
|
||
else
|
||
last = nklc - 1
|
||
ph = array.get(kh, last)
|
||
pl = array.get(kl, last)
|
||
pdir = array.get(kd, last)
|
||
[inc, mode] = klc_included(ph, pl, high, low)
|
||
if inc
|
||
if mode == 1
|
||
if pdir == 1
|
||
array.set(kl, last, low)
|
||
else
|
||
array.set(kh, last, high)
|
||
else if mode == 2
|
||
if pdir == 1
|
||
array.set(kh, last, high)
|
||
else
|
||
array.set(kl, last, low)
|
||
else
|
||
if pdir == 1
|
||
array.set(kh, last, high)
|
||
else
|
||
array.set(kl, last, low)
|
||
array.set(kc, last, close)
|
||
array.set(km, last, macd_hist)
|
||
array.set(ke, last, bar_index)
|
||
nh = array.get(kh, last)
|
||
nl = array.get(kl, last)
|
||
if array.get(ko, last) > nh
|
||
array.set(ko, last, nh)
|
||
if array.get(kc, last) > nh
|
||
array.set(kc, last, nh)
|
||
if array.get(kc, last) < nl
|
||
array.set(kc, last, nl)
|
||
if array.get(ko, last) < nl
|
||
array.set(ko, last, nl)
|
||
else
|
||
ndir = high > ph ? 1 : -1
|
||
array.push(kh, high)
|
||
array.push(kl, low)
|
||
array.push(ko, open)
|
||
array.push(kc, close)
|
||
array.push(km, macd_hist)
|
||
array.push(ks, bar_index)
|
||
array.push(ke, bar_index)
|
||
array.push(kd, ndir)
|
||
trim_klc()
|
||
|
||
// ============================================================================
|
||
// 结构重建 + 绘制:对齐完整版,全部放在最后一根
|
||
// ============================================================================
|
||
if barstate.islast
|
||
reset_struct()
|
||
|
||
int N = array.size(kh)
|
||
last_top := -1
|
||
last_bot := -1
|
||
|
||
// ---- 笔:cal_bi_list 有效路径(分型按结合律过滤,只画笔端点)----
|
||
if N >= 1
|
||
for i = 0 to N - 1
|
||
int fx = 0
|
||
if i >= 1 and i <= N - 3
|
||
h1 = array.get(kh, i - 1)
|
||
l1 = array.get(kl, i - 1)
|
||
h2 = array.get(kh, i)
|
||
l2 = array.get(kl, i)
|
||
h3 = array.get(kh, i + 1)
|
||
l3 = array.get(kl, i + 1)
|
||
if is_top_fx(h1, l1, h2, l2, h3, l3)
|
||
fx := 1
|
||
else if is_bot_fx(h1, l1, h2, l2, h3, l3)
|
||
fx := -1
|
||
if fx == 1 and last_bot >= 1 and last_bot + 1 < N and i >= 1 and i + 1 < N
|
||
bot_h = math.max(array.get(kh, last_bot), math.max(array.get(kh, last_bot - 1), array.get(kh, last_bot + 1)))
|
||
if (bot_h > array.get(kl, i - 1) or bot_h > array.get(kl, i + 1)) and (i - last_bot < 100)
|
||
fx := 0
|
||
if fx == -1 and last_top >= 1 and last_top + 1 < N and i >= 1 and i + 1 < N
|
||
top_l = math.min(array.get(kl, last_top), math.min(array.get(kl, last_top - 1), array.get(kl, last_top + 1)))
|
||
if (top_l < array.get(kh, i - 1) or top_l < array.get(kh, i + 1)) and (i - last_top < 100)
|
||
fx := 0
|
||
|
||
if fx == 0
|
||
add_klc_to_last(i)
|
||
else if fx == 1
|
||
if last_top >= 0
|
||
if last_bot >= 0
|
||
if last_bot < last_top
|
||
if array.get(kh, last_top) <= array.get(kh, i)
|
||
last_top := i
|
||
add_klc_to_last(i)
|
||
else if last_bot + bi_klc_min > i
|
||
add_klc_to_last(i)
|
||
else
|
||
confirm_bi(last_bot)
|
||
new_bi(last_bot, 1)
|
||
add_klc_to_last(i)
|
||
last_top := i
|
||
else
|
||
if array.get(kh, last_top) < array.get(kh, i)
|
||
bn0 = array.size(bi_s)
|
||
if bn0 > 0
|
||
array.set(bi_s, bn0 - 1, i)
|
||
array.set(bi_d, bn0 - 1, -1)
|
||
array.set(bi_h, bn0 - 1, array.get(kh, i))
|
||
array.set(bi_l, bn0 - 1, array.get(kl, i))
|
||
last_top := i
|
||
add_klc_to_last(i)
|
||
else if last_bot >= 0
|
||
if last_bot + bi_klc_min > i
|
||
add_klc_to_last(i)
|
||
else
|
||
last_top := i
|
||
add_klc_to_last(i)
|
||
else
|
||
last_top := i
|
||
new_bi(i, -1)
|
||
add_klc_to_last(i)
|
||
else
|
||
if last_bot >= 0
|
||
if last_top >= 0
|
||
if last_top < last_bot
|
||
if array.get(kl, last_bot) >= array.get(kl, i)
|
||
last_bot := i
|
||
add_klc_to_last(i)
|
||
else if last_top + bi_klc_min > i
|
||
add_klc_to_last(i)
|
||
else
|
||
confirm_bi(last_top)
|
||
new_bi(last_top, -1)
|
||
add_klc_to_last(i)
|
||
last_bot := i
|
||
else
|
||
if array.get(kl, last_bot) > array.get(kl, i)
|
||
bn1 = array.size(bi_s)
|
||
if bn1 > 0
|
||
array.set(bi_s, bn1 - 1, i)
|
||
array.set(bi_d, bn1 - 1, 1)
|
||
array.set(bi_h, bn1 - 1, array.get(kh, i))
|
||
array.set(bi_l, bn1 - 1, array.get(kl, i))
|
||
last_bot := i
|
||
add_klc_to_last(i)
|
||
else if last_top >= 0
|
||
if last_top + bi_klc_min > i
|
||
add_klc_to_last(i)
|
||
else
|
||
last_bot := i
|
||
add_klc_to_last(i)
|
||
else
|
||
last_bot := i
|
||
new_bi(i, 1)
|
||
add_klc_to_last(i)
|
||
|
||
int bn = array.size(bi_s)
|
||
if bn > 0 and array.get(bi_sure, bn - 1) == 0
|
||
array.set(bi_e, bn - 1, N - 1)
|
||
|
||
// ---- 分型:只画结合律之后的笔端点 + 当前未确认顶底 ----
|
||
if bn > 0
|
||
for i = 0 to bn - 1
|
||
push_fx(array.get(bi_s, i), array.get(bi_d, i) == 1 ? -1 : 1)
|
||
if i == bn - 1 and array.get(bi_sure, i) == 1
|
||
push_fx(array.get(bi_e, i), array.get(bi_d, i) == 1 ? 1 : -1)
|
||
if last_top >= 0 and not fx_has(last_top)
|
||
push_fx(last_top, 1)
|
||
if last_bot >= 0 and not fx_has(last_bot)
|
||
push_fx(last_bot, -1)
|
||
|
||
// ---- 线段:对齐 get_seg_list / ChanSBI(双特征序列 + 缺口确认)----
|
||
int last_up_bi = -1
|
||
int last_down_bi = -1
|
||
int look_for_top = 0
|
||
int look_for_bot = 0
|
||
if bn >= 3
|
||
for i = 0 to bn - 1
|
||
d = array.get(bi_d, i)
|
||
bh = array.get(bi_h, i)
|
||
bl = array.get(bi_l, i)
|
||
xn0 = array.size(xd_s)
|
||
if xn0 == 0
|
||
if bi_overlap(i)
|
||
push_xd(i, i, d, 0)
|
||
if d == 1
|
||
sbi_seed(us_hh, us_ll, us_bi, i)
|
||
else
|
||
sbi_seed(feat_hh, feat_ll, feat_bi, i)
|
||
else
|
||
array.set(xd_e, xn0 - 1, i)
|
||
cur = array.get(xd_d, xn0 - 1)
|
||
if cur == 1
|
||
if d == -1
|
||
ds_n = array.size(feat_bi)
|
||
if ds_n > 1
|
||
if not sbi_try_include(feat_hh, feat_ll, bh, bl, -1)
|
||
sbi_push(feat_hh, feat_ll, feat_bi, bh, bl, i)
|
||
[fxv, gapv] = sbi_fx(feat_hh, feat_ll)
|
||
if fxv == 1
|
||
mid_s = array.get(feat_bi, array.size(feat_bi) - 2)
|
||
end_i = mid_s - 1
|
||
if look_for_top == 1
|
||
if xn0 >= 2
|
||
array.set(xd_sure, xn0 - 2, 1)
|
||
look_for_top := 0
|
||
if gapv == 1
|
||
look_for_bot := 1
|
||
finish_xd(end_i, 0)
|
||
push_xd(mid_s, i, -1, 0)
|
||
sbi_seed(us_hh, us_ll, us_bi, last_up_bi)
|
||
else if look_for_bot == 1
|
||
look_for_bot := 0
|
||
array.set(xd_s, xn0 - 1, mid_s)
|
||
sync_xd_hl(xn0 - 1)
|
||
if xn0 >= 2
|
||
array.set(xd_e, xn0 - 2, end_i)
|
||
array.set(xd_sure, xn0 - 2, 1)
|
||
sync_xd_hl(xn0 - 2)
|
||
sbi_seed(us_hh, us_ll, us_bi, last_up_bi)
|
||
else
|
||
finish_xd(end_i, 1)
|
||
push_xd(mid_s, i, -1, 0)
|
||
sbi_seed(us_hh, us_ll, us_bi, last_up_bi)
|
||
else if ds_n == 1
|
||
if not sbi_try_include(feat_hh, feat_ll, bh, bl, -1)
|
||
sbi_push(feat_hh, feat_ll, feat_bi, bh, bl, i)
|
||
else
|
||
sbi_push(feat_hh, feat_ll, feat_bi, bh, bl, i)
|
||
else if array.size(us_bi) > 0
|
||
if not sbi_try_include(us_hh, us_ll, bh, bl, 1)
|
||
sbi_push(us_hh, us_ll, us_bi, bh, bl, i)
|
||
else
|
||
if d == 1
|
||
us_n = array.size(us_bi)
|
||
if us_n > 1
|
||
if not sbi_try_include(us_hh, us_ll, bh, bl, 1)
|
||
sbi_push(us_hh, us_ll, us_bi, bh, bl, i)
|
||
[fxv2, gapv2] = sbi_fx(us_hh, us_ll)
|
||
if fxv2 == -1
|
||
mid_s = array.get(us_bi, array.size(us_bi) - 2)
|
||
end_i = mid_s - 1
|
||
if look_for_bot == 1
|
||
if xn0 >= 2
|
||
array.set(xd_sure, xn0 - 2, 1)
|
||
look_for_bot := 0
|
||
if gapv2 == 1
|
||
look_for_top := 1
|
||
finish_xd(end_i, 0)
|
||
push_xd(mid_s, i, 1, 0)
|
||
sbi_seed(feat_hh, feat_ll, feat_bi, last_down_bi)
|
||
else if look_for_top == 1
|
||
look_for_top := 0
|
||
array.set(xd_s, xn0 - 1, mid_s)
|
||
sync_xd_hl(xn0 - 1)
|
||
if xn0 >= 2
|
||
array.set(xd_e, xn0 - 2, end_i)
|
||
array.set(xd_sure, xn0 - 2, 1)
|
||
sync_xd_hl(xn0 - 2)
|
||
sbi_seed(feat_hh, feat_ll, feat_bi, last_down_bi)
|
||
else
|
||
finish_xd(end_i, 1)
|
||
push_xd(mid_s, i, 1, 0)
|
||
sbi_seed(feat_hh, feat_ll, feat_bi, last_down_bi)
|
||
else if us_n == 1
|
||
if not sbi_try_include(us_hh, us_ll, bh, bl, 1)
|
||
sbi_push(us_hh, us_ll, us_bi, bh, bl, i)
|
||
else
|
||
sbi_push(us_hh, us_ll, us_bi, bh, bl, i)
|
||
else if array.size(feat_bi) > 0
|
||
if not sbi_try_include(feat_hh, feat_ll, bh, bl, -1)
|
||
sbi_push(feat_hh, feat_ll, feat_bi, bh, bl, i)
|
||
if d == 1
|
||
last_up_bi := i
|
||
else
|
||
last_down_bi := i
|
||
|
||
int xn = array.size(xd_s)
|
||
if xn > 0 and array.get(xd_sure, xn - 1) == 0 and bn > 0
|
||
array.set(xd_e, xn - 1, bn - 1)
|
||
sync_xd_hl(xn - 1)
|
||
|
||
// ---- 笔中枢:逐字对应 cal_bi_zs_list_pure ----
|
||
// zg/zd/gg/dd 只由前三笔钉死;按 leave+back 两笔一组延伸;位置过滤用整段首尾方向
|
||
if bn >= 3
|
||
int start_idx = 0
|
||
float last_zg = na
|
||
float last_zdv = na
|
||
while start_idx + 2 < bn
|
||
if array.get(bi_sure, start_idx) != 1 or array.get(bi_sure, start_idx + 1) != 1 or array.get(bi_sure, start_idx + 2) != 1
|
||
start_idx += 1
|
||
else
|
||
d1 = array.get(bi_d, start_idx)
|
||
d2 = array.get(bi_d, start_idx + 1)
|
||
d3 = array.get(bi_d, start_idx + 2)
|
||
if not (d1 != d2 and d1 == d3)
|
||
start_idx += 1
|
||
else
|
||
h1 = array.get(bi_h, start_idx)
|
||
h2 = array.get(bi_h, start_idx + 1)
|
||
h3 = array.get(bi_h, start_idx + 2)
|
||
l1 = array.get(bi_l, start_idx)
|
||
l2 = array.get(bi_l, start_idx + 1)
|
||
l3 = array.get(bi_l, start_idx + 2)
|
||
zg = math.min(h1, math.min(h2, h3))
|
||
zdv = math.max(l1, math.max(l2, l3))
|
||
gg = math.max(h1, math.max(h2, h3))
|
||
dd = math.min(l1, math.min(l2, l3))
|
||
if zg <= zdv
|
||
start_idx += 1
|
||
else
|
||
end_idx = start_idx + 2
|
||
ext = start_idx + 3
|
||
while ext + 1 < bn
|
||
if array.get(bi_sure, ext) != 1 or array.get(bi_sure, ext + 1) != 1
|
||
break
|
||
else if array.get(bi_h, ext + 1) >= zdv and array.get(bi_l, ext + 1) <= zg
|
||
end_idx := ext + 1
|
||
ext += 2
|
||
else
|
||
break
|
||
pos_ok = true
|
||
if not na(last_zg)
|
||
if zg <= last_zdv
|
||
pos_ok := d1 == 1 and array.get(bi_d, end_idx) == 1
|
||
else if zdv >= last_zg
|
||
pos_ok := d1 == -1 and array.get(bi_d, end_idx) == -1
|
||
if not pos_ok
|
||
start_idx += 1
|
||
else
|
||
array.push(zs_s, start_idx)
|
||
array.push(zs_e, end_idx)
|
||
array.push(zs_zg, zg)
|
||
array.push(zs_zd, zdv)
|
||
array.push(zs_gg, gg)
|
||
array.push(zs_dd, dd)
|
||
array.push(zs_dir, d1 == -1 ? 1 : -1)
|
||
array.push(zs_sure, 1)
|
||
last_zg := zg
|
||
last_zdv := zdv
|
||
start_idx := end_idx + 1
|
||
|
||
int zn = array.size(zs_s)
|
||
if zn > 0 and bn > 0
|
||
array.set(zs_sure, zn - 1, array.get(bi_sure, bn - 1))
|
||
if array.get(zs_sure, zn - 1) == 0
|
||
last_zs_bi = array.get(zs_e, zn - 1)
|
||
has_leave = false
|
||
if last_zs_bi + 1 < bn
|
||
zg0 = array.get(zs_zg, zn - 1)
|
||
zd0 = array.get(zs_zd, zn - 1)
|
||
for li = last_zs_bi + 1 to bn - 1
|
||
if array.get(bi_sure, li) == 1
|
||
bh0 = array.get(bi_h, li)
|
||
bl0 = array.get(bi_l, li)
|
||
if (bl0 > zg0 and bh0 > zg0) or (bh0 < zd0 and bl0 < zd0)
|
||
has_leave := true
|
||
break
|
||
if has_leave and array.get(bi_sure, last_zs_bi) == 1
|
||
array.set(zs_sure, zn - 1, 1)
|
||
|
||
// ---- 线段中枢:从第4根起 ----
|
||
if xn >= 6
|
||
int si = 3
|
||
float lz_zg = na
|
||
float lz_zd = na
|
||
while si + 2 < xn
|
||
if array.get(xd_sure, si) != 1 or array.get(xd_sure, si + 1) != 1 or array.get(xd_sure, si + 2) != 1
|
||
si += 1
|
||
else
|
||
a1 = array.get(xd_d, si)
|
||
a2 = array.get(xd_d, si + 1)
|
||
a3 = array.get(xd_d, si + 2)
|
||
zg = math.min(array.get(xd_h, si), math.min(array.get(xd_h, si + 1), array.get(xd_h, si + 2)))
|
||
zdv = math.max(array.get(xd_l, si), math.max(array.get(xd_l, si + 1), array.get(xd_l, si + 2)))
|
||
if zg <= zdv
|
||
si += 1
|
||
else
|
||
valid = false
|
||
zdir = 0
|
||
if na(lz_zg)
|
||
if a1 == -1
|
||
zdir := 1
|
||
valid := a2 == 1 and a3 == -1
|
||
else
|
||
zdir := -1
|
||
valid := a2 == -1 and a3 == 1
|
||
else if zdv > lz_zg
|
||
zdir := 1
|
||
valid := a1 == -1 and a2 == 1 and a3 == -1
|
||
else if zg < lz_zd
|
||
zdir := -1
|
||
valid := a1 == 1 and a2 == -1 and a3 == 1
|
||
if not valid
|
||
merged_zs = false
|
||
if not na(lz_zg)
|
||
in_last = (zdv > lz_zd and zdv < lz_zg) or (zg < lz_zg and zg > lz_zd) or (zg > lz_zg and zdv < lz_zd) or (zg < lz_zg and zdv > lz_zd)
|
||
if in_last
|
||
array.set(xzs_e, array.size(xzs_s) - 1, si + 2)
|
||
merged_zs := true
|
||
si += 4
|
||
if not merged_zs
|
||
si += 1
|
||
else
|
||
base_si = si
|
||
eidx = si + 2
|
||
li = si + 4
|
||
while li < xn
|
||
if array.get(xd_sure, li) != 1
|
||
break
|
||
else
|
||
bs = array.get(xd_s, li)
|
||
be = array.get(xd_e, li)
|
||
sh = math.max(array.get(bi_h, bs), array.get(bi_h, be))
|
||
sl = math.min(array.get(bi_l, bs), array.get(bi_l, be))
|
||
if sh >= zdv and sl <= zg
|
||
eidx := li
|
||
li += 2
|
||
else
|
||
break
|
||
array.push(xzs_s, base_si)
|
||
array.push(xzs_e, eidx)
|
||
array.push(xzs_zg, zg)
|
||
array.push(xzs_zd, zdv)
|
||
array.push(xzs_dir, zdir)
|
||
array.push(xzs_sure, 1)
|
||
lz_zg := zg
|
||
lz_zd := zdv
|
||
si := base_si + 4 + (eidx - (base_si + 2))
|
||
|
||
// ---- 买卖点 ----
|
||
if zn > 0 and bn >= 4
|
||
for z = 0 to zn - 1
|
||
if array.get(zs_sure, z) != 1
|
||
continue
|
||
ze = array.get(zs_e, z)
|
||
zg = array.get(zs_zg, z)
|
||
zdv = array.get(zs_zd, z)
|
||
zdir0 = array.get(zs_dir, z)
|
||
leave = ze
|
||
if leave < bn and array.get(bi_sure, leave) == 1
|
||
ek = array.get(bi_e, leave)
|
||
if array.get(bi_d, leave) == 1
|
||
if array.get(kh, ek) <= zg or (leave + 1 < bn and array.get(bi_sure, leave + 1) == 1 and array.get(kl, array.get(bi_e, leave + 1)) < zdv)
|
||
leave += 1
|
||
else if array.get(kl, ek) >= zdv or (leave + 1 < bn and array.get(bi_sure, leave + 1) == 1 and array.get(kh, array.get(bi_e, leave + 1)) > zg)
|
||
leave += 1
|
||
if leave >= bn or array.get(bi_sure, leave) != 1
|
||
continue
|
||
ek = array.get(bi_e, leave)
|
||
ldir = array.get(bi_d, leave)
|
||
if (zdir0 == 1 and ldir == 1 and array.get(kh, ek) < zg and array.get(kh, ek) > zdv) or (zdir0 == -1 and ldir == -1 and array.get(kl, ek) < zg and array.get(kl, ek) > zdv)
|
||
if leave + 1 < bn
|
||
leave += 1
|
||
if leave >= bn or array.get(bi_sure, leave) != 1
|
||
continue
|
||
ldir := array.get(bi_d, leave)
|
||
enter = array.get(zs_s, z) - 1
|
||
div = false
|
||
if enter >= 0 and array.get(bi_d, enter) == ldir
|
||
div := array.get(bi_macd, leave) < array.get(bi_macd, enter)
|
||
ebar = array.get(ke, array.get(bi_e, leave))
|
||
if ldir == 1
|
||
if div
|
||
array.push(bsp_bar, ebar)
|
||
array.push(bsp_px, array.get(bi_h, leave))
|
||
array.push(bsp_kind, -1)
|
||
array.push(bsp_txt, "S1")
|
||
pb = leave + 1
|
||
if pb < bn and array.get(bi_sure, pb) == 1 and array.get(bi_d, pb) == -1
|
||
if array.get(bi_l, pb) >= zg
|
||
array.push(bsp_bar, array.get(ke, array.get(bi_e, pb)))
|
||
array.push(bsp_px, array.get(bi_l, pb))
|
||
array.push(bsp_kind, 1)
|
||
array.push(bsp_txt, "B3")
|
||
if div
|
||
s2 = pb + 1
|
||
if s2 < bn and array.get(bi_sure, s2) == 1 and array.get(bi_h, s2) < array.get(bi_h, leave)
|
||
array.push(bsp_bar, array.get(ke, array.get(bi_e, s2)))
|
||
array.push(bsp_px, array.get(bi_h, s2))
|
||
array.push(bsp_kind, -1)
|
||
array.push(bsp_txt, "S2")
|
||
else
|
||
if div
|
||
array.push(bsp_bar, ebar)
|
||
array.push(bsp_px, array.get(bi_l, leave))
|
||
array.push(bsp_kind, 1)
|
||
array.push(bsp_txt, "B1")
|
||
pb = leave + 1
|
||
if pb < bn and array.get(bi_sure, pb) == 1 and array.get(bi_d, pb) == 1
|
||
if array.get(bi_h, pb) <= zdv
|
||
array.push(bsp_bar, array.get(ke, array.get(bi_e, pb)))
|
||
array.push(bsp_px, array.get(bi_h, pb))
|
||
array.push(bsp_kind, -1)
|
||
array.push(bsp_txt, "S3")
|
||
if div
|
||
b2 = pb + 1
|
||
if b2 < bn and array.get(bi_sure, b2) == 1 and array.get(bi_l, b2) > array.get(bi_l, leave)
|
||
array.push(bsp_bar, array.get(ke, array.get(bi_e, b2)))
|
||
array.push(bsp_px, array.get(bi_l, b2))
|
||
array.push(bsp_kind, 1)
|
||
array.push(bsp_txt, "B2")
|
||
|
||
// 画法对齐 chan_theory_complete.pine:默认 bar_index,只画最近 5000 根,不指定 xloc.bar_time
|
||
if barstate.islast
|
||
nK = array.size(kh)
|
||
nFx = array.size(fx_idx)
|
||
nBi = array.size(bi_s)
|
||
nXd = array.size(xd_s)
|
||
nZs = array.size(zs_s)
|
||
nXz = array.size(xzs_s)
|
||
|
||
if show_merged_k and nK > 0
|
||
for i = 0 to nK - 1
|
||
x1 = array.get(ks, i)
|
||
x2 = array.get(ke, i)
|
||
if in_xwin(x1)
|
||
box.new(x1, array.get(kh, i), x2, array.get(kl, i), border_color=color.purple, bgcolor=color.new(color.purple, 88), border_width=1)
|
||
|
||
if show_fenxing and nFx > 0
|
||
for i = 0 to nFx - 1
|
||
xb = array.get(fx_bar, i)
|
||
if in_xwin(xb)
|
||
if array.get(fx_typ, i) == 1
|
||
label.new(xb, array.get(fx_px, i), "T", color=color.new(color_fx_top, 100), textcolor=color_fx_top, style=label.style_label_down, size=size.large)
|
||
else
|
||
label.new(xb, array.get(fx_px, i), "B", color=color.new(color_fx_bot, 100), textcolor=color_fx_bot, style=label.style_label_up, size=size.large)
|
||
|
||
if show_fx_box and nFx > 0
|
||
for i = 0 to nFx - 1
|
||
ki = array.get(fx_idx, i)
|
||
if ki >= 1 and ki + 1 < nK
|
||
x1 = array.get(ke, ki - 1)
|
||
x2 = array.get(ke, ki + 1)
|
||
if in_xwin(x1)
|
||
if array.get(fx_typ, i) == 1
|
||
box.new(x1, array.get(kh, ki), x2, math.min(array.get(kl, ki - 1), array.get(kl, ki + 1)), border_color=color.new(color_fx_top, 40), bgcolor=color.new(color_fx_top, 92), border_width=1)
|
||
else
|
||
box.new(x1, math.max(array.get(kh, ki - 1), array.get(kh, ki + 1)), x2, array.get(kl, ki), border_color=color.new(color_fx_bot, 40), bgcolor=color.new(color_fx_bot, 92), border_width=1)
|
||
|
||
if not na(pending_bi_ln)
|
||
line.delete(pending_bi_ln)
|
||
pending_bi_ln := na
|
||
if not na(pending_xd_ln)
|
||
line.delete(pending_xd_ln)
|
||
pending_xd_ln := na
|
||
if array.size(zs_boxes) > 0
|
||
for zi = 0 to array.size(zs_boxes) - 1
|
||
box.delete(array.get(zs_boxes, zi))
|
||
line.delete(array.get(zs_gg_lns, zi))
|
||
line.delete(array.get(zs_dd_lns, zi))
|
||
array.clear(zs_boxes)
|
||
array.clear(zs_gg_lns)
|
||
array.clear(zs_dd_lns)
|
||
if array.size(xzs_boxes) > 0
|
||
for zi = 0 to array.size(xzs_boxes) - 1
|
||
box.delete(array.get(xzs_boxes, zi))
|
||
array.clear(xzs_boxes)
|
||
|
||
if show_bi and nBi > 0
|
||
for i = 0 to nBi - 1
|
||
si = array.get(bi_s, i)
|
||
ei = array.get(bi_e, i)
|
||
d = array.get(bi_d, i)
|
||
sure = array.get(bi_sure, i)
|
||
x1 = array.get(ke, si)
|
||
y1 = d == 1 ? array.get(kl, si) : array.get(kh, si)
|
||
if sure == 1
|
||
x2 = array.get(ke, ei)
|
||
y2 = d == 1 ? array.get(kh, ei) : array.get(kl, ei)
|
||
if in_xwin(x1)
|
||
line.new(x1, y1, x2, y2, color=d == 1 ? color_bi_up : color_bi_down, width=2)
|
||
else if show_bi_pending and i == nBi - 1 and in_xwin(x1)
|
||
pending_bi_ln := line.new(x1, y1, bar_index, d == 1 ? array.get(kh, nK - 1) : array.get(kl, nK - 1), color=color_bi_pending, width=2, style=line.style_dashed)
|
||
|
||
if show_xianduan and nXd > 0
|
||
for i = 0 to nXd - 1
|
||
si = array.get(xd_s, i)
|
||
ei = array.get(xd_e, i)
|
||
if si < 0 or ei < 0 or si >= nBi or ei >= nBi
|
||
continue
|
||
d = array.get(xd_d, i)
|
||
sure = array.get(xd_sure, i)
|
||
ek = array.get(bi_e, ei)
|
||
x1 = array.get(ke, array.get(bi_s, si))
|
||
y1 = d == 1 ? array.get(kl, array.get(bi_s, si)) : array.get(kh, array.get(bi_s, si))
|
||
if sure == 1
|
||
x2 = array.get(ke, ek)
|
||
y2 = d == 1 ? array.get(kh, ek) : array.get(kl, ek)
|
||
if in_xwin(x1)
|
||
line.new(x1, y1, x2, y2, color=d == 1 ? color_xd_up : color_xd_down, width=2)
|
||
else if show_xd_pending and i == nXd - 1 and in_xwin(x1)
|
||
pending_xd_ln := line.new(x1, y1, bar_index, d == 1 ? array.get(kh, nK - 1) : array.get(kl, nK - 1), color=color_xd_pending, width=2, style=line.style_dashed)
|
||
|
||
if show_bi_zs and nZs > 0
|
||
for i = 0 to nZs - 1
|
||
si = array.get(zs_s, i)
|
||
ei = array.get(zs_e, i)
|
||
x1 = array.get(ke, array.get(bi_s, si))
|
||
x2 = array.get(zs_sure, i) == 1 ? array.get(ke, array.get(bi_e, ei)) : bar_index
|
||
zg = array.get(zs_zg, i)
|
||
zdv = array.get(zs_zd, i)
|
||
gg = array.get(zs_gg, i)
|
||
dd = array.get(zs_dd, i)
|
||
if in_xwin(x1)
|
||
array.push(zs_boxes, box.new(x1, zg, x2, zdv, border_color=color_bi_zs, bgcolor=na, border_width=1))
|
||
array.push(zs_gg_lns, line.new(x1, gg, x2, gg, color=color_bi_zs, width=1))
|
||
array.push(zs_dd_lns, line.new(x1, dd, x2, dd, color=color_bi_zs, width=1))
|
||
|
||
if show_xd_zs and nXz > 0
|
||
for i = 0 to nXz - 1
|
||
si = array.get(xzs_s, i)
|
||
ei = array.get(xzs_e, i)
|
||
if si >= nXd or ei >= nXd
|
||
continue
|
||
b1 = array.get(xd_s, si)
|
||
b2 = array.get(xd_e, ei)
|
||
if b1 >= nBi or b2 >= nBi
|
||
continue
|
||
x1 = array.get(ke, array.get(bi_s, b1))
|
||
x2 = array.get(xzs_sure, i) == 1 ? array.get(ke, array.get(bi_e, b2)) : bar_index
|
||
if in_xwin(x1)
|
||
array.push(xzs_boxes, box.new(x1, array.get(xzs_zg, i), x2, array.get(xzs_zd, i), border_color=color_xd_zs, bgcolor=na, border_width=2))
|
||
|
||
if show_bsp
|
||
bpn = array.size(bsp_bar)
|
||
if bpn > 0
|
||
for i = 0 to bpn - 1
|
||
xb = array.get(bsp_bar, i)
|
||
if in_xwin(xb)
|
||
if array.get(bsp_kind, i) == 1
|
||
label.new(xb, array.get(bsp_px, i), array.get(bsp_txt, i), color=color.lime, style=label.style_label_up, textcolor=color.black, size=size.tiny)
|
||
else
|
||
label.new(xb, array.get(bsp_px, i), array.get(bsp_txt, i), color=color.red, style=label.style_label_down, textcolor=color.white, size=size.tiny)
|
||
|
||
if show_info
|
||
table.cell(info_tbl, 0, 0, "合并K", text_color=color.gray, text_size=size.small)
|
||
table.cell(info_tbl, 1, 0, str.tostring(nK), text_color=color.white, text_size=size.small)
|
||
table.cell(info_tbl, 0, 1, "分型", text_color=color.gray, text_size=size.small)
|
||
table.cell(info_tbl, 1, 1, str.tostring(nFx), text_color=color.white, text_size=size.small)
|
||
table.cell(info_tbl, 0, 2, "笔", text_color=color.gray, text_size=size.small)
|
||
table.cell(info_tbl, 1, 2, str.tostring(nBi), text_color=color.white, text_size=size.small)
|
||
table.cell(info_tbl, 0, 3, "线段", text_color=color.gray, text_size=size.small)
|
||
table.cell(info_tbl, 1, 3, str.tostring(nXd), text_color=color.white, text_size=size.small)
|
||
table.cell(info_tbl, 0, 4, "笔中枢", text_color=color.gray, text_size=size.small)
|
||
table.cell(info_tbl, 1, 4, str.tostring(nZs), text_color=color.white, text_size=size.small)
|
||
table.cell(info_tbl, 0, 5, "段中枢", text_color=color.gray, text_size=size.small)
|
||
table.cell(info_tbl, 1, 5, str.tostring(nXz), text_color=color.white, text_size=size.small)
|
||
table.cell(info_tbl, 0, 6, "买卖点", text_color=color.gray, text_size=size.small)
|
||
table.cell(info_tbl, 1, 6, str.tostring(array.size(bsp_bar)), text_color=color.white, text_size=size.small)
|
||
else
|
||
table.clear(info_tbl, 0, 0, 1, 6)
|