疑似オーダーフロー・スキャルピング:CVD×スプレッド回帰×時間帯で狙う初心者向け実践ガイド

FX

疑似オーダーフロー・スキャルピング:CVD×スプレッド回帰×時間帯で狙う初心者向け実践ガイド

本稿は、FXのようにレベル2板(ビッド・アスクの厚み)が見えにくい環境でも、
ローソク足の値動きティック出来高から疑似オーダーフロー(CVD: Cumulative Volume Delta)を推定し、
さらにスプレッドの一時的拡大→正常化の回帰時間帯の流動性特性を重ねて狙う、初心者向けの現実的なスキャルピング手法を解説します。
一般論ではなく、売買ルール検証フローリスク管理EAコード(MQL4)まで一本化して提示します。

1. 戦略コンセプト

多くの初心者は「順張りか逆張りか」で迷います。本戦略は、ミクロ逆張りに分類されます。
狙うのは「短時間での売り買いの偏りが出尽くして、価格が中値(ミッド)へ回帰しやすい瞬間」です。
根拠は次の3点です。

  • 疑似CVDの極端値:直近数本のバーで「売り(または買い)が出過ぎた」痕跡。
  • スプレッドの急拡大→平常化:板が薄い瞬間の成行集中は一過性になりやすい。
  • 時間帯フィルタ:流動性が戻りやすい時間帯(例:ロンドン前後)に限定。

これらを同時に満たすときだけエントリーし、短い滞在時間で素早く撤退します。

2. 疑似CVDとは何か(初心者向け)

本来のオーダーフローデータ(約定価格ごとの買い/売り成立量)がない場合、
バーの方向とティック出来高」から押し引きを推測します。
単純化した式は次の通りです。

疑似Δ(デルタ) = (Close - Open) / Point × sqrt(TickVolume)
CVD = 直近L本の疑似Δの合計

バーが陽線かつ出来高が多ければ「買い優勢」、陰線×出来高なら「売り優勢」とみなします。
CVDが極端なマイナス→反発余地、極端なプラス→反落余地、という読み筋です。
実データではないため完璧ではありませんが、「偏りの行き過ぎ」を検知するには十分です。

3. フルルール(最初の完成版)

通貨:EURUSD/USDJPY。時間足:M1またはM5。スキャル対象。

  1. 時間帯フィルタ:ブローカーサーバ時刻で開始H〜終了Hのみ取引。
    例:開始 07:00、終了 20:00(サーバ時刻)。流動の谷は避けます。
  2. CVD条件:直近L本のCVDが閾値(±T)を超える極端値。
    ・ロング仮説:CVD ≤ -T(売り偏りが出尽くし)
    ・ショート仮説:CVD ≥ +T(買い偏りが出尽くし)
  3. スプレッド回帰:直近数ティックでスプレッドが一時的に拡大→現在は平常比1.2倍以内に戻る。
  4. バンド確認(過度なトレンド回避):ボリンジャーバンド(期間20、2σ)。
    ロングは下バンドの外側クローズ直後は見送り、ショートは上バンド外側直後は見送り。
  5. エントリー:条件一致で成行。
    ・ロング:BidでBuy。
    ・ショート:AskでSell。
  6. 損切り/利確:初期SL=直近スイング±αポイント。TP=RR×SL(RRは1.2〜2.0で調整)。
    トレーリングは不要。滞在時間が延びたら時間切れクローズ(例:5〜10分)を優先。
  7. 同時ポジ制御:通貨ペアごとに1ポジまで。
  8. ニュース回避(任意):重要指標前後±15分は休止。

まずは保守的なパラメータで始め、週次で最小限のチューニングを行います。

4. 推奨初期パラメータ

項目 初期値 意図
L(CVD計算本数) 20 過去20本のミクロ偏りを集約
T(CVD閾値) ±60 過度な偏りのみ対象(通貨で要調整)
SpreadWiden 平常比1.8倍 一時的な板薄/成行集中を検知
SpreadNow 平常比1.2倍以下 回帰が始まったことを確認
RR(利確/損切り比) 1.5 勝率55〜60%を狙う設計
TimeExit 8分 粘らず撤退。回転重視
Lot 口座残高の0.5〜1%リスク 資金保全を最優先

5. 実装の全手順(MT4)

  1. 通貨ペア(EURUSD/USDJPY)を開く。時間足はM1またはM5。
  2. ヒストリーセンターで十分なデータをダウンロード。
  3. 本稿のEA(MQL4)を貼り付け、コンパイル。
  4. 戦略テスターで「毎ティック」モードを選択し、スプレッドは「現在値」か「固定1.5倍平常値」。
  5. 期間は直近3〜12か月から開始。最初はオーバーフィットを避ける。
  6. 最適化は最小限(L、T、RR、TimeExit)だけ触る。1変数ずつ。
  7. フォワード(直近未使用期間)で確認。エクイティの形が崩れたらやり直し。

