
本ページにはプロモーションが含まれています。
FXで移動平均線を使うとき、
- SMAは何期間に設定すればいいの?
- 5・20・75・200など、結局どの期間が使いやすいの?
と悩む方も多いのではないでしょうか。
移動平均線にはよく使われる期間がありますが、実際にどの設定が機能するかは、通貨や売買方向によって異なります。
そこで今回は、USDJPY・EURJPY・GBPJPY・EURUSD・AUDUSDの5通貨を対象に、短期SMA10種類×長期SMA10種類の100通りをLONG・SHORTそれぞれで検証しました。
単純な合計利益だけではなく、PF・最大DD・直近6か月の成績・周辺設定の安定性なども含めて評価し、成績が良かったSMAの期間設定を紹介します。
「移動平均線の期間をどう設定すればいいか迷っている」という方は、ぜひ参考にしてください。
FXの移動平均線(MA)とは

移動平均線(MA:Moving Average)とは、一定期間の価格の平均値を線で表したテクニカル指標です。
今回の検証では、基本的な単純移動平均線(SMA)を使用します。
SMAは期間が短いほど価格へ素早く反応し、期間が長いほど値動きが滑らかになります。
本記事では、短期SMAと長期SMAの組み合わせを変えながら、どの期間設定が成績につながりやすいのかを検証します。
ゴールデンクロスとデッドクロス
2本の移動平均線を使った代表的な売買シグナルが、ゴールデンクロスとデッドクロスです。
- ゴールデンクロス:短期SMAが長期SMAを下から上へ抜ける
- デッドクロス:短期SMAが長期SMAを上から下へ抜ける
今回の検証では、次の条件でLONG・SHORTを判定します。
| 方向 | エントリー | 決済 |
|---|---|---|
| LONG | ゴールデンクロス | デッドクロス |
| SHORT | デッドクロス | ゴールデンクロス |

クロスが確定した次のローソク足の始値で売買する条件としています。
移動平均線でよく使われる期間
移動平均線には「この期間を使えば必ず勝てる」という決まった設定はありません。
取引する時間足やトレードスタイルによって、使用される期間は異なります。
代表的な設定としては、短期では5・10・20・25、中期では50・75、長期では100・200などが使われることがあります。
ただし、実際にどの期間が有効なのかは、通貨や相場環境によって変わります。
そこで今回の検証では、一般的に使われる期間だけに限定せず、比較範囲を広げるために以下のSMAを使用します。
- 短期SMA:5、10、15、20、25、30、35、40、45、50
- 長期SMA:60、75、100、120、150、200、250、300、400、500
短期10種類×長期10種類で、1通貨・1方向につき100通りのSMA設定を比較します。
今回の移動平均線の検証条件

