mph-pine について
mphinanceのスタイルでTradingView Pine Script v6のインジケーターやストラテジーを作成・移植するスキルです。忠実な移植、v6固有の確認、ダッシュボードに加え、TradingViewでのユーザー主導のコンパイルを重視します。
主な機能
- 01Pine Script v6の作成と移植
- 02元のロジックと定数の再現
- 03mphinanceのコードスタイル適用
- 04ダッシュボードとAI向けデータ行の追加
- 05再利用可能な数式とアラートパターン
- 06v6の注意点と書式の確認
活用シーン
- 01PythonスキャナーをPineに移植
- 02インジケーターにアラートを追加
- 03v6のチャートダッシュボードを作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mphinance/ alpha-skills --skill mph-pineインストール後、Claude Code で/mph-pineを入力して読み込まれたか確認します。
同梱ファイルchannels.pineREADME.md
詳細
Mph Pine
mphinance ハウススタンダード(channels.pine、ghost_dashboard.pine、ghost_alpha.pine)と同じ見た目と挙動になる TradingView Pine Script v6 インジケーターを構築します。忠実な数式、クリーンな v6、シンセウェーブ調のダッシュボード、そして Gemini や Sam がチャートを読み取れるように圧縮された AI 可読ペイロード行を備えます。
呼び出すタイミング
ユーザーが TradingView のインジケーターやストラテジーの構築、移植、拡張を依頼したときに使用します:「pine インジケーターを書いて」「X 用の tradingview インジケーター」「この Python シグナルを Pine に移植して」「スクリプトにアラートを追加して」「/mph-pine」。ユーザーが既存のエンジン(Python スキャナー、スクリーナーのルール)を指定した場合は、それを唯一の正とみなし、追加要素を加える前に忠実に移植してください。
フロー
- まず v6 を土台にする。 書く前に最新のドキュメント(context7 / pine-script docs の MCP、または tradingview.com/pine-script-docs)を取得します。v5 の記憶を信用しないでください。バージョン行が
//@version=6であることを確認します。 - 唯一の正を見つける。 移植する場合は、Python または既存の Pine を最初から最後まで読み、フィールド名、定数、しきい値を正確に一致させます。定数はヘッダーコメントに引用します。新しい挙動は忠実な移植が完了した後にのみ追加し、どの部分が新しいかを明確に述べます。
- ハウススタイルで雛形を組む。 ヘッダーコメントブロック、パレット定数、グループ化された inputs、計算、描画、plots、アラート、ダッシュボード。以下のテンプレートを参照してください。
- 完成したファイルに対して v6 の地雷チェックリスト(以下)を実行します。
- em ダッシュを走査する。 コードコメントや文字列リテラルを含め、ファイル内の U+2014 と U+2013 を検索します。ハイフンまたはカンマに置き換えます。これは生成コードにおけるハウスルール違反の中で最もよくあるものです。
- コンパイルのために引き渡す。 オフラインの Pine コンパイラーはありません。完成したスクリプトをユーザーのクリップボードに読み込み、TradingView の Pine Editor に貼り付けて、Save、Add to chart を行い、赤いエラーがあれば報告するよう伝えます。報告されたエラーを修正し、クリップボードを再読み込みします。
- 保存し、出荷を提案する。 該当するリポジトリの
docs/pine/<name>.pineに書き込みます。/shipを提案します。頼まれない限りコミットしないでください。
v6 地雷チェックリスト
以下は、v5 または記憶から移植する際に痛い目を見る v6 の破壊的変更と落とし穴です:
boolはnaにできません。var bool x = naと決して書かないでください。三状態にはintフラグ (0 / 1 / -1) を使用します。na()、nz()、fixnan()は bool を受け付けなくなりました。- int や float から bool への暗黙のキャストはありません。 明示的な比較を書いてください:
if countではなくif count > 0。 and/orは遅延評価されます。 短絡評価は問題ありませんが、右オペランドの副作用に依存しないでください。- enum と
input.enum。 オプションのfield = "Title"文字列を伴うenum Nameを宣言し、次にinput.enum(Name.first, "Label")とします。==で比較します。マジック文字列よりもクリーンです。 - 動的な
request.security。 単一の呼び出しでseries stringのシンボルまたはタイムフレームを受け取れます。非リペイントを保つにはlookahead=barmerge.lookahead_offを使用します。 input.timeframe("")のオフスロットのトリック。 空のタイムフレームはチャートのタイムフレームを意味します。オプションの上位タイムフレーム確認では、空文字列に対する三項演算子の背後でrequest.securityをゲートしないでください (Pine は両方の分岐を評価します)。代わりにフォールバック (htf_on ? htf_tf : timeframe.period) でrequest.securityを呼び出し、オフのときは結果を無視します。plotchar/plotshapeの引数は const でなければなりません。char、text、locationは series にできません。方向依存のマーカーは、固定のlocation.belowbar/location.abovebarを持つ 2 つの呼び出しに分割してください。- ユーザー関数はグローバルでなければなりません。 すべての
f_*()をトップレベルで宣言し、ifブロックやローカルスコープの中では決して宣言しないでください。 - 中央値。 Pine には
ta.medianがありません。ta.percentile_linear_interpolation(src, len, 50)を使用してください。 - Pine は傾きや r2 を直接提供しません。 最小二乗法を自作してください (以下のスニペット)。
- 永続オブジェクトを描画したり履歴をループしたりするときは、
indicator()で余裕を持ったmax_bars_back、max_lines_count、max_labels_countを設定してください。 - バーごとの重いループ (ピボットスキャン、複数パスのフィッティング) は、長いイントラデイ履歴で実行時間制限に引っかかることがあります。ルックバックを控えめにし、トレードオフに留意してください。
ハウススタイルテンプレート
// <Name> [mph1nance] - <one line purpose>
// (c) mph1nance + Sam the Quant Ghost
//
// PURPOSE: <what it does and why it beats the generic version>
// Faithful port of <source>. Constants: <list them>.
//@version=6
indicator("<Name> [mph1nance]", "<glyph>", overlay=true, max_bars_back=600, max_lines_count=30, max_labels_count=50)
// Synthwave palette (reuse these names)
const color C_BULL = #00FFFF
const color C_BEAR = #FF00FF
const color C_NEUTRAL = #9C27B0
const color C_BREAK = #FF3D00
const color C_CONF = #00FFCC
const color C_WARN = #FFD740
const color C_BG = #090014
const color C_BORDER = #FF00FF
const color C_TEXT = #00FFFF
// Grouped inputs
g_main = "--- Main ---"
// ... input.int / input.float / input.enum, all with group=g_main
ダッシュボードのスキャフォールドと AI ペイロード行
テーブルは barstate.isfirst で一度構築し、barstate.islast で埋めます。左列はラベル、右列は値で、色が意味を担います。最後に、OCR やスクリーンショットリーダーが解析できる、圧縮されたパイプ区切りの単一行を付けます。
var table tbl = na
if barstate.isfirst and show_tbl
tbl := table.new(tbl_pos, 2, 16, bgcolor=C_BG, border_width=2, border_color=C_BORDER, frame_width=3, frame_color=C_BORDER)
if barstate.islast and show_tbl
int row = 0
table.cell(tbl, 0, row, "<TITLE>", text_color=C_TEXT, text_halign=text.align_center, bgcolor=color.new(C_BORDER, 70))
table.merge_cells(tbl, 0, row, 1, row)
row += 1
// ... one row per metric, color-coded ...
// Final AI payload row, merged across both columns:
string ai = syminfo.ticker + "|" + timeframe.period + "|" + verdict + "|" + str.tostring(value)
table.cell(tbl, 0, row, ai, text_color=color.new(C_TEXT, 75), text_size=size.tiny, text_halign=text.align_center)
table.merge_cells(tbl, 0, row, 1, row)
アラートのパターン
静的な alertcondition 呼び出し (離散的なイベントごとに 1 つ) と、バークローズ時に完全なコンテキスト文字列を運ぶ単一の動的な alert() を組み合わせます。
alertcondition(brk_above, "Breakout up", "Price broke above")
if barstate.isconfirmed and (brk_above or brk_below)
alert(syminfo.ticker + " " + timeframe.period + " | " + verdict + " | " + str.tostring(score), alert.freq_once_per_bar_close)
再利用可能な数学スニペット
最小二乗法: 傾き、切片、r2
配列インデックスの慣例: a = 0 はウィンドウ内で最も古いバー、a = len-1 は最新です。インデックス a の系列オフセットは src[(len-1)-a] です。
f_linreg(float src, int len) =>
float n = len, sx = 0.0, sy = 0.0, sxx = 0.0, sxy = 0.0, syy = 0.0
for i = 0 to len - 1
float xi = i, yi = src[(len - 1) - i]
sx += xi
sy += yi
sxx += xi * xi
sxy += xi * yi
syy += yi * yi
float denx = n * sxx - sx * sx
float deny = n * syy - sy * sy
float slope = denx == 0.0 ? 0.0 : (n * sxy - sx * sy) / denx
float icept = (sy - slope * sx) / n
float r2 = (denx == 0.0 or deny == 0.0) ? 0.0 : math.max(0.0, math.min(1.0, math.pow(n * sxy - sx * sy, 2) / (denx * deny)))
[slope, icept, r2]
注: 実際のコードでは各ローカルをそれぞれの行で宣言してください。Pine は 1 行でのカンマ区切りの宣言を受け付けません。上記はこのドキュメント用に圧縮したものです。
残差の標準偏差 (標準偏差レール用)
ウィンドウをループし、(yi - (slope*i + icept))^2 を累積し、sqrt(sum / len) を返します。numpy の np.std と一致します。
出来高確認の中央値
float vol_med = ta.percentile_linear_interpolation(volume, 20, 50)
bool vol_strong = vol_med > 0.0 and volume > 1.5 * vol_med // VOLUME_CONFIRM_MULT
リワード / リスクの幾何学
関連するレベルを超えてバッファ (例えば 0.5 ATR) でストップを置きます。チャネル内のセットアップは反対側のレールを目標にし、ブレイクアウトのセットアップは測定された動き (チャネル 1 つ分の高さ) を目標にします。除算の前に必ず risk > 0 をガードしてください。
コンテキストでゲートされたローソク足パターン
生のパターンを検出し、それがレベルに AT したときにのみフラグを立てます。何もない空間のハンマーはノイズです。上昇チャネルの下側レールに接触するハンマーはシグナルです。
float body = math.abs(close - open), rng = high - low
float up = high - math.max(close, open), dn = math.min(close, open) - low
bool doji = rng > 0.0 and body <= rng * 0.1
bool hammer = rng > 0.0 and dn >= body * 2.0 and up <= body and not doji
bool bull_eng = close > open and close[1] < open[1] and close >= open[1] and open <= close[1]
bool react_bull = tag_lower and (hammer or bull_eng) // tag_lower = price reached the level
厳守事項
- コードコメントや文字列リテラルを含め、どこにも em ダッシュを使用しないでください。納品前に U+2014 と U+2013 をスキャンしてください。ハイフンまたはカンマに置き換えてください。
- Substack 向けのあらゆる文章に Markdown テーブルを使用しないでください。このルールは成果物に関するものであり、このスキルファイルに関するものではありません。
- 見栄えよりも忠実さを優先してください。エンジンを移植する場合は、まずそのフィールド名と定数を正確に一致させてください。すべての追加分には new とラベル付けしてください。
- ユーザーが求めていないインジケーターの挙動を決して勝手に考案しないでください。提案してから、構築してください。
- オフラインの Pine コンパイラーは存在しません。常にクリップボード経由で TradingView に渡して検証し、検査だけでコンパイルが通ると主張しないでください。
- スクリプトは
docs/pine/<name>.pineに書き込んでください。絶対パスを提示してください。/shipを提案してください。自動コミットは決して行わないでください。
スコープ外
- スクリプトの自動コンパイルや自動デプロイ。TradingView が唯一のコンパイラーであり、ユーザーがそれを操作します。
- 取引の発注やライブ注文の接続。インジケーターは助言的なものです。
- 上記以外のすべて。ユーザーが隣接する事項を希望する場合は、スキルを拡張する前に確認してください。