トレーダー用コード集 — PythonとPine Script

コピーできる六つのコード例です。Pythonが四つ(CSV日誌の読込み、指標、ドローダウン付き純資産曲線、ATRポジションサイズ計算)、Pine Scriptが二つ(日中値幅のATR比とアラート、チャート上の計画時間枠)です。すべて分析用で、計算、描画、注意喚起を行います。売買シグナルや判断は生成しません。それはプレイブックの役割です。API名と実行用の識別子は英語のままで、pandasやPine Scriptの文書、一般的なエラーメッセージと対応します。この言語版では、人が読むコメントと出力ラベルを翻訳しています。 AI実践 でも、コード用プロンプトではこの区別を使います。周囲の解説は講座の言語で、使い方を順に説明します。環境については、Pythonの導入と初回実行を次で扱います: 11.8。日誌の列名は、 補助教材Fにあります。.

トレーダーと分析者の作業机。Pythonの日誌分析スクリプトを表示したエディターと、Pine Script指標を載せたチャートのモニター
60秒で押さえる要点
  • 戦略ではなくツール:コードはご自身のデータから指標を計算し、ご自身の計画を確認します。補助教材Hの「AIに任せられない仕事」と同じ範囲であり、理由も同じです。
  • 共通のデータ形式:Pythonは日誌ブック(補助教材F)の列名を読みます。勝率の分母には損益ゼロの取引を含め、期待値は純損益で求めます。プロンプトP5と同じ定義です。
  • ルックアヘッドを使わないPine Script:S5は次を使って日次データを取得します: lookahead=barmerge.lookahead_off。S6は上位時間足へアクセスせず、使うのは、 time 関数だけです。ルックアヘッドがないことは、リペイントがない証明ではありません。過去の足と実時間で見えるものの違いはS5で説明します。P3のコードレビューは、このような落とし穴を確認します。
  • サイズ計算は数量を切り捨てる:リスクからロットへ換算する際、切上げは計画以上のリスクを継続的に生みます。そのコード一行が、1%と「約1%」の違いです。

実行前の三つのルール

  • 実行前に読んでください。 各例は意図的に短くしており、一行ずつ理解してください。不明なコードは推測で変えず、P3レビューを使って修正します。掲示板やチャットのコードでは、この原則がさらに重要です。
  • ファイルからデータを入れますが、コードから取引判断は出ません。 スクリプトは日誌の出力(補助教材F形式)と、明示的に指定したパラメーターを読みます。出力は週次見直し用の数値とチャートです。15.10の監査手順に従い、標本数、取引間の依存、不確実性を考慮して、ご自身で結論を出します。
  • 11.8で説明した環境: Python 3.11以降と、 pandas および matplotlib を使います。導入と最初のスクリプトは同節で説明しています。S1–S4は2026年9月17日にPython 3.12.10、pandas 3.0.5、matplotlib 3.11.1で再実行しました。他のバージョンは未検証です。Pine Scriptはチャートプラットフォームの指標エディターへ貼り付けます。両指標ともバージョン6です。

最低限の実行手順:Python 3.11以降の環境で、次によりバージョンを確認し、 python --version次でパッケージをインストールします: python -m pip install pandas==3.0.5 matplotlib==3.11.1。S1+S2+S3を次の名前で保存し、 analiza_dziennika.py テストCSVを次の名前で保存して、 dziennik.csv次を実行します: python analiza_dziennika.py。S4は標準ライブラリーだけで動きます。S5とS6はPineエディターへ別々に貼り付けてください。二つのPineコードはv6文書と照合しましたが、コンパイルとTradingViewでのアラート動作は未検証です。

分析の流れ:CSV日誌をPythonへ読み込み、指標と純資産曲線を出力し、結論を週次見直しとプレイブックへ反映する CSV日誌補助教材Fの形式 Python:S1–S3指標 · 曲線 · ドローダウン EOWの見直し標本・依存関係・不確実性 プレイブックルールとテストの版を管理 この流れに「コード → 注文」の矢印がないのは、見落としではない

S1 · CSV日誌の読込み

Python 3 · pandas

