ダイナミックマルチペアEAの形成(第5回):スキャルピングとスイングトレードの切替設計
目次
はじめに
市場状況に応じて最適な取引手法を選択することは非常に難しいです。相場が急速に動く場合、スイング戦略は遅すぎると感じられ、変動の激しい時間帯ではスキャルピングの小さなターゲットがすぐにストップアウトしてしまうことがあります。このジレンマにより、トレーダーは短期的に高確率なチャンスを逃すか、または不適切な相場で過剰取引してしまい、利益が不安定になることがあります。さらに、ある資産や時間足で有効なシステムが、他の資産や時間足では機能しない場合もあります。
この課題は、スキャルピングとスイングトレードの両モードを統合したダイナミックマルチペアエキスパートアドバイザー(EA)を開発することで解決できます。トレーダーが市場のボラティリティや構造に応じてモードを手動または自動で切り替えられるようにすることで、EAはエントリーロジック、ストップレベル、取引時間足を動的に調整できるようになります。これにより、短期的な即時利益と長期的な高品質のスイングトレードとのバランスを保ちながら、さまざまな市場条件で安定的に利益を狙うことが可能です。
システムの概要
スキャルピングは、短時間(数秒〜数分)で非常に小さな価格変動を狙う取引手法です。このスタイルでは、トレーダーは1日を通して複数のポジションを開閉し、市場のマイクロフラクチュエーションから利益を狙います。大きな方向性の値動きではなく、小さな値動きを効率的に取るため、精度、高速な注文処理、そして厳格なルール遵守が求められます。スプレッドやスリッページ、手数料が利益に大きく影響するため、注意が必要です。スキャルパーは主に1分足や5分足などの短期足チャートを使用し、移動平均線、ボリュームスパイク、モメンタムオシレーターなどのテクニカル指標を駆使して、エントリーとエグジットのタイミングを高精度で判断します。

一方、スイングトレードは、数時間から数日、場合によっては数週間単位での比較的大きな価格変動を狙う手法です。市場のトレンドや押し目と戻り売り、サポートとレジスタンスの重要レベルに反応して生じる自然な値動き(スイング)を捉えることを重視します。スイングトレーダーは、テクニカル分析、市場構造や、場合によってはファンダメンタルズ分析も組み合わせて高確率のエントリーポイントと有利なリスクリワード設定を判断します。この手法は取引回数が少なく、画面に張り付く必要も低いため、戦略的かつ分析的に市場を観察するトレーダーに適しています。

