どうも、しゅん@Trade Techです。
チャート内の特定の日付/価格範囲を判別しやすくしたい時に、TradingViewでは描画ツールを使って四角形のボックスエリアを描画することができます。(以下のような感じで)

実はこのボックスエリア、実はPineScriptでも描画することができるんです!
手動で描画すると日付や価格を指定しづらいので思った通りの場所に引けないことも多いですが、PineScriptからボックスエリアを描画できれば、計算した日付や価格を基準にBOXエリアを自動で表示させることが可能になります。
今回はこのボックスエリアを描画できるbox関数について、どんな仕組みなのか?各パラメータで何が設定できるのか?などなど、サンプルコードも交えながら解説していきます。
box関数とは?
box関数は、その名の通りチャート上に四角形のボックスエリアを描画する関数です。
四角形の上下左右にあたる日付と価格を指定してあげることで、その中にボックスエリアを描画します。境界線や内部の色も指定可能です。

では具体的にどのようなPineScriptのコードを書いていけばよいのか?具体的に見ていきましょう。
基本的なbox関数の使い方
box関数の動作を理解しやすいように、まずは「特定の日付/価格基準にボックスエリアを描画する」というサンプルからご紹介します。
以下は、最終足の30足前~最終足にかけて、上が2,800円、下が2,400円となる黄色のボックスエリアを描画するサンプルコードです。
//@version=6
indicator("TTO_PineSample_Box", overlay=true)
if barstate.islast
box.new(bar_index - 30, 2800, bar_index, 2400)
チャートに適用すると、このような表示になります。

サンプルコードの解説ですが、今回もline関数の時と同様、チャートに1つだけラインを引きたかったので、barstate.islastで「最終足の時かどうか」を判定しています
if barstate.islast
~
続いて、実際にボックスエリアを描画するのがbox.new関数です。
box.new(bar_index - 30, 2800, bar_index, 2400)
最初の4つのパラメータで四角形の位置を設定します。上端と下端は価格、左端と右端は初期設定だと足番号で指定するので、以下のようになります。
1つ目(left):左端の足番号
2つ目(top):上端の価格
3つ目(right):右端の足番号
4つ目(bottom):下端の価格
境界線と背景色の設定
ボックスでは境界線と背景色の設定が可能です。
border_color、border_width、border_styleのパラメータで境界線のスタイルを、bgcolorでボックス内の背景色を、それぞれ設定できます。
例えば、境界線は「太さ3の黄色い実線」で、背景色は「透過率90%の灰色」で、それぞれ指定したい場合は以下のように書きます。
//@version=6
indicator("TTO_PineSample_Box", overlay=true)
if barstate.islast
box.new(bar_index - 30, 2800, bar_index, 2400, border_color=color.yellow, border_width=3, border_style=line.style_solid, bgcolor=color.new(color.gray, 90))

ボックス内テキストの設定
テキストのスタイル
ボックス内には任意のテキストを表示することもできます。
textパラメータで表示したいテキストを設定し、text_colorで文字の色を、text_sizeで文字の大きさを、それぞれ指定できます。また、text_font_familyでテキストフォントをmonospaceに変更することもできます。
以下は、「(2,400円~2,800円)」という白色テキストを、大きさsmallのmonospaceフォントで表示した様子です。
//@version=6
indicator("TTO_PineSample_Box", overlay=true)
if barstate.islast
box.new(bar_index - 30, 2800, bar_index, 2400, text="(2,400円~2,800円)", text_color=color.white, text_size=size.small, text_font_family=font.family_monospace, border_color=color.yellow, border_width=3, border_style=line.style_solid, bgcolor=color.new(color.gray, 90))

テキストの位置
ボックス内のテキストは表示位置を調整することもできます。text_halignで水平方向の寄せ方を、text_valignで垂直方向の寄せ方を、それぞれ指定できます。
例えば以下のように、text_halignをtext.align_right(右寄せ)に、text_valignをtext.align_bottom(下寄せ)にすると、ボックス内のテキストが右下に表示されるようになります。
//@version=6
indicator("TTO_PineSample_Box", overlay=true)
if barstate.islast
box.new(bar_index - 30, 2800, bar_index, 2400, text="(2,400円~2,800円)", text_color=color.white, text_size=size.small, text_font_family=font.family_monospace, text_halign=text.align_right, text_valign=text.align_bottom, border_color=color.yellow, border_width=3, border_style=line.style_solid, bgcolor=color.new(color.gray, 90))