S2とS3への入口です。補助教材Fのブック出力を読み、列名と項目数を確認してから、次の列を整形します: r_net 。列名の重複、空の列名、項目数の過不足があると読込みを止めます。二つの損益列から勝手に選んだり、データをインデックスへ移したりしません。空の項目にも区切り文字を残します。例: ;A+;;0。途中で切れた行は別の問題です。CSVの種類に合わせて区切り文字と小数記号(PLはセミコロンとカンマ、ENはカンマと小数点)、文字コードを設定します。補助教材Fの生成ファイルはUTF-8で、Excelの「CSV UTF-8」保存もUTF-8で読めます。古いポーランド語コードページの出力にはcp1250が必要な場合があります。画面の言語だけでは文字コードは決まらないため、保存形式を確認してください。空の r_net と、空の close_time_utc は未決済を意味し、除外します。決済時刻があるのに損益がない記録は不完全として計算を止めます。空欄でないのに数値として読めない値(「NA」やダッシュを含む)も、レコード番号を表示して停止します。補助教材F形式で、決済済みなのに決済時刻がない場合も同様です(2026-07-08 13:15)。そうでなければ、曲線の順序を推測することになるためです。

import pandas as pd

CSV_PATH = "dziennik.csv"   # 日誌の出力ファイル(補助ツールFの構成)
CSV_SEP  = ";"              # PL地域設定のCSVは";"、ENは","
DECIMAL  = ","              # PL地域設定のCSVは","、ENは"."
ENCODING = "utf-8-sig"      # 補助ツールFはUTF-8で生成し、BOMにも対応する。旧ポーランド語コードページのCSVには"cp1250"が必要な場合がある

REQUIRED = ["r_net", "setup", "setup_class", "error_code", "close_time_utc"]

# DataFrameを作る前に、端末内ファイルを読み、その構成を検証する。
# pandas.read_csvは重複見出しを改名したり、余分な項目からインデックスを推測したりする場合がある。
import csv

try:
    with open(CSV_PATH, encoding=ENCODING, newline="") as source:
        reader = csv.reader(source, delimiter=CSV_SEP, strict=True)
        header = next(reader, None)
        if not header:
            raise SystemExit("CSVを読めません。見出しが空です。")
        if any(not name or name != name.strip() for name in header):
            raise SystemExit("空の列名、または前後に空白のある列名があります。CSV見出しを修正してください。")
        duplicates = sorted({name for name in header if header.count(name) > 1})
        if duplicates:
            raise SystemExit(f"重複する列:{duplicates} — 日誌側で重複を解消してください。")
        rows, record_indexes = [], []
        for index, row in enumerate(reader):
            if not row:                              # 完全に空のCSVレコード
                continue
            if len(row) != len(header):
                raise SystemExit(f"レコード:{index + 1}、必要な項目数:{len(header)}、実際の項目数:{len(row)} "
                                 f"— 区切り文字と引用符を確認してください。項目は破棄していません。")
            rows.append(row)
            record_indexes.append(index)
    df = pd.DataFrame(rows, columns=header, index=record_indexes, dtype="string").replace("", pd.NA)
except UnicodeDecodeError:
    raise SystemExit(f"文字コードを解釈できません:{CSV_PATH}、指定した文字コード:{ENCODING} — UTF-8か旧cp1250かを確認してください。") from None
except (OSError, csv.Error) as exc:
    raise SystemExit(f"読み込めません:{CSV_PATH}: {exc}") from None

missing = [c for c in REQUIRED if c not in df.columns]
if missing:
    raise SystemExit(f"不足する列:{missing} — 見出しを補助ツールFと照合し、CSV_SEP設定を確認してください。")

raw = df["r_net"]                                   # 結果の空欄を許すのは、決済時刻も空欄の場合だけ
txt = raw.astype("string").str.strip().str.replace(DECIMAL, ".", regex=False)   # 列を自分で解析し、一つの不正セルが読めるセルまで隠さないようにする
r   = pd.to_numeric(txt, errors="coerce").astype("Float64")  # 後の合計で整数の桁あふれによる折り返しを避ける
r   = r.where(r.abs() != float("inf"))              # infも有効なR倍数ではない
invalid = raw.notna() & r.isna()                    # 入力があるが数値として読めない
if invalid.any():
    raise SystemExit(f"r_netが無効なレコード:{(df.index[invalid] + 1).tolist()} "
                     f"(レコード1 = 見出し直下の最初の行)。値とDECIMALを確認してください。"
                     f"NA、ダッシュ、無限大は数値ではありません。")

blank = df.isna().all(axis=1)                       # 行全体が空なら、未使用の表計算行(XLSX全シートの出力)であり、取引ではない
df, r = df[~blank], r[~blank]
has_close = df["close_time_utc"].fillna("").str.strip().ne("")
incomplete = r.isna() & has_close
if incomplete.any():
    raise SystemExit(f"決済済みでr_netがないレコード:{(df.index[incomplete] + 1).tolist()} "
                     f"— 指標を計算する前に、コスト控除後の結果を補ってください。")
open_trades = int(r.isna().sum())
df = df.assign(r_net=r).dropna(subset=["r_net"])   # インデックスを保ち、以下のメッセージにレコード番号を使う

