本記事では、USD/JPY(ドル円)の東京時間で機能しやすい「レンジブレイク」戦略を、初心者でも手順通りに再現できるように設計して解説します。使うのは時間帯フィルタとATRによるボラティリティ・フィルタの2つだけです。環境はTradingViewの無料プランで始められます。エントリーとイグジットの明確なルール、ポジションサイズ計算、バックテストのやり方、検証パラメータ、失敗パターンと対策、実運用チェックリストまで、一切の曖昧さが残らないよう具体的に落とし込みます。
戦略の狙いと全体像
東京午前はロンドン勢参入前でレンジを形成しやすく、特に08:00〜09:30(JST)の時間帯にその日の初動レンジが作られることが多いです。本戦略は、この時間帯にできた「基準レンジ」を上抜け/下抜けした方向に素直に追随します。ただし、毎日がトレンドではありません。そこでATR(Average True Range)で最小ボラティリティを要求し、動かない日は参加しない判断を自動化します。
使用ツール
- チャート:TradingView(FXのドル円、5分足)
- インジケータ:ATR(期間14、5分足)
- バックテスト:Pine Script v5(戦略スクリプトを提供)
具体的な売買ルール
対象・時間足
通貨ペアはUSD/JPY、時間足は5分足です。初心者はまず5分足で検証してください。慣れてきたら1分足や15分足に展開できます。
基準レンジ(ボックス)の定義
JST 08:00〜09:30の高値・安値を基準レンジとします。以降、その日の取引ではこのレンジの上限・下限を基準線として参照します。
エントリー条件
- 時間帯フィルタ:JST 08:15〜11:15に限って新規エントリーを許可します。
- ATRフィルタ:5分足ATR(14)が0.04円(4銭)以上のときだけ検討します(パラメータ化可能)。
- 上方向:基準レンジ上限 + 0.02円(2銭)を5分足の終値で明確に上回ったら成行でロング。
- 下方向:基準レンジ下限 – 0.02円(2銭)を5分足の終値で明確に下回ったら成行でショート。
- 同時保有は1ポジションのみ。先に成立した方向を優先します。
イグジット(損切り・利確)
- 初期ストップ:エントリー方向と反対側の基準レンジ端に0.02円のバッファを足した位置。
- 分割利確:0.5Rで数量の50%を利確。
- 最終利確:1.2Rで残りを全決済。以降伸ばしたい場合はトレーリングストップに切り替え可。
- デイリーストップ:一日あたり-2Rに達したら新規エントリーを停止。
ポジションサイズ(資金管理)
推奨は「口座残高の1%を一回の取引でリスクにさらす(1%ルール)」。ストップまでの距離(円)と1pipsあたりの価値から数量を算出します。
リスク額(円)= 口座残高 × 1%
数量(通貨) = リスク額 ÷ ストップ距離(円) ÷ 1通貨あたりの価格変動価値
例:口座残高100万円、ストップ距離が0.15円(15銭)のとき、1%=1万円をリスクに取るなら、為替レートの価値換算を考慮して数量を計算します(多くの国内業者は通貨単位が1,000または10,000単位なので、最も近い数量に丸めます)。
コストとスリッページの前提
バックテストでは平均スプレッド0.3銭〜0.5銭、スリッページ0.1銭程度を仮設定してください。スプレッドが広がる指標前は約定質が悪化するので経済指標の直前・直後は新規を見送る運用が無難です。
TradingViewでのバックテスト手順
- USD/JPYの5分足チャートを開きます。
- タイムゾーンをAsia/Tokyoに設定します。
- Pine Editorを開き、以下の戦略コードを貼り付けて「チャートに追加」。
- テスト期間を過去数年に設定し、パラメータを変更して感度を調整します。
- 約定ルールが想定どおり機能しているか、トレードリスト(履歴)を1件ずつ目視確認して検品します。
戦略コード(Pine Script v5)
以下は解説用のベース実装です。すべての数値は入力で変更できるようにしてあります。初心者の方はまずデフォルトのまま動かし、挙動を把握してから微調整してください。
//@version=5
strategy("Tokyo Range Breakout with ATR Filter (USDJPY, 5m)", overlay=true, initial_capital=1000000, currency=currency.JPY, commission_type=strategy.commission.cash_per_order, commission_value=0, slippage=1)
// ===== Inputs =====
useTokyoTZ = input.bool(true, "Use Asia/Tokyo Timezone")
boxStart = input.session("0800-0930", "Box Session (JST)")
tradeSess = input.session("0815-1115", "Entry Session (JST)")
atrLen = input.int(14, "ATR Length", minval=1)
atrMin = input.float(0.04, "ATR Min (JPY)", step=0.005)
bufBreak = input.float(0.02, "Break Buffer (JPY)", step=0.005)
bufStop = input.float(0.02, "Stop Buffer (JPY)", step=0.005)
riskR = input.float(1.0, "Risk (R) = 1", step=0.1)
tp1R = input.float(0.5, "TP1 (R)", step=0.1)
tp2R = input.float(1.2, "TP2 (R)", step=0.1)
dailyMaxR = input.float(2.0, "Daily Stop (R)", step=0.5)
// ===== Time filters =====
inBox = not na(time(timeframe.period, boxStart, useTokyoTZ ? "Asia/Tokyo" : na))
inTrade = not na(time(timeframe.period, tradeSess, useTokyoTZ ? "Asia/Tokyo" : na))
// New day detection (Tokyo)
var int prevDay = na
curDay = dayofmonth(time(useTokyoTZ ? "Asia/Tokyo" : timeframe.period))
isNewDay = na(prevDay) or curDay != prevDay
if isNewDay
prevDay := curDay
// ===== Build Box High/Low =====
var float boxHigh = na
var float boxLow = na
var bool boxLocked = false
if isNewDay
boxHigh := na
boxLow := na
boxLocked := false
if inBox
boxHigh := na(boxHigh) ? high : math.max(boxHigh, high)
boxLow := na(boxLow) ? low : math.min(boxLow, low)
if not inBox and not boxLocked and not na(boxHigh) and not na(boxLow)
boxLocked := true
plot(boxHigh, "Box High", color=color.new(color.green, 0), linewidth=1, style=plot.style_linebr)
plot(boxLow, "Box Low", color=color.new(color.red, 0), linewidth=1, style=plot.style_linebr)
// ===== ATR Filter =====
atrV = ta.atr(atrLen)
atrOK = atrV >= atrMin
// ===== Breakouts =====
longBreak = boxLocked and inTrade and atrOK and close > boxHigh + bufBreak
shortBreak = boxLocked and inTrade and atrOK and close < boxLow - bufBreak
// ===== Position sizing by fixed yen risk per trade (1% of equity) =====
riskPct = 0.01
riskJPY = strategy.equity * riskPct
// Compute stop distance (JPY)
longStop = boxLow - bufStop
shortStop = boxHigh + bufStop
longRisk = close - longStop
shortRisk = shortStop - close
// Size (units) = riskJPY / risk per unit
longQty = longRisk > 0 ? math.floor(riskJPY / longRisk) : 0
shortQty = shortRisk > 0 ? math.floor(riskJPY / shortRisk) : 0
// ===== Daily R tracking =====
var float todayR = 0.0
if isNewDay
todayR := 0.0
canTrade = todayR < dailyMaxR
// ===== Entries =====
if canTrade and longBreak and strategy.position_size == 0
strategy.entry("L", strategy.long, qty=longQty)
strategy.exit("L-Stop/TP", "L", stop=longStop, limit=na)
if canTrade and shortBreak and strategy.position_size == 0
strategy.entry("S", strategy.short, qty=shortQty)
strategy.exit("S-Stop/TP", "S", stop=shortStop, limit=na)
// ===== Partial take-profits using manual management =====
if strategy.position_size != 0
avgPrice = strategy.position_avg_price
rJPY = na
if strategy.position_size > 0
rJPY := (avgPrice - longStop)
tp1 = avgPrice + tp1R * rJPY
tp2 = avgPrice + tp2R * rJPY
if high >= tp1
strategy.close("L", qty_percent=50)
if high >= tp2
strategy.close("L")
else
rJPY := (shortStop - avgPrice)
tp1 = avgPrice - tp1R * rJPY
tp2 = avgPrice - tp2R * rJPY
if low <= tp1
strategy.close("S", qty_percent=50)
if low <= tp2
strategy.close("S")
// ===== Update daily R after flat =====
if strategy.closedtrades > 0
last = strategy.closedtrades - 1
pl = strategy.closedtrades.profit(last)
// Convert profit to R using entry-time stop distance
// Approximate R: profitJPY / riskJPY
todayR += pl / riskJPY
コードの読み解きとカスタマイズ要点
- boxStart / tradeSess:東京の基準レンジとエントリー許可時間をJSTで指定しています。マーケット状況に応じて微調整してください。
- atrMin:最小ボラティリティの閾値です。0.03〜0.05円の範囲で感度を調整すると傾向が掴みやすいです。
- bufBreak / bufStop:ブレイク判定と損切りのバッファです。広げるほどダマシは減る反面、見送りが増えます。
- dailyMaxR:一日の損失上限(R)です。メンタル崩壊を防ぐための安全弁です。
バックテスト設計(初心者の落とし穴を避ける)
期間の取り方
直近3年程度を推奨します。短すぎる期間は偶然性が強く、長すぎると相場構造の変化で意味が薄れる可能性があります。最初は「3年→直近1年→直近3ヶ月」の順で感度を確認すると、生きた戦略か、偶然の産物かを見分けやすいです。
手数料・スリッページの設定
現実に近い数字を入れます。スプレッドは0.3〜0.5銭、スリッページ0.1銭を標準とし、荒れた日は倍にして感度をテストします。
過剰最適化を避ける
パラメータを細かく最適化しすぎると、過去専用の美しい曲線ができあがります。ウォークフォワード(過去の一部で最適化→未使用期間で検証)や、モンテカルロ(約定順のシャッフル)で頑健性を確かめます。
相場局面別の特徴と対処
低ボラ横ばい
ATRが閾値未満なら参加しないのが正解です。ブレイクしても伸びず、フェイクの確率が高まります。
イベントドリブンの急変
指標や要人発言の直後は乱高下しやすく、ビッド・アスクが飛びやすいです。一定時間クールダウンを入れてから再開する運用が安定します。
日銀関係の見通し回転
政策観測のヘッドラインで東京時間にトレンドが出ることがあります。こうした日は損切りが浅すぎるとノイズに狩られやすいので、bufStopの拡大で対応します。
よくある失敗と改善手順
- 連敗後にサイズを上げる:逆効果になりがちです。サイズ一定、または勝率が戻るまで取引停止が無難です。
- ブレイク直前のフライング:ルールを守らず先走ると、平均損益比が悪化します。確定足での判定を徹底します。
- 毎日同じ気分で臨まない:体調や集中力が低い日は見送るのも戦略です。チェックリストを儀式化してください。
パラメータ最適化のロードマップ
- ATR閾値(0.03, 0.035, 0.04, 0.045, 0.05)でグリッドテスト。
- ブレイク・バッファ(0.01, 0.02, 0.03)を組み合わせ、トレード回数と平均Rのバランスを見る。
- 分割利確の比率(50/50→60/40)を微調整し、ドローダウンの浅さと月次の安定性を重視。
- デイリーストップ(1.5R, 2R, 2.5R)でメンタル負荷を最小化。
実運用チェックリスト
- 睡眠・集中力:取引前に3段階で自己評価し、最低基準を満たさない日は潔く休む。
- 経済指標:該当時間の新規を停止するルールを徹底。
- 通信・約定環境:回線・VPS・端末の冗長化。スマホ予備も用意。
- リスク上限:日次-2R、週次-6R、月次-12Rを超えたら休止。
- 週次レビュー:勝率・平均R・損益曲線の傾き、ミスの有無を点検。
応用レシピ(発展)
EMAバイアス追加
5分足のEMA50の上なら上方向のみ、下なら下方向のみを許可する「順張りフィルタ」を追加します。
ロンドン前の再ブレイク戦略
11:15以降は新規を止め、14:00〜16:00のレンジを定義してロンドンオープンのブレイクに備える発展版も有効です。
週次フィルタ
月曜日はパフォーマンスがブレやすい場合があります。曜日別の統計を取り、曜日停止をルールに組み込みます。
ケーススタディ(サンプルシナリオ)
08:00〜09:30のレンジが0.28円で形成。10:05に上限+0.02円で確定上抜け、ATR=0.045円のため条件クリア。ストップは下限-0.02円。0.5Rで半分を利確後、1.2Rで残りを決済。日次で+0.85Rを確保し、その日は終了。
よくある質問
- どの業者/スプレッドを想定すれば良いですか?
- テスト時はスプレッド0.3〜0.5銭、スリッページ0.1銭を標準に。ご自身の実口座条件に合わせて調整してください。
- 1分足はダメですか?
- 可能ですが、ノイズでフェイクが増えます。まず5分足で作法を固めることをおすすめします。
- 損切りが続いて辛いです。
- デイリーストップ(-2R)で機械的に停止し、週次で原因分析を行います。サイズを上げて取り返そうとしないのが鉄則です。
まとめ
東京午前の特性を素直に利用し、参加する日と見送る日をATRで切り分け、レンジブレイクに絞って追随する。ルールは単純でも、資金管理・停止ルール・検証手順を組み合わせることで、初心者でも安定運用に近づけます。まずは小さなサイズで、100回の検証と運用記録から始めてください。
コメント