[NOTICE & LICENSE]
・学習および情報提供のみを目的としており、投資助言ではありません。ツールを使用したことによる経済的損失について、一切の責任を負いません。
・Pine Script v6 で動作確認しています。将来のTradingView側の仕様変更に対するアップデート保証や、個別の導入サポート・改修依頼は一切受け付けません(現状有姿での提供)。
・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】 免責・ライセンス
// ==============================================================================
// インジケーターを無料で公開しています: https://www.nk-report.com/p/jp-0_0810719344.html
//
// 免責事項: 本スクリプトは学習および情報提供のみを目的としており、投資助言ではありません。
//
// 1. 本コードは2026年時点の Pine Script v6 で動作確認を行っています。
// 将来の仕様変更に伴う不具合等について、個別のサポートや改修は行いません。
// 2. 本スクリプトは一般的な計算ロジックに基づき、LLMを用いて独自に作成したものです。
// MITライセンスに則っています。
// ------------------------------------------------------------------------------
// 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 = "▼ 基本設定"
const string GRP_MAIN = "▼ メインレベル (ラウンドナンバー)"
const string GRP_SUB = "▼ サブレベル (半値のラウンドナンバー)"
const string OPT_STY_S = "実線"
const string OPT_STY_D = "破線"
const string OPT_STY_DT = "点線"
const string OPT_POS_L = "左"
const string OPT_POS_C = "中央"
const string OPT_POS_R = "右"
// 基本設定
i_step = input.float(1.0, title="ステップ幅 (ラウンドナンバーの単位)", step=0.1, group=GRP_GENERAL, tooltip="ドル円なら1や0.5、日経平均なら500や100など、対象銘柄の基準となる数値を指定してください。")
i_num_lines = input.int(10, title="上下の描画本数 (片側)", minval=1, maxval=50, group=GRP_GENERAL, tooltip="現在価格から上にX本、下にX本を描画します。デフォルト(10)の場合、合計21本の線が現在価格に追従します。")
i_show_lbl = input.bool(true, title="価格ラベルの表示", group=GRP_GENERAL, inline="lbl")
i_lbl_pos = input.string(OPT_POS_R, title="位置", options=[OPT_POS_L, OPT_POS_C, OPT_POS_R], group=GRP_GENERAL, inline="lbl")
i_lbl_offset = input.int(22, title="スライド調整 (バー数)", minval=0, group=GRP_GENERAL, tooltip="「左」または「右」を選択した場合に、最新のローソク足からどれくらい離すかを調整します。\n※「中央」を選択している場合、この数値は無視されます。")
// メインレベル設定
i_show_main = input.bool(true, title="表示", group=GRP_MAIN, inline="main1")
i_col_main = input.color(color.black, title="カラー", group=GRP_MAIN, inline="main1")
i_wid_main = input.int(1, title="太さ", minval=1, maxval=5, group=GRP_MAIN, inline="main1")
i_sty_main = input.string(OPT_STY_S, title="スタイル", options=[OPT_STY_S, OPT_STY_D, OPT_STY_DT], group=GRP_MAIN, inline="main1")
// サブレベル設定
i_show_sub = input.bool(false, title="表示", group=GRP_SUB, inline="sub1")
i_col_sub = input.color(color.black, title="カラー", group=GRP_SUB, inline="sub1")
i_wid_sub = input.int(1, title="太さ", minval=1, maxval=5, group=GRP_SUB, inline="sub1")
i_sty_sub = input.string(OPT_STY_DT, title="スタイル", 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)
// ※本ツールは「背景グリッド」としての役割に徹するため、ノイズ防止の観点からデータウィンドウへの出力は行いません。
※好みの配色に設定後、パラメータータブの「デフォルトを保存」を押してください。
※新規作成→インジケーター→ペーストする の順序で行わないと正しく表示されないことがあります。
