//@version=6 indicator(title="EMA+MACD 三态趋势判断", shorttitle="EMA+MACD趋势", overlay=true, max_labels_count=500) // ========================= 输入参数 ========================= // EMA 参数 ema1_len = input.int(9, "EMA1 快线周期", minval=1, inline="ema1") ema2_len = input.int(21, "EMA2 中线周期", minval=1, inline="ema2") ema3_len = input.int(55, "EMA3 慢线周期", minval=1, inline="ema3") ema4_len = input.int(200, "EMA4 超慢线周期", minval=1, inline="ema4") use_ema4 = input.bool(true, "启用第4条均线(EMA200)", inline="ema4") // MACD 参数 macd_fast = input.int(12, "MACD快线周期", minval=1, group="MACD设置") macd_slow = input.int(26, "MACD慢线周期", minval=1, group="MACD设置") macd_signal = input.int(9, "MACD信号线周期", minval=1, group="MACD设置") // 趋势判断参数 ema_spread_thresh = input.float(0.3, "EMA收束阈值(%)", minval=0.1, maxval=2.0, step=0.1, group="趋势判断") / 100 macd_zero_zone = input.float(0.1, "MACD零轴区域(%)", minval=0.01, maxval=0.5, step=0.01, group="趋势判断") / 100 confirm_bars = input.int(2, "趋势确认周期", minval=1, maxval=5, group="趋势判断") // 显示设置 show_ema = input.bool(true, "显示EMA线", group="显示设置") show_signals = input.bool(true, "显示状态切换信号", group="显示设置") show_background = input.bool(true, "背景着色", group="显示设置") show_info_panel = input.bool(true, "显示信息面板", group="显示设置") // 颜色设置 col_uptrend = input.color(color.new(color.teal, 80), "上涨趋势颜色", group="颜色设置") col_downtrend = input.color(color.new(color.red, 80), "下跌趋势颜色", group="颜色设置") col_consolidation = input.color(color.new(color.gray, 85), "盘整趋势颜色", group="颜色设置") // ========================= 指标计算 ========================= // EMA计算 ema1 = ta.ema(close, ema1_len) ema2 = ta.ema(close, ema2_len) ema3 = ta.ema(close, ema3_len) ema4 = use_ema4 ? ta.ema(close, ema4_len) : na // MACD计算 [macdLine, signalLine, histLine] = ta.macd(close, macd_fast, macd_slow, macd_signal) macd_normalized = macdLine / close // 归一化MACD便于比较 // ========================= EMA排列判断 ========================= // 多头排列: EMA1 > EMA2 > EMA3 (> EMA4 if enabled) bull_alignment_3 = ema1 > ema2 and ema2 > ema3 bull_alignment = use_ema4 ? (bull_alignment_3 and ema3 > ema4) : bull_alignment_3 // 空头排列: EMA1 < EMA2 < EMA3 (< EMA4 if enabled) bear_alignment_3 = ema1 < ema2 and ema2 < ema3 bear_alignment = use_ema4 ? (bear_alignment_3 and ema3 < ema4) : bear_alignment_3 // EMA方向一致性(斜率判断) ema1_rising = ema1 > ema1[1] ema2_rising = ema2 > ema2[1] ema3_rising = ema3 > ema3[1] ema4_rising = use_ema4 ? ema4 > ema4[1] : true ema1_falling = ema1 < ema1[1] ema2_falling = ema2 < ema2[1] ema3_falling = ema3 < ema3[1] ema4_falling = use_ema4 ? ema4 < ema4[1] : true all_rising = ema1_rising and ema2_rising and ema3_rising and (not use_ema4 or ema4_rising) all_falling = ema1_falling and ema2_falling and ema3_falling and (not use_ema4 or ema4_falling) // EMA收束程度(判断盘整) max_ema = math.max(math.max(ema1, ema2), ema3) min_ema = math.min(math.min(ema1, ema2), ema3) ema_spread = (max_ema - min_ema) / close emas_converged = ema_spread < ema_spread_thresh // ========================= MACD状态判断 ========================= // MACD方向 macd_bullish = macdLine > signalLine macd_bearish = macdLine < signalLine // MACD位置 macd_above_zero = macdLine > 0 macd_below_zero = macdLine < 0 macd_near_zero = math.abs(macd_normalized) < macd_zero_zone // MACD柱状图趋势 hist_expanding_up = histLine > histLine[1] and histLine > 0 hist_expanding_down = histLine < histLine[1] and histLine < 0 hist_shrinking = math.abs(histLine) < math.abs(histLine[1]) // MACD综合强度评分 (-2 到 +2) macd_score = 0 macd_score := macd_bullish ? macd_score + 1 : macd_score - 1 macd_score := macd_above_zero ? macd_score + 1 : macd_below_zero ? macd_score - 1 : macd_score // ========================= 综合趋势判断 ========================= // 上涨趋势条件: // 1. EMA多头排列 OR (EMA方向一致向上 AND 价格在EMA上方) // 2. MACD评分 >= 1 (至少看涨) price_above_emas = close > ema1 and close > ema2 and close > ema3 uptrend_ema = bull_alignment or (all_rising and price_above_emas) uptrend_macd = macd_score >= 1 or (macd_bullish and not macd_near_zero) uptrend_raw = uptrend_ema and uptrend_macd // 下跌趋势条件: // 1. EMA空头排列 OR (EMA方向一致向下 AND 价格在EMA下方) // 2. MACD评分 <= -1 (至少看跌) price_below_emas = close < ema1 and close < ema2 and close < ema3 downtrend_ema = bear_alignment or (all_falling and price_below_emas) downtrend_macd = macd_score <= -1 or (macd_bearish and not macd_near_zero) downtrend_raw = downtrend_ema and downtrend_macd // 盘整趋势条件: // 1. EMA收束 OR 无明确排列 // 2. MACD在零轴附近 OR 柱状图收缩 consolidation_ema = emas_converged or (not bull_alignment and not bear_alignment) consolidation_macd = macd_near_zero or hist_shrinking consolidation_raw = (consolidation_ema and consolidation_macd) or (not uptrend_raw and not downtrend_raw) // ========================= 连续确认计数 ========================= var int uptrend_count = 0 var int downtrend_count = 0 var int consolidation_count = 0 uptrend_count := uptrend_raw ? uptrend_count + 1 : 0 downtrend_count := downtrend_raw ? downtrend_count + 1 : 0 consolidation_count := consolidation_raw ? consolidation_count + 1 : 0 // 确认后的趋势信号 uptrend_confirmed = uptrend_count >= confirm_bars downtrend_confirmed = downtrend_count >= confirm_bars consolidation_confirmed = consolidation_count >= confirm_bars // ========================= 状态机 ========================= // 状态: 0=盘整, 1=上涨, -1=下跌 var int trend_state = 0 prev_state = nz(trend_state[1], 0) // 状态转换逻辑 int new_state = prev_state if prev_state == 0 // 当前盘整 if uptrend_confirmed new_state := 1 else if downtrend_confirmed new_state := -1 else if prev_state == 1 // 当前上涨 if downtrend_confirmed new_state := -1 else if consolidation_confirmed and not uptrend_raw new_state := 0 else if prev_state == -1 // 当前下跌 if uptrend_confirmed new_state := 1 else if consolidation_confirmed and not downtrend_raw new_state := 0 // 仅在K线收盘时更新状态 trend_state := barstate.isconfirmed ? new_state : prev_state // ========================= 可视化 ========================= // 绘制EMA线 plot(show_ema ? ema1 : na, "EMA1 快线", color=color.new(color.red, 30), linewidth=1) plot(show_ema ? ema2 : na, "EMA2 中线", color=color.new(color.orange, 30), linewidth=1) plot(show_ema ? ema3 : na, "EMA3 慢线", color=color.new(color.blue, 30), linewidth=2) plot(show_ema and use_ema4 ? ema4 : na, "EMA4 超慢线", color=color.new(color.purple, 30), linewidth=2) // 背景着色 bg_color = trend_state == 1 ? col_uptrend : trend_state == -1 ? col_downtrend : col_consolidation bgcolor(show_background ? bg_color : na, title="趋势背景") // 状态切换信号 entered_up = barstate.isconfirmed and trend_state == 1 and prev_state != 1 entered_down = barstate.isconfirmed and trend_state == -1 and prev_state != -1 entered_consolidation = barstate.isconfirmed and trend_state == 0 and prev_state != 0 exit_up = barstate.isconfirmed and prev_state == 1 and trend_state != 1 exit_down = barstate.isconfirmed and prev_state == -1 and trend_state != -1 // ========================= 类缠论笔的绘制 ========================= // 趋势线宽度 trend_line_width = input.int(2, "趋势笔宽度", minval=1, maxval=5, group="显示设置") // 上涨笔:记录起点 var int up_start_bar = na var float up_start_price = na // 下跌笔:记录起点 var int down_start_bar = na var float down_start_price = na // 上涨趋势开始 - 记录起点 if entered_up up_start_bar := bar_index up_start_price := low // 上涨趋势结束 - 画笔(终点 = 结束时的K线) if exit_up and show_signals and not na(up_start_bar) line.new(up_start_bar, up_start_price, bar_index, close, color=color.teal, width=trend_line_width, style=line.style_solid) // 下跌趋势开始 - 记录起点 if entered_down down_start_bar := bar_index down_start_price := high // 下跌趋势结束 - 画笔(终点 = 结束时的K线) if exit_down and show_signals and not na(down_start_bar) line.new(down_start_bar, down_start_price, bar_index, close, color=color.red, width=trend_line_width, style=line.style_solid) // 当前进行中的笔(实时显示) var line current_up_line = na var line current_down_line = na if show_signals if not na(current_up_line) line.delete(current_up_line) if not na(current_down_line) line.delete(current_down_line) // 上涨中 - 画到当前K线 if trend_state == 1 and not na(up_start_bar) current_up_line := line.new(up_start_bar, up_start_price, bar_index, close, color=color.new(color.teal, 40), width=trend_line_width, style=line.style_dotted) // 下跌中 - 画到当前K线 if trend_state == -1 and not na(down_start_bar) current_down_line := line.new(down_start_bar, down_start_price, bar_index, close, color=color.new(color.red, 40), width=trend_line_width, style=line.style_dotted) // ========================= 信息面板 ========================= if show_info_panel and barstate.islast var table info_table = table.new(position.top_right, 2, 10, bgcolor=color.new(color.black, 80), border_width=1) // 标题 table.cell(info_table, 0, 0, "EMA+MACD趋势", text_color=color.white, bgcolor=color.new(color.gray, 60), text_size=size.small) table.cell(info_table, 1, 0, "", bgcolor=color.new(color.gray, 60)) // 当前状态 state_text = trend_state == 1 ? "📈 上涨趋势" : trend_state == -1 ? "📉 下跌趋势" : "📊 盘整趋势" state_color = trend_state == 1 ? color.teal : trend_state == -1 ? color.red : color.gray table.cell(info_table, 0, 1, "当前状态", text_color=color.white, text_size=size.small) table.cell(info_table, 1, 1, state_text, text_color=state_color, text_size=size.small) // EMA排列 ema_text = bull_alignment ? "多头排列" : bear_alignment ? "空头排列" : "无序排列" ema_color = bull_alignment ? color.teal : bear_alignment ? color.red : color.gray table.cell(info_table, 0, 2, "EMA排列", text_color=color.white, text_size=size.small) table.cell(info_table, 1, 2, ema_text, text_color=ema_color, text_size=size.small) // EMA收束度 spread_text = str.tostring(math.round(ema_spread * 10000) / 100, "#.##") + "%" spread_color = emas_converged ? color.orange : color.white table.cell(info_table, 0, 3, "EMA间距", text_color=color.white, text_size=size.small) table.cell(info_table, 1, 3, spread_text + (emas_converged ? " 收束" : ""), text_color=spread_color, text_size=size.small) // EMA方向 dir_text = all_rising ? "全部上升" : all_falling ? "全部下降" : "方向分歧" dir_color = all_rising ? color.teal : all_falling ? color.red : color.gray table.cell(info_table, 0, 4, "EMA方向", text_color=color.white, text_size=size.small) table.cell(info_table, 1, 4, dir_text, text_color=dir_color, text_size=size.small) // MACD状态 macd_status = macd_bullish ? "看涨" : "看跌" macd_pos = macd_above_zero ? " (零上)" : macd_below_zero ? " (零下)" : " (零轴)" macd_color = macd_bullish and macd_above_zero ? color.teal : macd_bearish and macd_below_zero ? color.red : color.orange table.cell(info_table, 0, 5, "MACD状态", text_color=color.white, text_size=size.small) table.cell(info_table, 1, 5, macd_status + macd_pos, text_color=macd_color, text_size=size.small) // MACD数值 table.cell(info_table, 0, 6, "MACD值", text_color=color.white, text_size=size.small) table.cell(info_table, 1, 6, str.tostring(macdLine, "#.####"), text_color=macdLine > 0 ? color.teal : color.red, text_size=size.small) // 柱状图状态 hist_text = hist_expanding_up ? "放大(多)" : hist_expanding_down ? "放大(空)" : hist_shrinking ? "收缩" : "平稳" hist_color = hist_expanding_up ? color.teal : hist_expanding_down ? color.red : color.gray table.cell(info_table, 0, 7, "柱状图", text_color=color.white, text_size=size.small) table.cell(info_table, 1, 7, hist_text, text_color=hist_color, text_size=size.small) // MACD综合评分 score_text = macd_score > 0 ? "+" + str.tostring(macd_score) : str.tostring(macd_score) score_color = macd_score > 0 ? color.teal : macd_score < 0 ? color.red : color.gray table.cell(info_table, 0, 8, "MACD评分", text_color=color.white, text_size=size.small) table.cell(info_table, 1, 8, score_text + " / 2", text_color=score_color, text_size=size.small) // 价格位置 price_pos = price_above_emas ? "均线上方" : price_below_emas ? "均线下方" : "均线之间" price_color = price_above_emas ? color.teal : price_below_emas ? color.red : color.gray table.cell(info_table, 0, 9, "价格位置", text_color=color.white, text_size=size.small) table.cell(info_table, 1, 9, price_pos, text_color=price_color, text_size=size.small) // ========================= 告警 ========================= alertcondition(entered_up, title="上涨趋势开始", message="{{ticker}} {{interval}} 进入上涨趋势 价格:{{close}}") alertcondition(entered_down, title="下跌趋势开始", message="{{ticker}} {{interval}} 进入下跌趋势 价格:{{close}}") alertcondition(entered_consolidation, title="盘整趋势开始", message="{{ticker}} {{interval}} 进入盘整趋势 价格:{{close}}") // ========================= 指标说明 ========================= // 【EMA+MACD三态趋势判断指标】 // // 核心逻辑: // 1. 使用4条EMA(9/21/55/200)判断均线排列和方向 // 2. 结合MACD的位置、方向和柱状图状态 // 3. 综合判断市场处于三种状态之一 // // 📈 上涨趋势判定: // - EMA多头排列(快>中>慢>超慢)或均线同向上升+价格在上方 // - MACD看涨(MACD线>信号线 或 MACD在零轴上方) // // 📉 下跌趋势判定: // - EMA空头排列(快<中<慢<超慢)或均线同向下降+价格在下方 // - MACD看跌(MACD线<信号线 或 MACD在零轴下方) // // 📊 盘整趋势判定: // - EMA线收束(间距小于阈值)或无明确排列 // - MACD在零轴附近 或 柱状图收缩 // - 不满足上涨/下跌条件时自动判定为盘整 // // 参数建议: // - 短线交易:EMA 5/10/20/50, 确认周期1-2 // - 中线交易:EMA 9/21/55/200, 确认周期2-3(默认) // - 长线交易:EMA 20/50/100/200, 确认周期3-5