# 資金曲線とドローダウンには時系列順が必要(補助ツールFでは決済時刻順)。決済済みなのに時刻を読めない取引があれば停止する
close_text = df["close_time_utc"].fillna("").str.strip()
has_time = close_text.str.fullmatch(r"\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:Z|[+-]\d{2}:\d{2})?")
closed = pd.to_datetime(close_text.where(has_time), errors="coerce", format="ISO8601", utc=True)   # 補助ツールFの出力は2026-07-08 13:15。形式を固定して行順に依存せず確認し、utc=Trueで余分な"Z"/"+00:00"接尾辞によるエラーを防ぐ
if closed.isna().any():
    raise SystemExit(f"close_time_utcを読めないレコード:{(df.index[closed.isna()] + 1).tolist()} "
                     f"— すべての決済済み取引には、補助ツールF形式(2026-07-08 13:15)の決済時刻が必要です。スクリプトではなく日誌を修正してください。")
df = df.assign(_t=closed).sort_values("_t", kind="stable").drop(columns="_t").reset_index(drop=True)

print(f"読み込んだ件数:{len(df)}件の決済済み取引(除外:{open_trades}行。決済時刻とr_netの両方がありません)。")

出力は、次のDataFrameです: df。以降の例で使え、決済時刻順に並んでいます。曲線とドローダウンもその順に計算します。除外した未決済取引数も返します。空の行は、XLSX全体を出力した場合などの完全に空のレコードで、件数に含めません。データがあって損益も決済時刻もない行は未決済として除外し、決済済みで損益がない行は停止します。レコード一覧とともに停止したら、スクリプトでなく日誌の該当行を直してください。列全体に問題がある場合は、次の定数も確認します: DECIMAL 。レコード番号は列名の次から始まり、空のレコードも含みます。引用符で囲んだ項目は区切り文字や改行を含められますが、同じレコードです。各取引は一度だけ載せます。出力を結合する前に、次の識別子を確認してください: trade_id 。S1は履歴を重複排除しません。時刻のない日付では順序を復元できません。タイムゾーンのない日時はUTCとして扱い、明示的なISO 8601オフセットはUTCへ換算します。同時刻ならレコード順を保ちます。ドローダウンの経路に影響するため、日誌側で順序を定めてください。

S2 · 日誌の指標

Python 3 · pandas

P5とブックの集計画面と同じ定義です。勝率の分母には損益ゼロの取引も含め、 プロフィットファクター はゼロで割らずメッセージを返します。期待値は、 純R (r_net)の平均です。ドローダウンは0 Rから始まる累積曲線の最高値から測ります。最初の損失もすでにドローダウンで、ブックFの式と同じです。S1の後に実行してください。定義は共通ですが、エラーの扱いはP5と異なります。S1は決済取引の損益が無効なら分析を止め、P5はその行を除外して数えるよう指示します。両方の標本に含めた取引を確認してから結果を比較してください。

import math

def metrics(r):
    "コスト控除後のR倍数列から、日誌の基本指標を計算する。\n    定義(補助ツールFのダッシュボードと共通):\n    - 勝率:r > 0の取引数を、有効な全取引数で割る。損益ゼロも分母に残す\n    - プロフィットファクター:正のrの合計を、負のrの合計の絶対値で割る\n    - 期待値:rの算術平均(コスト控除後)\n    - 最大ドローダウン:累積R曲線が、その時点までの最高値から下落した最大幅。\n      曲線は0 Rから始めるため、最初の-1 Rの損失も、すでに1 Rのドローダウンになる"
    n = len(r)
    if n == 0:
        raise SystemExit("有効な取引がないため、測定できません。")
    try:
        r = r.astype(float)
    except (TypeError, ValueError):
        raise SystemExit("指標には数値のコスト控除後Rが必要です。先にS1を実行してください。") from None
    if not r.map(math.isfinite).all():
        raise SystemExit("指標には有限のコスト控除後Rが必要です。先にS1を実行してください。")
    wins   = r[r > 0]
    losses = r[r < 0]
    equity   = r.cumsum()
    peak     = equity.cummax().clip(lower=0)   # 補助ツールF:MAX(0; それまでの最高値)
    drawdown = peak - equity
    try:
        total = math.fsum(r)
        pf_value = None if losses.empty else math.fsum(wins) / abs(math.fsum(losses))
    except (OverflowError, ValueError, ZeroDivisionError):
        raise SystemExit("数値範囲を超えました。Rの値を確認してください。指標は返していません。") from None
    if (not equity.map(math.isfinite).all() or not drawdown.map(math.isfinite).all()
            or (pf_value is not None and not math.isfinite(pf_value))):
        raise SystemExit("数値範囲を超えました。Rの値を確認してください。指標は返していません。")
    pf = "標本に損失なし" if pf_value is None else round(pf_value, 2)
    return {
        "trades":         n,
        "win_rate":       round(len(wins) / n, 3),
        "profit_factor":  pf,
        "expectancy_R":   round(total / n, 3),
        "sum_R":          round(total, 2),
        "max_drawdown_R": round(drawdown.max(), 2),
    }

