Files
tradingview-pine/3in1.pine
2025-08-02 07:19:55 +00:00

2161 lines
141 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//@version=6
indicator('MRC+MA200+RSI 综合指标p', shorttitle='MRC+MA200+RSIp', overlay=true, max_labels_count=500)
//************************************************************************************************************
// 参数设置区域
//************************************************************************************************************
// ═════════ MRC 参数 ════════
mrcSet = input(false, '═════════ MRC Parameter ════════')
source = input(hlc3, title='Price Source', group='MRC')
type = input.string('SuperSmoother', title='Filter Type', options=['SuperSmoother', 'Ehlers EMA', 'Gaussian', 'Butterworth', 'BandStop', 'SMA', 'EMA', 'RMA'], group='MRC')
length = input.int(200, title='Lookback Period', minval=1, group='MRC')
innermult = input.float(1.0, title='Inner Channel Size Multiplier', minval=0.1, group='MRC')
outermult = input.float(2.415, title='Outer Channel Size Multiplier', minval=0.1, group='MRC')
// ═════════ MA200 参数 ════════
maSet = input(false, '═════════ MA200 Parameter ════════')
exponential = input.bool(true, title='使用指数移动平均线 (EMA)', group='MA200')
show_ma_lines = input.bool(true, title='显示MA线条', group='MA200')
// ═════════ MA200距离判定参数参考原MA200代码 ════════
distanceSet = input(false, '═════════ MA200 Distance Analysis Parameter ════════')
default_dist = input.float(3.0, title='默认 MA200 距离阈值', minval=0.1, step=0.1, group='Distance')
btc_dist = input.float(300.0, title='BTCUSD MA200 距离阈值', minval=0.1, step=0.1, group='Distance')
xau_dist = input.float(3.5, title='XAUUSD MA200 距离阈值', minval=0.1, step=0.1, group='Distance')
eth_dist = input.float(9.0, title='ETHUSD MA200 距离阈值', minval=0.1, step=0.1, group='Distance')
gbp_dist = input.float(0.3, title='GBPJPY MA200 距离阈值', minval=0.1, step=0.1, group='Distance')
flatness_period = input.int(20, title='MA200 波动回看周期', minval=1, group='Distance')
flatness_threshold = input.float(0.5, title='MA200 平坦度阈值', minval=0.01, step=0.01, group='Distance')
oscillation_bars = input.int(10, title='价格波动回看周期', minval=1, group='Distance')
oscillation_threshold = input.float(5.0, title='价格波动范围阈值', minval=0.1, step=0.1, group='Distance')
// ═════════ R1/S1距离判定参数 ════════
r1s1DistanceSet = input(false, '═════════ R1/S1 Distance Analysis Parameter ════════')
default_r1s1_dist = input.float(3.0, title='默认 R1/S1 距离阈值', minval=0.1, step=0.1, group='R1S1Distance')
btc_r1s1_dist = input.float(300.0, title='BTCUSD R1/S1 距离阈值', minval=0.1, step=0.1, group='R1S1Distance')
xau_r1s1_dist = input.float(3.5, title='XAUUSD R1/S1 距离阈值', minval=0.1, step=0.1, group='R1S1Distance')
eth_r1s1_dist = input.float(9.0, title='ETHUSD R1/S1 距离阈值', minval=0.1, step=0.1, group='R1S1Distance')
gbp_r1s1_dist = input.float(0.3, title='GBPJPY R1/S1 距离阈值', minval=0.1, step=0.1, group='R1S1Distance')
// ═════════ K线标记配置 ════════
signalSet = input(false, '═════════ Signal Marks Configuration ════════')
show_long_marks = input.bool(true, title='显示做多标记', group='Signals')
show_short_marks = input.bool(true, title='显示做空标记', group='Signals')
show_oscillation_marks = input.bool(false, title='显示震荡标记', group='Signals')
show_advanced_alerts = input.bool(true, title='显示高级警报标记', group='Signals')
advanced_alert_style = input.string('超级突出', title='高级警报样式', options=['普通', '突出', '超级突出'], group='Signals')
arrow_size = input.string('small', title='图形标记大小', options=['tiny', 'small', 'normal', 'large', 'huge'], group='Signals')
// ═════════ 高级警报配置 ════════
advancedAlertSet = input(false, '═════════ Advanced Alert Configuration ════════')
enable_advanced_alerts = input.bool(true, title='启用高级警报系统', group='AdvancedAlerts')
time_window_5min = input.int(5, title='条件2时间窗口分钟', minval=1, maxval=30, group='AdvancedAlerts')
time_window_15min = input.int(15, title='条件3时间窗口分钟', minval=5, maxval=60, group='AdvancedAlerts')
time_window_10min = input.int(10, title='条件4时间窗口分钟', minval=5, maxval=30, group='AdvancedAlerts')
require_all_conditions = input.bool(true, title='要求所有条件都满足', group='AdvancedAlerts')
alert_cooldown_minutes = input.int(30, title='警报冷却时间(分钟)', minval=1, maxval=120, group='AdvancedAlerts')
// ═════════ 成交量过滤配置 ════════ (更新版本:添加适中选项)
volumeFilterSet = input(false, '═════════ Volume Filter Configuration ════════')
enable_volume_filter = input.bool(true, title='启用成交量过滤', group='VolumeFilter')
vol_filter_length = input.int(5, title='成交量过滤长度', minval=1, maxval=20, group='VolumeFilter')
vol_multiplier = input.float(1.2, title='默认成交量倍数', minval=0.5, maxval=5.0, step=0.01, group='VolumeFilter')
volume_confirmation_bars = input.int(5, title='成交量确认K线数', minval=1, maxval=20, group='VolumeFilter')
volume_strength_multiplier = input.float(1.05, title='默认成交量强度倍数', minval=1.0, maxval=2.0, step=0.01, group='VolumeFilter')
volume_filter_mode = input.string('适中', title='过滤强度', options=['温和', '适中', '中等', '严格'], group='VolumeFilter')
apply_volume_to_trigger = input.bool(false, title='启动条件应用成交量过滤', group='VolumeFilter')
min_volume_ratio = input.float(0.3, title='默认最小成交量比率', minval=0.1, maxval=1.0, step=0.01, group='VolumeFilter')
show_volume_debug = input.bool(true, title='显示成交量调试信息', group='VolumeFilter')
// ═════════ 品种特定成交量参数 ════════
volumeSymbolSet = input(false, '═════════ Symbol-Specific Volume Parameters ════════')
btc_vol_multiplier = input.float(1.5, title='BTCUSD 成交量倍数', minval=0.1, maxval=5.0, step=0.01, group='SymbolVolume')
xau_vol_multiplier = input.float(1.8, title='XAUUSD 成交量倍数', minval=0.1, maxval=5.0, step=0.01, group='SymbolVolume')
eth_vol_multiplier = input.float(1.3, title='ETHUSD 成交量倍数', minval=0.1, maxval=5.0, step=0.01, group='SymbolVolume')
gbp_vol_multiplier = input.float(2.2, title='GBPJPY 成交量倍数', minval=0.1, maxval=5.0, step=0.01, group='SymbolVolume')
btc_vol_strength = input.float(1.15, title='BTCUSD 成交量强度倍数', minval=0.5, maxval=3.0, step=0.01, group='SymbolVolume')
xau_vol_strength = input.float(1.25, title='XAUUSD 成交量强度倍数', minval=0.5, maxval=3.0, step=0.01, group='SymbolVolume')
eth_vol_strength = input.float(1.1, title='ETHUSD 成交量强度倍数', minval=0.5, maxval=3.0, step=0.01, group='SymbolVolume')
gbp_vol_strength = input.float(1.4, title='GBPJPY 成交量强度倍数', minval=0.5, maxval=3.0, step=0.01, group='SymbolVolume')
btc_min_vol_ratio = input.float(0.35, title='BTCUSD 最小成交量比率', minval=0.05, maxval=1.0, step=0.01, group='SymbolVolume')
xau_min_vol_ratio = input.float(0.45, title='XAUUSD 最小成交量比率', minval=0.05, maxval=1.0, step=0.01, group='SymbolVolume')
eth_min_vol_ratio = input.float(0.4, title='ETHUSD 最小成交量比率', minval=0.05, maxval=1.0, step=0.01, group='SymbolVolume')
gbp_min_vol_ratio = input.float(0.55, title='GBPJPY 最小成交量比率', minval=0.05, maxval=1.0, step=0.01, group='SymbolVolume')
// ═════════ 价格标签配置 ════════
labelSet = input(false, '═════════ Price Labels Configuration ════════')
show_mean_label = input.bool(true, title='显示MEAN价格标签', group='Labels')
show_r1_label = input.bool(true, title='显示R1价格标签', group='Labels')
show_s1_label = input.bool(true, title='显示S1价格标签', group='Labels')
show_r2_label = input.bool(false, title='显示R2价格标签', group='Labels')
show_s2_label = input.bool(false, title='显示S2价格标签', group='Labels')
show_ma50_label = input.bool(true, title='显示MA50价格标签', group='Labels')
show_ma100_label = input.bool(false, title='显示MA100价格标签', group='Labels')
show_ma200_label = input.bool(true, title='显示MA200价格标签', group='Labels')
// ═════════ 线条粗细配置 ════════
lineSet = input(false, '═════════ Line Width Configuration ════════')
mean_width = input.int(3, title='MEAN线宽度', minval=1, maxval=5, group='Lines')
r1_s1_width = input.int(3, title='R1/S1线宽度', minval=1, maxval=5, group='Lines')
r2_s2_width = input.int(2, title='R2/S2线宽度', minval=1, maxval=5, group='Lines')
// ═════════ 表格大小配置 ════════
tableSet = input(false, '═════════ Table Size Configuration ════════')
table_text_size = input.string('tiny', title='表格文字大小', options=['auto', 'tiny', 'small', 'normal', 'large', 'huge'], group='Table')
table_rows = input.int(15, title='信息表格行数', minval=10, maxval=20, group='Table')
table_columns = input.int(4, title='信息表格列数', minval=2, maxval=6, group='Table')
mtf_table_rows = input.int(9, title='多时间框架表格行数', minval=6, maxval=12, group='Table')
mtf_table_columns = input.int(12, title='多时间框架表格列数', minval=8, maxval=14, group='Table')
// 删除不再使用的斜率阈值计算
// ═════════ RSI 参数 ════════
rsiSet = input(false, '═════════ RSI Parameter ════════')
rsi_src = input.source(close, 'RSI Calculation Source', group='RSI')
rsiLength = input.int(14, 'RSI Length', minval=2, group='RSI')
smooth = input.bool(true, 'Smooth RSI?', group='RSI')
maType = input.string('Ema', 'Moving Average Type', options=['SMA', 'Hull', 'Ema', 'Wma', 'DEMA', 'RMA', 'LINREG', 'TEMA', 'ALMA', 'T3'], group='RSI')
smoothP = input.int(4, 'Smoothing Period', group='RSI')
sig = input.int(6, 'Sigma for ALMA', group='RSI')
// ═════════ 多时间框架设置 ════════
mtfSet = input(false, '═════════ Multi-Timeframe Settings ════════')
show_mtf_table = input.bool(true, title='显示多时间框架表格', group='MTF')
mtf_1m = input.bool(true, title='显示1分钟数据', group='MTF')
mtf_5m = input.bool(true, title='显示5分钟数据', group='MTF')
mtf_15m = input.bool(true, title='显示15分钟数据', group='MTF')
mtf_30m = input.bool(true, title='显示30分钟数据', group='MTF')
mtf_45m = input.bool(true, title='显示45分钟数据', group='MTF')
mtf_1h = input.bool(true, title='显示1小时数据', group='MTF')
mtf_4h = input.bool(true, title='显示4小时数据', group='MTF')
// ═════════ 显示设置 ════════
displaySet = input(false, '═════════ Display Settings ════════')
show_info_table = input.bool(false, title='显示信息表格', group='Display')
show_rsi_table = input.bool(false, title='显示RSI表格', group='Display')
table_position = input.string('top_right', title='表格位置', options=['top_left', 'top_center', 'top_right', 'middle_left', 'middle_center', 'middle_right', 'bottom_left', 'bottom_center', 'bottom_right'], group='Display')
//************************************************************************************************************
// 辅助函数定义
//************************************************************************************************************
// ═════════ 品种特定成交量参数获取 ════════
get_volume_multiplier() =>
sym = ticker.standard(syminfo.tickerid)
switch sym
'TICKMILL:BTCUSD' => btc_vol_multiplier
'TICKMILL:XAUUSD' => xau_vol_multiplier
'TICKMILL:ETHUSD' => eth_vol_multiplier
'TICKMILL:GBPJPY' => gbp_vol_multiplier
=> vol_multiplier
get_volume_strength_multiplier() =>
sym = ticker.standard(syminfo.tickerid)
switch sym
'TICKMILL:BTCUSD' => btc_vol_strength
'TICKMILL:XAUUSD' => xau_vol_strength
'TICKMILL:ETHUSD' => eth_vol_strength
'TICKMILL:GBPJPY' => gbp_vol_strength
=> volume_strength_multiplier
get_min_volume_ratio() =>
sym = ticker.standard(syminfo.tickerid)
switch sym
'TICKMILL:BTCUSD' => btc_min_vol_ratio
'TICKMILL:XAUUSD' => xau_min_vol_ratio
'TICKMILL:ETHUSD' => eth_min_vol_ratio
'TICKMILL:GBPJPY' => gbp_min_vol_ratio
=> min_volume_ratio
// ═════════ 成交量分析函数(改进版本) ════════
// Delta Volume Function - 区分买卖成交量
upAndDownVolume() =>
// 简化版本根据K线颜色判断成交量性质
if close > open
volume // 阳线,正成交量
else if close < open
-volume // 阴线,负成交量
else
0.0 // 十字星,中性成交量
// 成交量过滤函数(温和版本,只过滤明显假信号)
get_volume_filter() =>
Vol = upAndDownVolume()
vol_abs = math.abs(Vol)
vol_avg = ta.sma(vol_abs, vol_filter_length)
if not enable_volume_filter
[true, true] // 如果未启用成交量过滤返回true
else
// 获取品种特定的成交量参数
symbol_vol_multiplier = get_volume_multiplier()
symbol_min_vol_ratio = get_min_volume_ratio()
// 根据过滤强度调整阈值
threshold_multiplier = switch volume_filter_mode
'温和' => symbol_vol_multiplier * 0.8 // 降低20%,更容易通过
'适中' => symbol_vol_multiplier * 0.9 // 降低10%,介于温和和中等之间
'中等' => symbol_vol_multiplier
'严格' => symbol_vol_multiplier * 1.3 // 提高30%,更难通过
=> symbol_vol_multiplier
vol_threshold = vol_avg * threshold_multiplier
// 温和过滤:只要成交量方向正确且不是极低成交量即可
long_volume_ok = false
short_volume_ok = false
if volume_filter_mode == '温和'
// 温和模式:只过滤极低成交量的假突破
min_volume_threshold = vol_avg * symbol_min_vol_ratio // 使用品种特定的最小比率
long_volume_ok := Vol > 0 and vol_abs > min_volume_threshold
short_volume_ok := Vol < 0 and vol_abs > min_volume_threshold
else if volume_filter_mode == '适中'
// 适中模式:介于温和和中等之间,使用稍高的最小成交量要求
moderate_volume_threshold = vol_avg * (symbol_min_vol_ratio + 0.2) // 比温和模式高20%
long_volume_ok := Vol > 0 and vol_abs > moderate_volume_threshold
short_volume_ok := Vol < 0 and vol_abs > moderate_volume_threshold
else
// 中等和严格模式:需要成交量强度超过阈值
long_volume_ok := Vol > 0 and vol_abs > vol_threshold
short_volume_ok := Vol < 0 and vol_abs > vol_threshold
[long_volume_ok, short_volume_ok]
// 成交量趋势确认函数(温和版本)
volume_trend_confirmation(signal_type) =>
if not enable_volume_filter
true
else
Vol = upAndDownVolume()
volume_avg = ta.sma(math.abs(Vol), volume_confirmation_bars)
current_volume = math.abs(Vol)
// 获取品种特定的成交量强度参数
symbol_vol_strength = get_volume_strength_multiplier()
// 根据过滤强度调整成交量强度要求
strength_multiplier = switch volume_filter_mode
'温和' => symbol_vol_strength * 0.9 // 降低10%
'适中' => symbol_vol_strength * 0.95 // 降低5%,介于温和和中等之间
'中等' => symbol_vol_strength
'严格' => symbol_vol_strength * 1.2 // 提高20%
=> symbol_vol_strength
volume_strength = current_volume > volume_avg * strength_multiplier
if signal_type == "long"
// 做多信号:需要正成交量且成交量增强
Vol > 0 and volume_strength
else if signal_type == "short"
// 做空信号:需要负成交量且成交量增强
Vol < 0 and volume_strength
else
volume_strength
// ═════════ 距离阈值切换参考原MA200代码 ════════
get_distance_threshold() =>
sym = ticker.standard(syminfo.tickerid)
switch sym
'TICKMILL:BTCUSD' => btc_dist
'TICKMILL:XAUUSD' => xau_dist
'TICKMILL:ETHUSD' => eth_dist
'TICKMILL:GBPJPY' => gbp_dist
=> default_dist
// ═════════ R1/S1距离阈值切换 ════════
get_r1s1_distance_threshold() =>
sym = ticker.standard(syminfo.tickerid)
switch sym
'TICKMILL:BTCUSD' => btc_r1s1_dist
'TICKMILL:XAUUSD' => xau_r1s1_dist
'TICKMILL:ETHUSD' => eth_r1s1_dist
'TICKMILL:GBPJPY' => gbp_r1s1_dist
=> default_r1s1_dist
// ═════════ 表格文字大小转换 ════════
get_text_size() =>
switch table_text_size
'auto' => size.auto
'tiny' => size.tiny
'small' => size.small
'normal' => size.normal
'large' => size.large
'huge' => size.huge
=> size.tiny
// ═════════ 距离背景颜色函数 ════════
get_distance_bg_color(distance_value, threshold) =>
if na(distance_value)
color.new(color.gray, 80) // 无数据时为灰色
else if distance_value > threshold
color.new(color.green, 80) // 距离大于阈值时为浅绿色
else
color.new(color.red, 80) // 距离小于阈值时为浅红色
// ═════════ 箭头大小转换 ════════
get_arrow_size() =>
switch arrow_size
'tiny' => size.tiny
'small' => size.small
'normal' => size.normal
'large' => size.large
'huge' => size.huge
=> size.large
// ═════════ 多时间框架辅助函数 ════════
// 获取信号颜色
get_signal_color(osc_sig, long_sig, short_sig) =>
osc_sig ? color.new(color.yellow, 60) : long_sig ? color.new(color.green, 40) : short_sig ? color.new(color.red, 40) : color.new(color.gray, 80)
// 获取信号文本
get_signal_text(osc_sig, long_sig, short_sig) =>
osc_sig ? "震荡⚡" : long_sig ? "做多🚀" : short_sig ? "做空🔻" : "观望"
// 获取最终判断
get_final_judgment(osc_sig, long_sig, short_sig) =>
osc_sig ? "✓震荡" : long_sig ? "✓做多" : short_sig ? "✓做空" : "观望"
// 获取RSI状态颜色根据条件标记
get_rsi_color(rsi_val, long_threshold, short_threshold, is_neutral, is_overbought, is_oversold) =>
if is_neutral
color.new(color.orange, 40) // 震荡条件
else if is_overbought
color.new(color.green, 40) // 做多条件
else if is_oversold
color.new(color.red, 40) // 做空条件
else
color.white
// 获取价格位置颜色(根据条件标记)
get_price_color(close_val, upband1_val, loband1_val, in_channel, above_r1, below_s1) =>
if in_channel
color.new(color.orange, 40) // 震荡条件
else if above_r1
color.new(color.green, 40) // 做多条件
else if below_s1
color.new(color.red, 40) // 做空条件
else
color.white
// 获取MA50位置颜色根据条件标记
get_ma50_color(ma50_val, meanline_val, above_mean, below_mean) =>
if above_mean
color.new(color.green, 40) // 做多条件
else if below_mean
color.new(color.red, 40) // 做空条件
else
color.white
// 获取MA200距离颜色根据条件标记
get_ma200_distance_color(distance_val, threshold_val, is_near, is_far) =>
if is_near
color.new(color.orange, 40) // 震荡条件
else if is_far
color.new(color.gray, 60) // 趋势条件(做多/做空都需要远离MA200
else
color.white
// 获取价格位置文本
get_price_position(close_val, upband1_val, loband1_val) =>
if na(close_val) or na(upband1_val) or na(loband1_val)
"N/A"
else if close_val > upband1_val
"R1上"
else if close_val < loband1_val
"S1下"
else
"通道内"
// 获取价格与MEAN位置关系文本
get_price_mean_position(close_val, meanline_val) =>
if na(close_val) or na(meanline_val)
"N/A"
else if close_val > meanline_val
"偏多"
else if close_val < meanline_val
"偏空"
else
"平衡"
// 获取价格与MEAN位置关系颜色
get_price_mean_color(close_val, meanline_val) =>
if na(close_val) or na(meanline_val)
color.white
else if close_val > meanline_val
color.new(color.green, 40) // 偏多 - 绿色
else if close_val < meanline_val
color.new(color.red, 40) // 偏空 - 红色
else
color.new(color.gray, 40) // 平衡 - 灰色
// 获取MA50位置文本
get_ma50_position(ma50_val, meanline_val) =>
if na(ma50_val) or na(meanline_val)
"N/A"
else if ma50_val > meanline_val
"MEAN上"
else if ma50_val < meanline_val
"MEAN下"
else
"MEAN附近"
// 获取RSI状态文本
get_rsi_status(rsi_val, long_threshold, short_threshold) =>
if na(rsi_val)
"N/A"
else if rsi_val > long_threshold
"超买"
else if rsi_val < short_threshold
"超卖"
else
"震荡"
// SuperSmoother 函数与原始MRC保持一致
supersmoother(src, len) =>
pi = 2 * math.asin(1)
s_a1 = math.exp(-math.sqrt(2) * pi / len)
s_b1 = 2 * s_a1 * math.cos(math.sqrt(2) * pi / len)
s_c3 = -math.pow(s_a1, 2)
s_c2 = s_b1
s_c1 = 1 - s_c2 - s_c3
ss = 0.0
ss := s_c1 * src + s_c2 * nz(ss[1], src[1]) + s_c3 * nz(ss[2], src[2])
ss
// SAK 平滑函数
SAK_smoothing(type, src, len) =>
switch type
'SMA' => ta.sma(src, len)
'EMA' => ta.ema(src, len)
'RMA' => ta.rma(src, len)
'Gaussian' => ta.sma(src, len) // 简化版本
'Butterworth' => ta.sma(src, len) // 简化版本
'BandStop' => ta.sma(src, len) // 简化版本
'Ehlers EMA' => ta.ema(src, len) // 简化版本
=> ta.sma(src, len)
// MRC 计算函数
get_mrc() =>
v_condition = 0
v_meanline = source
v_meanrange = supersmoother(ta.tr, length)
// 计算π乘数与原始MRC保持一致
pi = 2 * math.asin(1)
mult = pi * innermult
mult2 = pi * outermult
// 获取均线值
if type == 'SuperSmoother'
v_meanline := supersmoother(source, length)
else
v_meanline := SAK_smoothing(type, source, length)
// 计算通道(使用π乘数)
upband1 = v_meanline + v_meanrange * mult
loband1 = v_meanline - v_meanrange * mult
upband2 = v_meanline + v_meanrange * mult2
loband2 = v_meanline - v_meanrange * mult2
[v_meanline, v_meanrange, upband1, loband1, upband2, loband2, v_condition]
// RSI 移动平均函数
dema(src, length) =>
ema1 = ta.ema(src, length)
ema2 = ta.ema(ema1, length)
2 * ema1 - ema2
tema(src, length) =>
ema1 = ta.ema(src, length)
ema2 = ta.ema(ema1, length)
ema3 = ta.ema(ema2, length)
3 * ema1 - 3 * ema2 + ema3
t3(src, length, vfactor) =>
ema1 = ta.ema(src, length)
ema2 = ta.ema(ema1, length)
ema3 = ta.ema(ema2, length)
ema4 = ta.ema(ema3, length)
ema5 = ta.ema(ema4, length)
ema6 = ta.ema(ema5, length)
c1 = -vfactor * vfactor * vfactor
c2 = 3 * vfactor * vfactor + 3 * vfactor * vfactor * vfactor
c3 = -6 * vfactor * vfactor - 3 * vfactor - 3 * vfactor * vfactor * vfactor
c4 = 1 + 3 * vfactor + vfactor * vfactor * vfactor + 3 * vfactor * vfactor
c1 * ema6 + c2 * ema5 + c3 * ema4 + c4 * ema3
ma(src, len, type, almaSig) =>
switch type
'SMA' => ta.sma(src, len)
'Hull' => ta.hma(src, len)
'Ema' => ta.ema(src, len)
'Wma' => ta.wma(src, len)
'DEMA' => dema(src, len)
'RMA' => ta.rma(src, len)
'LINREG' => ta.linreg(src, len, 0)
'TEMA' => tema(src, len)
'ALMA' => ta.alma(src, len, 0, almaSig)
'T3' => t3(src, len, 0.7)
// 多时间框架RSI穿越次数计算函数
mtf_rsi_segment_count(long_threshold, short_threshold) =>
var int rsi_state = 0
var int extreme_type = 0
var int segment_count = 0
rsi_val = smooth ? ma(ta.rsi(rsi_src, rsiLength), smoothP, maType, sig) : ta.rsi(rsi_src, rsiLength)
current_state = rsi_val > long_threshold ? 1 : rsi_val < short_threshold ? -1 : 0
if current_state != rsi_state and not na(rsi_val)
if current_state == 1
if extreme_type != 1
extreme_type := 1
segment_count := 1
else
segment_count := segment_count + 1
else if current_state == -1
if extreme_type != -1
extreme_type := -1
segment_count := -1
else
segment_count := segment_count - 1
rsi_state := current_state
math.abs(segment_count)
// 计算多时间框架RSI穿越次数
get_mtf_rsi_crossover_count(tf, long_threshold, short_threshold) =>
request.security(syminfo.tickerid, tf, mtf_rsi_segment_count(long_threshold, short_threshold), lookahead=barmerge.lookahead_off)
//************************************************************************************************************
// 多时间框架计算函数
//************************************************************************************************************
// 多时间框架MRC计算函数
get_mtf_mrc(tf) =>
request.security(syminfo.tickerid, tf, get_mrc(), lookahead=barmerge.lookahead_off)
// 多时间框架MA计算函数
get_mtf_ma(tf) =>
ma50_mtf = request.security(syminfo.tickerid, tf, exponential ? ta.ema(close, 50) : ta.sma(close, 50), lookahead=barmerge.lookahead_off)
ma100_mtf = request.security(syminfo.tickerid, tf, exponential ? ta.ema(close, 100) : ta.sma(close, 100), lookahead=barmerge.lookahead_off)
ma200_mtf = request.security(syminfo.tickerid, tf, exponential ? ta.ema(close, 200) : ta.sma(close, 200), lookahead=barmerge.lookahead_off)
close_mtf = request.security(syminfo.tickerid, tf, close, lookahead=barmerge.lookahead_off)
[ma50_mtf, ma100_mtf, ma200_mtf, close_mtf]
// 多时间框架RSI计算函数
get_mtf_rsi(tf) =>
rsi_mtf = request.security(syminfo.tickerid, tf, ta.rsi(rsi_src, rsiLength), lookahead=barmerge.lookahead_off)
if smooth
rsi_mtf := request.security(syminfo.tickerid, tf, ma(ta.rsi(rsi_src, rsiLength), smoothP, maType, sig), lookahead=barmerge.lookahead_off)
rsi_mtf
//************************************************************************************************************
// 指标计算
//************************************************************************************************************
// ═════════ MA 计算 ═════════
src = close
ma50 = exponential ? ta.ema(src, 50) : ta.sma(src, 50)
ma100 = exponential ? ta.ema(src, 100) : ta.sma(src, 100)
ma200 = exponential ? ta.ema(src, 200) : ta.sma(src, 200)
// ═════════ MRC 计算 ═════════
[meanline, meanrange, upband1, loband1, upband2, loband2, condition] = get_mrc()
// ═════════ RSI 计算 ═════════
rsi = ta.rsi(rsi_src, rsiLength)
if smooth
rsi := ma(rsi, smoothP, maType, sig)
// RSI 机器学习阈值计算(简化版)
var rsi_values = array.new_float(0)
if last_bar_index - bar_index <= 1000
array.push(rsi_values, rsi)
var centroids = array.new_float(3)
if array.size(rsi_values) > 3
array.set(centroids, 0, array.percentile_linear_interpolation(rsi_values, 25))
array.set(centroids, 1, array.percentile_linear_interpolation(rsi_values, 50))
array.set(centroids, 2, array.percentile_linear_interpolation(rsi_values, 75))
long_S = array.get(centroids, 2)
short_S = array.get(centroids, 0)
// ═════════ 预先计算所有多时间框架RSI穿越次数避免在条件块内调用 ═════════
cross_count_1m = mtf_1m ? get_mtf_rsi_crossover_count("1", long_S, short_S) : na
cross_count_5m = mtf_5m ? get_mtf_rsi_crossover_count("5", long_S, short_S) : na
cross_count_15m = mtf_15m ? get_mtf_rsi_crossover_count("15", long_S, short_S) : na
cross_count_30m = mtf_30m ? get_mtf_rsi_crossover_count("30", long_S, short_S) : na
cross_count_45m = mtf_45m ? get_mtf_rsi_crossover_count("45", long_S, short_S) : na
cross_count_1h = mtf_1h ? get_mtf_rsi_crossover_count("60", long_S, short_S) : na
cross_count_4h = mtf_4h ? get_mtf_rsi_crossover_count("240", long_S, short_S) : na
// RSI 状态和计数逻辑
var int rsi_state = 0
var int extreme_type = 0
var int segment_count = 0
current_state = rsi > long_S ? 1 : rsi < short_S ? -1 : 0
if current_state != rsi_state and not na(rsi)
if current_state == 1
if extreme_type != 1
extreme_type := 1
segment_count := 1
else
segment_count := segment_count + 1
else if current_state == -1
if extreme_type != -1
extreme_type := -1
segment_count := -1
else
segment_count := segment_count - 1
rsi_state := current_state
// ═════════ 多时间框架数据获取 ═════════
// 直接获取多时间框架数据(简化方法)
// 1分钟数据
rsi_1m = mtf_1m ? get_mtf_rsi("1") : na
close_1m = mtf_1m ? request.security(syminfo.tickerid, "1", close, lookahead=barmerge.lookahead_off) : na
ma50_1m = mtf_1m ? request.security(syminfo.tickerid, "1", exponential ? ta.ema(close, 50) : ta.sma(close, 50), lookahead=barmerge.lookahead_off) : na
ma200_1m = mtf_1m ? request.security(syminfo.tickerid, "1", exponential ? ta.ema(close, 200) : ta.sma(close, 200), lookahead=barmerge.lookahead_off) : na
meanline_1m = mtf_1m ? request.security(syminfo.tickerid, "1", supersmoother(source, length), lookahead=barmerge.lookahead_off) : na
meanrange_1m = mtf_1m ? request.security(syminfo.tickerid, "1", supersmoother(ta.tr, length), lookahead=barmerge.lookahead_off) : na
upband1_1m = mtf_1m and not na(meanline_1m) and not na(meanrange_1m) ? meanline_1m + meanrange_1m * (2 * math.asin(1) * innermult) : na
loband1_1m = mtf_1m and not na(meanline_1m) and not na(meanrange_1m) ? meanline_1m - meanrange_1m * (2 * math.asin(1) * innermult) : na
// 5分钟数据
rsi_5m = mtf_5m ? get_mtf_rsi("5") : na
close_5m = mtf_5m ? request.security(syminfo.tickerid, "5", close, lookahead=barmerge.lookahead_off) : na
ma50_5m = mtf_5m ? request.security(syminfo.tickerid, "5", exponential ? ta.ema(close, 50) : ta.sma(close, 50), lookahead=barmerge.lookahead_off) : na
ma200_5m = mtf_5m ? request.security(syminfo.tickerid, "5", exponential ? ta.ema(close, 200) : ta.sma(close, 200), lookahead=barmerge.lookahead_off) : na
meanline_5m = mtf_5m ? request.security(syminfo.tickerid, "5", supersmoother(source, length), lookahead=barmerge.lookahead_off) : na
meanrange_5m = mtf_5m ? request.security(syminfo.tickerid, "5", supersmoother(ta.tr, length), lookahead=barmerge.lookahead_off) : na
upband1_5m = mtf_5m and not na(meanline_5m) and not na(meanrange_5m) ? meanline_5m + meanrange_5m * (2 * math.asin(1) * innermult) : na
loband1_5m = mtf_5m and not na(meanline_5m) and not na(meanrange_5m) ? meanline_5m - meanrange_5m * (2 * math.asin(1) * innermult) : na
// 15分钟数据
rsi_15m = mtf_15m ? get_mtf_rsi("15") : na
close_15m = mtf_15m ? request.security(syminfo.tickerid, "15", close, lookahead=barmerge.lookahead_off) : na
ma50_15m = mtf_15m ? request.security(syminfo.tickerid, "15", exponential ? ta.ema(close, 50) : ta.sma(close, 50), lookahead=barmerge.lookahead_off) : na
ma200_15m = mtf_15m ? request.security(syminfo.tickerid, "15", exponential ? ta.ema(close, 200) : ta.sma(close, 200), lookahead=barmerge.lookahead_off) : na
meanline_15m = mtf_15m ? request.security(syminfo.tickerid, "15", supersmoother(source, length), lookahead=barmerge.lookahead_off) : na
meanrange_15m = mtf_15m ? request.security(syminfo.tickerid, "15", supersmoother(ta.tr, length), lookahead=barmerge.lookahead_off) : na
upband1_15m = mtf_15m and not na(meanline_15m) and not na(meanrange_15m) ? meanline_15m + meanrange_15m * (2 * math.asin(1) * innermult) : na
loband1_15m = mtf_15m and not na(meanline_15m) and not na(meanrange_15m) ? meanline_15m - meanrange_15m * (2 * math.asin(1) * innermult) : na
// 30分钟数据
rsi_30m = mtf_30m ? get_mtf_rsi("30") : na
close_30m = mtf_30m ? request.security(syminfo.tickerid, "30", close, lookahead=barmerge.lookahead_off) : na
ma50_30m = mtf_30m ? request.security(syminfo.tickerid, "30", exponential ? ta.ema(close, 50) : ta.sma(close, 50), lookahead=barmerge.lookahead_off) : na
ma200_30m = mtf_30m ? request.security(syminfo.tickerid, "30", exponential ? ta.ema(close, 200) : ta.sma(close, 200), lookahead=barmerge.lookahead_off) : na
meanline_30m = mtf_30m ? request.security(syminfo.tickerid, "30", supersmoother(source, length), lookahead=barmerge.lookahead_off) : na
meanrange_30m = mtf_30m ? request.security(syminfo.tickerid, "30", supersmoother(ta.tr, length), lookahead=barmerge.lookahead_off) : na
upband1_30m = mtf_30m and not na(meanline_30m) and not na(meanrange_30m) ? meanline_30m + meanrange_30m * (2 * math.asin(1) * innermult) : na
loband1_30m = mtf_30m and not na(meanline_30m) and not na(meanrange_30m) ? meanline_30m - meanrange_30m * (2 * math.asin(1) * innermult) : na
// 45分钟数据
rsi_45m = mtf_45m ? get_mtf_rsi("45") : na
close_45m = mtf_45m ? request.security(syminfo.tickerid, "45", close, lookahead=barmerge.lookahead_off) : na
ma50_45m = mtf_45m ? request.security(syminfo.tickerid, "45", exponential ? ta.ema(close, 50) : ta.sma(close, 50), lookahead=barmerge.lookahead_off) : na
ma200_45m = mtf_45m ? request.security(syminfo.tickerid, "45", exponential ? ta.ema(close, 200) : ta.sma(close, 200), lookahead=barmerge.lookahead_off) : na
meanline_45m = mtf_45m ? request.security(syminfo.tickerid, "45", supersmoother(source, length), lookahead=barmerge.lookahead_off) : na
meanrange_45m = mtf_45m ? request.security(syminfo.tickerid, "45", supersmoother(ta.tr, length), lookahead=barmerge.lookahead_off) : na
upband1_45m = mtf_45m and not na(meanline_45m) and not na(meanrange_45m) ? meanline_45m + meanrange_45m * (2 * math.asin(1) * innermult) : na
loband1_45m = mtf_45m and not na(meanline_45m) and not na(meanrange_45m) ? meanline_45m - meanrange_45m * (2 * math.asin(1) * innermult) : na
// 1小时数据
rsi_1h = mtf_1h ? get_mtf_rsi("60") : na
close_1h = mtf_1h ? request.security(syminfo.tickerid, "60", close, lookahead=barmerge.lookahead_off) : na
ma50_1h = mtf_1h ? request.security(syminfo.tickerid, "60", exponential ? ta.ema(close, 50) : ta.sma(close, 50), lookahead=barmerge.lookahead_off) : na
ma200_1h = mtf_1h ? request.security(syminfo.tickerid, "60", exponential ? ta.ema(close, 200) : ta.sma(close, 200), lookahead=barmerge.lookahead_off) : na
meanline_1h = mtf_1h ? request.security(syminfo.tickerid, "60", supersmoother(source, length), lookahead=barmerge.lookahead_off) : na
meanrange_1h = mtf_1h ? request.security(syminfo.tickerid, "60", supersmoother(ta.tr, length), lookahead=barmerge.lookahead_off) : na
upband1_1h = mtf_1h and not na(meanline_1h) and not na(meanrange_1h) ? meanline_1h + meanrange_1h * (2 * math.asin(1) * innermult) : na
loband1_1h = mtf_1h and not na(meanline_1h) and not na(meanrange_1h) ? meanline_1h - meanrange_1h * (2 * math.asin(1) * innermult) : na
// 4小时数据
rsi_4h = mtf_4h ? get_mtf_rsi("240") : na
close_4h = mtf_4h ? request.security(syminfo.tickerid, "240", close, lookahead=barmerge.lookahead_off) : na
ma50_4h = mtf_4h ? request.security(syminfo.tickerid, "240", exponential ? ta.ema(close, 50) : ta.sma(close, 50), lookahead=barmerge.lookahead_off) : na
ma200_4h = mtf_4h ? request.security(syminfo.tickerid, "240", exponential ? ta.ema(close, 200) : ta.sma(close, 200), lookahead=barmerge.lookahead_off) : na
meanline_4h = mtf_4h ? request.security(syminfo.tickerid, "240", supersmoother(source, length), lookahead=barmerge.lookahead_off) : na
meanrange_4h = mtf_4h ? request.security(syminfo.tickerid, "240", supersmoother(ta.tr, length), lookahead=barmerge.lookahead_off) : na
upband1_4h = mtf_4h and not na(meanline_4h) and not na(meanrange_4h) ? meanline_4h + meanrange_4h * (2 * math.asin(1) * innermult) : na
loband1_4h = mtf_4h and not na(meanline_4h) and not na(meanrange_4h) ? meanline_4h - meanrange_4h * (2 * math.asin(1) * innermult) : na
// 计算多时间框架信号(修正版本,与原指标逻辑一致)
// 1分钟信号
distance_1m = mtf_1m and not na(close_1m) and not na(ma200_1m) ? math.abs(close_1m - ma200_1m) : na
distance_threshold_1m = get_distance_threshold()
// 1分钟R1/S1/MEAN距离计算
distance_to_r1_1m = mtf_1m and not na(close_1m) and not na(upband1_1m) ? math.abs(close_1m - upband1_1m) : na
distance_to_s1_1m = mtf_1m and not na(close_1m) and not na(loband1_1m) ? math.abs(close_1m - loband1_1m) : na
distance_to_mean_1m = mtf_1m and not na(close_1m) and not na(meanline_1m) ? math.abs(close_1m - meanline_1m) : na
// 1分钟完整信号判断
rsi_neutral_1m = mtf_1m and not na(rsi_1m) ? (rsi_1m >= short_S and rsi_1m <= long_S) : false
price_in_channel_1m = mtf_1m and not na(close_1m) and not na(upband1_1m) and not na(loband1_1m) ? (close_1m >= loband1_1m and close_1m <= upband1_1m) : false
ma200_near_1m = mtf_1m and not na(distance_1m) ? (distance_1m <= distance_threshold_1m) : false
osc_1m = rsi_neutral_1m or price_in_channel_1m or ma200_near_1m
rsi_overbought_1m = mtf_1m and not na(rsi_1m) ? (rsi_1m > long_S) : false
price_above_r1_1m = mtf_1m and not na(close_1m) and not na(upband1_1m) ? (close_1m > upband1_1m) : false
ma200_far_1m = mtf_1m and not na(distance_1m) ? (distance_1m > distance_threshold_1m) : false
ma50_above_mean_1m = mtf_1m and not na(ma50_1m) and not na(meanline_1m) ? (ma50_1m > meanline_1m) : false
long_1m = rsi_overbought_1m and price_above_r1_1m and ma200_far_1m and ma50_above_mean_1m
rsi_oversold_1m = mtf_1m and not na(rsi_1m) ? (rsi_1m < short_S) : false
price_below_s1_1m = mtf_1m and not na(close_1m) and not na(loband1_1m) ? (close_1m < loband1_1m) : false
ma50_below_mean_1m = mtf_1m and not na(ma50_1m) and not na(meanline_1m) ? (ma50_1m < meanline_1m) : false
short_1m = rsi_oversold_1m and price_below_s1_1m and ma200_far_1m and ma50_below_mean_1m
// 5分钟信号
distance_5m = mtf_5m and not na(close_5m) and not na(ma200_5m) ? math.abs(close_5m - ma200_5m) : na
// 5分钟R1/S1/MEAN距离计算
distance_to_r1_5m = mtf_5m and not na(close_5m) and not na(upband1_5m) ? math.abs(close_5m - upband1_5m) : na
distance_to_s1_5m = mtf_5m and not na(close_5m) and not na(loband1_5m) ? math.abs(close_5m - loband1_5m) : na
distance_to_mean_5m = mtf_5m and not na(close_5m) and not na(meanline_5m) ? math.abs(close_5m - meanline_5m) : na
rsi_neutral_5m = mtf_5m and not na(rsi_5m) ? (rsi_5m >= short_S and rsi_5m <= long_S) : false
price_in_channel_5m = mtf_5m and not na(close_5m) and not na(upband1_5m) and not na(loband1_5m) ? (close_5m >= loband1_5m and close_5m <= upband1_5m) : false
ma200_near_5m = mtf_5m and not na(distance_5m) ? (distance_5m <= distance_threshold_1m) : false
osc_5m = rsi_neutral_5m or price_in_channel_5m or ma200_near_5m
rsi_overbought_5m = mtf_5m and not na(rsi_5m) ? (rsi_5m > long_S) : false
price_above_r1_5m = mtf_5m and not na(close_5m) and not na(upband1_5m) ? (close_5m > upband1_5m) : false
price_above_mean_5m = mtf_5m and not na(close_5m) and not na(meanline_5m) ? (close_5m >= meanline_5m or math.abs(close_5m - meanline_5m) <= get_r1s1_distance_threshold()) : false
ma200_far_5m = mtf_5m and not na(distance_5m) ? (distance_5m > distance_threshold_1m) : false
ma50_above_mean_5m = mtf_5m and not na(ma50_5m) and not na(meanline_5m) ? (ma50_5m > meanline_5m) : false
long_5m = rsi_overbought_5m and price_above_r1_5m and ma200_far_5m and ma50_above_mean_5m
rsi_oversold_5m = mtf_5m and not na(rsi_5m) ? (rsi_5m < short_S) : false
price_below_s1_5m = mtf_5m and not na(close_5m) and not na(loband1_5m) ? (close_5m < loband1_5m) : false
price_below_mean_5m = mtf_5m and not na(close_5m) and not na(meanline_5m) ? (close_5m <= meanline_5m or math.abs(close_5m - meanline_5m) <= get_r1s1_distance_threshold()) : false
ma50_below_mean_5m = mtf_5m and not na(ma50_5m) and not na(meanline_5m) ? (ma50_5m < meanline_5m) : false
short_5m = rsi_oversold_5m and price_below_s1_5m and ma200_far_5m and ma50_below_mean_5m
// 15分钟信号
distance_15m = mtf_15m and not na(close_15m) and not na(ma200_15m) ? math.abs(close_15m - ma200_15m) : na
// 15分钟R1/S1/MEAN距离计算
distance_to_r1_15m = mtf_15m and not na(close_15m) and not na(upband1_15m) ? math.abs(close_15m - upband1_15m) : na
distance_to_s1_15m = mtf_15m and not na(close_15m) and not na(loband1_15m) ? math.abs(close_15m - loband1_15m) : na
distance_to_mean_15m = mtf_15m and not na(close_15m) and not na(meanline_15m) ? math.abs(close_15m - meanline_15m) : na
rsi_neutral_15m = mtf_15m and not na(rsi_15m) ? (rsi_15m >= short_S and rsi_15m <= long_S) : false
price_in_channel_15m = mtf_15m and not na(close_15m) and not na(upband1_15m) and not na(loband1_15m) ? (close_15m >= loband1_15m and close_15m <= upband1_15m) : false
ma200_near_15m = mtf_15m and not na(distance_15m) ? (distance_15m <= distance_threshold_1m) : false
osc_15m = rsi_neutral_15m or price_in_channel_15m or ma200_near_15m
rsi_overbought_15m = mtf_15m and not na(rsi_15m) ? (rsi_15m > long_S) : false
price_above_r1_15m = mtf_15m and not na(close_15m) and not na(upband1_15m) ? (close_15m > upband1_15m) : false
ma200_far_15m = mtf_15m and not na(distance_15m) ? (distance_15m > distance_threshold_1m) : false
ma50_above_mean_15m = mtf_15m and not na(ma50_15m) and not na(meanline_15m) ? (ma50_15m > meanline_15m) : false
long_15m = rsi_overbought_15m and price_above_r1_15m and ma200_far_15m and ma50_above_mean_15m
rsi_oversold_15m = mtf_15m and not na(rsi_15m) ? (rsi_15m < short_S) : false
price_below_s1_15m = mtf_15m and not na(close_15m) and not na(loband1_15m) ? (close_15m < loband1_15m) : false
ma50_below_mean_15m = mtf_15m and not na(ma50_15m) and not na(meanline_15m) ? (ma50_15m < meanline_15m) : false
short_15m = rsi_oversold_15m and price_below_s1_15m and ma200_far_15m and ma50_below_mean_15m
// 30分钟信号
distance_30m = mtf_30m and not na(close_30m) and not na(ma200_30m) ? math.abs(close_30m - ma200_30m) : na
// 30分钟R1/S1/MEAN距离计算
distance_to_r1_30m = mtf_30m and not na(close_30m) and not na(upband1_30m) ? math.abs(close_30m - upband1_30m) : na
distance_to_s1_30m = mtf_30m and not na(close_30m) and not na(loband1_30m) ? math.abs(close_30m - loband1_30m) : na
distance_to_mean_30m = mtf_30m and not na(close_30m) and not na(meanline_30m) ? math.abs(close_30m - meanline_30m) : na
rsi_neutral_30m = mtf_30m and not na(rsi_30m) ? (rsi_30m >= short_S and rsi_30m <= long_S) : false
price_in_channel_30m = mtf_30m and not na(close_30m) and not na(upband1_30m) and not na(loband1_30m) ? (close_30m >= loband1_30m and close_30m <= upband1_30m) : false
ma200_near_30m = mtf_30m and not na(distance_30m) ? (distance_30m <= distance_threshold_1m) : false
osc_30m = rsi_neutral_30m or price_in_channel_30m or ma200_near_30m
rsi_overbought_30m = mtf_30m and not na(rsi_30m) ? (rsi_30m > long_S) : false
price_above_r1_30m = mtf_30m and not na(close_30m) and not na(upband1_30m) ? (close_30m > upband1_30m) : false
ma200_far_30m = mtf_30m and not na(distance_30m) ? (distance_30m > distance_threshold_1m) : false
ma50_above_mean_30m = mtf_30m and not na(ma50_30m) and not na(meanline_30m) ? (ma50_30m > meanline_30m) : false
long_30m = rsi_overbought_30m and price_above_r1_30m and ma200_far_30m and ma50_above_mean_30m
rsi_oversold_30m = mtf_30m and not na(rsi_30m) ? (rsi_30m < short_S) : false
price_below_s1_30m = mtf_30m and not na(close_30m) and not na(loband1_30m) ? (close_30m < loband1_30m) : false
ma50_below_mean_30m = mtf_30m and not na(ma50_30m) and not na(meanline_30m) ? (ma50_30m < meanline_30m) : false
short_30m = rsi_oversold_30m and price_below_s1_30m and ma200_far_30m and ma50_below_mean_30m
// 45分钟信号
distance_45m = mtf_45m and not na(close_45m) and not na(ma200_45m) ? math.abs(close_45m - ma200_45m) : na
// 45分钟R1/S1/MEAN距离计算
distance_to_r1_45m = mtf_45m and not na(close_45m) and not na(upband1_45m) ? math.abs(close_45m - upband1_45m) : na
distance_to_s1_45m = mtf_45m and not na(close_45m) and not na(loband1_45m) ? math.abs(close_45m - loband1_45m) : na
distance_to_mean_45m = mtf_45m and not na(close_45m) and not na(meanline_45m) ? math.abs(close_45m - meanline_45m) : na
rsi_neutral_45m = mtf_45m and not na(rsi_45m) ? (rsi_45m >= short_S and rsi_45m <= long_S) : false
price_in_channel_45m = mtf_45m and not na(close_45m) and not na(upband1_45m) and not na(loband1_45m) ? (close_45m >= loband1_45m and close_45m <= upband1_45m) : false
ma200_near_45m = mtf_45m and not na(distance_45m) ? (distance_45m <= distance_threshold_1m) : false
osc_45m = rsi_neutral_45m or price_in_channel_45m or ma200_near_45m
rsi_overbought_45m = mtf_45m and not na(rsi_45m) ? (rsi_45m > long_S) : false
price_above_r1_45m = mtf_45m and not na(close_45m) and not na(upband1_45m) ? (close_45m > upband1_45m) : false
ma200_far_45m = mtf_45m and not na(distance_45m) ? (distance_45m > distance_threshold_1m) : false
ma50_above_mean_45m = mtf_45m and not na(ma50_45m) and not na(meanline_45m) ? (ma50_45m > meanline_45m) : false
long_45m = rsi_overbought_45m and price_above_r1_45m and ma200_far_45m and ma50_above_mean_45m
rsi_oversold_45m = mtf_45m and not na(rsi_45m) ? (rsi_45m < short_S) : false
price_below_s1_45m = mtf_45m and not na(close_45m) and not na(loband1_45m) ? (close_45m < loband1_45m) : false
ma50_below_mean_45m = mtf_45m and not na(ma50_45m) and not na(meanline_45m) ? (ma50_45m < meanline_45m) : false
short_45m = rsi_oversold_45m and price_below_s1_45m and ma200_far_45m and ma50_below_mean_45m
// 1小时信号
distance_1h = mtf_1h and not na(close_1h) and not na(ma200_1h) ? math.abs(close_1h - ma200_1h) : na
// 1小时R1/S1/MEAN距离计算
distance_to_r1_1h = mtf_1h and not na(close_1h) and not na(upband1_1h) ? math.abs(close_1h - upband1_1h) : na
distance_to_s1_1h = mtf_1h and not na(close_1h) and not na(loband1_1h) ? math.abs(close_1h - loband1_1h) : na
distance_to_mean_1h = mtf_1h and not na(close_1h) and not na(meanline_1h) ? math.abs(close_1h - meanline_1h) : na
rsi_neutral_1h = mtf_1h and not na(rsi_1h) ? (rsi_1h >= short_S and rsi_1h <= long_S) : false
price_in_channel_1h = mtf_1h and not na(close_1h) and not na(upband1_1h) and not na(loband1_1h) ? (close_1h >= loband1_1h and close_1h <= upband1_1h) : false
ma200_near_1h = mtf_1h and not na(distance_1h) ? (distance_1h <= distance_threshold_1m) : false
osc_1h = rsi_neutral_1h or price_in_channel_1h or ma200_near_1h
rsi_overbought_1h = mtf_1h and not na(rsi_1h) ? (rsi_1h > long_S) : false
price_above_r1_1h = mtf_1h and not na(close_1h) and not na(upband1_1h) ? (close_1h > upband1_1h) : false
ma200_far_1h = mtf_1h and not na(distance_1h) ? (distance_1h > distance_threshold_1m) : false
ma50_above_mean_1h = mtf_1h and not na(ma50_1h) and not na(meanline_1h) ? (ma50_1h > meanline_1h) : false
long_1h = rsi_overbought_1h and price_above_r1_1h and ma200_far_1h and ma50_above_mean_1h
rsi_oversold_1h = mtf_1h and not na(rsi_1h) ? (rsi_1h < short_S) : false
price_below_s1_1h = mtf_1h and not na(close_1h) and not na(loband1_1h) ? (close_1h < loband1_1h) : false
ma50_below_mean_1h = mtf_1h and not na(ma50_1h) and not na(meanline_1h) ? (ma50_1h < meanline_1h) : false
short_1h = rsi_oversold_1h and price_below_s1_1h and ma200_far_1h and ma50_below_mean_1h
// 4小时信号
distance_4h = mtf_4h and not na(close_4h) and not na(ma200_4h) ? math.abs(close_4h - ma200_4h) : na
// 4小时R1/S1/MEAN距离计算
distance_to_r1_4h = mtf_4h and not na(close_4h) and not na(upband1_4h) ? math.abs(close_4h - upband1_4h) : na
distance_to_s1_4h = mtf_4h and not na(close_4h) and not na(loband1_4h) ? math.abs(close_4h - loband1_4h) : na
distance_to_mean_4h = mtf_4h and not na(close_4h) and not na(meanline_4h) ? math.abs(close_4h - meanline_4h) : na
rsi_neutral_4h = mtf_4h and not na(rsi_4h) ? (rsi_4h >= short_S and rsi_4h <= long_S) : false
price_in_channel_4h = mtf_4h and not na(close_4h) and not na(upband1_4h) and not na(loband1_4h) ? (close_4h >= loband1_4h and close_4h <= upband1_4h) : false
ma200_near_4h = mtf_4h and not na(distance_4h) ? (distance_4h <= distance_threshold_1m) : false
osc_4h = rsi_neutral_4h or price_in_channel_4h or ma200_near_4h
rsi_overbought_4h = mtf_4h and not na(rsi_4h) ? (rsi_4h > long_S) : false
price_above_r1_4h = mtf_4h and not na(close_4h) and not na(upband1_4h) ? (close_4h > upband1_4h) : false
ma200_far_4h = mtf_4h and not na(distance_4h) ? (distance_4h > distance_threshold_1m) : false
ma50_above_mean_4h = mtf_4h and not na(ma50_4h) and not na(meanline_4h) ? (ma50_4h > meanline_4h) : false
long_4h = rsi_overbought_4h and price_above_r1_4h and ma200_far_4h and ma50_above_mean_4h
rsi_oversold_4h = mtf_4h and not na(rsi_4h) ? (rsi_4h < short_S) : false
price_below_s1_4h = mtf_4h and not na(close_4h) and not na(loband1_4h) ? (close_4h < loband1_4h) : false
ma50_below_mean_4h = mtf_4h and not na(ma50_4h) and not na(meanline_4h) ? (ma50_4h < meanline_4h) : false
short_4h = rsi_oversold_4h and price_below_s1_4h and ma200_far_4h and ma50_below_mean_4h
//************************************************************************************************************
// 计算实时数值
//************************************************************************************************************
// MA50 和 MEAN 的关系
ma50_vs_mean = ma50 > meanline ? "上方" : ma50 < meanline ? "下方" : "重合"
ma50_mean_distance = math.abs(ma50 - meanline)
// MA50 和 MA200 的关系
ma50_vs_ma200 = ma50 > ma200 ? "上方" : ma50 < ma200 ? "下方" : "重合"
ma50_ma200_distance = math.abs(ma50 - ma200)
// 价格和 MA200 的关系
price_vs_ma200 = close > ma200 ? "上方" : close < ma200 ? "下方" : "重合"
price_ma200_distance = math.abs(close - ma200)
// MA200 历史值
ma200_current = ma200
ma200_4bars_ago = ma200[4]
ma200_10bars_ago = ma200[10]
ma200_14bars_ago = ma200[14]
// MA200 斜率计算
ma200_slope_4 = not na(ma200_4bars_ago) ? (ma200_current - ma200_4bars_ago) / 4 : 0
ma200_slope_10 = not na(ma200_10bars_ago) ? (ma200_current - ma200_10bars_ago) / 10 : 0
ma200_slope_14 = not na(ma200_14bars_ago) ? (ma200_10bars_ago - ma200_14bars_ago) / 4 : 0
// MA200 斜率变化计算
ma200_slope_change_4 = not na(ma200_slope_4[1]) ? ma200_slope_4 - ma200_slope_4[1] : 0
ma200_slope_change_10 = not na(ma200_slope_10[1]) ? ma200_slope_10 - ma200_slope_10[1] : 0
// 删除不再使用的角度计算
// 保留原有斜率计算(用于其他功能)
ma200_slope_segment1 = not na(ma200_4bars_ago) ? (ma200_current - ma200_4bars_ago) / 4 : 0
ma200_slope_segment2 = not na(ma200_14bars_ago) and not na(ma200_10bars_ago) ? (ma200_10bars_ago - ma200_14bars_ago) / 4 : 0
// 删除不再使用的角度和百分比相关代码
// ═════════ MA200距离分析参考原MA200代码 ════════
distance_threshold = get_distance_threshold()
distance_usd = math.abs(close - ma200_current)
is_near_ma200 = distance_usd <= distance_threshold
// ═════════ R1/S1距离分析 ════════
r1s1_distance_threshold = get_r1s1_distance_threshold()
distance_to_r1 = math.abs(close - upband1)
distance_to_s1 = math.abs(close - loband1)
is_near_r1 = distance_to_r1 <= r1s1_distance_threshold
is_near_s1 = distance_to_s1 <= r1s1_distance_threshold
// MA200平坦度分析
ma200_max = ta.highest(ma200_current, flatness_period)
ma200_min = ta.lowest(ma200_current, flatness_period)
ma200_flatness = ma200_max - ma200_min
is_flat = ma200_flatness < flatness_threshold
// 价格波动分析
price_max = ta.highest(close, oscillation_bars)
price_min = ta.lowest(close, oscillation_bars)
price_range = price_max - price_min
cross_above = ta.crossover(close, ma200_current)
cross_below = ta.crossunder(close, ma200_current)
is_oscillating_price = price_range < oscillation_threshold and (cross_above or cross_below)
// 删除重复的百分比计算(已在前面定义)
// 删除残留的旧代码片段
// 删除不再使用的斜率变化方向计算
// ═════════ 基于距离的MA200分析逻辑参考原MA200代码 ════════
// 1. 基础状态判断
is_above_ma200 = close > ma200_current
is_below_ma200 = close < ma200_current
// 2. MA200趋势方向判断基于MA200自身变化
ma200_change_4 = not na(ma200_4bars_ago) ? ma200_current - ma200_4bars_ago : 0
ma200_change_10 = not na(ma200_10bars_ago) ? ma200_current - ma200_10bars_ago : 0
ma200_direction = ma200_change_10 > flatness_threshold ? "上升" : ma200_change_10 < -flatness_threshold ? "下降" : "横盘"
// 3. 趋势强度判断基于MA200变化幅度
ma200_change_abs = math.abs(ma200_change_10)
ma200_strength = ma200_change_abs >= flatness_threshold * 4 ? "强" : ma200_change_abs >= flatness_threshold * 2 ? "中" : ma200_change_abs >= flatness_threshold ? "弱" : "微弱"
// 4. 振荡判断参考原MA200逻辑
// 条件1MA200本身比较平坦
condition1_ma200_flat = is_flat
// 条件2价格在MA200附近波动
condition2_price_oscillating = is_oscillating_price
// 条件3价格靠近MA200
condition3_near_ma200 = is_near_ma200
// 综合振荡判断
is_oscillating = condition1_ma200_flat or condition2_price_oscillating or (condition3_near_ma200 and ma200_direction == "横盘")
// 5. 最终趋势判断
ma200_trend_strength = is_oscillating ? "震荡" : ma200_strength + "趋势"
ma200_trend_direction = is_oscillating ? "横盘" : ma200_direction
// 6. 趋势变化分析(基于距离变化)
distance_change = not na(distance_usd[1]) ? distance_usd - distance_usd[1] : 0
trend_acceleration = math.abs(distance_change) > distance_threshold * 0.1 ? (distance_change > 0 ? "远离" : "靠近") : "稳定"
// 综合趋势状态
ma200_trend_status = ma200_trend_direction + ma200_trend_strength
// 市场活跃度判断(基于距离和波动)
volatility_indicator = distance_usd + price_range
market_activity = volatility_indicator > distance_threshold * 2 ? "活跃" : volatility_indicator > distance_threshold ? "一般" : "平静"
// ═════════ 交易信号判断系统 ════════
// 1. 震荡条件判断修改为OR逻辑满足任一条件即为震荡
rsi_neutral = rsi >= short_S and rsi <= long_S // RSI处于中性区间
price_in_channel = close >= loband1 and close <= upband1 // 价格在MRC通道内S1-R1
ma200_near = distance_usd <= distance_threshold // 距离MA200小于等于阈值
oscillation_signal = rsi_neutral or price_in_channel or ma200_near
// 2. 做多条件判断
rsi_overbought_signal = rsi > long_S // RSI超买
price_above_r1 = close > upband1 // 价格在R1以上
ma200_far = distance_usd > distance_threshold // 距离MA200大于阈值
ma50_above_mean = ma50 > meanline // MA50在MEAN以上
long_signal = rsi_overbought_signal and price_above_r1 and ma200_far and ma50_above_mean
// 3. 做空条件判断
rsi_oversold_signal = rsi < short_S // RSI超卖
price_below_s1 = close < loband1 // 价格在S1以下
ma50_below_mean = ma50 < meanline // MA50在MEAN以下
short_signal = rsi_oversold_signal and price_below_s1 and ma200_far and ma50_below_mean
// ═════════ 时间窗口警报系统 ════════
// 存储启动条件的时间戳和冷却时间
var int long_trigger_time = na
var int short_trigger_time = na
var int last_long_alert_time = na
var int last_short_alert_time = na
// 1分钟时间周期数据获取用于启动条件检测
close_1m_current = request.security(syminfo.tickerid, "1", close, lookahead=barmerge.lookahead_off)
close_1m_prev = request.security(syminfo.tickerid, "1", close[1], lookahead=barmerge.lookahead_off)
upband1_1m_current = request.security(syminfo.tickerid, "1", upband1, lookahead=barmerge.lookahead_off)
loband1_1m_current = request.security(syminfo.tickerid, "1", loband1, lookahead=barmerge.lookahead_off)
// 获取成交量过滤结果
[long_volume_ok, short_volume_ok] = get_volume_filter()
// 成交量趋势确认(在全局作用域调用以避免警告)
long_volume_trend = volume_trend_confirmation("long")
short_volume_trend = volume_trend_confirmation("short")
neutral_volume_trend = volume_trend_confirmation("neutral")
// 成交量分析数据
current_delta_volume = upAndDownVolume()
volume_abs = math.abs(current_delta_volume)
volume_avg = ta.sma(volume_abs, volume_confirmation_bars)
volume_strength_ratio = volume_avg > 0 ? volume_abs / volume_avg : 0
volume_is_strong = volume_strength_ratio > volume_strength_multiplier
// 启动条件检测(加入成交量过滤)
long_trigger_price = ta.crossover(close_1m_current, upband1_1m_current) // 价格上穿R1
short_trigger_price = ta.crossunder(close_1m_current, loband1_1m_current) // 价格下穿S1
// 结合成交量过滤的启动条件(分层过滤)
// 第一层:价格突破条件
long_trigger_basic = long_trigger_price
short_trigger_basic = short_trigger_price
// 第二层:成交量确认条件(可选应用到启动条件)
// 用户可以选择是否在启动时就应用成交量过滤,或者只在后续条件中应用
long_trigger = (enable_volume_filter and apply_volume_to_trigger) ? (long_trigger_basic and long_volume_ok) : long_trigger_basic
short_trigger = (enable_volume_filter and apply_volume_to_trigger) ? (short_trigger_basic and short_volume_ok) : short_trigger_basic
// 记录启动时间
if long_trigger
long_trigger_time := time
if short_trigger
short_trigger_time := time
// 时间窗口检查函数
in_time_window(trigger_time, window_minutes) =>
if na(trigger_time)
false
else
time_diff = math.abs(time - trigger_time) / 60000 // 转换为分钟
time_diff <= window_minutes
// 冷却时间检查函数
is_cooldown_over(last_alert_time, cooldown_minutes) =>
if na(last_alert_time)
true
else
time_diff = (time - last_alert_time) / 60000 // 转换为分钟
time_diff >= cooldown_minutes
// 做多条件检查(时间窗口内,加入成交量确认)
check_long_conditions() =>
if not enable_advanced_alerts
false
else
// 成交量确认(使用预先计算的结果)
volume_confirm = enable_volume_filter ? long_volume_trend : true
// 条件2时间窗口启动前后5分钟1分钟时间周期下
condition2_1m = in_time_window(long_trigger_time, time_window_5min) and rsi_overbought_1m and price_above_r1_1m and ma200_far_1m and ma50_above_mean_1m and volume_confirm
// 条件3时间窗口启动前后15分钟5分钟时间周期下MA50关系使用1分钟数据
condition3_5m = in_time_window(long_trigger_time, time_window_15min) and rsi_overbought_5m and price_above_mean_5m and ma200_far_5m and ma50_above_mean_1m and volume_confirm
// 条件4时间窗口启动前后10分钟15分钟时间周期下S1和价格的距离> 阈值
condition4_15m = in_time_window(long_trigger_time, time_window_10min) and distance_to_s1_15m > get_r1s1_distance_threshold()
// 根据配置决定是否需要所有条件都满足
conditions_met = require_all_conditions ? (condition2_1m and condition3_5m and condition4_15m) : (condition2_1m or condition3_5m or condition4_15m)
// 检查冷却时间
cooldown_ok = is_cooldown_over(last_long_alert_time, alert_cooldown_minutes)
conditions_met and cooldown_ok
// 做空条件检查(时间窗口内,加入成交量确认)
check_short_conditions() =>
if not enable_advanced_alerts
false
else
// 成交量确认(使用预先计算的结果)
volume_confirm = enable_volume_filter ? short_volume_trend : true
// 条件2时间窗口启动前后5分钟1分钟时间周期下
condition2_1m = in_time_window(short_trigger_time, time_window_5min) and rsi_oversold_1m and price_below_s1_1m and ma200_far_1m and ma50_below_mean_1m and volume_confirm
// 条件3时间窗口启动前后15分钟5分钟时间周期下MA50关系使用1分钟数据
condition3_5m = in_time_window(short_trigger_time, time_window_15min) and rsi_oversold_5m and price_below_mean_5m and ma200_far_5m and ma50_below_mean_1m and volume_confirm
// 条件4时间窗口启动前后10分钟15分钟时间周期下R1和价格的距离> 阈值
condition4_15m = in_time_window(short_trigger_time, time_window_10min) and distance_to_r1_15m > get_r1s1_distance_threshold()
// 根据配置决定是否需要所有条件都满足
conditions_met = require_all_conditions ? (condition2_1m and condition3_5m and condition4_15m) : (condition2_1m or condition3_5m or condition4_15m)
// 检查冷却时间
cooldown_ok = is_cooldown_over(last_short_alert_time, alert_cooldown_minutes)
conditions_met and cooldown_ok
// 最终警报条件
advanced_long_alert = check_long_conditions()
advanced_short_alert = check_short_conditions()
// 更新最后警报时间
if advanced_long_alert
last_long_alert_time := time
if advanced_short_alert
last_short_alert_time := time
// ═════════ 警报系统(包含原有和新增) ════════
// 传统警报条件(使用常量消息)
alertcondition(oscillation_signal, title="震荡信号", message='{"指标名称":"cobinined","交易对":"{{ticker}}","周期":"{{interval}}","价格":"{{close}}","事件":"震荡信号","信号":"oscillation","时间":"{{time}}","描述":"震荡"}')
alertcondition(long_signal, title="做多信号", message='{"指标名称":"cobinined","交易对":"{{ticker}}","周期":"{{interval}}","价格":"{{close}}","事件":"做多信号","信号":"long","时间":"{{time}}","描述":"做多信号"}')
alertcondition(short_signal, title="做空信号", message='{"指标名称":"cobinined","交易对":"{{ticker}}","周期":"{{interval}}","价格":"{{close}}","事件":"做空信号","信号":"short","时间":"{{time}}","描述":"做空信号"}')
// 新增时间窗口警报
alertcondition(advanced_long_alert, title="高级做多警报", message='{"指标名称":"cobinined","交易对":"{{ticker}}","周期":"{{interval}}","价格":"{{close}}","事件":"高级做多警报","信号":"advanced_long","时间":"{{time}}","描述":"多时间周期做多确认信号"}')
alertcondition(advanced_short_alert, title="高级做空警报", message='{"指标名称":"cobinined","交易对":"{{ticker}}","周期":"{{interval}}","价格":"{{close}}","事件":"高级做空警报","信号":"advanced_short","时间":"{{time}}","描述":"多时间周期做空确认信号"}')
// R1/S1距离警报
alertcondition(is_near_r1, title="价格接近R1线", message='{"指标名称":"cobinined","交易对":"{{ticker}}","周期":"{{interval}}","价格":"{{close}}","事件":"价格接近R1线","信号":"near_r1","时间":"{{time}}","描述":"价格接近R1阻力线"}')
alertcondition(is_near_s1, title="价格接近S1线", message='{"指标名称":"cobinined","交易对":"{{ticker}}","周期":"{{interval}}","价格":"{{close}}","事件":"价格接近S1线","信号":"near_s1","时间":"{{time}}","描述":"价格接近S1支撑线"}')
// 成交量相关警报
alertcondition(long_volume_ok and enable_volume_filter, title="做多成交量确认", message='{"指标名称":"cobinined","交易对":"{{ticker}}","周期":"{{interval}}","价格":"{{close}}","事件":"做多成交量确认","信号":"long_volume","时间":"{{time}}","描述":"检测到强劲买盘成交量"}')
alertcondition(short_volume_ok and enable_volume_filter, title="做空成交量确认", message='{"指标名称":"cobinined","交易对":"{{ticker}}","周期":"{{interval}}","价格":"{{close}}","事件":"做空成交量确认","信号":"short_volume","时间":"{{time}}","描述":"检测到强劲卖盘成交量"}')
// ═════════ K线标记系统TradingView内置箭头可配置大小 ════════
// 做多信号标记(向上三角形)- 根据配置大小
plotshape(series=long_signal and show_long_marks and arrow_size == 'tiny', title="做多信号-tiny", location=location.belowbar, color=color.green, style=shape.triangleup, size=size.tiny)
plotshape(series=long_signal and show_long_marks and arrow_size == 'small', title="做多信号-small", location=location.belowbar, color=color.green, style=shape.triangleup, size=size.small)
plotshape(series=long_signal and show_long_marks and arrow_size == 'normal', title="做多信号-normal", location=location.belowbar, color=color.green, style=shape.triangleup, size=size.normal)
plotshape(series=long_signal and show_long_marks and arrow_size == 'large', title="做多信号-large", location=location.belowbar, color=color.green, style=shape.triangleup, size=size.large)
plotshape(series=long_signal and show_long_marks and arrow_size == 'huge', title="做多信号-huge", location=location.belowbar, color=color.green, style=shape.triangleup, size=size.huge)
// 做空信号标记(向下三角形)- 根据配置大小
plotshape(series=short_signal and show_short_marks and arrow_size == 'tiny', title="做空信号-tiny", location=location.abovebar, color=color.red, style=shape.triangledown, size=size.tiny)
plotshape(series=short_signal and show_short_marks and arrow_size == 'small', title="做空信号-small", location=location.abovebar, color=color.red, style=shape.triangledown, size=size.small)
plotshape(series=short_signal and show_short_marks and arrow_size == 'normal', title="做空信号-normal", location=location.abovebar, color=color.red, style=shape.triangledown, size=size.normal)
plotshape(series=short_signal and show_short_marks and arrow_size == 'large', title="做空信号-large", location=location.abovebar, color=color.red, style=shape.triangledown, size=size.large)
plotshape(series=short_signal and show_short_marks and arrow_size == 'huge', title="做空信号-huge", location=location.abovebar, color=color.red, style=shape.triangledown, size=size.huge)
// 震荡信号标记(黄色圆点标记)- 注释掉避免黄色横条问题
// plotshape(series=oscillation_signal and show_oscillation_marks and arrow_size == 'tiny', title="震荡信号-tiny", location=location.top, color=color.yellow, style=shape.circle, size=size.tiny)
// plotshape(series=oscillation_signal and show_oscillation_marks and arrow_size == 'small', title="震荡信号-small", location=location.top, color=color.yellow, style=shape.circle, size=size.small)
// plotshape(series=oscillation_signal and show_oscillation_marks and arrow_size == 'normal', title="震荡信号-normal", location=location.top, color=color.yellow, style=shape.circle, size=size.normal)
// plotshape(series=oscillation_signal and show_oscillation_marks and arrow_size == 'large', title="震荡信号-large", location=location.top, color=color.yellow, style=shape.circle, size=size.large)
// plotshape(series=oscillation_signal and show_oscillation_marks and arrow_size == 'huge', title="震荡信号-huge", location=location.top, color=color.yellow, style=shape.circle, size=size.huge)
// ═════════ 高级警报标记(超级突出版本) ════════
// 高级做多警报 - 根据样式参数显示不同突出效果
// 第1层大背景圆圈金色光晕效果- 仅超级突出模式
plotshape(series=advanced_long_alert and show_advanced_alerts and advanced_alert_style == '超级突出', title="高级做多背景", location=location.belowbar, color=color.new(color.yellow, 70), style=shape.circle, size=size.huge)
// 第2层中等背景圆圈绿色强调- 突出和超级突出模式
plotshape(series=advanced_long_alert and show_advanced_alerts and (advanced_alert_style == '突出' or advanced_alert_style == '超级突出'), title="高级做多中层", location=location.belowbar, color=color.new(color.lime, 30), style=shape.circle, size=size.large)
// 第3层主要标记根据配置大小
plotshape(series=advanced_long_alert and show_advanced_alerts and arrow_size == 'tiny', title="高级做多主标记-tiny", location=location.belowbar, color=color.new(color.white, 0), style=shape.labelup, size=size.small, text="🚀", textcolor=color.black)
plotshape(series=advanced_long_alert and show_advanced_alerts and arrow_size == 'small', title="高级做多主标记-small", location=location.belowbar, color=color.new(color.white, 0), style=shape.labelup, size=size.normal, text="🚀", textcolor=color.black)
plotshape(series=advanced_long_alert and show_advanced_alerts and arrow_size == 'normal', title="高级做多主标记-normal", location=location.belowbar, color=color.new(color.white, 0), style=shape.labelup, size=size.large, text="🚀", textcolor=color.black)
plotshape(series=advanced_long_alert and show_advanced_alerts and arrow_size == 'large', title="高级做多主标记-large", location=location.belowbar, color=color.new(color.white, 0), style=shape.labelup, size=size.huge, text="🚀", textcolor=color.black)
plotshape(series=advanced_long_alert and show_advanced_alerts and arrow_size == 'huge', title="高级做多主标记-huge", location=location.belowbar, color=color.new(color.white, 0), style=shape.labelup, size=size.huge, text="🚀🚀", textcolor=color.black)
// 第4层闪烁边框效果使用动态颜色- 仅超级突出模式
flash_color_long = advanced_long_alert and advanced_alert_style == '超级突出' ? (bar_index % 2 == 0 ? color.new(color.red, 0) : color.new(color.orange, 0)) : na
plotshape(series=advanced_long_alert and show_advanced_alerts and advanced_alert_style == '超级突出', title="高级做多闪烁", location=location.belowbar, color=flash_color_long, style=shape.diamond, size=size.tiny)
// 高级做空警报 - 根据样式参数显示不同突出效果
// 第1层大背景圆圈紫色光晕效果- 仅超级突出模式
plotshape(series=advanced_short_alert and show_advanced_alerts and advanced_alert_style == '超级突出', title="高级做空背景", location=location.abovebar, color=color.new(color.purple, 70), style=shape.circle, size=size.huge)
// 第2层中等背景圆圈红色强调- 突出和超级突出模式
plotshape(series=advanced_short_alert and show_advanced_alerts and (advanced_alert_style == '突出' or advanced_alert_style == '超级突出'), title="高级做空中层", location=location.abovebar, color=color.new(color.fuchsia, 30), style=shape.circle, size=size.large)
// 第3层主要标记根据配置大小
plotshape(series=advanced_short_alert and show_advanced_alerts and arrow_size == 'tiny', title="高级做空主标记-tiny", location=location.abovebar, color=color.new(color.white, 0), style=shape.labeldown, size=size.small, text="🔻", textcolor=color.black)
plotshape(series=advanced_short_alert and show_advanced_alerts and arrow_size == 'small', title="高级做空主标记-small", location=location.abovebar, color=color.new(color.white, 0), style=shape.labeldown, size=size.normal, text="🔻", textcolor=color.black)
plotshape(series=advanced_short_alert and show_advanced_alerts and arrow_size == 'normal', title="高级做空主标记-normal", location=location.abovebar, color=color.new(color.white, 0), style=shape.labeldown, size=size.large, text="🔻", textcolor=color.black)
plotshape(series=advanced_short_alert and show_advanced_alerts and arrow_size == 'large', title="高级做空主标记-large", location=location.abovebar, color=color.new(color.white, 0), style=shape.labeldown, size=size.huge, text="🔻", textcolor=color.black)
plotshape(series=advanced_short_alert and show_advanced_alerts and arrow_size == 'huge', title="高级做空主标记-huge", location=location.abovebar, color=color.new(color.white, 0), style=shape.labeldown, size=size.huge, text="🔻🔻", textcolor=color.black)
// 第4层闪烁边框效果使用动态颜色- 仅超级突出模式
flash_color_short = advanced_short_alert and advanced_alert_style == '超级突出' ? (bar_index % 2 == 0 ? color.new(color.red, 0) : color.new(color.orange, 0)) : na
plotshape(series=advanced_short_alert and show_advanced_alerts and advanced_alert_style == '超级突出', title="高级做空闪烁", location=location.abovebar, color=flash_color_short, style=shape.diamond, size=size.tiny)
// ═════════ 高级警报文本标签(额外突出) ════════
// 高级做多警报文本标签 - 仅突出和超级突出模式
if advanced_long_alert and show_advanced_alerts and (advanced_alert_style == '突出' or advanced_alert_style == '超级突出') and barstate.islast
var label advanced_long_label = na
label_text = advanced_alert_style == '超级突出' ? "⚡HIGH LEVEL LONG⚡" : "🚀 HIGH LEVEL LONG 🚀"
if na(advanced_long_label)
advanced_long_label := label.new(bar_index, low - (high - low) * 0.1, label_text, xloc=xloc.bar_index, style=label.style_label_up, color=color.new(color.lime, 0), textcolor=color.black, size=size.large)
else
label.set_xy(advanced_long_label, bar_index, low - (high - low) * 0.1)
label.set_text(advanced_long_label, label_text)
// 高级做空警报文本标签 - 仅突出和超级突出模式
if advanced_short_alert and show_advanced_alerts and (advanced_alert_style == '突出' or advanced_alert_style == '超级突出') and barstate.islast
var label advanced_short_label = na
label_text = advanced_alert_style == '超级突出' ? "⚡HIGH LEVEL SHORT⚡" : "🔻 HIGH LEVEL SHORT 🔻"
if na(advanced_short_label)
advanced_short_label := label.new(bar_index, high + (high - low) * 0.1, label_text, xloc=xloc.bar_index, style=label.style_label_down, color=color.new(color.fuchsia, 0), textcolor=color.white, size=size.large)
else
label.set_xy(advanced_short_label, bar_index, high + (high - low) * 0.1)
label.set_text(advanced_short_label, label_text)
// ═════════ 成交量强度标记 ════════
// 成交量强度标记(可选显示)
show_volume_marks = input.bool(false, title='显示成交量强度标记', group='Signals')
plotchar(series=volume_is_strong and current_delta_volume > 0 and show_volume_marks, title="强买盘成交量", char="📈", location=location.belowbar, color=color.new(color.blue, 30), size=size.small)
plotchar(series=volume_is_strong and current_delta_volume < 0 and show_volume_marks, title="强卖盘成交量", char="📉", location=location.abovebar, color=color.new(color.orange, 30), size=size.small)
// ═════════ K线背景高亮高级警报时 ════════
// 高级警报时的K线背景高亮 - 根据样式强度调整
bg_transparency = advanced_alert_style == '超级突出' ? 85 : advanced_alert_style == '突出' ? 92 : 95
bgcolor(advanced_long_alert and (advanced_alert_style == '突出' or advanced_alert_style == '超级突出') ? color.new(color.lime, bg_transparency) : advanced_short_alert and (advanced_alert_style == '突出' or advanced_alert_style == '超级突出') ? color.new(color.fuchsia, bg_transparency) : na, title="高级警报背景")
// 启动条件标记(增强版)
plotshape(series=long_trigger and show_advanced_alerts, title="做多启动", location=location.belowbar, color=color.new(color.aqua, 0), style=shape.arrowup, size=size.small)
plotshape(series=short_trigger and show_advanced_alerts, title="做空启动", location=location.abovebar, color=color.new(color.orange, 0), style=shape.arrowdown, size=size.small)
// 启动条件文本提示
plotchar(series=long_trigger and show_advanced_alerts, title="做多启动提示", location=location.belowbar, char="START", color=color.aqua, size=size.tiny)
plotchar(series=short_trigger and show_advanced_alerts, title="做空启动提示", location=location.abovebar, char="START", color=color.orange, size=size.tiny)
// RSI 状态
rsi_position = rsi > long_S ? "超买区" : rsi < short_S ? "超卖区" : "中性区"
rsi_cross_count = math.abs(segment_count)
//************************************************************************************************************
// 绘图部分
//************************************************************************************************************
// ═════════ 窗口一MRC 和 MA 线条 ═════════
plot(meanline, color=color.new(color.black, 0), style=plot.style_line, title='MEAN', linewidth=mean_width)
plot(upband1, color=color.new(color.red, 0), style=plot.style_line, title='R1', linewidth=r1_s1_width)
plot(loband1, color=color.new(color.green, 0), style=plot.style_line, title='S1', linewidth=r1_s1_width)
plot(upband2, color=color.new(color.red, 50), style=plot.style_line, title='R2', linewidth=r2_s2_width)
plot(loband2, color=color.new(color.green, 50), style=plot.style_line, title='S2', linewidth=r2_s2_width)
// MA 线条
maColor(ma, ref) => ma > ref ? color.lime : color.red
plot(show_ma_lines ? ma50 : na, color=maColor(ma50, ma100), linewidth=2, title='MA50')
plot(show_ma_lines ? ma100 : na, color=maColor(ma100, ma200), linewidth=2, title='MA100')
plot(show_ma_lines ? ma200 : na, color=color.rgb(25, 58, 243), linewidth=4, title='MA200')
//************************************************************************************************************
// 信息表格显示
//************************************************************************************************************
if show_info_table and barstate.islast
// 创建扩展的信息表格(包含高级警报状态和成交量信息)
var table info_table = table.new(
position = position.bottom_right, // 固定在右下角
columns = 12, // 扩展为12列原6列 + 高级警报4列 + 成交量2列
rows = 4, // 4行标题 + 数值 + 状态 + 信号
bgcolor = color.new(color.white, 85),
border_width = 1)
// 清空表格
table.clear(info_table, 0, 0, 11, 3)
// 获取配置的文字大小
text_size = get_text_size()
// ═════════ 扩展表格标题行原6列 + 高级警报4列 + 成交量2列 ═════════
table.cell(info_table, 0, 0, "RSI", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
table.cell(info_table, 1, 0, "价格位置", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
table.cell(info_table, 2, 0, "MA50位置", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
table.cell(info_table, 3, 0, "MA200距离", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
table.cell(info_table, 4, 0, "信号汇总", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
table.cell(info_table, 5, 0, "综合判断", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
// 高级警报相关列
table.cell(info_table, 6, 0, "高级启动", text_color=color.white, bgcolor=color.new(color.lime, 30), text_size=text_size)
table.cell(info_table, 7, 0, "条件2(1m)", text_color=color.white, bgcolor=color.new(color.lime, 30), text_size=text_size)
table.cell(info_table, 8, 0, "条件3(5m)", text_color=color.white, bgcolor=color.new(color.lime, 30), text_size=text_size)
table.cell(info_table, 9, 0, "条件4(15m)", text_color=color.white, bgcolor=color.new(color.lime, 30), text_size=text_size)
// 成交量相关列
table.cell(info_table, 10, 0, "成交量", text_color=color.white, bgcolor=color.new(color.blue, 30), text_size=text_size)
table.cell(info_table, 11, 0, "量能确认", text_color=color.white, bgcolor=color.new(color.blue, 30), text_size=text_size)
// ═════════ 多列紧凑数据 ═════════
// 计算各指标的背景颜色类似combined_mrc_ma200_rsi.pine
rsi_color = rsi_neutral ? color.new(color.orange, 40) : rsi_overbought_signal ? color.new(color.green, 40) : rsi_oversold_signal ? color.new(color.red, 40) : color.white
price_color = price_in_channel ? color.new(color.orange, 40) : price_above_r1 ? color.new(color.green, 40) : price_below_s1 ? color.new(color.red, 40) : color.white
ma50_color = ma50_above_mean ? color.new(color.green, 40) : ma50_below_mean ? color.new(color.red, 40) : color.white
ma200_color = ma200_near ? color.new(color.orange, 40) : color.new(color.gray, 60)
// 高级警报条件状态计算
condition2_1m_long = not na(long_trigger_time) and in_time_window(long_trigger_time, time_window_5min) and rsi_overbought_1m and price_above_r1_1m and ma200_far_1m and ma50_above_mean_1m
condition3_5m_long = not na(long_trigger_time) and in_time_window(long_trigger_time, time_window_15min) and rsi_overbought_5m and price_above_mean_5m and ma200_far_5m and ma50_above_mean_1m
condition4_15m_long = not na(long_trigger_time) and in_time_window(long_trigger_time, time_window_10min) and distance_to_s1_15m > get_r1s1_distance_threshold()
condition2_1m_short = not na(short_trigger_time) and in_time_window(short_trigger_time, time_window_5min) and rsi_oversold_1m and price_below_s1_1m and ma200_far_1m and ma50_below_mean_1m
condition3_5m_short = not na(short_trigger_time) and in_time_window(short_trigger_time, time_window_15min) and rsi_oversold_5m and price_below_mean_5m and ma200_far_5m and ma50_below_mean_1m
condition4_15m_short = not na(short_trigger_time) and in_time_window(short_trigger_time, time_window_10min) and distance_to_r1_15m > get_r1s1_distance_threshold()
// 高级警报颜色计算
trigger_color = (long_trigger or short_trigger) ? color.new(color.aqua, 40) : (not na(long_trigger_time) or not na(short_trigger_time)) ? color.new(color.yellow, 60) : color.new(color.gray, 80)
condition2_color = condition2_1m_long ? color.new(color.green, 40) : condition2_1m_short ? color.new(color.red, 40) : color.new(color.gray, 80)
condition3_color = condition3_5m_long ? color.new(color.green, 40) : condition3_5m_short ? color.new(color.red, 40) : color.new(color.gray, 80)
condition4_color = condition4_15m_long ? color.new(color.green, 40) : condition4_15m_short ? color.new(color.red, 40) : color.new(color.gray, 80)
// 综合信号颜色(包含高级警报)
signal_color = advanced_long_alert ? color.new(color.lime, 20) : advanced_short_alert ? color.new(color.fuchsia, 20) : oscillation_signal ? color.new(color.orange, 40) : long_signal ? color.new(color.green, 40) : short_signal ? color.new(color.red, 40) : color.new(color.gray, 80)
final_signal_color = advanced_long_alert ? color.new(color.lime, 20) : advanced_short_alert ? color.new(color.fuchsia, 20) : long_signal ? color.new(color.green, 30) : short_signal ? color.new(color.red, 30) : oscillation_signal ? color.new(color.orange, 30) : color.new(color.gray, 80)
// 计算成交量相关数据
current_volume = current_delta_volume
volume_trend = neutral_volume_trend
volume_color = current_volume > 0 ? color.new(color.green, 40) : current_volume < 0 ? color.new(color.red, 40) : color.new(color.gray, 60)
volume_confirm_color = volume_is_strong ? color.new(color.lime, 40) : color.new(color.gray, 80)
// 第1行数值
table.cell(info_table, 0, 1, str.tostring(rsi, '#.#'), text_color=color.black, bgcolor=rsi_color, text_size=text_size)
table.cell(info_table, 1, 1, str.tostring(close, '#.##'), text_color=color.black, bgcolor=price_color, text_size=text_size)
table.cell(info_table, 2, 1, str.tostring(ma50, '#.##'), text_color=color.black, bgcolor=ma50_color, text_size=text_size)
table.cell(info_table, 3, 1, str.tostring(distance_usd, '#.#'), text_color=color.black, bgcolor=ma200_color, text_size=text_size)
table.cell(info_table, 4, 1, advanced_long_alert ? "高级🚀" : advanced_short_alert ? "高级🔻" : oscillation_signal ? "震荡⚡" : long_signal ? "做多🚀" : short_signal ? "做空🔻" : "观望", text_color=color.black, bgcolor=signal_color, text_size=text_size)
table.cell(info_table, 5, 1, advanced_long_alert ? "✓高级做多" : advanced_short_alert ? "✓高级做空" : long_signal ? "✓做多" : short_signal ? "✓做空" : oscillation_signal ? "✓震荡" : "观望", text_color=color.black, bgcolor=final_signal_color, text_size=text_size)
// 高级警报数据
table.cell(info_table, 6, 1, long_trigger ? "🚀启动" : short_trigger ? "🔻启动" : not na(long_trigger_time) ? "🚀监控" : not na(short_trigger_time) ? "🔻监控" : "等待", text_color=color.black, bgcolor=trigger_color, text_size=text_size)
table.cell(info_table, 7, 1, condition2_1m_long ? "✓做多" : condition2_1m_short ? "✓做空" : "未满足", text_color=color.black, bgcolor=condition2_color, text_size=text_size)
table.cell(info_table, 8, 1, condition3_5m_long ? "✓做多" : condition3_5m_short ? "✓做空" : "未满足", text_color=color.black, bgcolor=condition3_color, text_size=text_size)
table.cell(info_table, 9, 1, condition4_15m_long ? "✓做多" : condition4_15m_short ? "✓做空" : "未满足", text_color=color.black, bgcolor=condition4_color, text_size=text_size)
// 成交量数据
table.cell(info_table, 10, 1, str.tostring(current_volume, '#.##'), text_color=color.black, bgcolor=volume_color, text_size=text_size)
table.cell(info_table, 11, 1, volume_trend ? "✓确认" : "待确认", text_color=color.black, bgcolor=volume_confirm_color, text_size=text_size)
// 第2行状态
table.cell(info_table, 0, 2, rsi_neutral ? "中性" : rsi_overbought_signal ? "超买" : rsi_oversold_signal ? "超卖" : "正常", text_color=color.black, bgcolor=rsi_color, text_size=text_size)
table.cell(info_table, 1, 2, price_in_channel ? "通道内" : price_above_r1 ? "R1上" : price_below_s1 ? "S1下" : "其他", text_color=color.black, bgcolor=price_color, text_size=text_size)
table.cell(info_table, 2, 2, ma50_above_mean ? "MEAN上" : ma50_below_mean ? "MEAN下" : "MEAN附近", text_color=color.black, bgcolor=ma50_color, text_size=text_size)
table.cell(info_table, 3, 2, ma200_near ? "≤阈值" : ">阈值", text_color=color.black, bgcolor=ma200_color, text_size=text_size)
table.cell(info_table, 4, 2, advanced_long_alert ? "高级AND" : advanced_short_alert ? "高级AND" : oscillation_signal ? "OR逻辑" : long_signal ? "AND逻辑" : short_signal ? "AND逻辑" : "无信号", text_color=color.black, bgcolor=signal_color, text_size=text_size)
table.cell(info_table, 5, 2, advanced_long_alert ? "🚀" : advanced_short_alert ? "🔻" : long_signal ? "🚀" : short_signal ? "🔻" : oscillation_signal ? "⚡" : "⚪", text_color=color.black, bgcolor=final_signal_color, text_size=text_size)
// 高级警报状态
trigger_window_status = not na(long_trigger_time) ? (in_time_window(long_trigger_time, time_window_15min) ? "窗口内" : "已过期") : not na(short_trigger_time) ? (in_time_window(short_trigger_time, time_window_15min) ? "窗口内" : "已过期") : "未启动"
cooldown_status = is_cooldown_over(last_long_alert_time, alert_cooldown_minutes) and is_cooldown_over(last_short_alert_time, alert_cooldown_minutes) ? "可用" : "冷却中"
table.cell(info_table, 6, 2, trigger_window_status, text_color=color.black, bgcolor=trigger_color, text_size=text_size)
table.cell(info_table, 7, 2, condition2_1m_long ? "5分钟内" : condition2_1m_short ? "5分钟内" : "窗口外", text_color=color.black, bgcolor=condition2_color, text_size=text_size)
table.cell(info_table, 8, 2, condition3_5m_long ? "15分钟内" : condition3_5m_short ? "15分钟内" : "窗口外", text_color=color.black, bgcolor=condition3_color, text_size=text_size)
table.cell(info_table, 9, 2, condition4_15m_long ? "10分钟内" : condition4_15m_short ? "10分钟内" : "窗口外", text_color=color.black, bgcolor=condition4_color, text_size=text_size)
// 成交量状态
volume_status = current_volume > 0 ? "买盘" : current_volume < 0 ? "卖盘" : "平衡"
volume_strength_text = enable_volume_filter ? (volume_is_strong ? "强势" : "弱势") + "|" + volume_filter_mode : "未启用"
table.cell(info_table, 10, 2, volume_status, text_color=color.black, bgcolor=volume_color, text_size=text_size)
table.cell(info_table, 11, 2, volume_strength_text, text_color=color.black, bgcolor=volume_confirm_color, text_size=text_size)
// 第3行条件说明
table.cell(info_table, 0, 3, rsi_neutral ? "震荡条件" : rsi_overbought_signal ? "做多条件" : rsi_oversold_signal ? "做空条件" : "中性", text_color=color.black, bgcolor=rsi_color, text_size=text_size)
table.cell(info_table, 1, 3, price_in_channel ? "震荡条件" : price_above_r1 ? "做多条件" : price_below_s1 ? "做空条件" : "中性", text_color=color.black, bgcolor=price_color, text_size=text_size)
table.cell(info_table, 2, 3, ma50_above_mean ? "做多条件" : ma50_below_mean ? "做空条件" : "中性", text_color=color.black, bgcolor=ma50_color, text_size=text_size)
table.cell(info_table, 3, 3, ma200_near ? "震荡条件" : "趋势条件", text_color=color.black, bgcolor=ma200_color, text_size=text_size)
table.cell(info_table, 4, 3, advanced_long_alert ? "高级做多" : advanced_short_alert ? "高级做空" : oscillation_signal ? "满足震荡" : long_signal ? "满足做多" : short_signal ? "满足做空" : "无满足", text_color=color.black, bgcolor=signal_color, text_size=text_size)
table.cell(info_table, 5, 3, advanced_long_alert ? "执行高级做多" : advanced_short_alert ? "执行高级做空" : long_signal ? "执行做多" : short_signal ? "执行做空" : oscillation_signal ? "保持震荡" : "继续观望", text_color=color.black, bgcolor=final_signal_color, text_size=text_size)
// 高级警报条件说明和调试信息
trigger_debug = "启动:" + (long_trigger ? "多" : short_trigger ? "空" : "无") + "|时间:" + (not na(long_trigger_time) ? "多" : not na(short_trigger_time) ? "空" : "无")
table.cell(info_table, 6, 3, trigger_debug, text_color=color.black, bgcolor=trigger_color, text_size=text_size)
table.cell(info_table, 7, 3, condition2_1m_long ? "1m做多就绪" : condition2_1m_short ? "1m做空就绪" : "1m条件未满足", text_color=color.black, bgcolor=condition2_color, text_size=text_size)
table.cell(info_table, 8, 3, condition3_5m_long ? "5m做多就绪" : condition3_5m_short ? "5m做空就绪" : "5m条件未满足", text_color=color.black, bgcolor=condition3_color, text_size=text_size)
table.cell(info_table, 9, 3, condition4_15m_long ? "15m距离满足" : condition4_15m_short ? "15m距离满足" : "15m距离不足", text_color=color.black, bgcolor=condition4_color, text_size=text_size)
// 成交量调试信息
volume_debug = "Vol:" + str.tostring(current_volume, '#.##') + "|模式:" + volume_filter_mode + "|过滤:" + (long_volume_ok ? "多✓" : short_volume_ok ? "空✓" : "✗")
table.cell(info_table, 10, 3, volume_debug, text_color=color.black, bgcolor=volume_color, text_size=text_size)
alert_debug = "高级:" + (advanced_long_alert ? "多" : advanced_short_alert ? "空" : "无") + "|冷却:" + (is_cooldown_over(last_long_alert_time, alert_cooldown_minutes) and is_cooldown_over(last_short_alert_time, alert_cooldown_minutes) ? "OK" : "NO")
table.cell(info_table, 11, 3, alert_debug, text_color=color.black, bgcolor=volume_confirm_color, text_size=text_size)
// ═════════ 关键数值表格(右中位置,避免与主表格重叠) ═════════
// 创建关键数值表格
var table key_values_table = table.new(
position = position.middle_right, // 改为右中位置
columns = 4, // 4列R1阻力 + S1支撑 + MEAN中线 + 距离阈值
rows = 3, // 3行标题 + 数值 + 通道信息
bgcolor = color.new(color.white, 85),
border_width = 1)
// 清空表格
table.clear(key_values_table, 0, 0, 3, 2)
// 关键数值标题行
table.cell(key_values_table, 0, 0, "R1阻力", text_color=color.white, bgcolor=color.new(color.red, 40), text_size=text_size)
table.cell(key_values_table, 1, 0, "S1支撑", text_color=color.white, bgcolor=color.new(color.green, 40), text_size=text_size)
table.cell(key_values_table, 2, 0, "MEAN中线", text_color=color.white, bgcolor=color.new(color.blue, 40), text_size=text_size)
table.cell(key_values_table, 3, 0, "距离阈值", text_color=color.white, bgcolor=color.new(color.gray, 40), text_size=text_size)
// 关键数值数据行
table.cell(key_values_table, 0, 1, str.tostring(upband1, '#.####'), text_color=color.black, bgcolor=color.new(color.red, 20), text_size=text_size)
table.cell(key_values_table, 1, 1, str.tostring(loband1, '#.####'), text_color=color.black, bgcolor=color.new(color.green, 20), text_size=text_size)
table.cell(key_values_table, 2, 1, str.tostring(meanline, '#.####'), text_color=color.black, bgcolor=color.new(color.blue, 20), text_size=text_size)
table.cell(key_values_table, 3, 1, str.tostring(distance_threshold, '#.##'), text_color=color.black, bgcolor=color.new(color.gray, 20), text_size=text_size)
// 通道距离信息行
channel_width = upband1 - loband1 // R1-S1通道宽度
r1_r2_distance = upband2 - upband1 // R1到R2距离
s1_s2_distance = loband1 - loband2 // S1到S2距离
table.cell(key_values_table, 0, 2, "R1-R2:" + str.tostring(r1_r2_distance, '#.##'), text_color=color.black, bgcolor=color.new(color.red, 10), text_size=text_size)
table.cell(key_values_table, 1, 2, "S1-S2:" + str.tostring(s1_s2_distance, '#.##'), text_color=color.black, bgcolor=color.new(color.green, 10), text_size=text_size)
table.cell(key_values_table, 2, 2, "通道宽度:" + str.tostring(channel_width, '#.##'), text_color=color.black, bgcolor=color.new(color.blue, 10), text_size=text_size)
table.cell(key_values_table, 3, 2, "当前距离:" + str.tostring(distance_usd, '#.#'), text_color=color.black, bgcolor=color.new(color.gray, 10), text_size=text_size)
// ═════════ 多时间框架表格显示 ═════════
if show_mtf_table and barstate.islast
// 创建多时间框架表格(右上角)- 增加MEAN距离列
var table mtf_table = table.new(
position = position.top_right,
columns = 13, // 增加到13列时间框架 + RSI + RSI状态 + 穿越次数 + 价格位置 + 价格MEAN位置 + MA50位置 + MA200距离 + MEAN距离 + R1距离 + S1距离 + 信号 + 判断
rows = mtf_table_rows,
bgcolor = color.new(color.white, 85),
border_width = 1)
// 清空表格
table.clear(mtf_table, 0, 0, 12, mtf_table_rows - 1)
// 获取配置的文字大小
text_size = get_text_size()
// 获取距离阈值
r1s1_threshold = get_r1s1_distance_threshold()
// ═════════ 多时间框架表格标题行 ═════════
table.cell(mtf_table, 0, 0, "时间框架", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
table.cell(mtf_table, 1, 0, "RSI", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
table.cell(mtf_table, 2, 0, "RSI状态", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
table.cell(mtf_table, 3, 0, "穿越次数", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
table.cell(mtf_table, 4, 0, "价格位置", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
table.cell(mtf_table, 5, 0, "价格MEAN", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
table.cell(mtf_table, 6, 0, "MA50位置", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
table.cell(mtf_table, 7, 0, "MA200距离", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
table.cell(mtf_table, 8, 0, "MEAN距离", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
table.cell(mtf_table, 9, 0, "R1距离", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
table.cell(mtf_table, 10, 0, "S1距离", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
table.cell(mtf_table, 11, 0, "信号", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
table.cell(mtf_table, 12, 0, "判断", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
// ═════════ 1分钟时间框架数据 ═════════
if mtf_1m and not na(rsi_1m)
signal_color_1m = get_signal_color(osc_1m, long_1m, short_1m)
rsi_status_1m = get_rsi_status(rsi_1m, long_S, short_S)
// 计算各个条件的颜色
rsi_color_1m = get_rsi_color(rsi_1m, long_S, short_S, rsi_neutral_1m, rsi_overbought_1m, rsi_oversold_1m)
price_color_1m = get_price_color(close_1m, upband1_1m, loband1_1m, price_in_channel_1m, price_above_r1_1m, price_below_s1_1m)
price_mean_color_1m = get_price_mean_color(close_1m, meanline_1m)
ma50_color_1m = get_ma50_color(ma50_1m, meanline_1m, ma50_above_mean_1m, ma50_below_mean_1m)
ma200_distance_color_1m = get_ma200_distance_color(distance_1m, distance_threshold_1m, ma200_near_1m, ma200_far_1m)
table.cell(mtf_table, 0, 1, "1分钟", text_color=color.black, text_size=text_size)
table.cell(mtf_table, 1, 1, str.tostring(rsi_1m, '#.#'), text_color=color.black, bgcolor=rsi_color_1m, text_size=text_size)
table.cell(mtf_table, 2, 1, rsi_status_1m, text_color=color.black, bgcolor=rsi_color_1m, text_size=text_size)
table.cell(mtf_table, 3, 1, na(cross_count_1m) ? "N/A" : str.tostring(cross_count_1m), text_color=color.black, text_size=text_size)
table.cell(mtf_table, 4, 1, get_price_position(close_1m, upband1_1m, loband1_1m), text_color=color.black, bgcolor=price_color_1m, text_size=text_size)
table.cell(mtf_table, 5, 1, get_price_mean_position(close_1m, meanline_1m), text_color=color.black, bgcolor=price_mean_color_1m, text_size=text_size)
table.cell(mtf_table, 6, 1, get_ma50_position(ma50_1m, meanline_1m), text_color=color.black, bgcolor=ma50_color_1m, text_size=text_size)
// 计算距离背景颜色
ma200_bg_color_1m = get_distance_bg_color(distance_1m, distance_threshold_1m)
mean_bg_color_1m = get_distance_bg_color(distance_to_mean_1m, r1s1_threshold)
r1_bg_color_1m = get_distance_bg_color(distance_to_r1_1m, r1s1_threshold)
s1_bg_color_1m = get_distance_bg_color(distance_to_s1_1m, r1s1_threshold)
table.cell(mtf_table, 7, 1, str.tostring(distance_1m, '#.##'), text_color=color.black, bgcolor=ma200_bg_color_1m, text_size=text_size)
table.cell(mtf_table, 8, 1, na(distance_to_mean_1m) ? "N/A" : str.tostring(distance_to_mean_1m, '#.##'), text_color=color.black, bgcolor=mean_bg_color_1m, text_size=text_size)
table.cell(mtf_table, 9, 1, na(distance_to_r1_1m) ? "N/A" : str.tostring(distance_to_r1_1m, '#.##'), text_color=color.black, bgcolor=r1_bg_color_1m, text_size=text_size)
table.cell(mtf_table, 10, 1, na(distance_to_s1_1m) ? "N/A" : str.tostring(distance_to_s1_1m, '#.##'), text_color=color.black, bgcolor=s1_bg_color_1m, text_size=text_size)
table.cell(mtf_table, 11, 1, get_signal_text(osc_1m, long_1m, short_1m), text_color=color.black, bgcolor=signal_color_1m, text_size=text_size)
table.cell(mtf_table, 12, 1, get_final_judgment(osc_1m, long_1m, short_1m), text_color=color.black, bgcolor=signal_color_1m, text_size=text_size)
// ═════════ 5分钟时间框架数据 ═════════
if mtf_5m and not na(rsi_5m)
signal_color_5m = get_signal_color(osc_5m, long_5m, short_5m)
rsi_status_5m = get_rsi_status(rsi_5m, long_S, short_S)
// 计算各个条件的颜色
rsi_color_5m = get_rsi_color(rsi_5m, long_S, short_S, rsi_neutral_5m, rsi_overbought_5m, rsi_oversold_5m)
price_color_5m = get_price_color(close_5m, upband1_5m, loband1_5m, price_in_channel_5m, price_above_r1_5m, price_below_s1_5m)
price_mean_color_5m = get_price_mean_color(close_5m, meanline_5m)
ma50_color_5m = get_ma50_color(ma50_5m, meanline_5m, ma50_above_mean_5m, ma50_below_mean_5m)
ma200_distance_color_5m = get_ma200_distance_color(distance_5m, distance_threshold_1m, ma200_near_5m, ma200_far_5m)
table.cell(mtf_table, 0, 2, "5分钟", text_color=color.black, text_size=text_size)
table.cell(mtf_table, 1, 2, str.tostring(rsi_5m, '#.#'), text_color=color.black, bgcolor=rsi_color_5m, text_size=text_size)
table.cell(mtf_table, 2, 2, rsi_status_5m, text_color=color.black, bgcolor=rsi_color_5m, text_size=text_size)
table.cell(mtf_table, 3, 2, na(cross_count_5m) ? "N/A" : str.tostring(cross_count_5m), text_color=color.black, text_size=text_size)
table.cell(mtf_table, 4, 2, get_price_position(close_5m, upband1_5m, loband1_5m), text_color=color.black, bgcolor=price_color_5m, text_size=text_size)
table.cell(mtf_table, 5, 2, get_price_mean_position(close_5m, meanline_5m), text_color=color.black, bgcolor=price_mean_color_5m, text_size=text_size)
table.cell(mtf_table, 6, 2, get_ma50_position(ma50_5m, meanline_5m), text_color=color.black, bgcolor=ma50_color_5m, text_size=text_size)
// 计算距离背景颜色
ma200_bg_color_5m = get_distance_bg_color(distance_5m, distance_threshold_1m)
mean_bg_color_5m = get_distance_bg_color(distance_to_mean_5m, r1s1_threshold)
r1_bg_color_5m = get_distance_bg_color(distance_to_r1_5m, r1s1_threshold)
s1_bg_color_5m = get_distance_bg_color(distance_to_s1_5m, r1s1_threshold)
table.cell(mtf_table, 7, 2, str.tostring(distance_5m, '#.##'), text_color=color.black, bgcolor=ma200_bg_color_5m, text_size=text_size)
table.cell(mtf_table, 8, 2, na(distance_to_mean_5m) ? "N/A" : str.tostring(distance_to_mean_5m, '#.##'), text_color=color.black, bgcolor=mean_bg_color_5m, text_size=text_size)
table.cell(mtf_table, 9, 2, na(distance_to_r1_5m) ? "N/A" : str.tostring(distance_to_r1_5m, '#.##'), text_color=color.black, bgcolor=r1_bg_color_5m, text_size=text_size)
table.cell(mtf_table, 10, 2, na(distance_to_s1_5m) ? "N/A" : str.tostring(distance_to_s1_5m, '#.##'), text_color=color.black, bgcolor=s1_bg_color_5m, text_size=text_size)
table.cell(mtf_table, 11, 2, get_signal_text(osc_5m, long_5m, short_5m), text_color=color.black, bgcolor=signal_color_5m, text_size=text_size)
table.cell(mtf_table, 12, 2, get_final_judgment(osc_5m, long_5m, short_5m), text_color=color.black, bgcolor=signal_color_5m, text_size=text_size)
// ═════════ 15分钟时间框架数据 ═════════
if mtf_15m and not na(rsi_15m)
signal_color_15m = get_signal_color(osc_15m, long_15m, short_15m)
rsi_status_15m = get_rsi_status(rsi_15m, long_S, short_S)
// 计算各个条件的颜色
rsi_color_15m = get_rsi_color(rsi_15m, long_S, short_S, rsi_neutral_15m, rsi_overbought_15m, rsi_oversold_15m)
price_color_15m = get_price_color(close_15m, upband1_15m, loband1_15m, price_in_channel_15m, price_above_r1_15m, price_below_s1_15m)
price_mean_color_15m = get_price_mean_color(close_15m, meanline_15m)
ma50_color_15m = get_ma50_color(ma50_15m, meanline_15m, ma50_above_mean_15m, ma50_below_mean_15m)
ma200_distance_color_15m = get_ma200_distance_color(distance_15m, distance_threshold_1m, ma200_near_15m, ma200_far_15m)
table.cell(mtf_table, 0, 3, "15分钟", text_color=color.black, text_size=text_size)
table.cell(mtf_table, 1, 3, str.tostring(rsi_15m, '#.#'), text_color=color.black, bgcolor=rsi_color_15m, text_size=text_size)
table.cell(mtf_table, 2, 3, rsi_status_15m, text_color=color.black, bgcolor=rsi_color_15m, text_size=text_size)
table.cell(mtf_table, 3, 3, na(cross_count_15m) ? "N/A" : str.tostring(cross_count_15m), text_color=color.black, text_size=text_size)
table.cell(mtf_table, 4, 3, get_price_position(close_15m, upband1_15m, loband1_15m), text_color=color.black, bgcolor=price_color_15m, text_size=text_size)
table.cell(mtf_table, 5, 3, get_price_mean_position(close_15m, meanline_15m), text_color=color.black, bgcolor=price_mean_color_15m, text_size=text_size)
table.cell(mtf_table, 6, 3, get_ma50_position(ma50_15m, meanline_15m), text_color=color.black, bgcolor=ma50_color_15m, text_size=text_size)
// 计算距离背景颜色
ma200_bg_color_15m = get_distance_bg_color(distance_15m, distance_threshold_1m)
mean_bg_color_15m = get_distance_bg_color(distance_to_mean_15m, r1s1_threshold)
r1_bg_color_15m = get_distance_bg_color(distance_to_r1_15m, r1s1_threshold)
s1_bg_color_15m = get_distance_bg_color(distance_to_s1_15m, r1s1_threshold)
table.cell(mtf_table, 7, 3, str.tostring(distance_15m, '#.##'), text_color=color.black, bgcolor=ma200_bg_color_15m, text_size=text_size)
table.cell(mtf_table, 8, 3, na(distance_to_mean_15m) ? "N/A" : str.tostring(distance_to_mean_15m, '#.##'), text_color=color.black, bgcolor=mean_bg_color_15m, text_size=text_size)
table.cell(mtf_table, 9, 3, na(distance_to_r1_15m) ? "N/A" : str.tostring(distance_to_r1_15m, '#.##'), text_color=color.black, bgcolor=r1_bg_color_15m, text_size=text_size)
table.cell(mtf_table, 10, 3, na(distance_to_s1_15m) ? "N/A" : str.tostring(distance_to_s1_15m, '#.##'), text_color=color.black, bgcolor=s1_bg_color_15m, text_size=text_size)
table.cell(mtf_table, 11, 3, get_signal_text(osc_15m, long_15m, short_15m), text_color=color.black, bgcolor=signal_color_15m, text_size=text_size)
table.cell(mtf_table, 12, 3, get_final_judgment(osc_15m, long_15m, short_15m), text_color=color.black, bgcolor=signal_color_15m, text_size=text_size)
// ═════════ 30分钟时间框架数据 ═════════
if mtf_30m and not na(rsi_30m)
signal_color_30m = get_signal_color(osc_30m, long_30m, short_30m)
rsi_status_30m = get_rsi_status(rsi_30m, long_S, short_S)
// 计算各个条件的颜色
rsi_color_30m = get_rsi_color(rsi_30m, long_S, short_S, rsi_neutral_30m, rsi_overbought_30m, rsi_oversold_30m)
price_color_30m = get_price_color(close_30m, upband1_30m, loband1_30m, price_in_channel_30m, price_above_r1_30m, price_below_s1_30m)
price_mean_color_30m = get_price_mean_color(close_30m, meanline_30m)
ma50_color_30m = get_ma50_color(ma50_30m, meanline_30m, ma50_above_mean_30m, ma50_below_mean_30m)
ma200_distance_color_30m = get_ma200_distance_color(distance_30m, distance_threshold_1m, ma200_near_30m, ma200_far_30m)
table.cell(mtf_table, 0, 4, "30分钟", text_color=color.black, text_size=text_size)
table.cell(mtf_table, 1, 4, str.tostring(rsi_30m, '#.#'), text_color=color.black, bgcolor=rsi_color_30m, text_size=text_size)
table.cell(mtf_table, 2, 4, rsi_status_30m, text_color=color.black, bgcolor=rsi_color_30m, text_size=text_size)
table.cell(mtf_table, 3, 4, na(cross_count_30m) ? "N/A" : str.tostring(cross_count_30m), text_color=color.black, text_size=text_size)
table.cell(mtf_table, 4, 4, get_price_position(close_30m, upband1_30m, loband1_30m), text_color=color.black, bgcolor=price_color_30m, text_size=text_size)
table.cell(mtf_table, 5, 4, get_price_mean_position(close_30m, meanline_30m), text_color=color.black, bgcolor=price_mean_color_30m, text_size=text_size)
table.cell(mtf_table, 6, 4, get_ma50_position(ma50_30m, meanline_30m), text_color=color.black, bgcolor=ma50_color_30m, text_size=text_size)
// 计算距离背景颜色
ma200_bg_color_30m = get_distance_bg_color(distance_30m, distance_threshold_1m)
mean_bg_color_30m = get_distance_bg_color(distance_to_mean_30m, r1s1_threshold)
r1_bg_color_30m = get_distance_bg_color(distance_to_r1_30m, r1s1_threshold)
s1_bg_color_30m = get_distance_bg_color(distance_to_s1_30m, r1s1_threshold)
table.cell(mtf_table, 7, 4, str.tostring(distance_30m, '#.##'), text_color=color.black, bgcolor=ma200_bg_color_30m, text_size=text_size)
table.cell(mtf_table, 8, 4, na(distance_to_mean_30m) ? "N/A" : str.tostring(distance_to_mean_30m, '#.##'), text_color=color.black, bgcolor=mean_bg_color_30m, text_size=text_size)
table.cell(mtf_table, 9, 4, na(distance_to_r1_30m) ? "N/A" : str.tostring(distance_to_r1_30m, '#.##'), text_color=color.black, bgcolor=r1_bg_color_30m, text_size=text_size)
table.cell(mtf_table, 10, 4, na(distance_to_s1_30m) ? "N/A" : str.tostring(distance_to_s1_30m, '#.##'), text_color=color.black, bgcolor=s1_bg_color_30m, text_size=text_size)
table.cell(mtf_table, 11, 4, get_signal_text(osc_30m, long_30m, short_30m), text_color=color.black, bgcolor=signal_color_30m, text_size=text_size)
table.cell(mtf_table, 12, 4, get_final_judgment(osc_30m, long_30m, short_30m), text_color=color.black, bgcolor=signal_color_30m, text_size=text_size)
// ═════════ 45分钟时间框架数据 ═════════
if mtf_45m and not na(rsi_45m)
signal_color_45m = get_signal_color(osc_45m, long_45m, short_45m)
rsi_status_45m = get_rsi_status(rsi_45m, long_S, short_S)
// 计算各个条件的颜色
rsi_color_45m = get_rsi_color(rsi_45m, long_S, short_S, rsi_neutral_45m, rsi_overbought_45m, rsi_oversold_45m)
price_color_45m = get_price_color(close_45m, upband1_45m, loband1_45m, price_in_channel_45m, price_above_r1_45m, price_below_s1_45m)
price_mean_color_45m = get_price_mean_color(close_45m, meanline_45m)
ma50_color_45m = get_ma50_color(ma50_45m, meanline_45m, ma50_above_mean_45m, ma50_below_mean_45m)
ma200_distance_color_45m = get_ma200_distance_color(distance_45m, distance_threshold_1m, ma200_near_45m, ma200_far_45m)
table.cell(mtf_table, 0, 5, "45分钟", text_color=color.black, text_size=text_size)
table.cell(mtf_table, 1, 5, str.tostring(rsi_45m, '#.#'), text_color=color.black, bgcolor=rsi_color_45m, text_size=text_size)
table.cell(mtf_table, 2, 5, rsi_status_45m, text_color=color.black, bgcolor=rsi_color_45m, text_size=text_size)
table.cell(mtf_table, 3, 5, na(cross_count_45m) ? "N/A" : str.tostring(cross_count_45m), text_color=color.black, text_size=text_size)
table.cell(mtf_table, 4, 5, get_price_position(close_45m, upband1_45m, loband1_45m), text_color=color.black, bgcolor=price_color_45m, text_size=text_size)
table.cell(mtf_table, 5, 5, get_price_mean_position(close_45m, meanline_45m), text_color=color.black, bgcolor=price_mean_color_45m, text_size=text_size)
table.cell(mtf_table, 6, 5, get_ma50_position(ma50_45m, meanline_45m), text_color=color.black, bgcolor=ma50_color_45m, text_size=text_size)
// 计算距离背景颜色
ma200_bg_color_45m = get_distance_bg_color(distance_45m, distance_threshold_1m)
mean_bg_color_45m = get_distance_bg_color(distance_to_mean_45m, r1s1_threshold)
r1_bg_color_45m = get_distance_bg_color(distance_to_r1_45m, r1s1_threshold)
s1_bg_color_45m = get_distance_bg_color(distance_to_s1_45m, r1s1_threshold)
table.cell(mtf_table, 7, 5, str.tostring(distance_45m, '#.##'), text_color=color.black, bgcolor=ma200_bg_color_45m, text_size=text_size)
table.cell(mtf_table, 8, 5, na(distance_to_mean_45m) ? "N/A" : str.tostring(distance_to_mean_45m, '#.##'), text_color=color.black, bgcolor=mean_bg_color_45m, text_size=text_size)
table.cell(mtf_table, 9, 5, na(distance_to_r1_45m) ? "N/A" : str.tostring(distance_to_r1_45m, '#.##'), text_color=color.black, bgcolor=r1_bg_color_45m, text_size=text_size)
table.cell(mtf_table, 10, 5, na(distance_to_s1_45m) ? "N/A" : str.tostring(distance_to_s1_45m, '#.##'), text_color=color.black, bgcolor=s1_bg_color_45m, text_size=text_size)
table.cell(mtf_table, 11, 5, get_signal_text(osc_45m, long_45m, short_45m), text_color=color.black, bgcolor=signal_color_45m, text_size=text_size)
table.cell(mtf_table, 12, 5, get_final_judgment(osc_45m, long_45m, short_45m), text_color=color.black, bgcolor=signal_color_45m, text_size=text_size)
// ═════════ 1小时时间框架数据 ═════════
if mtf_1h and not na(rsi_1h)
signal_color_1h = get_signal_color(osc_1h, long_1h, short_1h)
rsi_status_1h = get_rsi_status(rsi_1h, long_S, short_S)
// 计算各个条件的颜色
rsi_color_1h = get_rsi_color(rsi_1h, long_S, short_S, rsi_neutral_1h, rsi_overbought_1h, rsi_oversold_1h)
price_color_1h = get_price_color(close_1h, upband1_1h, loband1_1h, price_in_channel_1h, price_above_r1_1h, price_below_s1_1h)
price_mean_color_1h = get_price_mean_color(close_1h, meanline_1h)
ma50_color_1h = get_ma50_color(ma50_1h, meanline_1h, ma50_above_mean_1h, ma50_below_mean_1h)
ma200_distance_color_1h = get_ma200_distance_color(distance_1h, distance_threshold_1m, ma200_near_1h, ma200_far_1h)
table.cell(mtf_table, 0, 6, "1小时", text_color=color.black, text_size=text_size)
table.cell(mtf_table, 1, 6, str.tostring(rsi_1h, '#.#'), text_color=color.black, bgcolor=rsi_color_1h, text_size=text_size)
table.cell(mtf_table, 2, 6, rsi_status_1h, text_color=color.black, bgcolor=rsi_color_1h, text_size=text_size)
table.cell(mtf_table, 3, 6, na(cross_count_1h) ? "N/A" : str.tostring(cross_count_1h), text_color=color.black, text_size=text_size)
table.cell(mtf_table, 4, 6, get_price_position(close_1h, upband1_1h, loband1_1h), text_color=color.black, bgcolor=price_color_1h, text_size=text_size)
table.cell(mtf_table, 5, 6, get_price_mean_position(close_1h, meanline_1h), text_color=color.black, bgcolor=price_mean_color_1h, text_size=text_size)
table.cell(mtf_table, 6, 6, get_ma50_position(ma50_1h, meanline_1h), text_color=color.black, bgcolor=ma50_color_1h, text_size=text_size)
// 计算距离背景颜色
ma200_bg_color_1h = get_distance_bg_color(distance_1h, distance_threshold_1m)
mean_bg_color_1h = get_distance_bg_color(distance_to_mean_1h, r1s1_threshold)
r1_bg_color_1h = get_distance_bg_color(distance_to_r1_1h, r1s1_threshold)
s1_bg_color_1h = get_distance_bg_color(distance_to_s1_1h, r1s1_threshold)
table.cell(mtf_table, 7, 6, str.tostring(distance_1h, '#.##'), text_color=color.black, bgcolor=ma200_bg_color_1h, text_size=text_size)
table.cell(mtf_table, 8, 6, na(distance_to_mean_1h) ? "N/A" : str.tostring(distance_to_mean_1h, '#.##'), text_color=color.black, bgcolor=mean_bg_color_1h, text_size=text_size)
table.cell(mtf_table, 9, 6, na(distance_to_r1_1h) ? "N/A" : str.tostring(distance_to_r1_1h, '#.##'), text_color=color.black, bgcolor=r1_bg_color_1h, text_size=text_size)
table.cell(mtf_table, 10, 6, na(distance_to_s1_1h) ? "N/A" : str.tostring(distance_to_s1_1h, '#.##'), text_color=color.black, bgcolor=s1_bg_color_1h, text_size=text_size)
table.cell(mtf_table, 11, 6, get_signal_text(osc_1h, long_1h, short_1h), text_color=color.black, bgcolor=signal_color_1h, text_size=text_size)
table.cell(mtf_table, 12, 6, get_final_judgment(osc_1h, long_1h, short_1h), text_color=color.black, bgcolor=signal_color_1h, text_size=text_size)
// ═════════ 4小时时间框架数据 ═════════
if mtf_4h and not na(rsi_4h)
signal_color_4h = get_signal_color(osc_4h, long_4h, short_4h)
rsi_status_4h = get_rsi_status(rsi_4h, long_S, short_S)
// 计算各个条件的颜色
rsi_color_4h = get_rsi_color(rsi_4h, long_S, short_S, rsi_neutral_4h, rsi_overbought_4h, rsi_oversold_4h)
price_color_4h = get_price_color(close_4h, upband1_4h, loband1_4h, price_in_channel_4h, price_above_r1_4h, price_below_s1_4h)
price_mean_color_4h = get_price_mean_color(close_4h, meanline_4h)
ma50_color_4h = get_ma50_color(ma50_4h, meanline_4h, ma50_above_mean_4h, ma50_below_mean_4h)
ma200_distance_color_4h = get_ma200_distance_color(distance_4h, distance_threshold_1m, ma200_near_4h, ma200_far_4h)
table.cell(mtf_table, 0, 7, "4小时", text_color=color.black, text_size=text_size)
table.cell(mtf_table, 1, 7, str.tostring(rsi_4h, '#.#'), text_color=color.black, bgcolor=rsi_color_4h, text_size=text_size)
table.cell(mtf_table, 2, 7, rsi_status_4h, text_color=color.black, bgcolor=rsi_color_4h, text_size=text_size)
table.cell(mtf_table, 3, 7, na(cross_count_4h) ? "N/A" : str.tostring(cross_count_4h), text_color=color.black, text_size=text_size)
table.cell(mtf_table, 4, 7, get_price_position(close_4h, upband1_4h, loband1_4h), text_color=color.black, bgcolor=price_color_4h, text_size=text_size)
table.cell(mtf_table, 5, 7, get_price_mean_position(close_4h, meanline_4h), text_color=color.black, bgcolor=price_mean_color_4h, text_size=text_size)
table.cell(mtf_table, 6, 7, get_ma50_position(ma50_4h, meanline_4h), text_color=color.black, bgcolor=ma50_color_4h, text_size=text_size)
// 计算距离背景颜色
ma200_bg_color_4h = get_distance_bg_color(distance_4h, distance_threshold_1m)
mean_bg_color_4h = get_distance_bg_color(distance_to_mean_4h, r1s1_threshold)
r1_bg_color_4h = get_distance_bg_color(distance_to_r1_4h, r1s1_threshold)
s1_bg_color_4h = get_distance_bg_color(distance_to_s1_4h, r1s1_threshold)
table.cell(mtf_table, 7, 7, str.tostring(distance_4h, '#.##'), text_color=color.black, bgcolor=ma200_bg_color_4h, text_size=text_size)
table.cell(mtf_table, 8, 7, na(distance_to_mean_4h) ? "N/A" : str.tostring(distance_to_mean_4h, '#.##'), text_color=color.black, bgcolor=mean_bg_color_4h, text_size=text_size)
table.cell(mtf_table, 9, 7, na(distance_to_r1_4h) ? "N/A" : str.tostring(distance_to_r1_4h, '#.##'), text_color=color.black, bgcolor=r1_bg_color_4h, text_size=text_size)
table.cell(mtf_table, 10, 7, na(distance_to_s1_4h) ? "N/A" : str.tostring(distance_to_s1_4h, '#.##'), text_color=color.black, bgcolor=s1_bg_color_4h, text_size=text_size)
table.cell(mtf_table, 11, 7, get_signal_text(osc_4h, long_4h, short_4h), text_color=color.black, bgcolor=signal_color_4h, text_size=text_size)
table.cell(mtf_table, 12, 7, get_final_judgment(osc_4h, long_4h, short_4h), text_color=color.black, bgcolor=signal_color_4h, text_size=text_size)
// ═════════ RSI详细表格左下角可配置显示 ═════════
if show_rsi_table and barstate.islast
var table rsi_table = table.new(
position = position.bottom_left, // 左下角
columns = 2,
rows = 10,
bgcolor = color.new(color.white, 85),
border_width = 1)
table.clear(rsi_table, 0, 0, 1, 9)
// 获取RSI表格的文字大小
rsi_text_size = get_text_size()
// RSI详细信息表格内容预留
table.cell(rsi_table, 0, 0, "RSI详细分析", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=rsi_text_size)
table.cell(rsi_table, 1, 0, "", text_color=color.black, text_size=rsi_text_size)
// ═════════ 高级警报状态表格(已禁用,整合到信息表格中) ═════════
if false // 禁用独立的高级警报表格
var table alert_status_table = table.new(
position = position.top_right,
columns = 2,
rows = 12,
bgcolor = color.new(color.white, 85),
border_width = 1)
table.clear(alert_status_table, 0, 0, 1, 11)
text_size = get_text_size()
// 标题
table.cell(alert_status_table, 0, 0, "高级警报状态", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
table.cell(alert_status_table, 1, 0, "当前状态", text_color=color.white, bgcolor=color.new(color.purple, 30), text_size=text_size)
// 启动条件状态
long_trigger_status = long_trigger ? "✓ 已触发" : na(long_trigger_time) ? "等待中" : "监控中"
short_trigger_status = short_trigger ? "✓ 已触发" : na(short_trigger_time) ? "等待中" : "监控中"
table.cell(alert_status_table, 0, 1, "做多启动", text_color=color.black, text_size=text_size)
table.cell(alert_status_table, 1, 1, long_trigger_status, text_color=color.black, bgcolor=long_trigger ? color.new(color.green, 60) : color.white, text_size=text_size)
table.cell(alert_status_table, 0, 2, "做空启动", text_color=color.black, text_size=text_size)
table.cell(alert_status_table, 1, 2, short_trigger_status, text_color=color.black, bgcolor=short_trigger ? color.new(color.red, 60) : color.white, text_size=text_size)
// 时间窗口状态
long_window_status = not na(long_trigger_time) ? (in_time_window(long_trigger_time, time_window_15min) ? "窗口内" : "已过期") : "未启动"
short_window_status = not na(short_trigger_time) ? (in_time_window(short_trigger_time, time_window_15min) ? "窗口内" : "已过期") : "未启动"
table.cell(alert_status_table, 0, 3, "做多窗口", text_color=color.black, text_size=text_size)
table.cell(alert_status_table, 1, 3, long_window_status, text_color=color.black, text_size=text_size)
table.cell(alert_status_table, 0, 4, "做空窗口", text_color=color.black, text_size=text_size)
table.cell(alert_status_table, 1, 4, short_window_status, text_color=color.black, text_size=text_size)
// 冷却状态
long_cooldown_status = is_cooldown_over(last_long_alert_time, alert_cooldown_minutes) ? "可用" : "冷却中"
short_cooldown_status = is_cooldown_over(last_short_alert_time, alert_cooldown_minutes) ? "可用" : "冷却中"
table.cell(alert_status_table, 0, 5, "做多冷却", text_color=color.black, text_size=text_size)
table.cell(alert_status_table, 1, 5, long_cooldown_status, text_color=color.black, text_size=text_size)
table.cell(alert_status_table, 0, 6, "做空冷却", text_color=color.black, text_size=text_size)
table.cell(alert_status_table, 1, 6, short_cooldown_status, text_color=color.black, text_size=text_size)
// 条件状态检查
condition2_1m_long = not na(long_trigger_time) and in_time_window(long_trigger_time, time_window_5min) and rsi_overbought_1m and price_above_r1_1m and ma200_far_1m and ma50_above_mean_1m
condition3_5m_long = not na(long_trigger_time) and in_time_window(long_trigger_time, time_window_15min) and rsi_overbought_5m and price_above_mean_5m and ma200_far_5m and ma50_above_mean_1m
condition4_15m_long = not na(long_trigger_time) and in_time_window(long_trigger_time, time_window_10min) and distance_to_s1_15m > get_r1s1_distance_threshold()
condition2_1m_short = not na(short_trigger_time) and in_time_window(short_trigger_time, time_window_5min) and rsi_oversold_1m and price_below_s1_1m and ma200_far_1m and ma50_below_mean_1m
condition3_5m_short = not na(short_trigger_time) and in_time_window(short_trigger_time, time_window_15min) and rsi_oversold_5m and price_below_mean_5m and ma200_far_5m and ma50_below_mean_1m
condition4_15m_short = not na(short_trigger_time) and in_time_window(short_trigger_time, time_window_10min) and distance_to_r1_15m > get_r1s1_distance_threshold()
// 条件状态显示
table.cell(alert_status_table, 0, 7, "条件2(1m)", text_color=color.black, text_size=text_size)
condition2_status = condition2_1m_long ? "✓做多" : condition2_1m_short ? "✓做空" : "未满足"
condition2_color = condition2_1m_long ? color.new(color.green, 60) : condition2_1m_short ? color.new(color.red, 60) : color.white
table.cell(alert_status_table, 1, 7, condition2_status, text_color=color.black, bgcolor=condition2_color, text_size=text_size)
table.cell(alert_status_table, 0, 8, "条件3(5m)", text_color=color.black, text_size=text_size)
condition3_status = condition3_5m_long ? "✓做多" : condition3_5m_short ? "✓做空" : "未满足"
condition3_color = condition3_5m_long ? color.new(color.green, 60) : condition3_5m_short ? color.new(color.red, 60) : color.white
table.cell(alert_status_table, 1, 8, condition3_status, text_color=color.black, bgcolor=condition3_color, text_size=text_size)
table.cell(alert_status_table, 0, 9, "条件4(15m)", text_color=color.black, text_size=text_size)
condition4_status = condition4_15m_long ? "✓做多" : condition4_15m_short ? "✓做空" : "未满足"
condition4_color = condition4_15m_long ? color.new(color.green, 60) : condition4_15m_short ? color.new(color.red, 60) : color.white
table.cell(alert_status_table, 1, 9, condition4_status, text_color=color.black, bgcolor=condition4_color, text_size=text_size)
// 综合条件状态
all_long_conditions = condition2_1m_long and condition3_5m_long and condition4_15m_long
all_short_conditions = condition2_1m_short and condition3_5m_short and condition4_15m_short
table.cell(alert_status_table, 0, 10, "综合条件", text_color=color.black, text_size=text_size)
combined_status = all_long_conditions ? "✓做多就绪" : all_short_conditions ? "✓做空就绪" : "未就绪"
combined_color = all_long_conditions ? color.new(color.lime, 60) : all_short_conditions ? color.new(color.fuchsia, 60) : color.white
table.cell(alert_status_table, 1, 10, combined_status, text_color=color.black, bgcolor=combined_color, text_size=text_size)
// 最终警报状态
final_long_status = advanced_long_alert ? "🚀 警报!" : "等待中"
final_short_status = advanced_short_alert ? "🔻 警报!" : "等待中"
table.cell(alert_status_table, 0, 11, "警报状态", text_color=color.black, text_size=text_size)
alert_status_text = advanced_long_alert ? final_long_status : advanced_short_alert ? final_short_status : "无警报"
alert_status_color = advanced_long_alert ? color.new(color.lime, 40) : advanced_short_alert ? color.new(color.fuchsia, 40) : color.white
table.cell(alert_status_table, 1, 11, alert_status_text, text_color=color.black, bgcolor=alert_status_color, text_size=text_size)
// ═════════ 实时价格标签显示信号结论 ═════════
// 确定当前主要信号(包含高级警报)
current_signal = advanced_long_alert ? "🚀高级做多" : advanced_short_alert ? "🔻高级做空" : long_signal ? "🚀做多" : short_signal ? "🔻做空" : oscillation_signal ? "⚡震荡" : "观望"
signal_color = advanced_long_alert ? color.lime : advanced_short_alert ? color.fuchsia : long_signal ? color.green : short_signal ? color.red : oscillation_signal ? color.orange : color.gray
// 创建唯一的实时价格标签(避免重复)
var label price_signal_label = na
// 在最后一根K线上显示实时价格标签
if barstate.islast
// 删除之前的标签
if not na(price_signal_label)
label.delete(price_signal_label)
// 计算标签位置:使用时间坐标,右偏移避免重叠
label_time = time + (time - time[1]) * 3 // 右偏移3个时间单位
// 创建新的实时价格标签
price_label_text = str.tostring(close, '#.####') + " | " + current_signal
price_signal_label := label.new(x=label_time, y=close, text=price_label_text, style=label.style_label_left, color=color.new(signal_color, 20), textcolor=color.white, size=size.normal, xloc=xloc.bar_time)
// 删除超出表格范围的残留代码
//************************************************************************************************************
// RSI 窗口二显示
//************************************************************************************************************
// RSI 数据输出用于在单独的RSI指标中显示
// 注意由于TradingView限制RSI需要在单独的指标中显示
// 这里我们输出RSI数据供外部使用同时在表格中显示数值
// 为了在主图中也能看到RSI信息我们将RSI数据通过plot输出但不显示
plot(rsi, 'RSI_Data', display=display.none)
plot(long_S, 'RSI_Long_Threshold', display=display.none)
plot(short_S, 'RSI_Short_Threshold', display=display.none)
plot(segment_count, 'RSI_Segment_Count', display=display.none)
// RSI 信息表格(可选显示,计算始终保留用于警报)
if show_rsi_table and barstate.islast
// 创建RSI表格
var table rsi_table = table.new(
position = position.bottom_right,
columns = 2,
rows = 8,
bgcolor = color.new(color.yellow, 80),
border_width = 1)
// 清空表格
table.clear(rsi_table, 0, 0, 1, 7)
// 添加RSI标题
table.cell(rsi_table, 0, 0, "RSI指标", text_color=color.black, bgcolor=color.new(color.orange, 70), text_size=size.small)
table.cell(rsi_table, 1, 0, "实时数值", text_color=color.black, bgcolor=color.new(color.orange, 70), text_size=size.small)
// RSI 值
table.cell(rsi_table, 0, 1, "RSI值", text_color=color.black, text_size=size.tiny)
table.cell(rsi_table, 1, 1, str.tostring(rsi, '#.##'), text_color=color.black, text_size=size.tiny)
// RSI 位置
table.cell(rsi_table, 0, 2, "RSI位置", text_color=color.black, text_size=size.tiny)
table.cell(rsi_table, 1, 2, rsi_position, text_color=color.black, text_size=size.tiny)
// RSI 阈值
table.cell(rsi_table, 0, 3, "超买阈值", text_color=color.black, text_size=size.tiny)
table.cell(rsi_table, 1, 3, str.tostring(long_S, '#.##'), text_color=color.black, text_size=size.tiny)
table.cell(rsi_table, 0, 4, "超卖阈值", text_color=color.black, text_size=size.tiny)
table.cell(rsi_table, 1, 4, str.tostring(short_S, '#.##'), text_color=color.black, text_size=size.tiny)
// RSI 穿越次数
table.cell(rsi_table, 0, 5, "穿越次数", text_color=color.black, text_size=size.tiny)
table.cell(rsi_table, 1, 5, str.tostring(rsi_cross_count), text_color=color.black, text_size=size.tiny)
// RSI 穿越类型
cross_type = segment_count > 0 ? "超买穿越" : segment_count < 0 ? "超卖穿越" : "无穿越"
table.cell(rsi_table, 0, 6, "穿越类型", text_color=color.black, text_size=size.tiny)
table.cell(rsi_table, 1, 6, cross_type, text_color=color.black, text_size=size.tiny)
// RSI 状态标记
table.cell(rsi_table, 0, 7, "状态标记", text_color=color.black, text_size=size.tiny)
table.cell(rsi_table, 1, 7, str.tostring(segment_count), text_color=color.black, text_size=size.tiny)
//************************************************************************************************************
// 趋势判断逻辑
//************************************************************************************************************
// 综合趋势判断
trend_signal = ""
market_type = ""
// 删除不再使用的角度趋势判断(已在前面重新定义)
// 价格相对MA200位置
price_above_ma200 = close > ma200
price_below_ma200 = close < ma200
// RSI 趋势确认
rsi_bullish = rsi > 50 and rsi < long_S
rsi_bearish = rsi < 50 and rsi > short_S
rsi_overbought = rsi > long_S
rsi_oversold = rsi < short_S
// 重新设计的综合判断逻辑
// 首先判断是否为震荡
if is_oscillating
trend_signal := "震荡行情"
market_type := "震荡"
// 然后判断趋势强度和方向
else if ma200_trend_direction == "上升"
if ma200_strength == "强" and price_above_ma200 and (rsi_bullish or rsi_overbought)
trend_signal := "强多头趋势"
market_type := "强趋势"
else if (ma200_strength == "中" or ma200_strength == "弱") and price_above_ma200
trend_signal := "弱多头趋势"
market_type := "弱趋势"
else
trend_signal := "多头整理"
market_type := "整理"
else if ma200_trend_direction == "下降"
if ma200_strength == "强" and price_below_ma200 and (rsi_bearish or rsi_oversold)
trend_signal := "强空头趋势"
market_type := "强趋势"
else if (ma200_strength == "中" or ma200_strength == "弱") and price_below_ma200
trend_signal := "弱空头趋势"
market_type := "弱趋势"
else
trend_signal := "空头整理"
market_type := "整理"
else // 横盘
trend_signal := "横盘整理"
market_type := "整理"
// 在图表上显示趋势判断
if barstate.islast and show_info_table
// 创建趋势判断表格
var table trend_table = table.new(
position = position.top_left,
columns = 2,
rows = 4,
bgcolor = color.new(color.green, 80),
border_width = 2)
// 清空表格
table.clear(trend_table, 0, 0, 1, 3)
// 添加趋势标题
table.cell(trend_table, 0, 0, "市场分析", text_color=color.white, bgcolor=color.new(color.purple, 50), text_size=size.normal)
table.cell(trend_table, 1, 0, "判断结果", text_color=color.white, bgcolor=color.new(color.purple, 50), text_size=size.normal)
// 趋势方向
trend_color = trend_signal == "多头趋势" ? color.green : trend_signal == "空头趋势" ? color.red : color.orange
table.cell(trend_table, 0, 1, "趋势方向", text_color=color.black, text_size=size.small)
table.cell(trend_table, 1, 1, trend_signal, text_color=color.white, bgcolor=trend_color, text_size=size.small)
// 市场类型
table.cell(trend_table, 0, 2, "市场类型", text_color=color.black, text_size=size.small)
table.cell(trend_table, 1, 2, market_type, text_color=color.black, text_size=size.small)
// MA200趋势
table.cell(trend_table, 0, 3, "MA200趋势", text_color=color.black, text_size=size.small)
table.cell(trend_table, 1, 3, ma200_trend_direction, text_color=color.black, text_size=size.small)
//************************************************************************************************************
// RSI 分段线显示(已禁用 - 使用独立的RSI窗口
//************************************************************************************************************
// 注释由于使用了独立的RSI窗口2.c这里不再绘制RSI相关的线条和标签
// 避免在主图表K线0附近出现橙黄色横条
// RSI 状态变化时绘制分段线(已禁用)
var int prev_rsi_state = 0
// 禁用RSI分段线绘制因为有独立的RSI窗口
if false // 原条件current_state != rsi_state and not na(rsi)
// 确定分段线颜色
segment_color = color.black
if prev_rsi_state == 0 and current_state == 1
segment_color := color.new(color.red, 0) // 从中性区进入超买区
else if prev_rsi_state == 0 and current_state == -1
segment_color := color.new(color.blue, 0) // 从中性区进入超卖区
else if prev_rsi_state == 1 and current_state == 0
segment_color := color.new(color.orange, 0) // 从超买区进入中性区
else if prev_rsi_state == -1 and current_state == 0
segment_color := color.new(color.green, 0) // 从超卖区进入中性区
else if prev_rsi_state == 1 and current_state == -1
segment_color := color.new(color.purple, 0) // 从超买区直接到超卖区
else if prev_rsi_state == -1 and current_state == 1
segment_color := color.new(color.yellow, 0) // 从超卖区直接到超买区
else if prev_rsi_state == 1 and current_state == 1
segment_color := color.new(color.maroon, 0) // 超买区内的重复进入
else if prev_rsi_state == -1 and current_state == -1
segment_color := color.new(color.navy, 0) // 超卖区内的重复进入
// 在RSI窗口绘制垂直分段线已禁用
// line.new(bar_index, 0, bar_index, 100,
// color = segment_color,
// width = 2,
// style = line.style_solid,
// extend = extend.none)
// 显示计数标签(已禁用)
if current_state == 1 and segment_count > 0
label.new(bar_index, rsi,
text = str.tostring(segment_count),
style = label.style_label_down,
color = color.red,
textcolor = color.white,
size = size.small)
else if current_state == -1 and segment_count < 0
label.new(bar_index, rsi,
text = str.tostring(segment_count),
style = label.style_label_up,
color = color.blue,
textcolor = color.white,
size = size.small)
// 更新前一个状态
prev_rsi_state := rsi_state
//************************************************************************************************************
// 价格格式化函数
//************************************************************************************************************
format_price(price) =>
str.tostring(price, '#.####')
//************************************************************************************************************
// 价格标签显示参考MRC原始实现
//************************************************************************************************************
// 声明标签变量
var label mean_label = na
var label res1_label = na
var label sup1_label = na
var label res2_label = na
var label sup2_label = na
var label lbl50 = na
var label lbl100 = na
var label lbl200 = na
if barstate.islast
// MEAN 标签(独立控制)
if show_mean_label
if na(mean_label)
mean_label := label.new(bar_index, meanline, "MEAN: " + format_price(meanline), xloc=xloc.bar_index, style=label.style_label_left, color=color.new(color.black, 0), textcolor=color.white)
else
label.set_xy(mean_label, bar_index, meanline)
label.set_text(mean_label, "MEAN: " + format_price(meanline))
// R1 标签(独立控制)
if show_r1_label
if na(res1_label)
res1_label := label.new(bar_index, upband1, "R1: " + format_price(upband1), xloc=xloc.bar_index, style=label.style_label_left, color=color.new(color.red, 0), textcolor=color.white)
else
label.set_xy(res1_label, bar_index, upband1)
label.set_text(res1_label, "R1: " + format_price(upband1))
// S1 标签(独立控制)
if show_s1_label
if na(sup1_label)
sup1_label := label.new(bar_index, loband1, "S1: " + format_price(loband1), xloc=xloc.bar_index, style=label.style_label_left, color=color.new(color.green, 0), textcolor=color.white)
else
label.set_xy(sup1_label, bar_index, loband1)
label.set_text(sup1_label, "S1: " + format_price(loband1))
// R2 标签(独立控制)
if show_r2_label
if na(res2_label)
res2_label := label.new(bar_index, upband2, "R2: " + format_price(upband2), xloc=xloc.bar_index, style=label.style_label_left, color=color.new(color.red, 50), textcolor=color.white)
else
label.set_xy(res2_label, bar_index, upband2)
label.set_text(res2_label, "R2: " + format_price(upband2))
// S2 标签(独立控制)
if show_s2_label
if na(sup2_label)
sup2_label := label.new(bar_index, loband2, "S2: " + format_price(loband2), xloc=xloc.bar_index, style=label.style_label_left, color=color.new(color.red, 50), textcolor=color.white)
else
label.set_xy(sup2_label, bar_index, loband2)
label.set_text(sup2_label, "S2: " + format_price(loband2))
// MA50 标签(独立控制)
if show_ma50_label
if na(lbl50)
lbl50 := label.new(x=time, y=ma50, text='MA50: ' + format_price(ma50), xloc=xloc.bar_time, yloc=yloc.price, style=label.style_label_left, color=maColor(ma50, ma100), textcolor=color.white)
else
label.set_xy(lbl50, x=time, y=ma50)
label.set_text(lbl50, 'MA50: ' + format_price(ma50))
// MA100 标签(独立控制)
if show_ma100_label
if na(lbl100)
lbl100 := label.new(x=time, y=ma100, text='MA100: ' + format_price(ma100), xloc=xloc.bar_time, yloc=yloc.price, style=label.style_label_left, color=maColor(ma100, ma200), textcolor=color.white)
else
label.set_xy(lbl100, x=time, y=ma100)
label.set_text(lbl100, 'MA100: ' + format_price(ma100))
// MA200 标签(独立控制,包含斜率变化信息)
if show_ma200_label
ma200_label_text = 'MA200: ' + format_price(ma200) + ' [' + ma200_trend_status + '] 距离:' + str.tostring(distance_usd, '#.##') + ' 变化:' + str.tostring(ma200_change_10, '#.##') + ' (' + trend_acceleration + ')'
if na(lbl200)
lbl200 := label.new(x=time, y=ma200, text=ma200_label_text, xloc=xloc.bar_time, yloc=yloc.price, style=label.style_label_left, color=color.blue, textcolor=color.white)
else
label.set_xy(lbl200, x=time, y=ma200)
label.set_text(lbl200, ma200_label_text)
//************************************************************************************************************
// 功能对比说明(注释)
//************************************************************************************************************
// ═════════ 原始功能保留对比 ═════════
//
// MRC 指标功能:
// ✓ SuperSmoother 和其他滤波器类型支持
// ✓ MEAN 线计算和显示
// ✓ R1/S1 通道计算和显示
// ✓ 价格标签显示
// ✓ 多时间框架支持(简化版)
// ✓ 所有原始参数设置
//
// MA200 指标功能:
// ✓ MA50/MA100/MA200 计算
// ✓ EMA/SMA 选择
// ✓ MA 线条颜色逻辑
// ✓ 价格标签显示
// ✓ 距离计算
// ✓ 斜率计算
//
// RSI 指标功能:
// ✓ 机器学习动态阈值
// ✓ RSI 平滑处理
// ✓ 多种移动平均类型
// ✓ 分段计数逻辑
// ✓ 穿越次数统计
// ✓ 状态变化检测
// ✓ 分段线颜色编码
//
// 新增综合功能:
// ✓ 三指标统一显示
// ✓ 实时数值表格
// ✓ 趋势综合判断
// ✓ 震荡/趋势识别
// ✓ 窗口一K线+MRC+MA
// ✓ 窗口二RSI独立显示
// ✓ 表格化数值显示