| 項目 | スキャルピング | スイングトレード |
|---|---|---|
| 取引期間 | 数秒から数分 | 数時間から数日(場合によっては数週間) |
| 取引頻度 | 1日あたり数十回から数百回 | 週1~10回(平均) |
| 目標 | 小さく頻繁な値動きを狙う(50〜100pips、貴金属で$0.50〜1) | 大きな市場スイングを捉える(数百pips) |
| 時間的コミット | 高い、画面に張り付く必要がある | 中程度、分析中心 |
| 市場環境 | 高ボラティリティ・高流動性市場で有効(例:XAUUSDや主要FXペア) | トレンド相場やレンジ拡張相場で有効 |
| 損切り/利確 | タイトなSL(50〜150pips)/小さなTP(40〜100pips) | 広めのSL(200pips以上)/大きなTP(1000pips以上) |
| ポジションサイズ | 通常は大きめ(ターゲットが小さいため) | 通常は小さめ(ターゲットが広いため) |
導入手順
//+------------------------------------------------------------------+ //| Scalps and Swings.mq5 | //| GIT under Copyright 2025, MetaQuotes Ltd. | //| https://www.mql5.com/ja/users/johnhlomohang/ | //+------------------------------------------------------------------+ #property copyright "GIT under Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com/ja/users/johnhlomohang/" #property version "1.00" #property description "Dual-mode EA for Scalping and Swing Trading" #include <Trade/Trade.mqh>
いつも通り、まずはエキスパートアドバイザー(EA)が注文を実行しポジションを管理するために必要な取引ライブラリをインポートします。
//+------------------------------------------------------------------+ //| Input Parameters | //+------------------------------------------------------------------+ enum ENUM_MODE { MODE_SCALP, // Scalping MODE_SWING // Swing Trading }; input ENUM_MODE TradeMode = MODE_SCALP; // Trading Mode input string TradePairs = "XAUUSD,BTCUSD,US100,GBPUSD"; // Trading Pairs (comma separated) input bool UseATR = false; // Use ATR for SL/TP // Scalping Parameters input double LotSize_Scalp = 0.1; // Scalp Lot Size input int StopLoss_Scalp = 50; // Scalp Stop Loss (pips) input int TakeProfit_Scalp = 30; // Scalp Take Profit (pips) input int ScalpTrailingStop = 15; // Scalp Trailing Stop (pips) input ENUM_TIMEFRAMES ScalpTimeframe = PERIOD_M5; // Scalping Timeframe input int Scalp_EMA_Fast = 5; // Scalp Fast EMA input int Scalp_EMA_Slow = 20; // Scalp Slow EMA input int Scalp_RSI_Period = 14; // Scalp RSI Period input int Scalp_RSI_Overbought = 55; // Scalp RSI Overbought input int Scalp_RSI_Oversold = 45; // Scalp RSI Oversold // Swing Trading Parameters input double LotSize_Swing = 0.1; // Swing Lot Size input int StopLoss_Swing = 200; // Swing Stop Loss (pips) input int TakeProfit_Swing = 400; // Swing Take Profit (pips) input int SwingTrailingStop = 100; // Swing Trailing Stop (pips) input ENUM_TIMEFRAMES SwingTimeframe = PERIOD_H4; // Swing Timeframe input int Swing_Lookback = 20; // Swing Lookback Period input double Fib_Level = 0.618; // Fibonacci Retracement Level input bool UseHigherTFConfirmation = true; // Use D1 Confirmation input ENUM_TIMEFRAMES HigherTF = PERIOD_D1; // Higher Timeframe // Risk Management input int MaxOpenPositions = 4; // Max Open Positions per Pair input int MagicNumber = 12345; // Magic Number input int Slippage = 3; // Slippage (points)
まず、スキャルピングとスイングトレードの両方をサポートするマルチモード取引システムの入力パラメータを定義します。最初のセクションではENUM_MODEという列挙型を紹介しており、ユーザーはMODE_SCALPとMODE_SWINGのどちらかを選択できます。この入力により、EAの挙動(短期のデイトレードか、長期のスイングトレードか)を制御します。さらに、TradePairs入力により複数の銘柄(例:XAUUSD、BTCUSD、US100、GBPUSD)を柔軟に指定でき、UseATRオプションを有効にすると、固定のpips値ではなくボラティリティに応じた可変型のストップロス/テイクプロフィットを設定することが可能です。
スキャルピング用のパラメータは、高速・高頻度環境でのEAの挙動を定義します。ここでは、ストップロスおよびテイクプロフィットの距離を小さく設定し、短い時間足(例:M5)を使用します。また、5期間と20期間のEMAに加えて14期間のRSIを組み合わせた反応速度の高い指標を用います。RSIの閾値は55と45に設定されており、微妙なモメンタムの変化を検出できるようにしています。トレーリングストップの値も小さく設定し、日中のボラティリティに柔軟に対応します。これらの設定により、短期間の価格変動を効率的に捉えつつ、長時間の市場ノイズにさらされるリスクを抑えた迅速な取引サイクルを実現します。
一方、スイングトレード用のパラメータはより大きな市場の動きに対応するよう調整されています。EAは、より長期の時間足ボラティリティとトレンド継続を考慮して、ストップロスおよびテイクプロフィットの距離を広めに設定します。直近20本のバーを対象とするルックバック期間やフィボナッチリトレースメント(0.618)を用いて、潜在的な反転のための重要な修正ゾーンを特定します。さらに、上位時間足(通常はD1)での確認をおこなうことで、逆トレンドの取引を避けるためのトレンド検証を追加します。最後に、MaxOpenPositions、MagicNumber、Slippageといったリスク管理入力により、取引数量、識別、注文精度を厳密に制御でき、EAがすべての通貨ペアや市場状況で一貫性と安全性を保つように設計されています。
//+------------------------------------------------------------------+ //| Global Variables | //+------------------------------------------------------------------+ string SymbolList[]; int TotalPairs; datetime LastTickTime = 0; color TextColor = clrWhite; CTrade trade; int handleEmaFast_Scalp, handleEmaSlow_Scalp, handleRsi_Scalp; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Initialize trade object trade.SetExpertMagicNumber(MagicNumber); trade.SetDeviationInPoints(Slippage); // Split trading pairs SplitString(TradePairs, ",", SymbolList); TotalPairs = ArraySize(SymbolList); // Validate symbols for(int i = 0; i < TotalPairs; i++) { if(!SymbolInfoInteger(SymbolList[i], SYMBOL_TRADE_MODE)) { Print("Error: Symbol ", SymbolList[i], " is not available for trading"); return(INIT_FAILED); } } // Create indicator handles for scalping mode handleEmaFast_Scalp = iMA(NULL, ScalpTimeframe, Scalp_EMA_Fast, 0, MODE_EMA, PRICE_CLOSE); if(handleEmaFast_Scalp == INVALID_HANDLE) { Print("Failed to create handle for fast EMA (Scalp)"); return(INIT_FAILED); } handleEmaSlow_Scalp = iMA(NULL, ScalpTimeframe, Scalp_EMA_Slow, 0, MODE_EMA, PRICE_CLOSE); if(handleEmaSlow_Scalp == INVALID_HANDLE) { Print("Failed to create handle for slow EMA (Scalp)"); return(INIT_FAILED); } handleRsi_Scalp = iRSI(NULL, ScalpTimeframe, Scalp_RSI_Period, PRICE_CLOSE); if(handleRsi_Scalp == INVALID_HANDLE) { Print("Failed to create handle for RSI (Scalp)"); return(INIT_FAILED); } Print("EA initialized successfully with ", TotalPairs, " pairs"); Print("Trading Mode: ", EnumToString(TradeMode)); return(INIT_SUCCEEDED); }
次に、EAのグローバル変数と初期化ルーチンを定義します。グローバル変数では、取引銘柄のリスト、ペアの総数、取引実行を扱うCTradeクラスのインスタンスといった主要コンポーネントを宣言します。さらに、スキャルピングモード用のインジケーターハンドル(高速EMA、低速EMA、RSI)も用意されており、後にシグナル生成のためにリアルタイムデータを取得する際に使用されます。LastTickTime変数はティック処理の効率化を目的とし、TextColorはチャート上のテキスト要素(可視化やログ表示用)のデフォルト色を定義します。
OnInit()関数では、EAが取引環境をセットアップします。まず、一意のマジックナンバーとスリッページ許容値をCTradeオブジェクトに割り当て、注文管理の一貫性を確保します。入力文字列TradePairsはカスタム関数SplitString()を用いて配列に分割され、EAがどの銘柄で稼働するかを決定します。各銘柄は取引可能かどうか検証され、有効でない場合は処理を進めません。その後、スキャルピングモード用の高速EMA、低速EMA、RSIの指標ハンドルを作成します。各ハンドルの有効性もチェックされ、無効なインジケーターハンドルでEAが起動することを防ぎます。すべての検証が完了すると、初期化成功メッセージが表示されます。このメッセージには、アクティブなペアの数と選択された取引モードが示され、EAが実行準備完了であることを確認できます。
//+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { Comment(""); // Clear chart comment } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Avoid multiple processing in the same tick if(LastTickTime == iTime(_Symbol, _Period, 0)) return; LastTickTime = iTime(_Symbol, _Period, 0); // Process each trading pair for(int i = 0; i < TotalPairs; i++) { string symbol = SymbolList[i]; if(TradeMode == MODE_SCALP) { ScalpModeHandler(symbol); if(IsNewBar(symbol, ScalpTimeframe)) { ExecuteScalpTrade(symbol); } ManageScalpTrades(symbol); } else if(TradeMode == MODE_SWING) { if(SwingSignal(symbol)) { if(IsNewBar(symbol, SwingTimeframe)) { ExecuteSwingTrade(symbol); } } ManageSwingTrades(symbol); } } // Update dashboard UpdateDashboard(); } //+------------------------------------------------------------------+ //| Check if new bar formed | //+------------------------------------------------------------------+ bool IsNewBar(string symbol, ENUM_TIMEFRAMES timeframe) { static datetime lastBarTime = 0; datetime currentBarTime = iTime(symbol, timeframe, 0); if(currentBarTime != lastBarTime) { lastBarTime = currentBarTime; return true; } return false; }
ご存知の通り、OnTick()関数はEAのコア実行ループとして機能し、新しいティックが到着するたびに呼び出されます。まず、現在のティックの時刻が前回処理されたティックと同じかどうかを確認し、同じティック内での冗長な処理を防ぎます。その後、EAはSymbolListに定義されたすべての取引ペアを順番に処理し、選択されたTradeModeに応じてスキャルピングまたはスイングトレードのロジックを動的に扱います。スキャルピングモードでは、ScalpModeHandler()を呼び出してシグナルを評価し、新しいバーで取引を実行し、既存のスキャルプポジションを管理します。スイングモードでは、有効なスイングシグナルを検出し、適切に取引を配置し、ManageSwingTrades()を通じて進行中のポジションを更新します。最後に、関数は画面上のダッシュボードを更新し、リアルタイムで取引状況やパフォーマンスを表示します。これにより、EAはすべてのアクティブなペアにおいて効率的かつ適応的に動作できるようになります。
//+------------------------------------------------------------------+ //| Scalping Signal Function | //+------------------------------------------------------------------+ void ScalpModeHandler(string symbol) { // Define arrays to hold indicator values double emaFastArr[2], emaSlowArr[2], rsiArr[2]; // Copy values: current and previous if(CopyBuffer(handleEmaFast_Scalp, 0, 0, 2, emaFastArr) < 2) return; if(CopyBuffer(handleEmaSlow_Scalp, 0, 0, 2, emaSlowArr) < 2) return; if(CopyBuffer(handleRsi_Scalp, 0, 0, 2, rsiArr) < 2) return; // Assign named values double emaFastCurr = emaFastArr[0]; double emaFastPrev = emaFastArr[1]; double emaSlowCurr = emaSlowArr[0]; double emaSlowPrev = emaSlowArr[1]; double rsiCurr = rsiArr[0]; // Validate (avoid zero or invalid) if(emaFastCurr == 0 || emaSlowCurr == 0 || rsiCurr == 0) return; // Check open positions for this symbol if(CountOpenPositions(symbol) >= MaxOpenPositions) return; // BUY signal condition if(emaFastCurr > emaSlowCurr && emaFastPrev <= emaSlowPrev && rsiCurr > Scalp_RSI_Overbought) { ExecuteAdaptiveTrade(ORDER_TYPE_BUY, symbol, LotSize_Scalp); Print("Scalp BUY Signal executed for ", symbol); } // SELL signal condition else if(emaFastCurr < emaSlowCurr && emaFastPrev >= emaSlowPrev && rsiCurr < Scalp_RSI_Oversold) { ExecuteAdaptiveTrade(ORDER_TYPE_SELL, symbol, LotSize_Scalp); Print("Scalp SELL Signal executed for ", symbol); } } //+------------------------------------------------------------------+ //| Swing Trading Signal Function | //+------------------------------------------------------------------+ bool SwingSignal(string symbol) { int swingHighBar = iHighest(symbol, SwingTimeframe, MODE_HIGH, Swing_Lookback, 1); int swingLowBar = iLowest(symbol, SwingTimeframe, MODE_LOW, Swing_Lookback, 1); if(swingHighBar == -1 || swingLowBar == -1) return false; double swingHigh = iHigh(symbol, SwingTimeframe, swingHighBar); double swingLow = iLow(symbol, SwingTimeframe, swingLowBar); double currentClose = iClose(symbol, SwingTimeframe, 0); double range = swingHigh - swingLow; if(range == 0) return false; double fib618_Up = swingHigh - Fib_Level * range; double fib618_Down = swingLow + Fib_Level * range; bool higherTFBullish = true; bool higherTFBearish = true; if(UseHigherTFConfirmation) { int handleEMA = iMA(symbol, HigherTF, 20, 0, MODE_EMA, PRICE_CLOSE); if(handleEMA == INVALID_HANDLE) return false; double emaVal[1]; if(CopyBuffer(handleEMA, 0, 0, 1, emaVal) < 1) return false; double htEMA20 = emaVal[0]; double htClose = iClose(symbol, HigherTF, 0); higherTFBullish = htClose > htEMA20; higherTFBearish = htClose < htEMA20; } // --- Buy Signal if(currentClose <= fib618_Down && currentClose > swingLow && higherTFBullish) return true; // --- Sell Signal if(currentClose >= fib618_Up && currentClose < swingHigh && higherTFBearish) return true; return false; }
ScalpModeHandler()関数は、スキャルピングモードにおける短期売買シグナルの生成と実行を担当します。事前に初期化されたインジケーターハンドルからCopyBuffer()を用いて、高速EMA、低速EMA、RSIの最新値と前回値を取得します。これらの値を使用して、クロスオーバーやモメンタムの状態を検出し、スキャルプトレードのシグナルを生成します。具体的には、買いシグナルは、高速EMAが低速EMAを上抜けし、RSIが買われすぎ閾値を超えた場合に発生し、上昇モメンタムを示唆します。逆に、売りシグナルは、高速EMAが低速EMAを下抜けし、RSIが売られすぎ閾値を下回った場合に発生し、下降モメンタムを示唆します。取引を実行する前に、関数は指標データの有効性を確認し、対象銘柄の最大ポジション数を超えていないことをチェックします。これにより、効率的で適切に管理された取引運用が可能になります。
SwingSignal()関数は、上位時間足で市場の大きな反転やトレンド継続を特定します。指定されたルックバック期間内の最新のスイングハイとスイングローを取得し、取引レンジを算出します。さらに、フィボナッチリトレースメントレベルを計算して、価格の反応が起こりやすいゾーンを特定します。この情報を用いて、現在の市場価格が反転の可能性を示す主要なリトレースメントレベルに一致するかを確認します。上位時間足確認が有効になっている場合、追加のEMAフィルタにより、上位時間足のトレンドに沿った取引のみが実行されます。関数は、有効な買いまたは売りセットアップが検出された場合はtrue、そうでなければfalseを返します。このように、短期(スキャルピング)と長期(スイング)のロジックを分離することで、EAは市場状況に応じて戦略を動的に適応させることが可能になります。
//+------------------------------------------------------------------+ //| Execute Scalp Trade | //+------------------------------------------------------------------+ void ExecuteScalpTrade(string symbol) { if(CountOpenPositions(symbol) >= MaxOpenPositions) return; int handleEmaFast = iMA(symbol, ScalpTimeframe, Scalp_EMA_Fast, 0, MODE_EMA, PRICE_CLOSE); int handleEmaSlow = iMA(symbol, ScalpTimeframe, Scalp_EMA_Slow, 0, MODE_EMA, PRICE_CLOSE); int handleRSI = iRSI(symbol, ScalpTimeframe, Scalp_RSI_Period, PRICE_CLOSE); double emaFast[1], emaSlow[1], rsi[1]; if(CopyBuffer(handleEmaFast, 0, 0, 1, emaFast) < 1) return; if(CopyBuffer(handleEmaSlow, 0, 0, 1, emaSlow) < 1) return; if(CopyBuffer(handleRSI, 0, 0, 1, rsi) < 1) return; double emaF = emaFast[0]; double emaS = emaSlow[0]; double rsiV = rsi[0]; if(emaF > emaS && rsiV > Scalp_RSI_Overbought) ExecuteTrade(ORDER_TYPE_BUY, symbol, LotSize_Scalp, StopLoss_Scalp, TakeProfit_Scalp); else if(emaF < emaS && rsiV < Scalp_RSI_Oversold) ExecuteTrade(ORDER_TYPE_SELL, symbol, LotSize_Scalp, StopLoss_Scalp, TakeProfit_Scalp); } //+------------------------------------------------------------------+ //| Execute Swing Trade | //+------------------------------------------------------------------+ void ExecuteSwingTrade(string symbol) { if(CountOpenPositions(symbol) >= MaxOpenPositions) return; // Determine trade direction (simplified logic) int swingHighBar = iHighest(symbol, SwingTimeframe, MODE_HIGH, Swing_Lookback, 1); int swingLowBar = iLowest(symbol, SwingTimeframe, MODE_LOW, Swing_Lookback, 1); if(swingHighBar != -1 && swingLowBar != -1) { double swingHigh = iHigh(symbol, SwingTimeframe, swingHighBar); double swingLow = iLow(symbol, SwingTimeframe, swingLowBar); double currentClose = iClose(symbol, SwingTimeframe, 0); double range = swingHigh - swingLow; double fib618_Down = swingLow + Fib_Level * range; double fib618_Up = swingHigh - Fib_Level * range; if(currentClose <= fib618_Down && currentClose > swingLow) { ExecuteTrade(ORDER_TYPE_BUY, symbol, LotSize_Swing, StopLoss_Swing, TakeProfit_Swing); } else if(currentClose >= fib618_Up && currentClose < swingHigh) { ExecuteTrade(ORDER_TYPE_SELL, symbol, LotSize_Swing, StopLoss_Swing, TakeProfit_Swing); } } } //+------------------------------------------------------------------+ //| Execute trade with dynamic stop/TP adaption per symbol | //+------------------------------------------------------------------+ void ExecuteTrade(ENUM_ORDER_TYPE tradeType, string symbol, double lotSize, int stopLossPips, int takeProfitPips) { //--- Symbol info double point = SymbolInfoDouble(symbol, SYMBOL_POINT); int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS); double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE); double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE); double ask = SymbolInfoDouble(symbol, SYMBOL_ASK); double bid = SymbolInfoDouble(symbol, SYMBOL_BID); double price = (tradeType == ORDER_TYPE_BUY) ? ask : bid; //--- Detect pip size automatically (handles forex, gold, crypto, indices) double pipSize; if(StringFind(symbol, "JPY") != -1) // JPY pairs (2/3 digits) pipSize = (digits == 3) ? point * 10 : point; else if(StringFind(symbol, "XAU") != -1 || StringFind(symbol, "GOLD") != -1) // Metals pipSize = 0.10; else if(StringFind(symbol, "BTC") != -1 || StringFind(symbol, "ETH") != -1) // Cryptos pipSize = point * 100.0; else if(StringFind(symbol, "US") != -1 && digits <= 2) // Indices pipSize = point; else pipSize = (digits == 3 || digits == 5) ? point * 10 : point; // Default Forex //--- Convert SL/TP from pips to price distances double sl_distance = stopLossPips * pipSize; double tp_distance = takeProfitPips * pipSize; //--- Determine broker minimum stop levels double minStopPoints = 0.0; if(SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL) > 0) minStopPoints = SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL); else if(SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL) > 0) minStopPoints = SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL); else minStopPoints = 30; // fallback default (points) double minStop = minStopPoints * point; //--- Ensure SL/TP distances are greater than min stop level if(sl_distance < minStop) sl_distance = minStop; if(tp_distance < minStop) tp_distance = minStop; //--- Calculate final SL/TP prices double sl = (tradeType == ORDER_TYPE_BUY) ? price - sl_distance : price + sl_distance; double tp = (tradeType == ORDER_TYPE_BUY) ? price + tp_distance : price - tp_distance; //--- Normalize prices sl = NormalizeDouble(sl, digits); tp = NormalizeDouble(tp, digits); price = NormalizeDouble(price, digits); //--- Safety validation (correct SL/TP relation) if((tradeType == ORDER_TYPE_BUY && (sl >= price || tp <= price)) || (tradeType == ORDER_TYPE_SELL && (sl <= price || tp >= price))) { Print("Invalid SL/TP detected for ", symbol, " — auto-adjusting..."); if(tradeType == ORDER_TYPE_BUY) { sl = NormalizeDouble(price - minStop, digits); tp = NormalizeDouble(price + minStop * 2, digits); } else { sl = NormalizeDouble(price + minStop, digits); tp = NormalizeDouble(price - minStop * 2, digits); } } //--- Try executing trade if(trade.PositionOpen(symbol, tradeType, lotSize, price, sl, tp, "Adaptive Multi-Pair EA")) { PrintFormat("%s opened on %s | Lot: %.2f | SL: %.5f | TP: %.5f | TickValue: %.2f", EnumToString(tradeType), symbol, lotSize, sl, tp, tickValue); } else { int err = GetLastError(); PrintFormat("Failed to open %s on %s | Error %d: %s", EnumToString(tradeType), symbol, err, err); ResetLastError(); } }ExecuteScalpTrade()関数とExecuteSwingTrade()関数は、2つの異なる実行ロジックを定義しています。1つは短期の精密エントリー用、もう1つは高時間足スイング用のセットアップ用です。スキャルピングのロジックは、高いモメンタム環境での迅速なエントリーに焦点を当てています。高速EMAと低速EMA、RSIの閾値を用いて短期的なトレンドを検出し、高速EMAが低速EMAをクロスし、RSIが買われすぎ・売られすぎ条件に到達した瞬間に即座にトレードを実行します。これにより、ボラティリティの高い値動きに迅速に対応できます。一方、スイングトレードの関数は、より大きな市場構造を特定します。直近のスイングハイとスイングローを分析し、フィボナッチリトレースメントレベルを計算して、リトレースメントに基づく最適なエントリーゾーンを特定します。これにより、EAは中期的な反転やトレンド継続を広範なトレンド内で捉えることが可能です。
ExecuteTrade()関数は、EAのコア実行エンジンとして機能し、各市場銘柄に応じてピップサイズを計算し、ブローカーの制約を確認し、価格を正規化して安全に取引を配置できるようにします。ストップロス(SL)やテイクプロフィット(TP)のレベルも、銘柄の特性(FX、ゴールド、暗号資産、株価指数など)に応じて動的に調整され、各取引がブローカーの最小ストップレベルを尊重しつつ論理的なSL/TP距離を維持できるようになっています。これらの機能により、ExecuteScalpTrade()、ExecuteSwingTrade()、ExecuteTrade()の3つの関数が一体となり、高速および低速の市場環境の両方に適応可能な堅牢な実行システムを形成し、複数の資産クラスにおいて精度、安全性、一貫性の高い取引を実現します。
//+------------------------------------------------------------------+ //| Execute trade with adaptive SL/TP by symbol type | //+------------------------------------------------------------------+ void ExecuteAdaptiveTrade(ENUM_ORDER_TYPE type, string symbol, double lotSize) { double point = SymbolInfoDouble(symbol, SYMBOL_POINT); int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS); double ask = SymbolInfoDouble(symbol, SYMBOL_ASK); double bid = SymbolInfoDouble(symbol, SYMBOL_BID); double price = (type == ORDER_TYPE_BUY) ? ask : bid; //--- Determine adaptive pip scale per asset double pipScale; if(StringFind(symbol, "XAU") != -1 || StringFind(symbol, "GOLD") != -1) pipScale = 1.0; // Gold → 1 dollar movement = 1 pip else if(StringFind(symbol, "BTC") != -1) pipScale = 50.0; // Crypto → 50-point unit for volatility else if(StringFind(symbol, "US") != -1 && digits <= 2) pipScale = 10.0; // Indices (US100, US30) else if(StringFind(symbol, "JPY") != -1) pipScale = 0.1; // Yen pairs else pipScale = 0.0001; // Standard Forex ENUM_TIMEFRAMES tf = ScalpTimeframe; //--- Calculate SL/TP dynamically double atr = iATR(symbol, tf, 14); if(atr <= 0) atr = pipScale * 30; // Fallback default double slDistance = atr * 1.5; // SL = 1.5x ATR double tpDistance = atr * 3.0; // TP = 3x ATR //--- Validate broker min stop distance double minStop = 0; if(SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL) > 0) minStop = SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL) * point; else if(SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL) > 0) minStop = SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL) * point; else minStop = atr * 0.5; if(slDistance < minStop) slDistance = minStop; if(tpDistance < minStop) tpDistance = minStop * 2; //--- Final price calculation double sl = (type == ORDER_TYPE_BUY) ? price - slDistance : price + slDistance; double tp = (type == ORDER_TYPE_BUY) ? price + tpDistance : price - tpDistance; sl = NormalizeDouble(sl, digits); tp = NormalizeDouble(tp, digits); //--- Trade execution if(trade.PositionOpen(symbol, type, lotSize, price, sl, tp, "Scalp-Mode")) { PrintFormat("%s %s | Lot: %.2f | SL: %.5f | TP: %.5f | ATR: %.5f", EnumToString(type), symbol, lotSize, sl, tp, atr); } else { int err = GetLastError(); PrintFormat("Trade failed on %s | Error %d: %s", symbol, err, GetLastError()); ResetLastError(); } } //+------------------------------------------------------------------+ //| Dashboard Functions | //+------------------------------------------------------------------+ void UpdateDashboard() { string dashboardText = ""; string newLine = "\n"; dashboardText += "=== MULTI-PAIR TRADING EA ===" + newLine; dashboardText += "Trading Mode: " + EnumToString(TradeMode) + newLine; dashboardText += "Active Pairs: " + IntegerToString(TotalPairs) + newLine; dashboardText += "Account Balance: " + DoubleToString(AccountInfoDouble(ACCOUNT_BALANCE), 2) + newLine; dashboardText += "=================================" + newLine; // Show status for each pair for(int i = 0; i < TotalPairs; i++) { string symbol = SymbolList[i]; int positions = CountOpenPositions(symbol); dashboardText += symbol + ":" + newLine; dashboardText += " Positions: " + IntegerToString(positions) + newLine; // Add signal status with detailed info if(TradeMode == MODE_SCALP) { //bool signal = ScalpModeHandler(symbol); double emaFast = iMA(symbol, ScalpTimeframe, Scalp_EMA_Fast, 0, MODE_EMA, PRICE_CLOSE); double emaSlow = iMA(symbol, ScalpTimeframe, Scalp_EMA_Slow, 0, MODE_EMA, PRICE_CLOSE); double rsi = iRSI(symbol, ScalpTimeframe, Scalp_RSI_Period, PRICE_CLOSE); //dashboardText += " Scalp Signal: " + (signal ? "ACTIVE" : "INACTIVE") + newLine; dashboardText += " EMA Fast: " + DoubleToString(emaFast, 5) + newLine; dashboardText += " EMA Slow: " + DoubleToString(emaSlow, 5) + newLine; dashboardText += " RSI: " + DoubleToString(rsi, 1) + newLine; } else { bool signal = SwingSignal(symbol); dashboardText += " Swing Signal: " + (signal ? "ACTIVE" : "INACTIVE") + newLine; } dashboardText += newLine; } Comment(dashboardText); } //+------------------------------------------------------------------+
ExecuteAdaptiveTrade()関数は、各資産の独自のボラティリティプロファイルに基づいてストップロス(SL)およびテイクプロフィット(TP)の距離を動的に調整するインテリジェントな取引実行メカニズムを導入します。対象銘柄がゴールド、暗号資産、株価指数、JPYペア、または標準FXであるかを判別し、それぞれに適したピップスケールを適用したうえで、ATR (Average True Range)インジケーターを用いて適応型SL/TPレベルを計算します。これにより、ボラティリティの高い市場でトレードがタイトになりすぎたり、安定した市場で広すぎたりすることを防ぎ、リスクとリワードのバランスをリアルタイムで最適化します。関数にはブローカーの最小ストップ距離の保護や自動補正メカニズムも組み込まれており、マルチ資産環境においても正確かつボラティリティに対応した取引配置が可能です。
UpdateDashboard()関数は、適応型トレードロジックを補完し、リアルタイムでのパフォーマンスの透明性を提供します。各取引ペアのアクティブポジション、主要なテクニカル指標(EMA値、RSI、またはスイングシグナル)、およびEAの全体的な動作モードを表示し、トレーダーがチャート上から直接意思決定の流れやシステムの状態を視覚的に監視できるようにします。これらのコンポーネントにより、ボラティリティに応じた適応型実行とライブダッシュボードによる監視がシームレスに連携し、トレーダーは複数ペアを自信を持って効率的に管理し、さまざまな市場状況下でのシステム挙動を明確に理解しながら運用できる環境が整います。
バックテスト結果
スキャルピングパラメータ| 入力変数 | パラメータ |
|---|---|
| SL/TPにATRを使用 | True |
| ロットサイズ | 0.35 |
| SL(pips単位) | 950 |
| TP(pips単位) | 30 |
| トレーリングストップ | 15 |
| 時間足 | 3分 |
| 高速EMA | 20 |
| 低速EMA | 50 |
| RSI期間 | 14 |
| RSI買われ過ぎ | 55 |
| RSI売られ過ぎ | 45 |


