This indicator allows you to draw horizontal lines at round numbers.
Please enter your desired base value in the "Step width" field (e.g., 1 for USD/JPY).
Please enter your desired base value in the "Step width" field (e.g., 1 for USD/JPY).
Source: TradingView
[NOTICE & LICENSE]
・For educational and informational purposes only; does not constitute investment advice. We assume no liability for any economic loss arising from the use of this tool.
・Tested on Pine Script v6. Provided "As-Is" with no guarantee of updates in response to future TradingView specification changes. We do not provide individual installation support or accept modification requests.
・Governed by the MIT License.
// SPDX-FileCopyrightText: 2026 NK-report https://www.nk-report.com/
// SPDX-License-Identifier: MIT
//
// Disclaimer: This script is for educational purposes only and does not constitute investment advice.
//@version=6
// ※ダイナミックグリッドの描画上限を確保するため、linesとlabelsの上限を拡張しています
indicator("NK-Horizon Round", shorttitle="NK-Horizon", overlay=true, max_lines_count=500, max_labels_count=500)
// ==============================================================================
// 【01】 免責・ライセンス
// ==============================================================================
//
// Indicator is published for free: https://www.nk-report.com/p/tradingview-code.html
//
// Disclaimer: This script is for educational and informational purposes only and does not constitute investment advice.
//
// 1. This code has been tested with Pine Script v6 as of 2026.
// We do not provide individual support or modifications for any issues caused by future specification changes.
// 2. This script was independently created using an LLM, based on general calculation logic.
// It is distributed under the MIT License.
// ------------------------------------------------------------------------------
// MIT License
//
// Copyright 2026 NK-report https://www.nk-report.com/
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// ==============================================================================
// 【02】 UI設定と言語
// ==============================================================================
const string GRP_GENERAL = "▼ General Settings"
const string GRP_MAIN = "▼ Main Level (Round Numbers)"
const string GRP_SUB = "▼ Sub Level (Half Round Numbers)"
const string OPT_STY_S = "Solid"
const string OPT_STY_D = "Dashed"
const string OPT_STY_DT = "Dotted"
const string OPT_POS_L = "Left"
const string OPT_POS_C = "Center"
const string OPT_POS_R = "Right"
// 基本設定
i_step = input.float(1.0, title="Step Size (Round Number Unit)", step=0.1, group=GRP_GENERAL, tooltip="Specify the base value for the asset (e.g., 1 or 0.5 for USDJPY, 500 or 100 for Nikkei).")
i_num_lines = input.int(10, title="Number of Lines Above/Below (One side)", minval=1, maxval=50, group=GRP_GENERAL, tooltip="Draws X lines above and below the current price. If default (10), a total of 21 lines will follow the current price.")
i_show_lbl = input.bool(true, title="Show Price Labels", group=GRP_GENERAL, inline="lbl")
i_lbl_pos = input.string(OPT_POS_R, title="Position", options=[OPT_POS_L, OPT_POS_C, OPT_POS_R], group=GRP_GENERAL, inline="lbl")
i_lbl_offset = input.int(22, title="Slide Adjustment (Bars)", minval=0, group=GRP_GENERAL, tooltip="Adjusts the distance from the latest candle when 'Left' or 'Right' is selected.\n* This value is ignored if 'Center' is selected.")
// メインレベル設定
i_show_main = input.bool(true, title="Show", group=GRP_MAIN, inline="main1")
i_col_main = input.color(color.black, title="Color", group=GRP_MAIN, inline="main1")
i_wid_main = input.int(1, title="Width", minval=1, maxval=5, group=GRP_MAIN, inline="main1")
i_sty_main = input.string(OPT_STY_S, title="Style", options=[OPT_STY_S, OPT_STY_D, OPT_STY_DT], group=GRP_MAIN, inline="main1")
// サブレベル設定
i_show_sub = input.bool(false, title="Show", group=GRP_SUB, inline="sub1")
i_col_sub = input.color(color.black, title="Color", group=GRP_SUB, inline="sub1")
i_wid_sub = input.int(1, title="Width", minval=1, maxval=5, group=GRP_SUB, inline="sub1")
i_sty_sub = input.string(OPT_STY_DT, title="Style", options=[OPT_STY_S, OPT_STY_D, OPT_STY_DT], group=GRP_SUB, inline="sub1")
// ==============================================================================
// 【03】 全コード共通仕様(時間・インフラ処理)
// ==============================================================================
// ※該当コードなし
// (本ツールは時間枠に依存せず、常に現在の価格のみを参照して水平線を引くため、時間の変換処理は不要です)
// ==============================================================================
// 【04】 各カテゴリ共通仕様 (描画インフラと判定ロジック)
// ==============================================================================
f_get_style(sty_str) =>
sty_str == OPT_STY_S ? line.style_solid : sty_str == OPT_STY_D ? line.style_dashed : line.style_dotted
// ==============================================================================
// 【05】 このコード固有の計算仕様 (Specific Indicator Logic)
// ==============================================================================
// エレベーター方式の描画オブジェクトを格納する配列群 (Object Pooling)
var array<line> a_main_l = array.new<line>()
var array<label> a_main_lbl = array.new<label>()
var array<line> a_sub_l = array.new<line>()
var array<label> a_sub_lbl = array.new<label>()
// 初回ロード時:必要な本数分のオブジェクトを1セットだけ生成し、配列に格納・待機させる
if barstate.isfirst
int total_lines = (i_num_lines * 2) + 1
for i = 0 to total_lines - 1
// メインライン用
a_main_l.push(line.new(na, na, na, na, extend=extend.both, color=i_col_main, width=i_wid_main, style=f_get_style(i_sty_main)))
a_main_lbl.push(label.new(na, na, text="", color=color.new(color.white, 100), textcolor=i_col_main, style=label.style_none, size=size.small))
// サブライン用
a_sub_l.push(line.new(na, na, na, na, extend=extend.both, color=i_col_sub, width=i_wid_sub, style=f_get_style(i_sty_sub)))
a_sub_lbl.push(label.new(na, na, text="", color=color.new(color.white, 100), textcolor=i_col_sub, style=label.style_none, size=size.small))
// ==============================================================================
// 【06】 描画と出力 (Rendering & Outputs)
// ==============================================================================
// リアルタイム更新:過去の足では計算せず、最新の足でのみ配列内の座標をスライド更新する
if barstate.islast
// 剰余算による「最も近いラウンドナンバー」の数学的特定
float center_p = math.round(close / i_step) * i_step
int total_lines = (i_num_lines * 2) + 1
// 最新足(最前線)をアンカーにしたラベルX座標の決定
int lbl_x = bar_index
if i_lbl_pos == OPT_POS_L
lbl_x := bar_index - i_lbl_offset
else if i_lbl_pos == OPT_POS_R
lbl_x := bar_index + i_lbl_offset
for i = 0 to total_lines - 1
int offset = i - i_num_lines
float p_main = center_p + (offset * i_step)
// --- メインレベルの更新 ---
line l_m = a_main_l.get(i)
label lbl_m = a_main_lbl.get(i)
if i_show_main
line.set_xy1(l_m, bar_index, p_main)
line.set_xy2(l_m, bar_index + 1, p_main)
line.set_color(l_m, i_col_main)
line.set_width(l_m, i_wid_main)
line.set_style(l_m, f_get_style(i_sty_main))
if i_show_lbl
label.set_xy(lbl_m, lbl_x, p_main)
label.set_text(lbl_m, str.tostring(p_main, format.mintick))
label.set_textcolor(lbl_m, i_col_main)
else
label.set_xy(lbl_m, na, na)
else
line.set_xy1(l_m, na, na)
line.set_xy2(l_m, na, na)
label.set_xy(lbl_m, na, na)
// --- サブレベル (半値) の更新 ---
line l_s = a_sub_l.get(i)
label lbl_s = a_sub_lbl.get(i)
if i_show_sub
float p_sub = p_main + (i_step * 0.5)
line.set_xy1(l_s, bar_index, p_sub)
line.set_xy2(l_s, bar_index + 1, p_sub)
line.set_color(l_s, i_col_sub)
line.set_width(l_s, i_wid_sub)
line.set_style(l_s, f_get_style(i_sty_sub))
if i_show_lbl
label.set_xy(lbl_s, lbl_x, p_sub)
label.set_text(lbl_s, str.tostring(p_sub, format.mintick))
label.set_textcolor(lbl_s, i_col_sub)
else
label.set_xy(lbl_s, na, na)
else
line.set_xy1(l_s, na, na)
line.set_xy2(l_s, na, na)
label.set_xy(lbl_s, na, na)
// ※本ツールは「背景グリッド」としての役割に徹するため、ノイズ防止の観点からデータウィンドウへの出力は行いません。
* After setting your preferred colors, please click "Save as default" in the settings tab.
* The indicator may not display correctly unless you follow the steps: Create New -> Indicator -> Paste.