今回は、5通貨の15分足データを使用して、短期SMAと長期SMAの組み合わせを検証します。
1通貨・1方向につき100通りのSMA設定を比較し、LONG・SHORTをそれぞれ検証します。
今回検証する通貨・期間・SMA
今回の主な検証条件は以下のとおりです。
| 項目 | 検証条件 |
|---|---|
| 通貨 | USDJPY・EURJPY・GBPJPY・EURUSD・AUDUSD |
| 時間足 | 15分足 |
| 移動平均線 | SMA(単純移動平均線) |
| 短期SMA | 5・10・15・20・25・30・35・40・45・50 |
| 長期SMA | 60・75・100・120・150・200・250・300・400・500 |
| 組み合わせ | 1通貨・1方向につき100通り |
| 検証期間 | 2024年1月1日 ~ 2026年7月31日 |
| 価格データ | GMO FX APIで取得したローソク足 |
| 使用価格 | ASK |
今回は移動平均線そのものの成績を確認するため、1時間足・4時間足・日足などの上位足フィルターは使用しません。
データはGMOのAPIを利用し、取得しています。
実際に取得をしてみたい方は、以下の記事を参考にしてみてください。
LONG・SHORTの検証条件
LONGとSHORTはそれぞれ独立して検証します。
| 項目 | LONG | SHORT |
|---|---|---|
| エントリー | ゴールデンクロス | デッドクロス |
| 約定 | クロス確定後の次足始値 | クロス確定後の次足始値 |
| 決済 | デッドクロス後の次足始値 | ゴールデンクロス後の次足始値 |
| TP・SL | 使用しない | 使用しない |
| 同時保有 | 最大1ポジション | 最大1ポジション |
| データ終了時 | 最終足終値で決済 | 最終足終値で決済 |
今回はSMAの期間設定による違いを比較するため、固定のTP・SLは使用せず、反対方向のクロスが発生するまでポジションを保有する条件としています。
なお、今回の検証ではASK価格のみを使用しており、以下の取引コストは考慮していません。
- スプレッド
- スリッページ
- 手数料
- スワップ
そのため、平均利益が小さい設定については、実際の取引では成績が悪化する可能性があります。
成績が良かったSMA設定の選定基準
今回検証した100通りのSMA設定から、成績が良かった組み合わせを選ぶため、単純に合計pipsが大きい順では順位を決めていません。
全期間だけで好成績だった設定や、特定の期間だけ偶然良かった設定をできるだけ避けるため、まず以下の条件で候補を絞り込みます。
足切り条件
- 全検証期間の合計pipsがプラス
- 全検証期間のPFが1.05以上
- 全検証期間の取引回数が100回以上
- 直近6か月の合計pipsがプラス
- 直近6か月のうち3か月以上がプラス
条件を通過した設定について、以下の7項目を100点満点で評価します。
| 評価項目 | 配点 |
|---|---|
| 全検証期間の合計pips | 20点 |
| PF | 15点 |
| 利益 ÷ 最大DD | 20点 |
| 平均pips | 10点 |
| 周辺パラメータの安定性 | 15点 |
| 直近6か月の成績 | 15点 |
| 取引回数 | 5点 |
| 合計 | 100点 |
特に重視するのが、利益に対する最大DDと周辺パラメータの安定性です。
例えば、短期SMA45・長期SMA60だけが好成績でも、その周辺設定がすべてマイナスであれば、偶然その組み合わせだけが良かった可能性があります。
そこで、短期・長期SMAの一覧上で隣接する設定を確認し「条件を満たした周辺設定数 ÷ 存在する周辺設定数」から周辺パラメータの安定性を評価します。
最終的に、評価点が高かった設定を最大5つまで掲載します。
足切り条件を満たす設定が3つならTOP3、候補がなければ「今回の条件では有効な設定なし」として結果を掲載します。
また、今回の検証に使用したPythonスクリプトも掲載しておきます。
短期SMA10種類×長期SMA10種類の100通りについて、5通貨のLONG・SHORTをそれぞれ検証できるようにしています。
気になる方は、是非以下のコードをコピーして使ってみてください。
"""15分足のSMAクロスを100パターン一括検証する。
15分足のシグナルが確定した次の足の始値で約定し、反対クロスで決済する。
標準ライブラリだけで実行できる。
"""
import csv
import time
from datetime import datetime, timedelta
from pathlib import Path
# 使い方:
# 1. fetch_gmo_candles.pyで、5通貨の15分足を取得します。
# 2. GMO-APIフォルダで次のコマンドを実行します。
# python backtest_research/moving_average/run_ma_backtest.py
# 3. 結果は backtest_research/moving_average/results に通貨別で保存されます。
# 検証する通貨ペアです。
SYMBOLS = ("USD_JPY", "EUR_JPY", "GBP_JPY", "EUR_USD", "AUD_USD")
# 売買の判断には15分足だけを使います。
ENTRY_TIMEFRAME = "15min"
ENTRY_TIMEFRAME_DURATION = timedelta(minutes=15)
PRICE_TYPE = "ASK"
# 15分足で検証する短期SMAと長期SMAです。
# すべての短期期間がすべての長期期間より短いため、10 × 10 = 100通りになります。
DEFAULT_FAST_PERIODS = (5, 10, 15, 20, 25, 30, 35, 40, 45, 50)
DEFAULT_SLOW_PERIODS = (60, 75, 100, 120, 150, 200, 250, 300, 400, 500)
# 入力CSVと検証結果の保存場所です。
# __file__を基準にするため、どのフォルダからコマンドを実行しても同じ場所を参照します。
SCRIPT_DIR = Path(__file__).resolve().parent
GMO_API_DIR = SCRIPT_DIR.parents[1]
DEFAULT_DATA_DIR = GMO_API_DIR / "data" / "candles"
DEFAULT_OUTPUT_DIR = SCRIPT_DIR / "results"
# 結果CSVへ出力する列と、その並び順です。
RESULT_COLUMNS = (
"通貨ペア",
"短期SMA期間",
"長期SMA期間",
"取引回数",
"勝ち取引数",
"負け取引数",
"勝率(%)",
"合計損益(pips)",
"平均損益(pips)",
"プロフィットファクター",
"最大ドローダウン(pips)",
)
# 1回ごとの取引履歴に保存する列です。
TRADE_COLUMNS = (
"取引番号",
"エントリー日時",
"エントリー価格",
"決済日時",
"決済価格",
"決済理由",
"保有時間(分)",
"損益(pips)",
)
def load_candles(path):
"""fetch_gmo_candles.pyが作るOHLC CSVを読み込む。"""
candles = []
# 始値と終値をバックテストで使いやすい数値に変換します。
# 高値と安値は今回のクロス決済では使わないため読み込みません。
with path.open("r", encoding="utf-8-sig", newline="") as file:
for row in csv.DictReader(file):
timestamp = datetime.fromisoformat(row["timestamp_jst"])
candles.append(
{
"open_time": timestamp,
"close_time": timestamp + ENTRY_TIMEFRAME_DURATION,
"open": float(row["open"]),
"close": float(row["close"]),
}
)
return candles
def calculate_sma(closes, period):
"""終値の単純移動平均を未来参照なしで計算する。"""
# 例:終値が [100, 101, 102, 103]、期間が3の場合、
# SMAは [None, None, 101, 102] になります。
# 101 = (100 + 101 + 102) ÷ 3、102 = (101 + 102 + 103) ÷ 3です。
# SMAをまだ計算できない最初の期間にはNoneを入れます。
values = [None] * len(closes)
window_sum = 0.0
for index, close in enumerate(closes):
# 新しい終値を合計へ追加し、期間より古い終値を合計から外します。
# 上のSMA3の4本目なら、103を加えた後、期間外になった100を引きます。
window_sum += close
if index >= period:
window_sum -= closes[index - period]
# 必要な本数が揃った位置からSMAを記録します。
# SMA3なら、3本目にあたるindex=2から計算できます。
if index >= period - 1:
values[index] = window_sum / period
return values
def crossover(previous_fast, previous_slow, fast, slow):
"""ゴールデンクロスなら1、デッドクロスなら-1、それ以外は0。"""
# 短期SMAが長期SMAを下から上へ抜けた場合です。
# 例:前の足が「短期99、長期100」、現在足が「短期101、長期100」なら、
# 短期SMAが下側から上側へ移ったため、ゴールデンクロスとして1を返します。
if previous_fast <= previous_slow and fast > slow:
return 1
# 短期SMAが長期SMAを上から下へ抜けた場合です。
# 例:前の足が「短期101、長期100」、現在足が「短期99、長期100」なら、
# 短期SMAが上側から下側へ移ったため、デッドクロスとして-1を返します。
if previous_fast >= previous_slow and fast < slow:
return -1
return 0
def collect_trades(
candles,
fast_sma,
slow_sma,
side,
pip_size,
evaluation_start_index,
):
"""片側戦略を検証し、1回ごとの取引履歴を返す。"""
# LONGはゴールデンクロスで入り、デッドクロスで出ます。
# SHORTはその反対です。
entry_signal = 1 if side == "LONG" else -1
exit_signal = -entry_signal
# entry_priceがNoneならポジションを持っていない状態です。
# pendingは、前の足で決まった注文を次の足の始値で実行するための印です。
entry_price = None
entry_time = None
entry_index = None
pending_entry = False
pending_exit = False
trades = []
# 全設定を公平に比べるため、最長のSMA500が計算できる位置から始めます。
for index in range(max(1, evaluation_start_index), len(candles)):
# 前の15分足で決済が決まっていれば、現在足の始値で決済します。
if entry_price is not None and pending_exit:
direction = 1.0 if side == "LONG" else -1.0
exit_price = candles[index]["open"]
# USDJPYのLONGを150.00円で買い、150.20円で決済した例では、
# (150.20 - 150.00) ÷ 0.01 = 20pipsです。
# SHORTはdirectionが-1になるため、値下がりしたときに利益がプラスになります。
trades.append(
{
"取引番号": len(trades) + 1,
"エントリー日時": entry_time.isoformat(),
"エントリー価格": round(entry_price, 6),
"決済日時": candles[index]["open_time"].isoformat(),
"決済価格": round(exit_price, 6),
"決済理由": "反対クロス",
"保有時間(分)": (index - entry_index) * 15,
"損益(pips)": round(
direction * (exit_price - entry_price) / pip_size, 2
),
}
)
entry_price = None
entry_time = None
entry_index = None
pending_exit = False
# 前の15分足でエントリーが決まっていれば、現在足の始値で約定します。
# 例:10:00開始の足が10:15に確定してクロスした場合、
# クロスした足の終値ではなく、10:15開始足の始値で約定します。
if entry_price is None and pending_entry:
entry_price = candles[index]["open"]
entry_time = candles[index]["open_time"]
entry_index = index
pending_entry = False
# 直前と現在の短期SMA・長期SMAを比べてクロスを判定します。
previous_fast = fast_sma[index - 1]
previous_slow = slow_sma[index - 1]
current_fast = fast_sma[index]
current_slow = slow_sma[index]
if None in (previous_fast, previous_slow, current_fast, current_slow):
continue
signal = crossover(
float(previous_fast), float(previous_slow), float(current_fast), float(current_slow)
)
# ポジションがない場合は、15分足でクロスした次の足でエントリーします。
# ここではまだ約定せず、pending_entryをTrueにして次のループまで待ちます。
if entry_price is None and signal == entry_signal:
pending_entry = True
# ポジション保有中に反対クロスが出たら、次の15分足で決済します。
elif entry_price is not None and signal == exit_signal:
pending_exit = True
# データの最後までポジションが残った場合は、最終終値で決済します。
if entry_price is not None:
direction = 1.0 if side == "LONG" else -1.0
exit_price = candles[-1]["close"]
trades.append(
{
"取引番号": len(trades) + 1,
"エントリー日時": entry_time.isoformat(),
"エントリー価格": round(entry_price, 6),
"決済日時": candles[-1]["close_time"].isoformat(),
"決済価格": round(exit_price, 6),
"決済理由": "データ終了",
"保有時間(分)": (len(candles) - entry_index) * 15,
"損益(pips)": round(
direction * (exit_price - entry_price) / pip_size, 2
),
}
)
return trades
def summarize(symbol, fast_period, slow_period, trades):
"""取引ごとのpips損益から、成績をまとめる。"""
profits = [trade["損益(pips)"] for trade in trades]
# プラスなら勝ち、マイナスなら負けとして分けます。
wins = [profit for profit in profits if profit > 0]
losses = [profit for profit in profits if profit < 0]
gross_profit = sum(wins)
gross_loss = abs(sum(losses))
# プロフィットファクターは「総利益 ÷ 総損失」です。
# 例:勝ち取引の合計が300pips、負け取引の合計が-200pipsなら、
# プロフィットファクターは 300 ÷ 200 = 1.5 です。
profit_factor = gross_profit / gross_loss if gross_loss else None
# 取引順に累積損益を作り、過去の最高値からの最大下落幅を求めます。
# 例:累積損益が [100, 250, 180, 50] と推移した場合、
# 過去最高の250から50まで200pips下落するため、最大DDは200pipsです。
equity = peak = max_drawdown = 0.0
for profit in profits:
equity += profit
peak = max(peak, equity)
max_drawdown = max(max_drawdown, peak - equity)
trade_count = len(profits)
return {
"通貨ペア": symbol,
"短期SMA期間": fast_period,
"長期SMA期間": slow_period,
"取引回数": trade_count,
"勝ち取引数": len(wins),
"負け取引数": len(losses),
"勝率(%)": round(len(wins) / trade_count * 100, 2) if trade_count else 0.0,
"合計損益(pips)": round(sum(profits), 2),
"平均損益(pips)": round(sum(profits) / trade_count, 2) if trade_count else 0.0,
"プロフィットファクター": round(profit_factor, 4) if profit_factor is not None else "",
"最大ドローダウン(pips)": round(max_drawdown, 2),
}
def run_grid(candles, symbol, fast_periods, slow_periods, output_dir):
"""1通貨について、15分足のMA100パターンを検証して順次保存する。"""
# 15分足の終値から、検証で必要なすべてのSMAを先に計算します。
all_periods = set(fast_periods) | set(slow_periods)
closes = [candle["close"] for candle in candles]
entry_sma_by_period = {
period: calculate_sma(closes, period) for period in all_periods
}
# 全組み合わせを最長MAが計算可能になった同じ時点から比較します。
evaluation_start_index = max(all_periods)
# 円を含む通貨ペアは1pips=0.01円、それ以外は1pips=0.0001です。
pip_size = 0.01 if symbol.endswith("_JPY") else 0.0001
# LONGとSHORTを分け、result.csvを検証中に1回だけ開きます。
for side in ("LONG", "SHORT"):
result_path = output_dir / symbol / side / "result.csv"
result_path.parent.mkdir(parents=True, exist_ok=True)
# "w"で開くため、再実行時は以前のresult.csvを上書きします。
with result_path.open("w", encoding="utf-8-sig", newline="") as file:
writer = csv.DictWriter(file, fieldnames=RESULT_COLUMNS)
writer.writeheader()
# 短期10種類 × 長期10種類を順番に検証します。
for fast_period in fast_periods:
for slow_period in slow_periods:
if fast_period >= slow_period:
continue
trades = collect_trades(
candles,
entry_sma_by_period[fast_period],
entry_sma_by_period[slow_period],
side,
pip_size,
evaluation_start_index,
)
# 1設定の検証が終わった時点で取引履歴を保存します。
# 次の設定へ進む前にtradesが置き換わるため、全設定分を保持しません。
trade_path = (
output_dir
/ symbol
/ side
/ "trades"
/ f"SMA_{fast_period}_{slow_period}.csv"
)
write_csv(trade_path, trades, TRADE_COLUMNS)
# 取引履歴を保存した直後に、この設定の検証結果を1行追加します。
writer.writerow(
summarize(symbol, fast_period, slow_period, trades)
)
def write_csv(path, rows, columns):
"""検証結果をCSVへ保存する。"""
# 保存先フォルダがなければ作成します。
path.parent.mkdir(parents=True, exist_ok=True)
# Excelでも文字化けしにくいUTF-8 BOM付きで保存します。
with path.open("w", encoding="utf-8-sig", newline="") as file:
writer = csv.DictWriter(file, fieldnames=columns)
writer.writeheader()
writer.writerows(rows)
def main():
"""CSVの読み込みから検証結果の保存までを実行する。"""
# スクリプト全体の実行時間を測り始めます。
start_time = time.perf_counter()
# 短期MAが長期MAより短い、有効な組み合わせ数を確認します。
combinations = sum(
fast < slow for fast in DEFAULT_FAST_PERIODS for slow in DEFAULT_SLOW_PERIODS
)
if combinations == 0:
raise SystemExit("短期期間 < 長期期間となる組み合わせがありません")
print(f"有効なMA組み合わせ: {combinations}パターン")
# 5通貨を1つずつ検証します。
for symbol in SYMBOLS:
# この通貨の15分足CSVを読み込みます。
path = DEFAULT_DATA_DIR / symbol / f"{ENTRY_TIMEFRAME}_{PRICE_TYPE}.csv"
candles = load_candles(path)
# 100パターンを実行し、全結果を保存します。
print(f"[RUN] {symbol}: 15min")
run_grid(
candles,
symbol,
DEFAULT_FAST_PERIODS,
DEFAULT_SLOW_PERIODS,
DEFAULT_OUTPUT_DIR,
)
elapsed_seconds = time.perf_counter() - start_time
print(f"完了: {DEFAULT_OUTPUT_DIR}")
print(f"実行時間: {elapsed_seconds:.2f}秒")
return 0
# このファイルを直接実行したときだけmain()を動かします。
if __name__ == "__main__":
raise SystemExit(main())
実行コマンドは以下です。
python run_ma_backtest.py
検証結果は通貨・LONG・SHORTごとにCSVへ保存されるため、次の章ではその結果をもとに成績が良かったSMA設定を紹介します。
通貨別に成績が良かった移動平均線

