TradingView点击式计算器及重复功能开发技术问询
TradingView K线点击计算器开发方案
需求概述
开发一款TradingView图表计算器,实现以下功能:
- 点击图表上K线的最高价/最低价,获取对应价格
- 收集3个价格后执行计算,将结果绘制在图表上
- 支持重置功能,重置后可重新收集新的3个价格,同时保留历史绘制的结果
原技术问题解决
1. 单次点击同时获取价格与时间
使用Pine Script v5的input.timeprice()函数,该函数允许用户点击图表,同时返回点击位置的时间(X轴)和价格(Y轴)。结合label.new()可在点击位置生成标记标签。
2. 重置功能实现(保留历史记录)
通过var关键字定义数组存储历史计算结果与标签对象,添加一个布尔型输入作为重置按钮。重置时仅清空当前待输入的A/B/C变量,不清除历史数组中的数据,从而保留已绘制的结果。
完整实现代码
//@version=5 indicator("ABC_Calculator", overlay=true) // 全局状态变量:当前收集阶段(A/B/C)、历史数据存储 var int current_step = 0 var float[] history_prices = array.new_float() var label[] history_labels = array.new_label() var table results_table = na // 重置按钮 reset_btn = input.bool(false, title="重置当前输入", group="控制", confirm=true) if reset_btn current_step := 0 // 仅重置当前输入,保留历史数据 Price_A := na Price_B := na Price_C := na // 重置按钮自动弹回 input.set_options(reset_btn, confirm=true) // 收集3个价格点(时间+价格) Price_A = input.timeprice(defval=na, title="选择价格A", group="价格收集", confirm=true) if current_step == 0 else Price_A if na(Price_A) == false and current_step == 0 current_step := 1 // 在点击位置生成标签 label_A = label.new(Price_A.time, Price_A.price, "A", color=color.new(color.blue, 0), textcolor=color.white, style=label.style_label_up) array.push(history_labels, label_A) array.push(history_prices, Price_A.price) Price_B = input.timeprice(defval=na, title="选择价格B", group="价格收集", confirm=true) if current_step == 1 else Price_B if na(Price_B) == false and current_step == 1 current_step := 2 label_B = label.new(Price_B.time, Price_B.price, "B", color=color.new(color.red, 0), textcolor=color.white, style=label.style_label_up) array.push(history_labels, label_B) array.push(history_prices, Price_B.price) Price_C = input.timeprice(defval=na, title="选择价格C", group="价格收集", confirm=true) if current_step == 2 else Price_C if na(Price_C) == false and current_step == 2 current_step := 3 label_C = label.new(Price_C.time, Price_C.price, "C", color=color.new(color.green, 0), textcolor=color.white, style=label.style_label_up) array.push(history_labels, label_C) array.push(history_prices, Price_C.price) // 计算逻辑 Price_N = na(Price_C) ? na : Price_C.price + (Price_B.price - Price_A.price) Price_V = na(Price_C) ? na : Price_B.price + (Price_B.price - Price_C.price) Price_E = na(Price_C) ? na : Price_B.price + (Price_B.price - Price_A.price) Price_NT= na(Price_C) ? na : Price_C.price + (Price_C.price - Price_A.price) // 绘制计算结果(当3个价格都收集完成时) if current_step == 3 // 绘制水平线 hline(Price_N, "N値", color=color.orange) hline(Price_V, "V値", color=color.purple) hline(Price_E, "E値", color=color.teal) hline(Price_NT, "NT値", color=color.yellow) // 在最新K线位置标注结果 label.new(bar_index, Price_N, str.tostring(Price_N, format.mintick), color=color.orange, textcolor=color.white) label.new(bar_index, Price_V, str.tostring(Price_V, format.mintick), color=color.purple, textcolor=color.white) label.new(bar_index, Price_E, str.tostring(Price_E, format.mintick), color=color.teal, textcolor=color.white) label.new(bar_index, Price_NT, str.tostring(Price_NT, format.mintick), color=color.yellow, textcolor=color.white) // 保存结果到历史数组(可选,用于扩展功能) array.push(history_prices, Price_N) array.push(history_prices, Price_V) array.push(history_prices, Price_E) array.push(history_prices, Price_NT) // 结果表格配置(复用原逻辑) tblPos = input.string(title="表格位置", defval="右下角", options=["左上角", "右上角", "左下角", "右下角", "左中部", "右中部", "底部中部"], group = "表格设置") tblposition = tblPos == "左上角" ? position.top_left : tblPos == "右上角" ? position.top_right : tblPos == "左下角" ? position.bottom_left : tblPos == "右下角" ? position.bottom_right : tblPos == "左中部" ? position.middle_left : tblPos == "右中部" ? position.middle_right : position.bottom_center text_halign = input.string(defval = "居中", title="水平对齐", options=["左对齐", "居中", "右对齐"], group = "表格设置") text_halign_pos = text_halign == "左对齐" ? text.align_left : text_halign == "居中" ? text.align_center : text.align_right text_valign = input.string(defval = "居中", title="垂直对齐", options=["顶部", "居中", "底部"], group = "表格设置") text_valign_pos = text_valign == "顶部" ? text.align_top : text_valign == "居中" ? text.align_center : text.align_bottom text_size = input.string(defval = "自动", title="文字大小", options=["自动", "极小", "小", "正常", "大", "极大"], group = "表格设置") text_size_op = text_size == "自动" ? size.auto : text_size == "极小" ? size.tiny : text_size == "小" ? size.small : text_size == "正常" ? size.normal : text_size == "大" ? size.large : size.huge border_width = input.int(defval=1, title="边框宽度", group = "表格尺寸") frame_width = input.int(defval=5, title="外框宽度", group = "表格尺寸") table_width = input.int(defval=5, title="单元格宽度", group = "表格尺寸") table_height = input.int(defval=5, title="单元格高度", group = "表格尺寸") tblBorderColor = input.color(title="边框颜色", defval=#636363, group = "表格样式") cellBgColor = input.color(title="背景颜色", defval=#d1d1d1, group = "表格样式") cellTextColor = input.color(title="文字颜色", defval=#000000, group = "表格样式") // 创建表格(仅初始化一次) if na(results_table) results_table = table.new(position = tblposition, columns = 6, rows = 6, bgcolor = #ffffff, border_width = border_width, frame_color = tblBorderColor, frame_width = frame_width) // 更新表格内容 if not na(results_table) // A/B/C价格 table.cell(results_table, column=0, row=0, text= "A", width = table_width, height = table_height, text_size = text_size_op, text_color=cellTextColor, text_halign=text_halign_pos, text_valign=text_valign_pos, bgcolor=cellBgColor) table.cell(results_table, column=1, row=0, text= str.tostring(Price_A.price, format.mintick) if not na(Price_A) else "未选择", width = table_width, height = table_height, text_size = text_size_op, text_color=cellTextColor, text_halign=text_halign_pos, text_valign=text_valign_pos, bgcolor=cellBgColor) table.cell(results_table, column=0, row=1, text= "B", width = table_width, height = table_height, text_size = text_size_op, text_color=cellTextColor, text_halign=text_halign_pos, text_valign=text_valign_pos, bgcolor=cellBgColor) table.cell(results_table, column=1, row=1, text= str.tostring(Price_B.price, format.mintick) if not na(Price_B) else "未选择", width = table_width, height = table_height, text_size = text_size_op, text_color=cellTextColor, text_halign=text_halign_pos, text_valign=text_valign_pos, bgcolor=cellBgColor) table.cell(results_table, column=0, row=2, text= "C", width = table_width, height = table_height, text_size = text_size_op, text_color=cellTextColor, text_halign=text_halign_pos, text_valign=text_valign_pos, bgcolor=cellBgColor) table.cell(results_table, column=1, row=2, text= str.tostring(Price_C.price, format.mintick) if not na(Price_C) else "未选择", width = table_width, height = table_height, text_size = text_size_op, text_color=cellTextColor, text_halign=text_halign_pos, text_valign=text_valign_pos, bgcolor=cellBgColor) // 计算结果 table.cell(results_table, column=2, row=0, text= "N値", width = table_width, height = table_height, text_size = text_size_op, text_color=cellTextColor, text_halign=text_halign_pos, text_valign=text_valign_pos, bgcolor=cellBgColor) table.cell(results_table, column=3, row=0, text= str.tostring(Price_N, format.mintick) if not na(Price_N) else "-", width = table_width, height = table_height, text_size = text_size_op, text_color=cellTextColor, text_halign=text_halign_pos, text_valign=text_valign_pos, bgcolor=cellBgColor) table.cell(results_table, column=2, row=1, text= "V値", width = table_width, height = table_height, text_size = text_size_op, text_color=cellTextColor, text_halign=text_halign_pos, text_valign=text_valign_pos, bgcolor=cellBgColor) table.cell(results_table, column=3, row=1, text= str.tostring(Price_V, format.mintick) if not na(Price_V) else "-", width = table_width, height = table_height, text_size = text_size_op, text_color=cellTextColor, text_halign=text_halign_pos, text_valign=text_valign_pos, bgcolor=cellBgColor) table.cell(results_table, column=2, row=2, text= "E値", width = table_width, height = table_height, text_size = text_size_op, text_color=cellTextColor, text_halign=text_halign_pos, text_valign=text_valign_pos, bgcolor=cellBgColor) table.cell(results_table, column=3, row=2, text= str.tostring(Price_E, format.mintick) if not na(Price_E) else "-", width = table_width, height = table_height, text_size = text_size_op, text_color=cellTextColor, text_halign=text_halign_pos, text_valign=text_valign_pos, bgcolor=cellBgColor) table.cell(results_table, column=2, row=3, text= "NT値", width = table_width, height = table_height, text_size = text_size_op, text_color=cellTextColor, text_halign=text_halign_pos, text_valign=text_valign_pos, bgcolor=cellBgColor) table.cell(results_table, column=3, row=3, text= str.tostring(Price_NT, format.mintick) if not na(Price_NT) else "-", width = table_width, height = table_height, text_size = text_size_op, text_color=cellTextColor, text_halign=text_halign_pos, text_valign=text_valign_pos, bgcolor=cellBgColor)
关键功能说明
- 点击获取时间与价格:使用
input.timeprice()替代原代码的input.price(),点击时自动获取点击位置的time(时间)和price(价格),并通过label.new()在对应K线位置生成标记。 - 分步收集价格:通过
current_step变量控制收集进度(0=待选A,1=待选B,2=待选C,3=完成收集),完成3次点击后自动执行计算并绘制结果。 - 重置功能:点击"重置当前输入"按钮后,仅将
current_step重置为0,并清空当前的A/B/C价格变量,历史绘制的标签和水平线会保留在图表上。 - 结果可视化:计算完成后,通过
hline()绘制结果水平线,同时在最新K线位置生成结果标签,表格实时更新当前收集的价格和计算结果。
内容的提问来源于stack exchange,提问作者とっぷあめりあ
相关产品推荐
相关产品推荐