改行方法の指定
ボックスの横幅に対して表示したいテキストが長い場合、以下のようにテキストがボックス幅を超えて表示されます。
//@version=6
indicator("TTO_PineSample_Box", overlay=true)
if barstate.islast
box.new(bar_index - 20, 2800, bar_index, 2400, text="価格帯(2,400円~2,800円)", text_size=size.large, text_color=color.white, border_color=color.yellow, border_width=3, border_style=line.style_solid, bgcolor=color.new(color.gray, 90))

自動的にボックス内で収まるようにしたい場合は、text_wrapをtext.wrap_autoに設定すると、任意の位置で自動改行してくれます。
//@version=6
indicator("TTO_PineSample_Box", overlay=true)
if barstate.islast
box.new(bar_index - 20, 2800, bar_index, 2400, text="価格帯(2,400円~2,800円)", text_size=size.large, text_color=color.white, text_wrap=text.wrap_auto ,border_color=color.yellow, border_width=3, border_style=line.style_solid, bgcolor=color.new(color.gray, 90))

また、特定の場所で改行したい場合は、テキスト内に改行文字(\n)を入れるのが便利です。(これはbox関数以外でも多くのテキスト表示時に使える裏技?です)
//@version=6
indicator("TTO_PineSample_Box", overlay=true)
if barstate.islast
box.new(bar_index - 20, 2800, bar_index, 2400, text="価格帯\n(2,400円~2,800円)", text_color=color.white, border_color=color.yellow, border_width=3, border_style=line.style_solid, bgcolor=color.new(color.gray, 90))

より高度な描画方法
計算した価格を指定
ここまでのサンプルコードでは上端/下端の価格を固定値にしていましたが、PineScriptで計算した結果を指定することも可能です。
例えば以下は、直近20日間の最高値/最安値を計算し、その価格を上端/下端としたボックスを描画するためのサンプルコードになります。テキスト部分にstr.format関数を使うことで、最高値/最安値の価格をボックス内にも表示させています。
//@version=6
indicator("TTO_PineSample_Box", overlay=true)
highest = ta.highest(20)
lowest = ta.lowest(20)
if barstate.islast
box.new(bar_index - 20, highest, bar_index, lowest, text=str.format("({0}円~{1}円)", lowest, highest), text_size=size.small, border_color=color.yellow, bgcolor=color.new(color.gray, 90))

ボックスを左右に拡張
line関数などと同様、box関数にも左右に拡張する(引き延ばす)ためのextendパラメータが用意されています。
以下は上のサンプルコードにextend=extend.rightを追加し、ボックスを右側に拡張したものです。
//@version=6
indicator("TTO_PineSample_Box", overlay=true)
highest = ta.highest(20)
lowest = ta.lowest(20)
if barstate.islast
box.new(bar_index - 20, highest, bar_index, lowest, text=str.format("({0}円~{1}円)", lowest, highest), text_size=size.small, border_color=color.yellow, bgcolor=color.new(color.gray, 90), extend=extend.right)

任意の日付/時間帯にボックスを描画
パラメータxlocは初期値がxloc.bar_indexですが、これをxloc.bar_timeにすると足番号ではなくUNIX時刻でボックスの左端/右端を指定できます。
UNIX時刻の指定方法は色々ありますが、timeで現在足の時刻、timestamp(Y, M, D)でY年M月D日の時刻となります。
例えば以下は、2024年11月1日から11月29日までの期間にボックスエリアを描画する例です。
//@version=6
indicator("TTO_PineSample_Box", overlay=true)
if barstate.islast
box.new(timestamp(2024, 11, 1), 2800, timestamp(2024, 11, 29), 2400, xloc=xloc.bar_time, border_color=color.yellow, bgcolor=color.new(color.gray, 90))

おわりに
以上、box関数の基本的な仕組みと、表示スタイルやパラメータの一覧をまとめてご紹介しました。
ぜひサンプルコードを参考にして、ボックスエリアの表示にチャレンジしてみてください。