---
title: "PineScript（Pine Script）とは？TradingViewでの書き方と自動売買の仕組みをv6のコード例で解説"
url: "https://www.issoh.co.jp/tech/details/5313/"
published: 2025-02-13
updated: 2026-10-18
categories: ["プログラミング言語"]
publisher: "株式会社一創"
---

# PineScript（Pine Script）とは？TradingViewでの書き方と自動売買の仕組みをv6のコード例で解説

PineScript（Pine Script、Pineスクリプト、パインスクリプト）は、チャートツールTradingViewの中だけで動くプログラミング言語です。移動平均線のような独自のインジケーターを描いたり、売買ルールを書いて過去データで損益を検証（バックテスト）したりできます。コードはTradingViewのサーバーで実行されるので、PCに開発環境を入れる必要はありません。現行版は2024年11月に公開されたv6で、それ以降の機能追加はv6にだけ入ります。この記事のコードはすべてv6で書き、TradingViewのコンパイラでエラーが出ないことを確認しています。

## まとめ：Pine Scriptの要点

- **何ができるか**：インジケーター（チャートへの描画）、ストラテジー（売買シミュレーションとバックテスト）、ライブラリ（関数の共有）の3種類を書けます。
- **無料で使えるか**：無料のBasicプランでも書いてチャートに表示できます。ただし1チャートに載せられるインジケーターは2つまでで、インジケーターやストラテジーを条件にしたアラートは作れません。
- **書き方の骨格**：1行目に `//@version=6`、次に `indicator()` か `strategy()` で宣言し、`plot()` などで出力します。
- **つまずきやすい点**：`plot()` や `plotshape()` は `if` の中に書けません。描き分けは値を `na` にして行います。
- **自動売買**：Pine Script単体では証券会社や取引所へ発注できません。約定アラートをwebhookで外部サーバーへ送り、そこから発注APIを呼びます。webhook通知はEssential以上の有料プランが必要です。
- **できないこと**：取り込めるデータは `request.*()` 関数が対応する範囲（他銘柄・他時間足・決算・経済指標など）に限られ、自前のデータを読み込む仕組みだったPine Seedsは新規の受け付けを止めています。
- **古いコードを使うとき**：1行目の `//@version=` で版を確かめます。エディタの「Convert code to v6」で変換できるが、`bool` が `na` を取れなくなった点や `and`・`or` の遅延評価など、手で直す箇所が残ります。

## Pine Scriptの3種類のスクリプトと実行環境

Pine Scriptのスクリプトは、2行目あたりに置く宣言文で種類が決まります。宣言によって使える関数も変わり、たとえば発注をシミュレーションする `strategy.*` の関数は `strategy()` で宣言したスクリプトからしか呼べません。

| 宣言文           | 種類      | 主な出力             |
| ------------- | ------- | ---------------- |
| `indicator()` | インジケーター | 線・図形・背景色・アラート条件  |
| `strategy()`  | ストラテジー  | 仮想売買と損益レポート      |
| `library()`   | ライブラリ   | 他スクリプトから読み込む関数・型 |

スクリプトはチャートの1本1本の足（バー）ごとに、古い足から順に最後まで実行されます。`close` と書けば「いま計算している足の終値」を指し、`close[1]` で1本前の終値を参照できます。ループで配列を回すのではなく、足ごとに同じコードが繰り返し走る前提で書くのが、他の言語との一番大きな違いです。

## Pine Scriptでできないこと：Python・MQL5との使い分け

Pine Scriptはチャートの上で計算して描くための言語で、汎用言語が持つ機能の多くはありません。書き始める前に知っておきたい制約は次のとおりです。

