Files
tradingview-pine/3in11.pine
2025-08-02 07:29:33 +00:00

1978 lines
131 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 综合指标4', shorttitle='MRC+MA200+RSI4', 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')
// ═════════ 价格标签配置 ════════
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')
//************************************************************************************************************
// 辅助函数定义
//************************************************************************************************************
// ═════════ 距离阈值切换参考原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_trigger = ta.crossover(close_1m_current, upband1_1m_current) // 价格上穿R1
short_trigger = ta.crossunder(close_1m_current, loband1_1m_current) // 价格下穿S1
// 记录启动时间
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
// 条件21分钟时间框架确认5分钟时间窗口快速技术指标验证
// - 时间窗口启动信号后5分钟内必须满足所有子条件
// - RSI超买确认1分钟RSI > 超买阈值,确认短期多头动能
// - 价格突破确认1分钟价格突破R1阻力线确认突破有效性
// - MA200距离确认1分钟价格距离MA200足够远避免长期均线阻力
// - MA50趋势确认1分钟MA50在MEAN线上方确认短期趋势一致性
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
// 条件35分钟时间框架确认15分钟时间窗口多重技术指标综合验证
// - 时间窗口启动信号后15分钟内必须满足所有子条件
// - RSI超买确认5分钟RSI > 超买阈值,确认多头动能充足
// - 价格位置确认5分钟价格在MEAN线上方或附近确认趋势方向
// - MA200距离确认5分钟价格距离MA200足够远避免长期均线阻力
// - MA50趋势确认1分钟MA50在MEAN线上方确认短期趋势向上
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
// 条件415分钟时间框架确认10分钟时间窗口长期趋势距离验证
// - 时间窗口启动信号后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
// 条件21分钟时间框架确认5分钟时间窗口快速技术指标验证
// - 时间窗口启动信号后5分钟内必须满足所有子条件
// - RSI超卖确认1分钟RSI < 超卖阈值,确认短期空头动能
// - 价格突破确认1分钟价格跌破S1支撑线确认突破有效性
// - MA200距离确认1分钟价格距离MA200足够远避免长期均线支撑
// - MA50趋势确认1分钟MA50在MEAN线下方确认短期趋势一致性
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
// 条件35分钟时间框架确认15分钟时间窗口多重技术指标综合验证
// - 时间窗口启动信号后15分钟内必须满足所有子条件
// - RSI超卖确认5分钟RSI < 超卖阈值,确认空头动能充足
// - 价格位置确认5分钟价格在MEAN线下方或附近确认趋势方向
// - MA200距离确认5分钟价格距离MA200足够远避免长期均线支撑
// - MA50趋势确认1分钟MA50在MEAN线下方确认短期趋势向下
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
// 条件415分钟时间框架确认10分钟时间窗口长期趋势距离验证
// - 时间窗口启动信号后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支撑线"}')
// ═════════ 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)
// ═════════ 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 = 10, // 扩展为10列原6列 + 高级警报启动 + 条件2 + 条件3 + 条件4
rows = 4, // 4行标题 + 数值 + 状态 + 信号
bgcolor = color.new(color.white, 85),
border_width = 1)
// 清空表格
table.clear(info_table, 0, 0, 9, 3)
// 获取配置的文字大小
text_size = get_text_size()
// ═════════ 扩展表格标题行原6列 + 高级警报4列 ═════════
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)
// ═════════ 多列紧凑数据 ═════════
// 计算各指标的背景颜色类似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)
// 第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)
// 第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)
// 第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)
// 高级警报条件说明
table.cell(info_table, 6, 3, long_trigger ? "价格上穿R1" : short_trigger ? "价格下穿S1" : 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, 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)
// ═════════ 关键数值表格(右中位置,避免与主表格重叠) ═════════
// 创建关键数值表格
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独立显示
// ✓ 表格化数值显示