6. 完全自動売買EA(MQL4)

以下は教育目的のシンプル実装です。ブローカー仕様差・約定品質・スプレッド変動で結果は変わります。

//+------------------------------------------------------------------+
//|  Pseudo Orderflow Scalper (CVD x Spread Revert)                  |
//|  Timeframe: M1/M5, Symbols: EURUSD / USDJPY                      |
//|  Note: Educational sample. Use at your own risk.                 |
//+------------------------------------------------------------------+
#property strict

input double Lots            = 0.10;
input int    Magic           = 240906;
input int    CVD_Len         = 20;      // L
input double CVD_Thr         = 60;      // T (points-weighted)
input double RR              = 1.5;     // TP = RR * SL
input int    MaxMinutesHold  = 8;       // TimeExit (minutes)
input int    StartHour       = 7;       // Broker server time
input int    EndHour         = 20;      // Broker server time
input int    Slip            = 3;       // slippage (points)
input int    LookbackSwing   = 5;       // swing window for SL
input double SpreadWideMul   = 1.8;     // SpreadWiden
input double SpreadNowMul    = 1.2;     // SpreadNow

datetime lastBarTime = 0;
double   avgSpread   = 0;
int      spreadSamples = 0;

bool NewBar()
{
   datetime ct = iTime(Symbol(), Period(), 0);
   if(ct != lastBarTime){ lastBarTime = ct; return true; }
   return false;
}

double GetSpreadPoints(){ return (Ask - Bid) / Point; }

double GetAvgSpread()
{
   if(spreadSamples <= 0) return GetSpreadPoints();
   return avgSpread / spreadSamples;
}

void UpdateSpreadAvg()
{
   double sp = GetSpreadPoints();
   avgSpread += sp;
   spreadSamples++;
   if(spreadSamples > 5000){ avgSpread /= 2.0; spreadSamples /= 2; } // prevent overflow
}

// Pseudo delta = (Close-Open)/Point * sqrt(TickVolume)
double BarPseudoDelta(int shift)
{
   double op = iOpen(Symbol(), Period(), shift);
   double cl = iClose(Symbol(), Period(), shift);
   double tv = iVolume(Symbol(), Period(), shift); // tick volume
   return (cl - op) / Point * MathSqrt(MathMax(tv,1));
}

double CalcCVD(int len)
{
   double sum = 0;
   for(int i=1; i<=len; i++) sum += BarPseudoDelta(i);
   return sum;
}

bool TimeFilter()
{
   int h = TimeHour(TimeCurrent());
   if(StartHour <= EndHour) return (h >= StartHour && h < EndHour);
   // overnight case
   return (h >= StartHour || h < EndHour);
}

int CountPositions(int dir)
{
   int c=0;
   for(int i=0;i<OrdersTotal();i++)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(OrderSymbol()!=Symbol()) continue;
      if(OrderMagicNumber()!=Magic) continue;
      if(dir==0 || (dir>0 && OrderType()==OP_BUY) || (dir<0 && OrderType()==OP_SELL)) c++;
   }
   return c;
}

double SwingLowSLPoints()
{
   int w = LookbackSwing;
   double low = High[1]; // init high to ensure replacement
   for(int i=1;i<=w;i++) if(Low[i]<low) low=Low[i];
   double sl = (Bid - low)/Point;
   return MathMax(sl, 5); // safety min
}

double SwingHighSLPoints()
{
   int w = LookbackSwing;
   double high = Low[1];
   for(int i=1;i<=w;i++) if(High[i]>high) high=High[i];
   double sl = (high - Ask)/Point;
   return MathMax(sl, 5);
}

void CloseByTime()
{
   for(int i=0;i<OrdersTotal();i++)
   {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic) continue;
      datetime opent = OrderOpenTime();
      if((TimeCurrent() - opent) >= MaxMinutesHold*60)
      {
         if(OrderType()==OP_BUY)  OrderClose(OrderTicket(), OrderLots(), Bid, Slip, clrNONE);
         if(OrderType()==OP_SELL) OrderClose(OrderTicket(), OrderLots(), Ask, Slip, clrNONE);
      }
   }
}

int OnInit(){ return(INIT_SUCCEEDED); }
void OnDeinit(const int reason){}

