You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)

关键功能说明

  1. 点击获取时间与价格:使用input.timeprice()替代原代码的input.price(),点击时自动获取点击位置的time(时间)和price(价格),并通过label.new()在对应K线位置生成标记。
  2. 分步收集价格:通过current_step变量控制收集进度(0=待选A,1=待选B,2=待选C,3=完成收集),完成3次点击后自动执行计算并绘制结果。
  3. 重置功能:点击"重置当前输入"按钮后,仅将current_step重置为0,并清空当前的A/B/C价格变量,历史绘制的标签和水平线会保留在图表上。
  4. 结果可视化:计算完成后,通过hline()绘制结果水平线,同时在最新K线位置生成结果标签,表格实时更新当前收集的价格和计算结果。

内容的提问来源于stack exchange,提问作者とっぷあめりあ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 19:25:27