ここでは、足切り条件と100点評価を通過した設定を、通貨ごとに紹介します。
正式評価では、条件を満たした設定が5つ未満の場合は、無理にTOP5を作らず、通過した設定のみを掲載します。
今回の候補数は以下のとおりです。
| 通貨 | LONG | SHORT |
|---|---|---|
| USDJPY | TOP5 | TOP5 |
| EURJPY | TOP4 | 候補なし |
| GBPJPY | TOP4 | 候補なし |
| EURUSD | 候補なし | 候補なし |
| AUDUSD | TOP4 | 候補なし |
USDJPYの検証結果
LONG
USDJPYのLONGでは、81設定が足切り条件を通過しました。
その中で総合評価が高かったTOP5は以下のとおりです。
| 順位 | 短期SMA | 長期SMA | 点数 | 合計pips | PF | 利益/DD | 周辺安定率 | 直近6か月の合計pips |
|---|---|---|---|---|---|---|---|---|
| 1 | 35 | 100 | 91.50 | +2,348.1 | 1.3274 | 1.57 | 100% | +618.5 |
| 2 | 45 | 75 | 89.00 | +1,905.6 | 1.2355 | 1.50 | 100% | +576.3 |
| 3 | 30 | 60 | 86.60 | +2,249.7 | 1.2500 | 1.68 | 100% | +683.9 |
| 4 | 50 | 60 | 86.60 | +1,960.3 | 1.1877 | 1.71 | 100% | +440.4 |
| 5 | 30 | 100 | 86.00 | +2,082.3 | 1.2707 | 1.36 | 100% | +755.8 |
最も評価が高かったのは、短期SMA35・長期SMA100の組み合わせです。
合計pipsだけを見ると短期SMA30・長期SMA60の成績も非常に良好でしたが、PF・最大DD・直近6か月の成績・周辺設定の安定性まで含めて評価した結果、短期SMA35・長期SMA100が1位となりました。
また、TOP5すべてで周辺安定率が100%となっており、USDJPYのLONGは今回の5通貨の中でも比較的安定した結果です。
SHORT
USDJPYのSHORTでは、10設定が足切り条件を通過しました。
その中で総合評価が高かったTOP5は以下のとおりです。
| 順位 | 短期SMA | 長期SMA | 点数 | 合計pips | PF | 利益/DD | 周辺安定率 | 直近6か月の合計pips |
|---|---|---|---|---|---|---|---|---|
| 1 | 30 | 60 | 74.30 | +1,295.4 | 1.1305 | 1.22 | 100% | +24.4 |
| 2 | 30 | 100 | 71.30 | +1,107.3 | 1.1467 | 0.85 | 100% | +80.8 |
| 3 | 40 | 100 | 69.15 | +952.7 | 1.1282 | 0.72 | 75% | +224.8 |
| 4 | 35 | 60 | 67.10 | +916.8 | 1.0911 | 1.00 | 100% | +42.6 |
| 5 | 20 | 100 | 61.88 | +841.1 | 1.1004 | 0.70 | 62.5% | +281.0 |
SHORTで最も評価が高かったのは、短期SMA30・長期SMA60の組み合わせです。
SHORTでも有効候補は見つかりましたが、LONGと比べるとPFや利益/DDは低めです。
USDJPYではLONG・SHORTの両方で候補が見つかりましたが、総合的にはLONGの方が安定した結果となりました。
EURJPYの検証結果
LONG
EURJPYのLONGで足切り条件を通過したのは4設定です。
| 順位 | 短期SMA | 長期SMA | 点数 | 合計pips | PF | 利益/DD | 周辺安定率 | 直近6か月の合計pips |
|---|---|---|---|---|---|---|---|---|
| 1 | 45 | 60 | 64.80 | +1,143.9 | 1.1046 | 0.94 | 40% | +185.9 |
| 2 | 5 | 400 | 61.10 | +705.8 | 1.1278 | 0.55 | 60% | +63.4 |
| 3 | 35 | 60 | 55.70 | +942.0 | 1.0894 | 0.62 | 20% | +26.7 |
| 4 | 40 | 60 | 50.30 | +749.6 | 1.0693 | 0.50 | 40% | +71.7 |
最も評価が高かったのは、短期SMA45・長期SMA60の組み合わせです。
また、短期SMA35・40・45と長期SMA60の組み合わせが複数候補に残っており、長期SMA60付近に一定の傾向が確認できます。
ただし、利益/DDはUSDJPYのLONGより低く、安定性はやや劣る結果です。
SHORT
EURJPYのSHORTでは、正式な足切り条件を満たす設定はありませんでした。
直近の一部期間で利益が出た設定はありましたが、長期的な成績を含めて評価すると、優位性は確認できませんでした。
今回の条件では、EURJPYのSHORTに有効なSMA設定は見つかりませんでした。
GBPJPYの検証結果
LONG
GBPJPYのLONGでは、4設定が足切り条件を通過しました。
| 順位 | 短期SMA | 長期SMA | 点数 | 合計pips | PF | 利益/DD | 周辺安定率 | 直近6か月の合計pips |
|---|---|---|---|---|---|---|---|---|
| 1 | 45 | 60 | 82.50 | +2,645.0 | 1.2168 | 2.22 | 40% | +841.4 |
| 2 | 40 | 60 | 73.80 | +1,970.5 | 1.1623 | 1.67 | 20% | +414.3 |
| 3 | 50 | 60 | 69.60 | +1,594.7 | 1.1204 | 1.16 | 33.3% | +486.6 |
| 4 | 5 | 100 | 52.00 | +1,076.5 | 1.0957 | 0.96 | 0% | +18.0 |
最も評価が高かったのは、短期SMA45・長期SMA60の組み合わせです。
短期SMA40・45・50と長期SMA60の組み合わせがすべて候補に残っており、短期SMA40~50・長期SMA60付近に好成績が集中しています。
特に短期SMA45・長期SMA60は、利益・PF・最大DD・直近6か月の成績のバランスが良く、今回の有力候補です。
SHORT
GBPJPYのSHORTでは、正式な足切り条件を満たす設定はありませんでした。
全期間では小幅にプラスとなった設定もありましたが、PFなどの足切り条件を満たさなかったため候補から除外しています。
EURUSDの検証結果
LONG
EURUSDのLONGでは、正式な足切り条件を通過した設定はありませんでした。
全期間だけを見ると利益が出ていた設定はありましたが、直近6か月の成績まで確認すると候補が残りませんでした。
つまり、過去の全期間成績だけでは良く見えても、最近の相場では機能していない設定があったということです。
全期間の合計pipsだけで設定を選ばないことの重要性が分かる結果となりました。
SHORT
EURUSDのSHORTでも、正式な候補はありませんでした。
今回のMAクロス条件では、EURUSDはLONG・SHORTともに有効な設定を選出できない結果となりました。
AUDUSDの検証結果
LONG
AUDUSDのLONGでは、4設定が足切り条件を通過しました。
| 順位 | 短期SMA | 長期SMA | 点数 | 合計pips | PF | 利益/DD | 周辺安定率 | 直近6か月の合計pips |
|---|---|---|---|---|---|---|---|---|
| 1 | 25 | 60 | 57.30 | +267.1 | 1.0626 | 0.51 | 40% | +56.3 |
| 2 | 50 | 60 | 51.60 | +235.2 | 1.0513 | 0.50 | 0% | +182.0 |
| 3 | 20 | 75 | 49.38 | +302.9 | 1.0796 | 0.47 | 12.5% | +156.3 |
| 4 | 30 | 60 | 44.90 | +219.7 | 1.0541 | 0.39 | 20% | +60.3 |
最も評価が高かったのは、短期SMA25・長期SMA60の組み合わせです。
ただし、4設定ともPFは1.05~1.08程度で、利益/DDや平均pipsも低めです。
形式上は候補として残っていますが、スプレッドやスリッページなどの取引コストを考慮すると、優位性がなくなる可能性があります。
そのため、AUDUSDのLONGは候補はあるものの、実運用では慎重に評価したい結果です。
SHORT
AUDUSDのSHORTでは、正式な足切り条件を満たす設定はありませんでした。
全期間では小幅に利益が出た設定もありましたが、PFなどの正式基準を満たさなかったため、有効候補とは判断しませんでした。
移動平均線の検証結果を考察