for key, value in metrics(df["r_net"]).items():
    print(f"{key:>16}: {value}")

週次見直し用の六指標を出力します。損失がなければPFは数値ではなくメッセージです。値が計算範囲を超えると分析を止め、次のような値を返しません: inf, NaN 。見かけ上ゼロのドローダウンも返しません。WR = 0.4は40%です。PFはPLNでなくRで計算するため、金額リスクが変わると結果が異なることがあります。コストはすでに、 r_net に含まれ、S2で再び引きません。平均だけ、または20件や50件を超えたというだけで、優位性を評価できるとは考えないでください。集計画面の定義は、 補助教材Fに、標本選択、コスト、検証の計画は、 補助教材Nにあります。.

S3 · 純資産曲線とドローダウン

Python 3 · pandas + matplotlib

累積R曲線と、その下に最高値からのドローダウンを描きます。実行したディレクトリーにかかわらず、次で指定するCSVの隣にPNGを保存します: CSV_PATH (S1)。曲線では、集計値では消える結果の順序や損失の集中が見えます。これはRの合計であり、PLNの口座残高や純資産の割合ではありません。金額リスクが変わる場合は残高変化を再現しません。入出金や未決済ポジションの損益も含めません。S1の後に実行します。

import math
import matplotlib.pyplot as plt
from pathlib import Path

if len(df) == 0:
    raise SystemExit("決済済み取引がないため、グラフを描けません。")

equity   = df["r_net"].astype(float).cumsum()
drawdown = equity.cummax().clip(lower=0) - equity   # S2と補助ツールFと同じ定義(曲線は0 Rから開始)

if not equity.map(math.isfinite).all() or not drawdown.map(math.isfinite).all():
    raise SystemExit("数値範囲を超えました。Rの値を確認してください。グラフは保存していません。")

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(9, 6), sharex=True,
                               gridspec_kw={"height_ratios": [3, 1]})
x = [0, *(equity.index + 1)]                        # 取引0は、ドローダウンの基点となる開始時の0 Rを表す
ax1.plot(x, [0.0, *equity.values])
ax1.set_ylabel("資金(R)")
ax1.set_title("資金曲線 — コスト控除後Rの累積")
ax1.grid(True, alpha=0.3)

ax2.fill_between(x, [0.0, *(-drawdown.values)], 0, alpha=0.5)
ax2.set_ylabel("ドローダウン(R)")
ax2.set_xlabel("取引番号")
ax2.grid(True, alpha=0.3)

fig.tight_layout()
PNG_PATH = Path(CSV_PATH).with_name("equity_curve.png")   # 作業フォルダーにかかわらず、日誌ファイルの横に保存する
fig.savefig(PNG_PATH, dpi=150)
plt.close(fig)
print(f"保存先:{PNG_PATH}")

出力されるのは、日誌の隣に保存する、 equity_curve.png ファイルです。曲線は0 R(取引0)から始まり、そこからドローダウンを測ります。下のパネルは、全履歴での累積Rの最高値からの下落です。S2やブックFと同じく0 Rから始まり、週次損失を示すものではありません。計画(補助教材E)の週次上限は、その単位とリセット規則を使い、週ごとに別途確認してください。

テストファイルと期待出力(S1 + S2 + S3) CSV · PL形式

次の名前で保存: dziennik.csv 。UTF-8で、結合したS1+S2+S3スクリプトの隣に置き、実行してください。ファイルはS1に必要な列だけですが、補助教材Fの全出力(26列)も同様に読めます。最終行は未決済(r_netが空)です。最初の二つの決済取引が損失なので、ドローダウンは0 Rから測ります。

trade_id;close_time_utc;setup;setup_class;r_net;error_code
2026-041;2026-07-08 13:15;wybicie-azja-londyn;A+;-1,00;5
2026-042;2026-07-09 16:40;powrot-do-sredniej;B;-1,08;3
2026-043;2026-07-10 09:05;wybicie-azja-londyn;A+;1,83;0
2026-044;2026-07-13 12:20;wybicie-azja-londyn;B;0,00;0
2026-045;2026-07-14 14:30;powrot-do-sredniej;C;2,40;0
2026-046;;wybicie-azja-londyn;B;;