スイングトレードのパラメータ
| 入力変数 | パラメータ |
|---|---|
| ロットサイズ | 0.45 |
| SL(pips単位) | 200 |
| TP(pips単位) | 1800 |
| トレーリングストップ(pips単位) | 100 |
| 時間足 | 4時間 |
| ルックバック期間 | 20 |
| フィボナッチリトレースメントレベル | 0.618 |
| D1確認を使用 | true |
| 上位時間足 | 1日 |


結論
スキャルピングとスイングトレードの両方に切り替え可能で、ゴールド、FX、暗号資産、株価指数などのさまざまな資産に適応できるダイナミックマルチペアEAを開発しました。このシステムは、EMAクロスオーバー、RSIフィルタ、フィボナッチリトレースメント、ATRベースのボラティリティ測定などのテクニカルモデルを統合し、取引方向とポジション管理をインテリジェントに判断します。適応型SL/TPレベルと堅牢なマルチシンボル構造を実装することで、EAはリスク管理を最適化し、効率的な実行を実現し、多様な市場条件において一貫したロジックを適用できます。これにより、短期スキャルプでも長期スイングセットアップでも最適な運用が可能となります。
結論として、このフレームワークはトレーダーに市場のボラティリティ、銘柄特性、取引目標に動的に適応する多機能かつ自動化された取引ソリューションを提供します。ユーザーは1つのEAで積極的なスキャルピングと忍耐強いスイング戦略の両方をシームレスに運用でき、手動介入を最小化できます。この統一設計により、実行精度とリスク管理が向上し、市場適応力が強化されます。これは、複数の資産クラスにおいて一貫性と拡張性を求めるトレーダーにとって大きな利点となります。
MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/19989
警告: これらの資料についてのすべての権利はMetaQuotes Ltd.が保有しています。これらの資料の全部または一部の複製や再プリントは禁じられています。
この記事はサイトのユーザーによって執筆されたものであり、著者の個人的な見解を反映しています。MetaQuotes Ltdは、提示された情報の正確性や、記載されているソリューション、戦略、または推奨事項の使用によって生じたいかなる結果についても責任を負いません。
古典的な戦略を再構築する(第18回):ローソク足パターンの探索
MQL5における市場ポジショニング戦略の体系(第2回): Nvidia向けマルチパターンのビット単位学習
MQL5での取引戦略の自動化(第39回):信頼区間とダッシュボードを備えた統計的平均回帰
MQL5における二変量コピュラ(第2回):MQL5でのアルキメデスコピュラの実装
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索
スキャルピングの画像に単なる誤植があると思います:
ダウンロードしましたが、バックテストに失敗しました。
入力記号に注意してください。例えば、"EURUSD.m "は接尾辞".m "を持っています。もし、あなたのブローカーのシンボルに接尾辞や接頭辞がある場合は、入力シンボルに入力してください。
こんにちは、
デモMt5で実行しましたが、バックテストは失敗しました。
このEAは素晴らしい!このEAは素晴らしい!!!!これからもよろしくお願いします。一つ質問があります!バックテストはどのペアですか?
フィードバックありがとう。
バックテストはデフォルトの入力シンボル設定で行っています:
"XAUUSD,BTCUSD,US100,GBPUSD"