- **発注**：ストラテジーの売買はTradingViewの中のシミュレーションで、証券会社や取引所に注文は届きません（[公式マニュアルのFAQ](https://www.tradingview.com/pine-script-docs/faq/strategies/)）。実際の発注は、後述のwebhook連携で外部のプログラムに任せます。
- **外部データ**：他の銘柄や時間足、配当・分割・決算、FactSetの財務データ、経済指標、出来高フットプリントは `request.*()` 関数で取得できます（[Other timeframes and data](https://www.tradingview.com/pine-script-docs/concepts/other-timeframes-and-data/)）。利用者が用意した日足データをGitHub経由で読ませるPine Seedsは、新しいリポジトリの作成を受け付けていません（既存のデータは引き続き読めます）。
- **実行場所とライブラリ**：公式の実行環境はTradingViewのサーバーだけです。読み込めるのは `library()` で公開されたPineのライブラリで、Pythonのpandasのような外部パッケージは使えません。

売買ルールを書く言語はほかにもあり、どこで発注まで完結させたいかで選び方が変わります。

| 観点     | Pine Script      | MQL5            | Python       |
| ------ | ---------------- | --------------- | ------------ |
| 動く場所   | TradingViewのサーバー | MetaTrader 5の端末 | 自分のPC・サーバー   |
| 発注     | 不可（webhookで外部へ）  | OrderSend()で直接  | ブローカーのAPIを呼ぶ |
| 価格データ  | TradingViewのデータ  | 接続先の業者の価格       | 自分で用意する      |
| チャート描画 | 組み込み             | 組み込み            | ライブラリで自作     |

MQL5は、MetaTrader 5の端末から `OrderSend()` で業者の取引サーバーへ注文を送れます（[MQL5リファレンス](https://www.mql5.com/en/docs/trading/ordersend)）。TradingViewのチャートで描いて確かめ、通知まで受けられれば足りるならPine Script、MetaTrader 5に対応した業者の口座で発注まで端末に任せたいならMQL5を選びます。機械学習や複数の取引所をまたぐ処理が要るならPythonで組み、Pine Scriptはチャート上の確認用に残すのが無理のない分担です。Pythonで使う価格データの入手先は「[金融データプロバイダーとは？Bloomberg・LSEGから日本株APIまで料金と選び方](/tech/details/10368/)」で比べています。

## 無料プランで使える範囲とスクリプトの制限値

Pine Script自体は無料のBasicプランでも使えます。2026年10月18日時点のTradingView[公式料金表](https://www.tradingview.com/pricing/)では、Basicは1チャートあたりインジケーター2つまで、価格アラート3件まで、インジケーター・ストラテジー・描画を条件にしたアラートは0件です。作ったインジケーターをチャートに載せて眺める用途なら無料で足りますが、自作のサインで通知を受けるには有料プランが、webhookで外部へ送るにはEssential以上のプランが要ります。

スクリプト1本あたりの上限は、公式マニュアルの「[Limitations](https://www.tradingview.com/pine-script-docs/writing/limitations/)」と料金表に定められています。実行時間のように、プランで変わる項目もあります。

| 項目                             | 上限                                                 |
| ------------------------------ | -------------------------------------------------- |
| plotカウント（1回の関数呼び出しで複数消費する場合あり） | 64                                                 |
| コンパイル後のトークン数                   | 100,256                                            |
| 変数（スコープごと）                     | 1,000                                              |
| line・box・label（既定の表示数）         | 各500（既定50）                                         |
| request.\*() の一意な呼び出し          | 40（Ultimateは64）                                    |
| 1バー上の1ループの実行時間                 | 500ミリ秒                                             |
| 全バーの実行時間                       | Basic 20秒／Essential・Plus・Premium 40秒／Ultimate 100秒 |

入門段階でぶつかりやすいのは、描画オブジェクトの既定表示数50です。`label.new()` でサインに文字を添えると、古いものから消えていきます。`indicator("…", max_labels_count = 500)` のように宣言文で上限を500まで引き上げられます。

## 最初のスクリプトを動かす手順

1. TradingViewでチャートを開き、画面右側のサイドパネルから「Pineエディタ」を開く（2025年8月の更新で下部パネルから移動）。
2. 新規作成からインジケーターを選び、表示されたひな形を次のコードに置き換える。
3. 保存してスクリプト名を付け、「チャートに追加（Add to chart）」を押す。

```
//@version=6
indicator("My first MA", overlay = true)
int lenInput = input.int(20, "期間", minval = 1)
float ma = ta.sma(close, lenInput)
plot(ma, "SMA", color.orange, 2)
```

1行目の `//@version=6` はコンパイラにバージョンを伝える注釈で、省略するとv1として解釈されます。`input.int()` で作った期間は、チャート上のインジケーター設定画面から数値を変えられます。`ta.sma()` は単純移動平均を返す組み込み関数で、`ta.` 名前空間にRSI・ボリンジャーバンド・ATRなど主要なテクニカル指標がそろっています。

変数は `float ma = …` のように型を書いて宣言でき、型は省略もできます。宣言は `=`、宣言済み変数への再代入は `:=` と使い分けます。足をまたいで値を持ち越したいときは `var` を付けて宣言します。グローバルスコープでは最初の足で、ローカルスコープではそのブロックが初めて実行されたときに、1回だけ初期化されます。

書き方の手本には、TradingViewの組み込みインジケーターが使えます。公式ヘルプ「[Pineスクリプトとは](https://jp.tradingview.com/support/solutions/43000561836/)」のとおり、組み込みインジケーターのコードは公開されていて、一覧から選ぶとエディタに表示されます。関数にカーソルを合わせるとポップアップに説明が出て、そこからリファレンスマニュアルを開けます。マニュアルで解決しない疑問は、Telegramの「PineCoders Pine Script® Q&A」かStack Overflowの「\[pine-script\]」タグで質問できます。

## インジケーターの描き方：plot・plotshape・色の切り替え

短期・長期のEMA（指数平滑移動平均）を描き、交差した足に三角形のサインを出すインジケーターです。インジケーターでよく使う `plot`・`plotshape`・色指定を1本にまとめています。

```
//@version=6
indicator("EMAクロスのサイン", overlay = true)
int fastLen = input.int(9, "短期EMA", minval = 1)
int slowLen = input.int(21, "長期EMA", minval = 1)
float fast = ta.ema(close, fastLen)
float slow = ta.ema(close, slowLen)
bool goldenCross = ta.crossover(fast, slow)
bool deadCross = ta.crossunder(fast, slow)

// 短期EMAが長期EMAより上なら青緑、それ以外は赤
plot(fast, "短期EMA", fast > slow ? color.teal : color.red, 2)
plot(slow, "長期EMA", color.gray)
plotshape(goldenCross, "GC", shape.triangleup, location.belowbar, color.teal, size = size.small)
plotshape(deadCross, "DC", shape.triangledown, location.abovebar, color.red, size = size.small)
bgcolor(fast > slow ? color.new(color.teal, 90) : na)
alertcondition(goldenCross, "ゴールデンクロス", "短期EMAが長期EMAを上抜けました")
```

色は `color.teal` のような定数のほか、`color.new(color.teal, 90)` で透明度（0〜100）を付けられます。v5まで使えた `transp` 引数はv6で削除されたので、透明度は色の値に含めて指定します。この例では `color.new()` を使いますが、`color.rgb(255, 128, 0, 50)` の第4引数や、アルファ値付きの16進カラー表記でも指定できます。

`plotshape()` の第2引数以降は、名前・形（`shape.triangleup` など）・位置（`location.belowbar` は足の下）・色の順です。最後の `alertcondition()` を書いておくと、アラート作成画面の条件にこのサインが出てきます。

### 「Cannot use “plot” in local scope」の原因と直し方

`if` の中に `plot()` を書くと、コンパイル時に `Cannot use "plot" in local scope` というエラーになります。`plotshape()`・`bgcolor()` も同じです。コンパイラはスクリプトが描くplotの本数をコンパイル時に確定させる必要があり、条件によって増減する書き方を受け付けないためです。

```
//@version=6
indicator("条件付きplot", overlay = true)
bool goldenCross = ta.crossover(ta.ema(close, 9), ta.ema(close, 21))

// NG：if の中（ローカルスコープ）で plot() を呼ぶとコンパイルエラー
// if goldenCross
//     plot(close)

// OK：plot() はグローバルスコープに置き、描かない足は na を渡す
plot(goldenCross ? close : na, "GC時の終値", color.teal, 4, plot.style_circles)
```

この例の円描画では、描かない足に `na` を渡すと円が表示されません。ただし、既定の線描画は `na` の区間をまたいで線をつなぐため、線を途切れさせる場合は `plot.style_linebr` などを指定します。色を `na` にする、`plotshape()` の第1引数に真偽値を渡す、という方法でも同じ結果になります。なお `label.new()` は `if` の中でも呼べるので、サインの足に文字を出すだけならそちらでも書けます。

## 上位足のデータと水平線：request.security・line.new

15分足のチャートに日足の値を重ねる、前日の高値に線を引く、といった処理は、別の時間足のデータを取る `request.security()` と、線を描く `line.new()` を組み合わせて書きます。

### request.security()による上位足の取得とリペイント対策

`request.security(銘柄, 時間足, 式)` は、別の時間足で計算した式の値を、いまのチャートの足に合わせて返します。結果を左右するのは `lookahead` 引数です（[公式マニュアル](https://www.tradingview.com/pine-script-docs/concepts/other-timeframes-and-data/)）。

- **既定（`barmerge.lookahead_off`）**：リアルタイムの足では日足が確定するまで値が動き、スクリプトを読み込み直すと過去の表示が変わる（リペイント）。
- **`lookahead_on` だけを付ける**：過去の足に、その時点ではまだ確定していない日足の値が入る。バックテストが未来を知っている状態になる。
- **式を1本ずらして `lookahead_on`**：常に直前に確定した上位足の値を使うので、過去の足とリアルタイムの足で結果が同じになる。公式マニュアルが例示している形。

```
//@version=6
indicator("前日高値・安値", overlay = true)
// 1本ずらした式と lookahead_on を組み合わせ、確定済みの前日の値だけを使う
[prevHigh, prevLow] = request.security(syminfo.tickerid, "D", [high[1], low[1]], lookahead = barmerge.lookahead_on)
plot(prevHigh, "前日高値", color.red, 1, plot.style_stepline)
plot(prevLow, "前日安値", color.teal, 1, plot.style_stepline)
```

複数の値はタプル `[high[1], low[1]]` にまとめると1回の呼び出しで取れます。`request.*()` の一意な呼び出しは1本のスクリプトで40まで（Ultimateは64）なので、値ごとに呼び出しを分けるより上限に余裕が残ります。

### line.new()による前日高値の水平線描画

`plot()` は1本の線をチャート全体に描きますが、日ごとに区切った線や、特定の足から引く線は `line.new()` で作ります。

```
//@version=6
indicator("前日高値の水平線", overlay = true, max_lines_count = 100)
float prevHigh = request.security(syminfo.tickerid, "D", high[1], lookahead = barmerge.lookahead_on)

// 日が替わった最初の足で線を引き、同じ日の間は右端を今の足まで伸ばす
var line hiLine = na
if timeframe.change("D")
    hiLine := line.new(bar_index, prevHigh, bar_index + 1, prevHigh, color = color.red, style = line.style_dashed)
else
    line.set_x2(hiLine, bar_index)
```

`line.new()` は `plot()` と違って `if` の中で呼べます。座標は既定で足の番号（`bar_index`）と価格で指定し、`extend = extend.right` を渡すと右へ伸ばし続けられます。作った線のIDを変数に持っておけば、`line.set_x2()` などで後から位置や色を変えられます。1本のスクリプトが表示する線は既定で約50本で、`max_lines_count` で最大500本まで増やせます。上限を超えると古い線から自動で消えます（[Lines and boxes](https://www.tradingview.com/pine-script-docs/visuals/lines-and-boxes/)）。

## 自作関数・メソッド・ユーザー定義型の書き方

Pine Scriptでは自作関数を使えます。`関数名(引数) =>` と書き、1行なら同じ行に、複数行ならインデントしたブロックに処理を書きます。ブロックの最後の式が戻り値になり、`return` はありません。v5以降は、型に処理を結び付けるメソッドと、複数の値をまとめるユーザー定義型（`type`）も書けます。

```
//@version=6
indicator("自作関数・メソッド・型の例")

// 自作関数：終値と移動平均の乖離率(%)を返す
gapPct(float src, int len) =>
    float ma = ta.sma(src, len)
    (src - ma) / ma * 100

// ユーザー定義型：しきい値に名前を付けて持つ
type Threshold
    string name
    float  level

// メソッド：Threshold型に「値がしきい値を超えたか」を判定させる
method isOver(Threshold t, float value) =>
    value > t.level

float gap = gapPct(close, 25)
var Threshold overheat = Threshold.new("過熱", 5.0)

plot(gap, "25本乖離率(%)")
hline(5.0, "過熱ライン", color.red)
bgcolor(overheat.isOver(gap) ? color.new(color.red, 85) : na)
```

自作関数には公式マニュアルが定める制約があります。

- 定義はグローバルスコープに書く。関数の中や `if` の中では定義できない。
- 自分自身を呼ぶ再帰は書けない。
- 引数やグローバル変数そのものへの再代入はできない。ただし、配列やユーザー定義型などの参照型では、参照先の要素やフィールドを変更できる。
- `plot()` のように、グローバルスコープでしか呼べない関数は中で呼べない。

複数のスクリプトで同じ関数を使い回すなら、`library()` で宣言したライブラリに `export` 付きで書いて公開し、`import ユーザー名/ライブラリ名/版番号` で読み込みます。版番号の指定は必須です。

## ストラテジーの書き方とバックテストの読み方

ストラテジーは `strategy()` で宣言し、`strategy.entry()` で仮想の注文を出します。次のコードは公式マニュアルの例をもとにしたもので、短期SMAが長期SMAを上抜けたら買い、下抜けたら売りに切り替えます。2行目の注釈は、後述の自動売買で使うアラート文面の既定値です。

```
//@version=6
//@strategy_alert_message {"action":"{{strategy.order.action}}","ticker":"{{ticker}}","position":"{{strategy.position_size}}","price":"{{strategy.order.price}}"}
strategy("SMAクロス戦略", overlay = true)

int lengthInput = input.int(14, "基準期間", minval = 2)
float fastMA = ta.sma(close, lengthInput)
float slowMA = ta.sma(close, lengthInput * 2)

// 短期が長期を上抜けたら買い（売りポジションがあればドテン）
if ta.crossover(fastMA, slowMA)
    strategy.entry("Buy", strategy.long)
// 短期が長期を下抜けたら売り（買いポジションがあればドテン）
if ta.crossunder(fastMA, slowMA)
    strategy.entry("Sell", strategy.short)

plot(fastMA, "Fast MA", color.aqua)
plot(slowMA, "Slow MA", color.orange)
```

チャートに追加すると、チャート下のパネルに損益レポートが出ます。公式では「ストラテジーレポート（旧称ストラテジーテスター）」と呼ばれている画面です。最初に見る指標は次の4つです。

| 指標                | 意味           | 見方                 |
| ----------------- | ------------ | ------------------ |
| Total P&L         | 期間中の損益合計     | 手数料・スリッページ設定後の値で見る |
| Max drawdown      | ピークから底への最大下落 | 資金が耐えられる幅か         |
| Profit factor     | 総利益÷総損失      | 1.0を超えれば利益超過       |
| Profitable trades | 勝率           | 損益比と合わせて読む         |

### バックテストの結果が実運用とずれる原因

ストラテジーの売買は、TradingViewの「ブローカーエミュレーター」がチャートのデータだけで約定を再現したものです。既定では足の確定時に売買条件を計算し、そこで生成した成行注文は通常、次の足の始値で約定します。足の中の値動きは始値・高値・安値・終値の位置関係から推定しています。こうした前提に加え、スクリプトの書き方と設定の漏れによって、次の3点で実運用より良い結果が出やすくなります。

- **先読み（lookahead）**：その時点では得られない未来のデータが計算に混じる。`request.security()` で上位足を参照するときに起きやすい。
- **リペイント**：過去の足と現在の足で計算結果や表示が変わる。確定前の足でサインが出ては消える。
- **コスト設定の漏れ**：手数料とスリッページは、指定しなければ0で計算される。設定画面か `strategy()` の引数で入れる。

足の中の値動きまで再現したい場合は、2026年7月に追加された `calc_on_every_history_tick = true` を `strategy()` に渡します。過去の足でも、足が形成途中だった時点のティックごとに計算と約定をやり直すので、先読みの危険も減ります。PremiumとUltimateプランの利用者が、標準チャートで使える機能です（[Release notes](https://www.tradingview.com/pine-script-docs/release-notes/)）。同じ更新で「Using bar magnifier」のチェックボックスは「Bar detalization」メニューに置き換わり、`use_bar_magnifier` 引数はこのメニューの既定値を決めるものになりました。

## 自動売買の仕組み：アラートとwebhookによる外部連携

Pine Scriptのストラテジーもインジケーターも、取引所や証券会社へ直接注文を出すことはできません。自動売買にするには、TradingViewのアラートが発火したときにwebhookで外部のURLへHTTP POSTを送り、それを受けたサーバーやサービスがブローカーの発注APIを呼ぶ、という構成です。webhookそのものの仕組みは「[Webhookとは？読み方・仕組み・APIとの違いを実際のHTTPリクエストで解説](/tech/details/3289/)」で説明しています。

ストラテジーでは、約定のたびに発火する「注文約定アラート」を使います。上のコードの `//@strategy_alert_message` に書いたJSONが、アラート作成画面の「メッセージ」欄に入ります。`{{strategy.order.action}}` は売買方向、`{{ticker}}` は銘柄に置き換わって送信されます。

受け側を作る前に確認しておきたい、TradingView側の制約は次のとおりです。

- webhook通知はEssential以上のプランで、2要素認証を有効にしたアカウントでしか使えない（[公式ヘルプ](https://www.tradingview.com/support/solutions/43000529348-how-to-configure-webhook-alerts/)）。
- 送信先URLのポートは80か443だけ。それ以外のポート番号付きURLは拒否される。
- 受け側が3秒以内に処理を返さないとリクエストは取り消される。IPv6には非対応。
- webhookは届かないことがある、と公式ヘルプ自身が書いている。

このため受け側は、受信内容を検証して永続キューなどへ保存した後、3秒以内に200を返し、発注処理は非同期で行います。発注APIの応答を待って3秒を超えるとTradingView側のリクエストは取り消されますが、受け側の発注処理まで取り消されるとは限りません。また、受け側が500〜599（504を除く）を返すと、TradingViewは5秒後に同じ通知を再送し、1回の発火で最大4回届きます（[Webhook resubmission](https://www.tradingview.com/support/solutions/43000735201-webhook-resubmission/)）。受信・発注済みの記録で重複を判定し、再発注する前に注文の処理状況を照合してください。届かなかった場合に備えて、アラートログの「Webhook status」列とブローカー側の建玉を突き合わせる仕組みも要ります。受け側のサーバーとブローカーの発注APIをつなぐ部分は、[API開発・システム連携](/service/system/api/)として外部に開発を任せることもできます。

ローカルPCで受信テストをするなら「[ngrokでローカルサーバーを外部公開する手順｜認証設定とTraffic Policy](/tech/details/17470/)」の方法でHTTPSのURLを発行すれば、ポート443の条件を満たせます。発注せずにSlackへ通知するだけなら「[Slack Incoming Webhookの実装手順：URL発行・Block Kit整形・SDK送信と429対策](/tech/details/17652/)」の受け口に送れます。ただしSlackは `text` キーを持つJSONしか受け付けないため、上の発注用JSONのままでは届きません。メッセージ欄を `{"text":"{{ticker}} {{strategy.order.action}}"}` のように書き換えます（[公式ヘルプ](https://www.tradingview.com/support/solutions/43000529313-i-cannot-send-webhooks-to-slack/)）。

## v4・v5のコードをv6へ移行するときに壊れる箇所

検索上位の日本語解説や書籍の多くは、v5以前のコードのままです。版はコードの1行目の `//@version=` でわかります。v4以前のコードは、宣言や関数名でも見分けられます（[v5への移行ガイド](https://www.tradingview.com/pine-script-docs/migration-guides/to-pine-version-5/)）。

| 書き方        | v4以前                              | v5以降                      |
| ---------- | --------------------------------- | ------------------------- |
| インジケーターの宣言 | `study()`                         | `indicator()`             |
| テクニカル関数    | `sma()`・`highest()`               | `ta.sma()`・`ta.highest()` |
| 他の時間足の取得   | `security()`                      | `request.security()`      |
| 入力         | `input(14, type = input.integer)` | `input.int(14)`           |
| 透明度        | `transp` 引数                       | `color.new()`             |

v4のコードの1行目だけを `//@version=6` に書き換えると、コンパイラは「Could not find function or function reference ‘study’」（`sma` も同じ）、「The “input” function does not have an argument with the name “type”」、「Undeclared identifier “input.integer”」を返します。`transp` を残した `plot()` には「The “plot” function does not have an argument with the name “transp”」が出ます（2026年10月18日にTradingViewのコンパイラで確認）。版の行だけ変えても動かないので、エディタのコンバーターで1版ずつ上げてください。v1・v2の `security()` には `lookahead` 引数がなく、後の版の `lookahead_on` と同じく過去の足に上位足の未確定の値が入ります。v1・v2のコードで上位足を参照していて、式を `[1]` などでずらしていない場合、そのバックテスト結果は先読みを含んだ数字として扱います。

v5のコードもv6でそのまま動くわけではなく、エディタの「Manage script」メニューにある「Convert code to v6」で変換した後も、手で直す箇所が出ることがあります。[公式の移行ガイド](https://www.tradingview.com/pine-script-docs/migration-guides/to-pine-version-6/)のうち、入門者が書くコードに影響しやすい変更を抜き出しました。

| 変更点                   | v5            | v6            |
| --------------------- | ------------- | ------------- |
| bool の値               | true・false・na | true・false のみ |
| 数値から bool への暗黙変換      | できる           | できない          |
| and・or の評価            | 両辺を評価         | 遅延評価          |
| 5 / 2（定数どうし）          | 2             | 2.5           |
| strategy.\* の when 引数 | 非推奨           | 削除            |
| transp 引数             | 非推奨（非表示）      | 削除            |
| ストラテジーの既定証拠金率         | 0%            | 100%          |
| request.\*() の動的呼び出し  | 指定が必要         | 既定で有効         |

気付きにくいのは遅延評価です。v6では `and` の左辺が false なら右辺を評価しません。右辺に `ta.cross()` のような過去の値を使う関数を置くと、その関数が毎バー実行されず、計算がずれます。次のコードはv5では何も言われませんが、v6では「条件式の中の呼び出しが毎バー実行されない可能性がある」という警告が出ます。

```
//@version=6
indicator("遅延評価の警告例", overlay = true)
float fast = ta.ema(close, 9)
float slow = ta.ema(close, 21)
plot(fast)
if barstate.isconfirmed and ta.cross(fast, slow)
    log.info("クロス発生")
```

直し方は、関数の結果をグローバルスコープの変数に入れてから条件に使うことです。次章のコードがその形になっています。証拠金率の既定値が100%に変わった点も要注意です。v5のストラテジーをそのままv6にすると、資金を超えるエントリーが見送られ、損失が膨らんだ売りポジションはマージンコールで強制決済されるので、損益レポートの数字が変わります。v5と同じ結果を再現したい場合は `strategy()` に `margin_long = 0, margin_short = 0` を明示します。2026年7月から設定画面では「Long leverage」「Short leverage」と表示されますが、この2つの引数はそのまま使えます。

v6公開後も言語仕様は更新が続いており、2026年4月には複数行の文字列（`"""…"""`）、8月には確定した足で条件が初めて成立したときの1回だけブロックを実行する `once` キーワードが加わりました。9月には、スクリプトが描いたテーブルをチャート下部のパネルへ移せるようになり、下部パネルではテーブルの文字を選んでコピーできます。更新内容は公式の[Release notes](https://www.tradingview.com/pine-script-docs/release-notes/)に月ごとに載ります。

## エラーと値の調べ方：Pine LogsとPine Profiler

計算途中の値を確かめるなら、`log.info()` で「Pine Logs」ペインに出力するのが手軽です。`plot()` と違ってローカルスコープからも呼べるので、条件が成立した足だけ値を書き出せます。

```
//@version=6
indicator("Pine Logsで値を確認", overlay = true)
float fast = ta.ema(close, 9)
float slow = ta.ema(close, 21)
plot(fast)
bool crossed = ta.cross(fast, slow)
if barstate.isconfirmed and crossed
    log.info("クロス発生 fast={0} slow={1}", fast, slow)
```

`log.warning()`・`log.error()` を使い分けると、ペインで重要度ごとに絞り込めます。処理が重くて実行時間の上限（Basicは全バーで20秒）に近づいたら、Pine Profilerを使います。コードの行やブロックごとに実行回数とおおよその実行時間をエディタ内に表示するので、どのループや `request.*()` が遅いかを特定できます。

## PineScriptに関するよくある質問

### PineScriptとは何ですか？

TradingViewが提供する、チャート上で動くインジケーターやストラテジーを書くための専用言語です。公式の実行環境はTradingViewのサーバーだけで、自分のPCに入れて動かすものではありません。

### PineScriptは無料で使えますか？

無料のBasicプランでも、スクリプトを書いてチャートに表示できます。ただし1チャートに載せられるインジケーターは2つまでで、インジケーターやストラテジーを条件にしたアラートは作れません（2026年10月18日時点の公式料金表）。

### Pine Scriptで自動売買はできますか？

Pine Script単体ではできません。ストラテジーの約定アラートをwebhookで外部サーバーへ送り、そのサーバーがブローカーの発注APIを呼ぶ構成が必要です。webhook通知にはEssential以上のプランと、2要素認証の有効化が要ります。

### Pineスクリーナーとは何ですか？

Pine Scriptのインジケーターを条件にして、ウォッチリストや指数の銘柄をまとめて絞り込むTradingViewの機能です。PremiumとUltimateプランで使えます（2026年10月18日時点の公式料金表）。使えるのは `plot*()`・`hline()` などの対応する描画出力か、`alertcondition()` を1つ以上含むインジケーターで、計算対象は各銘柄の直近500本です（[公式ヘルプ](https://www.tradingview.com/support/solutions/43000742436-tradingview-pine-screener-key-features-and-requirements/)）。2026年8月から、ウォッチリストを作らなくても指数の構成銘柄を最大4,000件まで対象にできるようになりました。

### ChatGPTやClaudeなどの生成AIでPineScriptを書けますか？

書けますが、Web上のコード例にv5以前のものが多く、`transp` 引数や `when` 引数などv6で削除された書き方が混ざりがちです。指示の最初に「Pine Script v6で」と指定し、Pineエディタで出たエラー文を生成AIに渡して修正を依頼し、修正後は再コンパイルとチャート上の挙動確認を行ってください。TradingViewは[公式のMCPサーバー](https://www.tradingview.com/mcp/docs)（ベータ・Essential以上）を公開していますが、2026年10月18日時点のツールはウォッチリスト・相場データ・スクリーナー・ニュース・決算資料・アラートなど9分類で、Pineスクリプトのコンパイルや保存を行うツールは含まれていません。

## 関連記事

- [Webhookとは？読み方・仕組み・APIとの違いを実際のHTTPリクエストで解説](/tech/details/3289/)
- [ngrokでローカルサーバーを外部公開する手順｜認証設定とTraffic Policy](/tech/details/17470/)
- [Slack Incoming Webhookの実装手順：URL発行・Block Kit整形・SDK送信と429対策](/tech/details/17652/)
- [Incoming Webhookとは？Slack・Discord・Teams・Google Chatの使い方と違い【2026年版】](/tech/details/6596/)
- [金融データプロバイダーとは？Bloomberg・LSEGから日本株APIまで料金と選び方](/tech/details/10368/)

---

出典: [PineScript（Pine Script）とは？TradingViewでの書き方と自動売買の仕組みをv6のコード例で解説](<https://www.issoh.co.jp/tech/details/5313/>)（株式会社一創）