今回の検証では、5通貨すべてで同じSMA設定が有効になるわけではなく、通貨や売買方向によって成績に大きな差が出ることが分かりました。
特に目立ったのは、LONGの方がSHORTより候補が多かった点です。
USDJPYではLONG・SHORTの両方で有効候補が見つかりましたが、EURJPY・GBPJPY・AUDUSDではLONGのみ候補が残り、EURUSDではLONG・SHORTとも正式な条件を満たす設定がありませんでした。
また、LONGでは長期SMA60付近が好成績となるケースが複数確認できました。
- EURJPY:短期SMA35~45・長期SMA60
- GBPJPY:短期SMA40~50・長期SMA60
- AUDUSD:短期SMA25~30・長期SMA60など
特にGBPJPYでは、短期SMA40・45・50と長期SMA60の組み合わせが複数候補に残っています。
このように、1つの設定だけが突出するよりも、近い期間設定でも好成績が続いている範囲の方が信頼しやすいと考えられます。
一方、全期間の合計pipsだけでは判断できないケースもありました。
EURUSD LONGでは全期間で利益が出ていた設定がありましたが、直近6か月の成績まで確認すると、正式な候補は0となりました。
そのため、移動平均線の設定を選ぶ際は、過去の合計利益だけではなく、PF・最大DD・周辺設定の安定性・直近の成績まで確認することが重要です。
今回の結果から、すべての通貨に共通する「最適なSMA期間」があるとは言えません。
ただし、USDJPYやGBPJPYのLONGのように複数の設定で安定した成績が確認できるケースもあり、通貨と売買方向を分けて検証することで、有力な期間設定を絞り込めることが分かりました。
移動平均線をFXで使う際の注意点