期待出力(Python 3.12.10、pandas 3.0.5、matplotlib 3.11.1。2026年9月17日に実行):

5件の決済済み取引を読み込みました(1行を除外。決済時刻とr_netがありません)。
          trades: 5
        win_rate: 0.4
   profit_factor: 2.03
    expectancy_R: 0.43
           sum_R: 2.15
  max_drawdown_R: 2.08
保存先: equity_curve.png

手計算の確認:利益1.83 + 2.40 = 4.23 R、損失1.00 + 1.08 = 2.08 R → PF 2.03。合計2.15 R / 5 = 0.43 R。曲線は−1.00 → −2.08 → −0.25 → −0.25 → 2.15で、当初の最高値0 Rからのドローダウンは2.08 Rです。0 Rの点がなければ1.08 Rとなり、これが補助教材Fの定義上の違いです。この出力は、指定のファイルとバージョンに対応します。違う場合は、データ(区切り、小数記号、文字コード、行順)、S1の定数、コード、パッケージの版を、その順に確認します。

S4 · ATRポジションサイズ計算

Python 3 · 標準ライブラリー

ストップ距離k × ATRに対応するロット数です。リスク額は資金と割合から、距離はATRから求め、数量は口座のロット刻みへ切り捨てます。次の、 lot_step と、 min_lot の両パラメーターの初期値は0.01です。計画リスクが予算を超えないようにします。ただし実損失は増える場合があります。スリッページ、ストップを飛び越す窓、スプレッド、手数料、スワップを含めない計算だからです。資金とpip価値は同じ口座通貨で表し、最大数量と必要証拠金は仕様で別途確認します。 ATR はpipsで入力します。EURUSD 0.0080 → 80、USDJPY 0.80 → 80です。pipサイズは通貨ペアの特徴(補助教材B)で説明します。1ロットのpip価値は商品仕様を使うか、補助教材Cの計算ツールで求めます。

import math
from decimal import Decimal
from fractions import Fraction

def atr_position_size(capital, risk_pct, atr_pips, atr_mult, pip_value_per_lot,
                      lot_step=0.01, min_lot=0.01):
    "損切り幅atr_mult × ATRに対するロット数。\n    atr_pips:価格単位ではなくPIPS単位のATR(EURUSDのATR 0.0080 -> 80、USDJPYのATR 0.80 -> 80。ペアのpipサイズを使う)。\n    pip_value_per_lot:1.00ロットの1 pipの価値を口座通貨で表す\n    (例:USD口座のEURUSDで約10 USD。銘柄仕様を確認する)。\n    lot_step / min_lot:自分の口座の取引量の刻みと最小取引量。0.01は一般的だが、すべてに共通ではない。\n    ゼロを基点とするlot_stepの倍数に切り捨てる。Fractionの演算により、\n    全体のDecimal精度に依存せず、入力した小数を保つ。\n    計画リスクは最大損失ではない。スリッページ、価格の飛び、スプレッド、スワップはこのモデルに含めない。"
    inputs = (capital, risk_pct, atr_pips, atr_mult, pip_value_per_lot, lot_step, min_lot)
    if any(isinstance(x, bool) or not isinstance(x, (int, float, Decimal)) for x in inputs):
        raise ValueError("文字列や真偽値ではなく、数値を使ってください。Pythonの小数はドットです。")
    decimals = tuple(Decimal(str(x)) for x in inputs)
    if not all(x.is_finite() and x > 0 for x in decimals):
        raise ValueError("すべての入力値は、有限で正の数である必要があります。")
    c, p, a, k, v, step, minimum = map(Fraction, decimals)
    if p > 100:
        raise ValueError("risk_pctは資金に対する百分率です(1.0 = 1%)。")
    risk_amount = c * p / 100
    sl_pips     = a * k
    lots        = math.floor(risk_amount / (sl_pips * v * step)) * step
    if lots < minimum:
        return {"warning": "このlot_stepとmin_lotでは、許容リスク額に収まる取引量がありません。"}
    exact = {"risk_amount": risk_amount, "sl_pips": sl_pips,
             "lots": lots, "planned_risk": lots * sl_pips * v}
    try:
        result = {key: float(value) for key, value in exact.items()}
    except OverflowError:
        raise ValueError("入力値が出力の数値範囲を超えています。") from None
    if not all(math.isfinite(value) and value > 0 for value in result.values()):
        raise ValueError("入力値が出力の数値範囲を超えています。")
    return result  # 表示用の浮動小数点数。損切り幅や金額を追加で丸めない


