This indicator can display the opening and closing times of the Japan, London, and New York stock markets as vertical lines.
Since there are individual checkboxes for the start and end times, flexible configurations are also possible.
It will primarily be used on timeframes lower than 1 hour.
Since there are individual checkboxes for the start and end times, flexible configurations are also possible.
It will primarily be used on timeframes lower than 1 hour.
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
// ※各市場のオープン・クローズの垂直線を履歴として長期間残すため、描画上限を拡張しています
indicator("NK-Session", shorttitle="NK-Session", overlay=true, max_lines_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_JP = "▼ Japanese Market (TOKYO)"
const string GRP_LON = "▼ London Market (LONDON)"
const string GRP_NY = "▼ New York Market (NEW YORK)"
const string OPT_STY_S = "Solid"
const string OPT_STY_D = "Dashed"
const string OPT_STY_DT = "Dotted"
// 日本市場 (TOKYO) 09:00 - 15:30 JST
i_show_jp_s = input.bool(true, title="Start Line (09:00 JST)", group=GRP_JP, inline="jp_s")
i_col_jp_s = input.color(#4CAF50, title="", group=GRP_JP, inline="jp_s") // 緑色 (透過なし)
i_wid_jp_s = input.int(1, title="Width", minval=1, maxval=5, group=GRP_JP, inline="jp_s")
i_sty_jp_s = input.string(OPT_STY_S, title="", options=[OPT_STY_S, OPT_STY_D, OPT_STY_DT], group=GRP_JP, inline="jp_s")
i_show_jp_e = input.bool(true, title="End Line (15:30 JST)", group=GRP_JP, inline="jp_e")
i_col_jp_e = input.color(#4CAF50, title="", group=GRP_JP, inline="jp_e") // 緑色 (透過なし)
i_wid_jp_e = input.int(1, title="Width", minval=1, maxval=5, group=GRP_JP, inline="jp_e")
i_sty_jp_e = input.string(OPT_STY_S, title="", options=[OPT_STY_S, OPT_STY_D, OPT_STY_DT], group=GRP_JP, inline="jp_e")
// ロンドン市場 (LONDON) 08:00 - 16:30 GMT/BST
i_show_lon_s = input.bool(true, title="Start Line (08:00 GMT/BST)", group=GRP_LON, inline="lon_s")
i_col_lon_s = input.color(#2196F3, title="", group=GRP_LON, inline="lon_s") // 青色 (透過なし)
i_wid_lon_s = input.int(1, title="Width", minval=1, maxval=5, group=GRP_LON, inline="lon_s")
i_sty_lon_s = input.string(OPT_STY_S, title="", options=[OPT_STY_S, OPT_STY_D, OPT_STY_DT], group=GRP_LON, inline="lon_s")
i_show_lon_e = input.bool(true, title="End Line (16:30 GMT/BST)", group=GRP_LON, inline="lon_e")
i_col_lon_e = input.color(#2196F3, title="", group=GRP_LON, inline="lon_e") // 青色 (透過なし)
i_wid_lon_e = input.int(1, title="Width", minval=1, maxval=5, group=GRP_LON, inline="lon_e")
i_sty_lon_e = input.string(OPT_STY_S, title="", options=[OPT_STY_S, OPT_STY_D, OPT_STY_DT], group=GRP_LON, inline="lon_e")
// ニューヨーク市場 (NEW YORK) 09:30 - 16:00 EST/EDT
i_show_ny_s = input.bool(true, title="Start Line (09:30 EST/EDT)", group=GRP_NY, inline="ny_s")
i_col_ny_s = input.color(#673AB7, title="", group=GRP_NY, inline="ny_s") // 紫色 (透過なし)
i_wid_ny_s = input.int(1, title="Width", minval=1, maxval=5, group=GRP_NY, inline="ny_s")
i_sty_ny_s = input.string(OPT_STY_S, title="", options=[OPT_STY_S, OPT_STY_D, OPT_STY_DT], group=GRP_NY, inline="ny_s")
i_show_ny_e = input.bool(true, title="End Line (16:00 EST/EDT)", group=GRP_NY, inline="ny_e")
i_col_ny_e = input.color(#673AB7, title="", group=GRP_NY, inline="ny_e") // 紫色 (透過なし)
i_wid_ny_e = input.int(1, title="Width", minval=1, maxval=5, group=GRP_NY, inline="ny_e")
i_sty_ny_e = input.string(OPT_STY_S, title="", options=[OPT_STY_S, OPT_STY_D, OPT_STY_DT], group=GRP_NY, inline="ny_e")
// ==============================================================================
// 【03】 全コード共通仕様(時間・インフラ処理)
// ==============================================================================
// イントラデイ(日中足)でのみ起動させる安全装置
bool is_intra = timeframe.isintraday
// タイムゾーンと時間をハードコード化し、システムに時差・サマータイムを完全自動追従させる
const string TZ_JP = "Asia/Tokyo"
const string TZ_LON = "Europe/London"
const string TZ_NY = "America/New_York"
// TradingViewの仕様に基づき、指定時間内の足が「in_sess」として判定されます
bool in_jp = not na(time(timeframe.period, "0900-1530", TZ_JP))
bool in_lon = not na(time(timeframe.period, "0800-1630", TZ_LON))
bool in_ny = not na(time(timeframe.period, "0930-1600", TZ_NY))
// ==============================================================================
// 【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
// 垂直線を前後の足に「ずらして」引くための専用関数
f_draw_session_lines(in_sess, tz_str, show_s, col_s, wid_s, sty_s, show_e, col_e, wid_e, sty_e) =>
if is_intra
// 関数(na/nz)を一切使わず、bar_index(足の番号)を利用して過去の状態を安全に取得
int prev_time = bar_index > 0 ? time[1] : time
bool prev_in_sess = bar_index > 0 ? in_sess[1] : false
// 各国のタイムゾーン基準で「日が変わったか」を判定
bool is_new_exchange_day = dayofmonth(time, tz_str) != dayofmonth(prev_time, tz_str)
// セッションの開始エッジと終了エッジの検知
bool is_start = in_sess and (not prev_in_sess or is_new_exchange_day)
bool is_end = not in_sess and prev_in_sess
bool missed_end = is_new_exchange_day and prev_in_sess
// チャートのオートスケール崩壊を防ぐため、Y座標を「現在の価格」にロックする
float y1 = close
float y2 = close + syminfo.mintick
// 【ユーザー様考案:究極のサンドイッチ・ロジック】
// ① 始まりの垂直線 (対象セッションの最初の足に被らないよう、「左側に1つずらす」)
if show_s and is_start
int start_idx = math.max(0, bar_index - 1)
line.new(start_idx, y1, start_idx, y2, xloc=xloc.bar_index, extend=extend.both, color=col_s, width=wid_s, style=f_get_style(sty_s))
// ② 終わりの垂直線 (対象セッションの最後の足に被らないよう、「右側に1つずらす」)
// is_end や missed_end が発火した足は、すでに「セッションが終了した最初の足(=右に1つずれた足)」なので、そのまま引く
if show_e and (is_end or missed_end)
line.new(bar_index, y1, bar_index, y2, xloc=xloc.bar_index, extend=extend.both, color=col_e, width=wid_e, style=f_get_style(sty_e))
// ==============================================================================
// 【05】 このコード固有の計算仕様 (Specific Indicator Logic)
// ==============================================================================
// ※計算用の変数は不要です(純粋なタイム・セパレーター)
// ==============================================================================
// 【06】 描画と出力 (Rendering & Outputs)
// ==============================================================================
f_draw_session_lines(in_jp, TZ_JP, i_show_jp_s, i_col_jp_s, i_wid_jp_s, i_sty_jp_s, i_show_jp_e, i_col_jp_e, i_wid_jp_e, i_sty_jp_e)
f_draw_session_lines(in_lon, TZ_LON, i_show_lon_s, i_col_lon_s, i_wid_lon_s, i_sty_lon_s, i_show_lon_e, i_col_lon_e, i_wid_lon_e, i_sty_lon_e)
f_draw_session_lines(in_ny, TZ_NY, i_show_ny_s, i_col_ny_s, i_wid_ny_s, i_sty_ny_s, i_show_ny_e, i_col_ny_e, i_wid_ny_e, i_sty_ny_e)
// ※本ツールは「背景の空間認識」としての役割に徹するため、ノイズ防止の観点からデータウィンドウへの数値出力は行いません。
* 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.