void OnTick()
{
   UpdateSpreadAvg();
   CloseByTime();

   if(!TimeFilter()) return;
   if(CountPositions(0)>=1) return;

   // Evaluate on new bar to reduce noise
   if(!NewBar()) return;

   double cvd = CalcCVD(CVD_Len);
   double sp  = GetSpreadPoints();
   double spAvg = GetAvgSpread();

   bool spreadWasWide = (sp >= spAvg * SpreadWideMul);
   bool spreadIsOk    = (sp <= spAvg * SpreadNowMul);

   // Use last bar info for band filter
   double bbMid = iMA(Symbol(), Period(), 20, 0, MODE_SMA, PRICE_CLOSE, 1);
   double bbStd = iStdDev(Symbol(), Period(), 20, 0, MODE_SMA, PRICE_CLOSE, 1);
   double bbUp  = bbMid + 2*bbStd;
   double bbLo  = bbMid - 2*bbStd;
   double prevClose = iClose(Symbol(), Period(), 1);

   // Long setup
   if(cvd <= -CVD_Thr && spreadIsOk)
   {
      if(prevClose > bbLo) // avoid fresh band break
      {
         double slPts = SwingLowSLPoints();
         double tpPts = slPts * RR;
         double sl = Bid - slPts*Point;
         double tp = Bid + tpPts*Point;
         int tk = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slip, sl, tp, "CVD Long", Magic, 0, clrNONE);
      }
   }

   // Short setup
   if(cvd >= CVD_Thr && spreadIsOk)
   {
      if(prevClose < bbUp)
      {
         double slPts = SwingHighSLPoints();
         double tpPts = slPts * RR;
         double sl = Ask + slPts*Point;
         double tp = Ask - tpPts*Point;
         int tk = OrderSend(Symbol(), OP_SELL, Lots, Bid, Slip, sl, tp, "CVD Short", Magic, 0, clrNONE);
      }
   }
}
//+------------------------------------------------------------------+

7. 初心者向けの検証チェックリスト

  • 相場が一方向に走るトレンド局面では、エントリー頻度が落ちる設計になっているか。
  • 平均スプレッドの推定が安定しているか(初期数千ティックは学習期間)。
  • 通貨ごとのCVD閾値Tを適切化したか(USDJPYは狭く、GBP系は広め)。
  • 勝率とRRのバランス:勝率55%・RR1.5でPF>1.2をまず目標。
  • 8分ルールでの時間切れクローズが機能しているか。

8. 具体的なトレード例(イメージ)

東京後場の薄い時間に一時的な売りが重なり、M1でCVDが-85まで沈む。
直後にスプレッドが平常比2.0倍→1.15倍へ縮小。ボリンジャー下沿いから内側へ復帰。
条件一致でロング、SLは直近安値-0.6pips、TPはRR1.5で+0.9pips。
約6分で利確。以後は同方向の再エントリーを避け、回転の質を担保します。

9. リスク管理とよくある失敗

  • オーバートレード:時間帯と同時ポジ制限でコントロールします。
  • ニュース突発:重大指標は休む。EAにニュース回避機能を後付け可。
  • 過剰最適化:パラメータを絞り、外部期間で必ずフォワード確認。
  • スプレッド常時広めのブローカー:本戦略は不利。口座選定は重要。
  • Lot過大:1トレードの損失が口座残高の1%超にならない範囲に。

10. 投資用語の簡易解説

  • ティック出来高:ティック更新回数の近似出来高。実出来高の代替。
  • CVD:買い/売りの優勢を累積した指標。本稿は疑似版。
  • スプレッド:Ask−Bid。拡大は板薄や成行集中のサイン。
  • RR(リスクリワード):利確幅/損切り幅の比率。
  • PF(プロフィットファクター):総利益/総損失。1超で優位性。

11. 国内FX口座の一般的な開設手順(要約)

  1. 金融商品取引業者(第一種)の公式サイトから申込。
  2. 氏名・住所・職業・年収・投資経験などを入力。
  3. 本人確認書類(運転免許証など)とマイナンバー送付。
  4. リスク・重要事項の確認と同意。
  5. 審査通過後、ログイン情報が届き、入金方法を設定。
  6. MT4/MT5の接続情報を設定して動作確認。

スプレッド、約定力、サポート、出金手続きは口座選びの重要比較軸です。

12. 運用オペレーション(デイリー/ウィークリー)

  • デイリー:ログ点検、約定履歴の異常検知、スリッページ監視。
  • ウィークリー:パラメータの微調整(±1段階まで)、損益の偏り要因の洗い出し。
  • マンスリー:ブローカー品質の見直し、通貨ペアの入替検討。

13. まとめ(実務観点)

板が見えなくても、疑似CVD×スプレッド回帰×時間帯を重ねるだけで、
初心者が取り組める再現性の高いスキャル土台は作れます。重要なのは、
小さく素早く・淡々と・再現可能の3点です。EAで機械化し、
過度な裁量と感情を排除することで、学習速度と資金保全の両立を図れます。

本記事では、具体的な売買ルール、検証手順、MQL4コードを提示しました。各自の環境に合わせて微調整し、必ずデモ検証を経てから実運用に移行してください。

コメント

タイトルとURLをコピーしました