print(atr_position_size(capital=10_000, risk_pct=1.0,
                        atr_pips=80, atr_mult=1.5, pip_value_per_lot=10.0))
# {'risk_amount': 100.0, 'sl_pips': 120.0, 'lots': 0.08, 'planned_risk': 96.0}

数量刻みに切り捨てたロット数と、その計画リスク額を返します。コストなしのモデルでは予算以下ですが、実損失は大きくなり得ます。刻みはゼロ起点なので、口座の数量体系と一致するか確認してください。ストップや金額をさらに丸めることはありません。例えばATR 0.26 pips × 1.25は0.325 pipsで、0.3ではありません。結果は読みやすい、 float の値で返しますが、ロット刻みの個数は厳密な分数で計算します。商品の最小価格刻みは別に確認が必要です。そこへストップを調整したら数量も再計算します。エントリー判断は行いません。計算するのは「いくら」であって、「入るべきか」ではありません。

S5 · 日中値幅とATR・アラート付き

Pine Script v6 · 指標

変動幅を意識するための日中指標です。実時間の足では、日次ATRに対して現在の値幅がどの割合まで進んだかを示し、閾値超過で通知します。値動きを追い掛ける合図ではなく、計画を確認する時点です。日次データはルックアヘッド、つまり未来の値を使わず取得します。過去の足では、 request.security が次のD期間の終わりまで最後の確定済み日次値を保ち、新しい期間の結果は最後の日中足に表示されます。実時間では現在のD足の形成中の値幅とATRを取得するため、再読み込み後に以前の表示が変わる場合があります(リペイント)。一日はデータ提供元のD足で、Europe/Warsawの暦日ではありません。分母のATRも日中に変化し、100%は値動きの上限ではありません。この方法では、今日の連続した閾値超過を過去の足上で復元できません。

//@version=6
indicator("日中値幅とATRの比較(気付きを促すツール)", overlay=false)

if not timeframe.isintraday
    runtime.error("1D未満の、時間ベースの日中チャートを使ってください。")

atrLen  = input.int(14, "ATR期間", minval=2)
warnPct = input.int(80, "日中値幅がATRの何%に達したら通知するか", minval=10, maxval=200)

// 過去の足:最後に確定したDの値を、各D期間の終了時に更新する。
// リアルタイム:形成中のDの値を使う。経過済みのリアルタイム値も再読み込み後に変わる場合がある。
dayHigh = request.security(syminfo.tickerid, "D", high,            lookahead=barmerge.lookahead_off)
dayLow  = request.security(syminfo.tickerid, "D", low,             lookahead=barmerge.lookahead_off)
dayAtr  = request.security(syminfo.tickerid, "D", ta.atr(atrLen),  lookahead=barmerge.lookahead_off)

rangePct = dayAtr > 0 ? 100.0 * (dayHigh - dayLow) / dayAtr : na

plot(rangePct, "日中値幅のATR比(%)", linewidth=2)
hline(100, "ATRの100%")
hline(warnPct, "通知水準", linestyle=hline.style_dotted)

alertcondition(ta.crossover(rangePct, warnPct),
     title="値幅がATRの%に到達",
     message="日中値幅が指定したATR比率に達しました。新規エントリーの前に計画を読み直してください。")

チャート下のパネルとアラート条件を出力します。指標を追加してから、プラットフォームで「値幅がATRの%に到達」を選んで自分でアラートを作成してください。標準的な時間ベースの日中足を使います。平均足やRenkoのデータは性質が異なる場合があります。欠損値(na)は必要なATRやデータがない意味で、0%ではありません。条件は閾値以下から閾値超へ移ることです。超えたままでは再通知しません。「Once Per Bar Close」は日中足の確定時だけに通知を制限しますが、D足全体の確定ではありません。設定を変えたらアラートも作り直してください。方向シグナルではなく、高い値は「すでに値動きが起きた」ことを示すだけです。対応はプレイブックで決めます。

S6 · チャート上の計画時間枠

Pine Script v6 · 指標

計画の第3節(補助教材E)をチャートへ描き、新規ポジションを持ってよい時間を強調し、終了時に通知します。計画に明記した正確なIANAゾーンを設定し、計画の時間枠を同じゾーンで入力してください。例えばEurope/Londonは日付に応じてGMT/BSTを適用します。コードのEurope/Warsawは地域事例(CET/CEST)です。計画が別のゾーンを使う場合は初期値を置き換えてください。初期設定は月曜から金曜で、全曜日への拡張も可能です。表示が確認するのは計画の時間だけで、他のエントリー条件ではありません。標準的な時間ベースの日中足を使います。

