This commit is contained in:
2025-08-02 04:21:30 +00:00
parent cdf930d597
commit e513c9d2d2
23 changed files with 2098 additions and 0 deletions

293
参考/rsi_conbinined.pine Normal file
View File

@@ -0,0 +1,293 @@
//@version=6
indicator('RSI 窗口二显示', shorttitle='RSI-W2', overlay=false, max_labels_count=500)
//************************************************************************************************************
// RSI 参数设置
//************************************************************************************************************
// RSI 参数组
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')
// 显示设置
show_segments = input.bool(true, 'Show RSI Segments?', group='Display')
show_counting = input.bool(true, 'Show Segment Counting?', group='Display')
show_rsi_table = input.bool(true, 'Show RSI Info Table?', group='Display')
show_price_labels = input.bool(true, 'Show Price Labels?', group='Display')
//************************************************************************************************************
// 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 计算
//************************************************************************************************************
// 计算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 状态和计数逻辑
var int rsi_state = 0
var int prev_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)
// 确定分段线颜色
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) // 超卖区内的重复进入
// 绘制分段线
if show_segments
line.new(bar_index, 0, bar_index, 100,
color = segment_color,
width = 2,
style = line.style_solid,
extend = extend.none)
// 更新计数逻辑
if current_state == 1
if extreme_type != 1
extreme_type := 1
segment_count := 1
else
segment_count := segment_count + 1
// 显示超买计数标签(保留历史标签)
if show_counting
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
if extreme_type != -1
extreme_type := -1
segment_count := -1
else
segment_count := segment_count - 1
// 显示超卖计数标签(保留历史标签)
if show_counting
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
rsi_state := current_state
//************************************************************************************************************
// RSI 绘图
//************************************************************************************************************
// RSI 主线
rsi_color = rsi > long_S ? color.red : rsi < short_S ? color.blue : color.gray
plot(rsi, 'RSI', color=rsi_color, linewidth=2)
// 动态阈值线
plot(long_S, 'Long ML Threshold', color=color.red, linewidth=1)
plot(short_S, 'Short ML Threshold', color=color.blue, linewidth=1)
// 50中线
hline(50, 'RSI 50', color=color.gray, linestyle=hline.style_dashed)
//************************************************************************************************************
// RSI 变化方向计算
//************************************************************************************************************
// 计算RSI变化
rsi_change = not na(rsi[1]) ? rsi - rsi[1] : 0
rsi_direction = rsi_change > 0.1 ? "↗" : rsi_change < -0.1 ? "↘" : "→"
rsi_direction_text = rsi_change > 0.1 ? "上升" : rsi_change < -0.1 ? "下降" : "平稳"
rsi_change_value = str.tostring(math.abs(rsi_change), '#.##')
//************************************************************************************************************
// RSI 价格标签显示参考MRC原始实现
//************************************************************************************************************
// 价格格式化函数
format_rsi_value(value) =>
str.tostring(value, '#.##')
// 声明RSI标签变量
var label rsi_label = na
var label long_threshold_label = na
var label short_threshold_label = na
var label midline_label = na
if show_price_labels and barstate.islast
// RSI 主线标签(包含变化方向)
rsi_label_text = "RSI: " + format_rsi_value(rsi) + " " + rsi_direction + " (" + rsi_direction_text + " " + rsi_change_value + ")"
if na(rsi_label)
rsi_label := label.new(bar_index, rsi, rsi_label_text, xloc=xloc.bar_index, style=label.style_label_left, color=rsi_color, textcolor=color.white)
else
label.set_xy(rsi_label, bar_index, rsi)
label.set_text(rsi_label, rsi_label_text)
label.set_color(rsi_label, rsi_color)
// 超买阈值标签
if na(long_threshold_label)
long_threshold_label := label.new(bar_index, long_S, "超买: " + format_rsi_value(long_S), xloc=xloc.bar_index, style=label.style_label_left, color=color.red, textcolor=color.white)
else
label.set_xy(long_threshold_label, bar_index, long_S)
label.set_text(long_threshold_label, "超买: " + format_rsi_value(long_S))
// 超卖阈值标签
if na(short_threshold_label)
short_threshold_label := label.new(bar_index, short_S, "超卖: " + format_rsi_value(short_S), xloc=xloc.bar_index, style=label.style_label_left, color=color.blue, textcolor=color.white)
else
label.set_xy(short_threshold_label, bar_index, short_S)
label.set_text(short_threshold_label, "超卖: " + format_rsi_value(short_S))
// 50中线标签
if na(midline_label)
midline_label := label.new(bar_index, 50, "中线: 50.00", xloc=xloc.bar_index, style=label.style_label_left, color=color.gray, textcolor=color.white)
else
label.set_xy(midline_label, bar_index, 50)
label.set_text(midline_label, "中线: 50.00")
//************************************************************************************************************
// RSI 信息表格
//************************************************************************************************************
if show_rsi_table and barstate.islast
// RSI 状态
rsi_position = rsi > long_S ? "超买区" : rsi < short_S ? "超卖区" : "中性区"
rsi_cross_count = math.abs(segment_count)
cross_type = segment_count > 0 ? "超买穿越" : segment_count < 0 ? "超卖穿越" : "无穿越"
// 创建RSI表格扩展为10行
var table rsi_table = table.new(
position = position.bottom_right,
columns = 2,
rows = 10,
bgcolor = color.new(color.yellow, 80),
border_width = 1)
// 清空表格
table.clear(rsi_table, 0, 0, 1, 9)
// 添加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 穿越类型
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)
// RSI 变化方向
table.cell(rsi_table, 0, 8, "变化方向", text_color=color.black, text_size=size.tiny)
table.cell(rsi_table, 1, 8, rsi_direction_text + " " + rsi_direction, text_color=color.black, text_size=size.tiny)
// RSI 变化幅度
table.cell(rsi_table, 0, 9, "变化幅度", text_color=color.black, text_size=size.tiny)
table.cell(rsi_table, 1, 9, rsi_change_value, text_color=color.black, text_size=size.tiny)