本記事は一般的な情報提供を目的としており、特定の金融商品の勧誘や将来の利益を保証するものではありません。ご自身のリスク許容度に応じて、自己責任でご判断ください。
なぜ「ATR×時間帯」のブレイクアウトなのか
ブレイクアウトは、価格が一定のレンジを抜けて新しいトレンド方向へ動き出す局面を捉える戦略です。USD/JPYは、東京時間(アジア)にレンジを形成し、ロンドン時間~NY時間にかけてボラティリティが拡大しやすい特徴があります。ATRは直近の実質的な値動き幅を数値化するため、当日の「期待変動幅」に応じてブレイクアウト閾値(エントリートリガー)や損切り・利食いの距離を自動調整できます。相場が静かな日は小さく、荒い日は大きく構える――この発想は、初心者の方が最初に身につけるべき「ボラティリティ連動の資金管理」に直結します。
時間帯フィルターは、騙しの多い薄商いの時間帯を避け、動きやすい時間だけ戦うための実務的な工夫です。具体的には、東京午前に当日の基準レンジを測り、ロンドン入り前後でのブレイクを狙う設計が効果的です。これにより、シグナル品質の向上とトレード回数の適正化を同時に狙います。
まず押さえるFXの基礎:用語とリスク
初心者の方がつまずきやすいポイントを簡潔に整理します。
スプレッドとコスト
スプレッドは売値と買値の差です。ブレイクアウトのように短期で仕掛ける戦略では、スプレッドが実質的なハンデになります。USD/JPYは主要通貨ペアの中でもスプレッドが狭い傾向にあり、初心者に適しています。
レバレッジとロスカット
レバレッジは効率よく資金を使える一方、損失拡大の速度も増大します。ロスカットは証拠金維持率が一定以下になったときの強制決済です。戦略は常に「事前の損切り幅を明確に」定義し、過度なレバレッジを避けます。
ボラティリティとATR
ATRは一定期間の平均的な実質値動き幅です。ATRが大きい=相場が荒い、小さい=静かな相場、と読み替えられます。本戦略はATRでブレイク閾値や損切り幅、トレーリング幅を決めるため、相場の状態に応じて柔軟に振る舞えます。
戦略のエッジ(優位性)の直感
USD/JPYは東京時間に方向感が乏しい日があり、欧州勢参入でトレンドの初動が出ることがあります。東京午前の高安を基準に、ATRで厚みを持たせたブレイク水準を設定し、ロンドン入りでのトレンド初動に同調する発想です。騙しを減らすための工夫として、一度にフルサイズで入らず段階的に追撃する、逆側のブレイクでカットする、含み益が一定に達したら建値に引き上げるなどの機械的ルールを組み込みます。
売買ルール(完全版)
1. 取引対象と時間足
対象はUSD/JPY、M15(15分足)を推奨します。短すぎるとノイズが増え、長すぎると機会損失が増えます。
2. 基準レンジの測定
当日00:00~11:00(東京午前・日本時間、ブローカー時間差は調整)における高値Hと安値Lを取得します。このレンジ幅をR = H - L
とし、同期間のATR値(例:ATR(14))を算出します。
3. ブレイクアウト水準
ロングエントリーはH + k × ATR
、ショートエントリーはL - k × ATR
に買い/売りストップの指値を置きます。kの初期値は1.0~1.5が目安です。日によってノイズの多寡が異なるため、ATR連動にすることで適応性を持たせます。
4. 損切りとポジションサイズ
初期ストップはエントリー価格からs × ATR
(例:1.0~1.5)に置きます。口座残高に対する1回の許容リスク(%)を0.3~0.8%に固定し、ロットは逆算で決めます。これにより、どの相場でも損失額が一定割合に収まります。
5. 利食いとトレーリング
利食いは固定幅t × ATR
(例:2.0~3.0)を初期ターゲットに設定し、含み益が1.0×ATR
に到達したら建値(または+0.2×ATR)へストップを引き上げます。以降はTrailATRMult × ATR
のトレーリングストップで追随します。
6. 時間帯フィルター
新規エントリーはロンドン序盤~NY前半に限定し、日本時間でおおむね16:00~24:00を目安とします。これにより薄商いでの誤作動を抑えます。
7. ポジション管理
同方向のポジションは最大1~2本まで。逆方向シグナル出現時は全決済のうえでドテンは行わない(初学者は同時保有を避ける)。
8. 取引停止条件
指標発表直前直後は新規を停止する運用が無難です(裁量で回避)。また、連敗が規定回数(例:5回)に達したら当日停止とします。
資金管理:ATR連動ロットの具体計算
例:口座残高100万円、許容リスク0.5%、USD/JPY、ATR=0.20円(=20pips)、初期ストップ距離=1.2×ATR=24pipsの場合、1回の許容損失は5,000円です。USD/JPYの1万通貨で1pip=約100円なので、24pipsの損失は2,400円/万通貨。したがって理論上は約2万通貨まで保有可能です(実運用ではスリッページ等を考慮し1.8万通貨など控えめに丸めると安定します)。
取引シナリオ例(文章ベース)
東京午前にH=158.40、L=157.90、ATR=0.18円。k=1.2なら、ロングトリガーは158.40+0.216=158.616、ショートは157.90-0.216=157.684です。16時以降に上抜けしロング成立、初期SLは1.2×ATR=0.216円下、TPは2.5×ATR=0.45円上。含み益がATR分進んだらストップを建値上へ移動し、以後はTrail=1.3×ATRで追随します。ストップが引き上がっているので、反転で利確または小損失に収まりやすくなります。
実行の手順(ブローカー設定から発注まで)
- USD/JPYのM15チャートにATR(14)を表示します。
- 当日00:00~11:00の高安を水平線で印付けします。
- k、s、t、TrailATRMult等のパラメータを決めます。
- ロンドン入り前に買い/売りストップの注文をセットします(またはEA任せ)。
- 発注後はルール通りにストップと利食いを管理し、裁量の介入は極力排します。
MQL4 EA(完全自動売買、初心者向けの安全設計)
以下は、上記ルールのコアを実装した教育用EAです。実弾の前に必ずデモ口座で動作確認とバックテストを行ってください。パラメータの初期値は保守的に設定し、取引回数・損益曲線・ドローダウンを確認しながら調整します。
//+------------------------------------------------------------------+
//| USDJPY_ATR_Breakout_SessionEA.mq4 |
//| 教育用サンプル:ATR×時間帯ブレイクアウト(M15推奨) |
//+------------------------------------------------------------------+
#property strict
input string InpSymbol = "USDJPY";
input ENUM_TIMEFRAMES InpTF = PERIOD_M15;
input int ATR_Period = 14;
input double K_Mult = 1.2; // ブレイクアウト閾値(k×ATR)
input double SL_ATR_Mult = 1.2; // 初期ストップ(s×ATR)
input double TP_ATR_Mult = 2.5; // 初期利食い(t×ATR)
input double Trail_ATR_Mult = 1.3; // トレーリング(Trail×ATR)
input double Risk_Percent = 0.5; // 1トレード許容損失(%)
input int StartHour_JST = 16; // 新規許可開始(JST)
input int EndHour_JST = 24; // 新規許可終了(JST)
input int TokyoStart_JST = 0; // 東京午前開始(JST)
input int TokyoEnd_JST = 11; // 東京午前終了(JST)
input int Magic = 20250912;
input int Slippage = 3;
input bool OnePositionPerDir = true;
input bool CloseOnReverseBreak = true;
double pipValuePerLot()
{
// USDJPYの1pip=0.01(ブローカーで異なる場合あり)
// 1ロット=100,000通貨を想定
return MarketInfo(InpSymbol, MODE_TICKVALUE);
}
double getATR()
{
int tf = (int)InpTF;
return iATR(InpSymbol, tf, ATR_Period, 1);
}
bool jstInRange(int startH, int endH)
{
datetime t = TimeCurrent();
// サーバー時間→JSTはブローカーにより異なるため、ここでは簡略化のためにサーバー時間をそのまま使用。
// 実運用ではサーバー時差をパラメータ化し、JSTに補正してください。
int hour = TimeHour(t);
if(startH <= endH) return (hour >= startH && hour < endH);
// 24時跨ぎ
return (hour >= startH || hour < endH);
}
void getTokyoRange(double &H, double &L)
{
H = -DBL_MAX;
L = DBL_MAX;
int tf = (int)InpTF;
datetime now = TimeCurrent();
datetime dayStart = iTime(InpSymbol, PERIOD_D1, 0); // 当日0時(サーバー)
int bars = iBars(InpSymbol, tf);
for(int i=1; i= TokyoStart_JST && h < TokyoEnd_JST)
{
double hi = iHigh(InpSymbol, tf, i);
double lo = iLow(InpSymbol, tf, i);
if(hi > H) H = hi;
if(lo < L) L = lo;
}
}
}
bool hasOpenPosition(int dir)
{
for(int i=0; i<OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol()==InpSymbol && OrderMagicNumber()==Magic)
{
if((dir>0 && OrderType()==OP_BUY) || (dir<0 && OrderType()==OP_SELL))
return true;
}
}
}
return false;
}
int countPositions()
{
int c=0;
for(int i=0;i<OrdersTotal();i++)
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
if(OrderSymbol()==InpSymbol && OrderMagicNumber()==Magic) c++;
return c;
}
void trailStops(double atr)
{
for(int i=0; i<OrdersTotal(); i++)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if(OrderSymbol()!=InpSymbol || OrderMagicNumber()!=Magic) continue;
double trail = Trail_ATR_Mult * atr;
if(OrderType()==OP_BUY)
{
double newSL = MathMax(OrderStopLoss(), Bid - trail);
// 建値引き上げ(含み益がATR以上)
if((Bid - OrderOpenPrice()) >= atr) newSL = MathMax(newSL, OrderOpenPrice()+0.0002);
if(newSL > OrderStopLoss()+Point*2)
OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE);
}
else if(OrderType()==OP_SELL)
{
double newSL = MathMin(OrderStopLoss(), Ask + trail);
if((OrderOpenPrice() - Ask) >= atr) newSL = MathMin(newSL, OrderOpenPrice()-0.0002);
if(newSL < OrderStopLoss()-Point*2)
OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE);
}
}
}
void closeOnReverse(double H, double L, double atr)
{
if(!CloseOnReverseBreak) return;
for(int i=0; i<OrdersTotal(); i++)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if(OrderSymbol()!=InpSymbol || OrderMagicNumber()!=Magic) continue;
if(OrderType()==OP_BUY && Bid < (L - K_Mult*atr))
OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, clrNONE);
if(OrderType()==OP_SELL && Ask > (H + K_Mult*atr))
OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, clrNONE);
}
}
double calcLots(double atr, double sl_mult)
{
if(atr<=0.0) return 0.0;
double accEquity = AccountEquity();
double riskMoney = accEquity * (Risk_Percent/100.0);
// USDJPYでの1pip換算(Pointに依存)
double point = MarketInfo(InpSymbol, MODE_POINT);
double pip = (point==0.001 || point==0.0001) ? point*10 : 0.01; // 簡易
double sl_pips = (sl_mult * atr) / pip;
if(sl_pips <= 0.0) return 0.0;
double tickValue = MarketInfo(InpSymbol, MODE_TICKVALUE);
double tickSize = MarketInfo(InpSymbol, MODE_TICKSIZE);
double pipValue = (pip/tickSize) * tickValue;
double lots = riskMoney / (sl_pips * pipValue);
// ブローカーの最小・刻みに丸め
double minLot = MarketInfo(InpSymbol, MODE_MINLOT);
double lotStep= MarketInfo(InpSymbol, MODE_LOTSTEP);
double maxLot = MarketInfo(InpSymbol, MODE_MAXLOT);
lots = MathFloor(lots/lotStep)*lotStep;
if(lots < minLot) lots = minLot;
if(lots > maxLot) lots = maxLot;
return NormalizeDouble(lots, 2);
}
int OnInit(){ return(INIT_SUCCEEDED); }
int OnDeinit(){ return(0); }
int OnTick()
{
if(Symbol()!=InpSymbol) return(0);
if(Period()!=(int)InpTF) return(0);
double atr = getATR();
if(atr<=0.0) return(0);
double H, L;
getTokyoRange(H, L);
if(H==-DBL_MAX || L==DBL_MAX) return(0);
trailStops(atr);
closeOnReverse(H, L, atr);
// 新規は時間帯で制限
if(!jstInRange(StartHour_JST, EndHour_JST)) return(0);
// すでにポジションが多すぎる場合は新規不可
if(OnePositionPerDir && (hasOpenPosition(+1) || hasOpenPosition(-1))) return(0);
if(countPositions()>=2) return(0);
double buyTrig = H + K_Mult*atr;
double sellTrig = L - K_Mult*atr;
// ブレイク判定(成行で簡略化:本来はBuyStop/SellStopが無難)
if(Ask > buyTrig && !hasOpenPosition(+1))
{
double sl = Bid - SL_ATR_Mult*atr;
double tp = Ask + TP_ATR_Mult*atr;
double lots = calcLots(atr, SL_ATR_Mult);
if(lots>0.0)
{
int tk = OrderSend(InpSymbol, OP_BUY, lots, Ask, Slippage, sl, tp, "ATR Breakout Buy", Magic, 0, clrBlue);
}
}
if(Bid < sellTrig && !hasOpenPosition(-1))
{
double sl = Ask + SL_ATR_Mult*atr;
double tp = Bid - TP_ATR_Mult*atr;
double lots = calcLots(atr, SL_ATR_Mult);
if(lots>0.0)
{
int tk = OrderSend(InpSymbol, OP_SELL, lots, Bid, Slippage, sl, tp, "ATR Breakout Sell", Magic, 0, clrRed);
}
}
return(0);
}
//+------------------------------------------------------------------+
注意:ブローカーのサーバー時差とJSTの扱いは簡略化しています。実運用ではサーバー時間→JST補正をパラメータで調整してください。また、スリッページやブローカー仕様に応じて発注が拒否される可能性があるため、成行と指値の併用や再試行ロジックの拡張が有効です。
バックテスト手順(MT4)
- ブローカーのヒストリカルデータを最新までダウンロードします(M1まで取得後にM15へ変換すると精度向上)。
- ストラテジーテスターで通貨ペアUSDJPY、期間は最低でも3~5年を選びます。
- 初期証拠金は十分な額(例:100万円)に設定し、スプレッドは固定値ではなくブローカー近似値を使用します。
- パラメータは初期値でまず全体像を把握し、その後は1軸ずつ変動させて感応度を確認します。
- 勝率・PF・最大ドローダウン・リカバリーファクター・月別の損益分布を確認します。
最適化の落とし穴と回避策
最適化は過去に過剰適合しやすいため、以下を守ると堅実です。
- パラメータは少数に保ち、意味のある範囲だけを探索します。
- 期間を分割してウォークフォワード検証を行います。
- 相関の高いパラメータを同時にチューニングしないでください。
- 手数料・スリッページは保守的に見積もります。
リスク管理と想定外シナリオ
市場急変やスプレッド拡大、ギャップ、通信断は必ず起こり得ます。EA任せでも、以下の安全網を準備してください。
- ロットは常にリスク%から逆算し、連敗時は逓減させます。
- 重要指標や要人発言前は新規停止・既存はタイトに管理します。
- VPS等で安定稼働させ、回線断の影響を減らします。
- 週末持ち越しは基本避け、持つ場合はロット縮小とヘッジを検討します。
よくある質問
Q1. いつからでも始められますか?
はい、デモ環境での動作確認から始めてください。少額・低リスクでの実弾移行を推奨します。
Q2. 他通貨でも使えますか?
原理的には可能ですが、スプレッド・ボラティリティ・時間帯特性が異なるためUSD/JPYでの慣熟後に拡張してください。
Q3. 勝率が低くても大丈夫ですか?
ブレイクアウトは勝率が中庸でも、損小利大で期待値を積み上げる設計です。損切り徹底とトレーリングが鍵です。
日次チェックリスト(印刷推奨)
- 当日の東京午前高安線を引いたか
- ATR値を確認したか(急変時は再計算)
- k/s/t/Trailのパラメータを確認したか
- 重要指標カレンダーを確認したか
- リスク%とロットが合致しているか
- 連敗時の逓減ルールを適用したか
用語ミニ解説(初心者向け)
レバレッジ:預けた証拠金より大きな金額を取引できる仕組みです。利益も損失も拡大します。
スプレッド:売値と買値の差です。取引のたびに支払うコストの一種です。
ATR:一定期間の平均的な値動き幅です。相場の荒さを数値化します。
トレーリングストップ:含み益に追随してストップを自動で引き上げ(下げ)る仕組みです。
コメント