//@version=6
indicator("取引計画のセッション時間枠", overlay=true)

if not timeframe.isintraday
    runtime.error("1D未満の、時間ベースの日中チャートを使ってください。")

// 地域事例:初期値を計画に明記した正確なIANAゾーンに置き換える。
tz   = input.string("Europe/Warsaw", "計画のIANAタイムゾーン")
win1 = input.session("0900-1200", "時間枠1")
win2 = input.session("1400-1700", "時間枠2")

weekdaysOnly = input.bool(true, "月曜日から金曜日のみ")
days = weekdaysOnly ? ":23456" : ":1234567"

inWin = not na(time(timeframe.period, win1 + days, tz)) or not na(time(timeframe.period, win2 + days, tz))

bgcolor(inWin ? color.new(color.teal, 88) : na, title="計画の時間枠内")

windowJustClosed = inWin[1] and not inWin
alertcondition(windowJustClosed,
     title="計画の時間枠が終了",
     message="取引時間枠が終了しました。未決済ポジションの管理だけを行い、新規エントリーはしないでください(計画、第3節)。")

取引時間の背景色と、時間枠終了のアラート条件(「計画の時間枠が終了」)を出力します。指標追加後、プラットフォームでアラートを作成してください。内側の足の次に初めて現れた外側の足を検出するため、終了時刻ちょうどの通知は保証しません。新しい足とデータ更新がなければ判定しません。開始・終了が時間枠の境界に合う時間足を使います。例えばM15、09:00–12:00の枠で12:00の足があれば、背景色は12:00で終わり、その最初の外側の足で条件が有効です。「Once Per Bar」は最初の更新時、「Once Per Bar Close」は確定時に通知し得ます。重なる時間枠は和集合なので、最初の終了で二つ目は閉じません。時刻変更後はアラートを作り直します。注文を禁止する機能ではありません。指標が計画を思い出させ、取引前チェックリストで実行します。

TradingViewのEUR/USDにPine Script v6指標を表示。計画の時間枠(S6)を強調し、下部に80%アラート水準付きの日中値幅 / ATRパネル(S5)
TradingViewのEUR/USDにPine Script v6指標を表示。計画の時間枠(S6)を強調し、下部に80%アラート水準付きの日中値幅 / ATRパネル(S5)
コード集を一ファイルにまとめる ブラウザ内で生成

見出し付きの六つの例、設定手順とライブラリーのバージョン、テストCSV、期待出力を一つのテキストファイルにまとめます。日誌と一緒に保管するか、ご自身のリポジトリーへ置いてください。TXTには複数の言語を含むので、全体をPythonとして実行してはいけません。S1+S2+S3、単独のS4、または一つのPine指標を選んでください。

五つのテスト取引による実際のS3出力。Pythonスクリプトのエディターと端末の指標、その隣に生成された純資産曲線とドローダウンのチャート
五つのテスト取引による実際のS3出力。Pythonスクリプトのエディターと端末の指標、その隣に生成された純資産曲線とドローダウンのチャート

よくある質問

コードのどの部分を英語のまま残しますか?

API名と実行用の識別子は英語のまま残し、pandasやPine Scriptの文書、通常英語のエラーメッセージと対応させます。日本語版では、人が読むコメントと出力ラベルを翻訳します。周囲の解説は何をするコードか、いつ使うかを、コメントは処理方法を説明します。元のポーランド語講座では、このライブラリーのコメントは英語のままで、P5のポーランド語コメントの例外は個別に生成する一回用のコードに適用されていました。AI実践もコード用プロンプトでこの区別を使います(補助教材H、P3)。

Pythonの例をどう実行しますか?

11.8 で、Python、環境、パッケージの導入を順に説明します。このコード集では、 pandas と、 matplotlib があれば十分です。S1–S3を一つの次のファイルへまとめ、 analiza_dziennika.py S1を先頭に置いて、次を実行します: python analiza_dziennika.py 。日誌の出力があるディレクトリーで実行し、S4は単独で動きます。相対パスの、 CSV_PATH は端末の作業ディレクトリーを基準にします。まずテストCSVを使い、実際の日誌はコピーで分析してください。 equity_curve.png は次の実行時に上書きします。不明なエラーが出たら、推測で直さず、コードとメッセージ全文を、 補助教材HのP3レビューへ貼り付けてください。

これらの例を変更・拡張できますか?