今回の検証結果を実際のトレードへ活用する際は、以下の点に注意が必要です。
- 最適な期間は通貨や売買方向によって異なる
今回の検証でも、同じSMA設定でも通貨やLONG・SHORTによって成績に大きな差がありました。 - 過去に好成績でも将来の利益は保証されない
全期間では利益が出ていても、直近6か月では成績が悪化した設定もありました。 - 1つだけ突出した設定には注意する
特定の期間だけが好成績の場合は、偶然その設定だけが良かった可能性があります。近いSMA設定でも成績が維持されているか確認することが重要です。 - 実際の取引では成績が悪化する可能性がある
今回はスプレッド・スリッページ・手数料・スワップを考慮していません。特に平均pipsが小さい設定は、実取引では利益が残らない可能性があります。
今回の結果は「この期間を使えば必ず勝てる」というものではなく、SMAクロスを使った場合に比較的成績が良かった期間設定を確認したものです。
まとめ

今回は、USDJPY・EURJPY・GBPJPY・EURUSD・AUDUSDの5通貨を対象に、短期SMA10種類×長期SMA10種類の100通りをLONG・SHORTそれぞれで検証しました。
その結果、すべての通貨・方向に共通する「最適なSMA期間」はありませんでした。
一方で、USDJPYやGBPJPYのLONGでは複数の設定が足切り条件を通過し、比較的安定した成績が確認できました。
特に、
- USDJPY LONG:短期SMA35・長期SMA100
- GBPJPY LONG:短期SMA45・長期SMA60
- EURJPY LONG:短期SMA45・長期SMA60
などが有力候補となっています。
反対に、EURJPY・GBPJPY・AUDUSDのSHORTや、EURUSDのLONG・SHORTでは正式な候補を選出できませんでした。
今回の検証から、移動平均線の期間設定は合計pipsだけで決めるのではなく、PF・最大DD・周辺設定の安定性・直近の成績まで含めて評価することが重要だと分かりました。
移動平均線を使う際は、通貨やLONG・SHORTごとに検証し、自分の取引条件に合った期間を選ぶようにしましょう。
今後は、TP・SLの設定や上位足の方向を考慮した条件も追加し、今回のSMAクロス戦略から成績がどのように変わるのか検証していく予定です。