そのためのスターターキットです。例えば、S2の関数を呼ぶ前にsetup列でまとめてセットアップ別に指標を計算し、error_codeで問題のない執行の期待値を求め、A+/B別の曲線を描けます。変更には二つの原則があります。特にPineのrequest.securityを含む変更は、すべてP3レビューに通すこと。指標の定義と戦略ルールの両方を版管理することです。計算ミスはすぐ修正し、比較期間を同じ方法で再計算します。戦略ルールの変更は、 テストの実施記録(補助教材N) に記録し、新しいデータで確認します。四半期の終わり自体は変更理由にならず、途中であることも誤りを残す理由にはなりません。

戦略やEAが入っていないのはなぜですか?

AI実践がシグナルを作らないのと同じ理由です。ネットの既成戦略は、優位性も前提も不明で、ご自身の計画と結び付いていません。他人のロジックを口座で動かすEAは、ご自身だけが代償を負う判断を委ねることです。この講座のコードは、測定、可視化、計画遵守という手順を補強し、置き換えはしません。自分で検証した戦略の自動化を目指すなら、 15.4のバックテスト、補助教材Nの実施記録、P3コードレビューを経てください。「儲かる」スクリプトをコピーする道ではありません。

説明用の事例:「きりの良い数」への丸め。 計算は0.07ロットでしたが、「見た目だけの違いで、きりも良い」と0.1にしたとします。この見た目の調整は、毎回+43%のリスクを四半期中ずっと加えることです。日次−2R上限は実質−2.9Rとなり、本人は小さな変更と思っていても曲線のドローダウンは計画を超えます。そのためS4は、 math.floor を使い、次は使いません: round。機械は異議なく切り捨て、人は理由を付けて切り上げます。
説明用の事例:曲線で初めて見えた損失の集中。 四半期の指標は期待値が正で、ドローダウンも想定内に見えました。しかしS3の曲線では全下落がある一週に集中し、S2にエントリー時間フィルターを加えると、損失はすべて21:00–23:00 UTCでした。補助教材Fの日誌はUTCを使います。スプレッドが広いのに「もう少し残る」と取引していました。ロールオーバーと重なるかはブローカーとタイムゾーン次第なので、決め付けず仕様を確認します。集計値は平均化しますが、曲線はいつ損失が出たかを示します。「21:00 UTC、つまり23:00 CEST / 22:00 CET以降は新規エントリーしない」という計画の一行を、計画とS6にはEurope/Warsawで記録します。この事例では、その結論は今後の週で検証するもので、完成した成績改善策ではありません。コード集はこのような結論を支援します。
免責事項: 本ページは教育用で、投資助言ではありません。コード例は自己責任で実行する分析ツールです。使用前に読み、例えば補助教材Cの計算ツールで結果を確認し、自分の計画で取引判断をしてください。Python(S1–S4)はネットや口座に接続せず、端末内ファイルを読み、チャートを描きます。Pine指標(S5–S6)は、プラットフォーム上でそのデータを使って動きます。売買シグナルの生成や発注を行う例はありません。

出典

  1. 文書: pandas 3.0.5 および matplotlib 3.11.1 (S1–S3で使う関数)。Python: CSVの読込み と、 分数の演算 (形式検証とロット刻みの個数の厳密な計算)。S1–S4は2026年9月17日、Python 3.12.10で架空データを使って実行しました。TradingView Pine Script v6: 他の時間足とデータ, 取引時間帯, 時刻とタイムゾーン, アラート (lookahead設定とリペイントに関するrequest.security、hline、input.session、alertcondition)。S5–S6は文書と照合し、コンパイルはしていません。
  2. 内部資料: 11.8 取引で使うPython (環境)、 15.9 (指標の定義と日誌形式)、 15.10 (結論を出す原則)。コード集は、それらを実務向けにまとめた実装です。
  3. Van K. Tharp、 Trade Your Way to Financial Freedom、第2版、McGraw-Hill、2007年。R倍数と期待値。S2、ブックF、P5に共通する言葉です。

Jarosław Wasiński (ヤロスワフ・ヴァシンスキ)

編集長、ForexMechanics.com • マクロ・FXアナリスト

金融市場で20年以上の経験を持つ独立系プロアナリスト。2007年からFX市場で活動し、ファンダメンタル分析・OTC市場構造・規律ある資本リスク管理を専門としています。

  • 2004年より信頼性の高い金融教育を提供するMyBank.plの創設者兼編集長。
  • 投資家・トレーダー向けに数百本の詳細な市場解説、構造分析、教育コンテンツを執筆。
  • 市場の透明性を支持し、具体的なデータと機関投資家レポート(BIS・ESMA・CFTC)に基づく教育を推進。

すべてのコンテンツは教育・情報提供のみを目的としており、投資アドバイスや推奨を構成するものではありません。レバレッジ取引(Forex/CFD)は急速な資本損失リスクを伴います。